From 96780a1b0ffad18837f69a1b6739fa950cb7ceba Mon Sep 17 00:00:00 2001 From: samay2504 Date: Sun, 18 Jan 2026 00:28:06 +0530 Subject: [PATCH 1/2] Deprecate shape_index() in favor of radii_ratio() to resolve #248 - shape_index() is identical to radii_ratio() - Added deprecation warning to shape_index() with clear migration path - Updated radii_ratio() docstring to clarify it is also known as Schumm's shape index - Added comprehensive test to verify deprecation warning is raised - Test confirms shape_index() and radii_ratio() produce identical results - Formatted with ruff and black Closes #248 --- esda/shape.py | 33 ++++++++++++++++++++++++++++++--- esda/tests/test_shape.py | 18 ++++++++++++++++-- 2 files changed, 46 insertions(+), 5 deletions(-) diff --git a/esda/shape.py b/esda/shape.py index 1a620447..9d7e5c61 100644 --- a/esda/shape.py +++ b/esda/shape.py @@ -1,4 +1,5 @@ import contextlib +import warnings import numpy import pandas @@ -198,7 +199,23 @@ def radii_ratio(collection): """ The Flaherty & Crumplin (1992) index, OS_3 in :cite:`altman1998Districting`. + Also known as Schumm's shape index (Schumm (1956) in MacEachren 1985). + The ratio of the radius of the equi-areal circle to the radius of the MBC + + .. math:: + {\\sqrt{{A} \\over {\\pi}}} \\over {R} + + where :math:`A` is the area and :math:`R` is the radius of the minimum bounding + circle. + + Notes + ----- + Implementation follows :cite:`maceachren1985compactness`. + + See Also + -------- + shape_index : Deprecated alias for this function. """ ga = _cast(collection) r_eac = numpy.sqrt(shapely.area(ga) / numpy.pi) @@ -350,7 +367,12 @@ def rectangularity(collection): def shape_index(collection): """ - Schumm’s shape index (Schumm (1956) in MacEachren 1985) + .. deprecated:: 2.5.0 + ``shape_index`` is deprecated and will be removed in version 3.0.0. + Use ``radii_ratio`` instead, which computes the same Schumm's shape index + (Schumm (1956) in MacEachren 1985). + + Schumm's shape index (Schumm (1956) in MacEachren 1985) .. math:: {\\sqrt{{A} \\over {\\pi}}} \\over {R} @@ -363,8 +385,13 @@ def shape_index(collection): Implementation follows :cite:`maceachren1985compactness`. """ - ga = _cast(collection) - return numpy.sqrt(shapely.area(ga) / numpy.pi) / shapely.minimum_bounding_radius(ga) + warnings.warn( + "shape_index is deprecated and will be removed in version 3.0.0. " + "Use radii_ratio instead, which computes the same index.", + DeprecationWarning, + stacklevel=2, + ) + return radii_ratio(collection) def equivalent_rectangular_index(collection): diff --git a/esda/tests/test_shape.py b/esda/tests/test_shape.py index d049aa2a..f66686e2 100644 --- a/esda/tests/test_shape.py +++ b/esda/tests/test_shape.py @@ -1,3 +1,5 @@ +import warnings + import geopandas import numpy import pytest @@ -176,8 +178,20 @@ def test_rectangularity(): def test_shape_index(): - observed = esda.shape.shape_index(shape) - testing.assert_allclose(observed, 0.659366, atol=ATOL) + """Test that shape_index is deprecated and returns same value as radii_ratio.""" + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter("always") + observed = esda.shape.shape_index(shape) + + # Check that deprecation warning was raised + assert len(w) == 1 + assert issubclass(w[0].category, DeprecationWarning) + assert "deprecated" in str(w[0].message).lower() + assert "radii_ratio" in str(w[0].message) + + # Check that result matches radii_ratio + expected = esda.shape.radii_ratio(shape) + testing.assert_allclose(observed, expected, atol=ATOL) def test_equivalent_rectangular_index(): From 9200a4977f3c09848c139052a47221b0d5390b90 Mon Sep 17 00:00:00 2001 From: samay2504 Date: Sun, 18 Jan 2026 23:18:44 +0530 Subject: [PATCH 2/2] Issue #248: Apply maintainer feedback - use pytest.warns, update deprecation messages to 'future', add func cross-references --- esda/shape.py | 6 +++--- esda/tests/test_shape.py | 9 +-------- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/esda/shape.py b/esda/shape.py index 9d7e5c61..27d5ff9b 100644 --- a/esda/shape.py +++ b/esda/shape.py @@ -368,8 +368,8 @@ def rectangularity(collection): def shape_index(collection): """ .. deprecated:: 2.5.0 - ``shape_index`` is deprecated and will be removed in version 3.0.0. - Use ``radii_ratio`` instead, which computes the same Schumm's shape index + ``shape_index`` is deprecated and will be removed in future. + Use :func:`radii_ratio` instead, which computes the same Schumm's shape index (Schumm (1956) in MacEachren 1985). Schumm's shape index (Schumm (1956) in MacEachren 1985) @@ -386,7 +386,7 @@ def shape_index(collection): """ warnings.warn( - "shape_index is deprecated and will be removed in version 3.0.0. " + "shape_index is deprecated and will be removed in future. " "Use radii_ratio instead, which computes the same index.", DeprecationWarning, stacklevel=2, diff --git a/esda/tests/test_shape.py b/esda/tests/test_shape.py index f66686e2..4c169bdd 100644 --- a/esda/tests/test_shape.py +++ b/esda/tests/test_shape.py @@ -179,16 +179,9 @@ def test_rectangularity(): def test_shape_index(): """Test that shape_index is deprecated and returns same value as radii_ratio.""" - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter("always") + with pytest.warns(DeprecationWarning, match="deprecated"): observed = esda.shape.shape_index(shape) - # Check that deprecation warning was raised - assert len(w) == 1 - assert issubclass(w[0].category, DeprecationWarning) - assert "deprecated" in str(w[0].message).lower() - assert "radii_ratio" in str(w[0].message) - # Check that result matches radii_ratio expected = esda.shape.radii_ratio(shape) testing.assert_allclose(observed, expected, atol=ATOL)