diff --git a/django/contrib/gis/geos/prepared.py b/django/contrib/gis/geos/prepared.py index a6a205da5ee..d5b531bb430 100644 --- a/django/contrib/gis/geos/prepared.py +++ b/django/contrib/gis/geos/prepared.py @@ -12,6 +12,10 @@ class PreparedGeometry(GEOSBase): ptr_type = capi.PREPGEOM_PTR def __init__(self, geom): + # Keeping a reference to the original geometry object to prevent it + # from being garbage collected which could then crash the prepared one + # See #21662 + self._base_geom = geom if not isinstance(geom, GEOSGeometry): raise TypeError self.ptr = capi.geos_prepare(geom.ptr) diff --git a/django/contrib/gis/geos/tests/test_geos.py b/django/contrib/gis/geos/tests/test_geos.py index 3f0ce0652b7..9ce7e0d73d8 100644 --- a/django/contrib/gis/geos/tests/test_geos.py +++ b/django/contrib/gis/geos/tests/test_geos.py @@ -1046,6 +1046,10 @@ class GEOSTest(unittest.TestCase, TestDataMixin): self.assertEqual(mpoly.intersects(pnt), prep.intersects(pnt)) self.assertEqual(c, prep.covers(pnt)) + # Original geometry deletion should not crash the prepared one (#21662) + del mpoly + self.assertTrue(prep.covers(Point(5, 5))) + def test_line_merge(self): "Testing line merge support" ref_geoms = (fromstr('LINESTRING(1 1, 1 1, 3 3)'),