Blob Blame History Raw
From 395f5a8eb8c292c82ca072fabdc3b7e8a16b565e Mon Sep 17 00:00:00 2001
From: "Benjamin A. Beasley" <code@musicinmybrain.net>
Date: Wed, 22 Nov 2023 12:15:45 -0500
Subject: [PATCH 1/2] Adjust tests for docstring indent stripping in Python
 3.13

Fixes #1937.
---
 shapely/tests/test_misc.py | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/shapely/tests/test_misc.py b/shapely/tests/test_misc.py
index 027b1a2..02d6eaf 100644
--- a/shapely/tests/test_misc.py
+++ b/shapely/tests/test_misc.py
@@ -1,5 +1,6 @@
 import os
 import sys
+from inspect import cleandoc
 from itertools import chain
 from string import ascii_letters, digits
 from unittest import mock
@@ -83,13 +84,22 @@ class SomeClass:
         """
 
 
-expected_docstring = """Docstring that will be mocked.
+def expected_docstring(**kwds):
+    doc = """Docstring that will be mocked.
 {indent}A multiline.
 
-{indent}.. note:: 'func' requires at least GEOS {version}.
+{indent}{extra_indent}.. note:: 'func' requires at least GEOS {version}.
 
 {indent}Some description.
 {indent}"""
+    if sys.version_info[:2] >= (3, 13):
+        # There are subtle differences between inspect.cleandoc() and
+        # _PyCompile_CleanDoc(). Most significantly, the latter does not remove
+        # leading or trailing blank lines. The extra_indent is required because
+        # the algorithm in shapely.decorators.requires_geos assumes a minimum
+        # indent of two spaces.
+        return cleandoc(doc.format(extra_indent="  ", **kwds)) + "\n"
+    return doc.format(extra_indent="", **kwds)
 
 
 @pytest.mark.parametrize("version", ["3.7.0", "3.7.1", "3.6.2"])
@@ -104,7 +114,7 @@ def test_requires_geos_not_ok(version, mocked_geos_version):
     with pytest.raises(shapely.errors.UnsupportedGEOSVersionError):
         wrapped()
 
-    assert wrapped.__doc__ == expected_docstring.format(version=version, indent=" " * 4)
+    assert wrapped.__doc__ == expected_docstring(version=version, indent=" " * 4)
 
 
 @pytest.mark.parametrize("version", ["3.6.0", "3.8.0"])
@@ -112,7 +122,7 @@ def test_requires_geos_doc_build(version, mocked_geos_version, sphinx_doc_build)
     """The requires_geos decorator always adapts the docstring."""
     wrapped = requires_geos(version)(func)
 
-    assert wrapped.__doc__ == expected_docstring.format(version=version, indent=" " * 4)
+    assert wrapped.__doc__ == expected_docstring(version=version, indent=" " * 4)
 
 
 @pytest.mark.parametrize("version", ["3.6.0", "3.8.0"])
@@ -120,7 +130,7 @@ def test_requires_geos_method(version, mocked_geos_version, sphinx_doc_build):
     """The requires_geos decorator adjusts methods docstrings correctly"""
     wrapped = requires_geos(version)(SomeClass.func)
 
-    assert wrapped.__doc__ == expected_docstring.format(version=version, indent=" " * 8)
+    assert wrapped.__doc__ == expected_docstring(version=version, indent=" " * 8)
 
 
 @multithreading_enabled
-- 
2.42.0


From 3ed91a4a246a603c23a78bec77eb54b3a30ede54 Mon Sep 17 00:00:00 2001
From: "Benjamin A. Beasley" <code@musicinmybrain.net>
Date: Sun, 26 Nov 2023 08:13:07 -0500
Subject: [PATCH 2/2] =?UTF-8?q?In=20require=5Fgeos=20decorator,=20don?=
 =?UTF-8?q?=E2=80=99t=20assume=20a=20minimum=20indent?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This fixes “extra” indentation before the GEOS version note in Python
3.13, where the compiler strips indentation from docstrings.
---
 shapely/decorators.py      |  2 +-
 shapely/tests/test_misc.py | 14 +++++++-------
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/shapely/decorators.py b/shapely/decorators.py
index a8dbac7..39a436d 100644
--- a/shapely/decorators.py
+++ b/shapely/decorators.py
@@ -39,7 +39,7 @@ class requires_geos:
             # Insert the message at the first double newline
             position = doc.find("\n\n") + 2
             # Figure out the indentation level
-            indent = 2
+            indent = 0
             while True:
                 if doc[position + indent] == " ":
                     indent += 1
diff --git a/shapely/tests/test_misc.py b/shapely/tests/test_misc.py
index 02d6eaf..5eb62d4 100644
--- a/shapely/tests/test_misc.py
+++ b/shapely/tests/test_misc.py
@@ -88,18 +88,18 @@ def expected_docstring(**kwds):
     doc = """Docstring that will be mocked.
 {indent}A multiline.
 
-{indent}{extra_indent}.. note:: 'func' requires at least GEOS {version}.
+{indent}.. note:: 'func' requires at least GEOS {version}.
 
 {indent}Some description.
-{indent}"""
+{indent}""".format(
+        **kwds
+    )
     if sys.version_info[:2] >= (3, 13):
         # There are subtle differences between inspect.cleandoc() and
         # _PyCompile_CleanDoc(). Most significantly, the latter does not remove
-        # leading or trailing blank lines. The extra_indent is required because
-        # the algorithm in shapely.decorators.requires_geos assumes a minimum
-        # indent of two spaces.
-        return cleandoc(doc.format(extra_indent="  ", **kwds)) + "\n"
-    return doc.format(extra_indent="", **kwds)
+        # leading or trailing blank lines.
+        return cleandoc(doc) + "\n"
+    return doc
 
 
 @pytest.mark.parametrize("version", ["3.7.0", "3.7.1", "3.6.2"])
-- 
2.42.0