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