]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- Fixed a leak which would occur in the unsupported and highly
authorMike Bayer <mike_mp@zzzcomputing.com>
Thu, 13 Nov 2014 18:17:38 +0000 (13:17 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Thu, 13 Nov 2014 18:18:03 +0000 (13:18 -0500)
non-recommended use case of replacing a relationship on a fixed
mapped class many times, referring to an arbitrarily growing number of
target mappers.  A warning is emitted when the old relationship is
replaced, however if the mapping were already used for querying, the
old relationship would still be referenced within some registries.
fixes #3251

doc/build/changelog/changelog_09.rst
lib/sqlalchemy/orm/mapper.py
test/aaa_profiling/test_memusage.py

index 66a7da8dab30514e0c8872b76de912e30e75a054..abf564875da36bd6bfa7c6a7d7af6cab4f7eea07 100644 (file)
 .. changelog::
     :version: 0.9.9
 
+    .. change::
+        :tags: bug, orm
+        :versions: 1.0.0
+        :tickets: 3251
+
+        Fixed a leak which would occur in the unsupported and highly
+        non-recommended use case of replacing a relationship on a fixed
+        mapped class many times, referring to an arbitrarily growing number of
+        target mappers.  A warning is emitted when the old relationship is
+        replaced, however if the mapping were already used for querying, the
+        old relationship would still be referenced within some registries.
+
     .. change::
         :tags: bug, sql
         :versions: 1.0.0
index 1bcbb9a6eff52b5795f1e9a69ff8757bb687351a..6e94a6498b9936f184d4d4ad18a9ca02f200fdc4 100644 (file)
@@ -1584,6 +1584,8 @@ class Mapper(_InspectionAttr):
                           self,
                           prop,
                       ))
+            oldprop = self._props[key]
+            self._path_registry.pop(oldprop, None)
 
         self._props[key] = prop
 
index 9ed812c88ac172e5f497ffdd38848bed36947189..6f56508b90583dae6384911aad142742e982de82 100644 (file)
@@ -621,6 +621,32 @@ class MemUsageTest(EnsureZeroed):
                 row[t.c.x]
         go()
 
+    def test_many_discarded_relationships(self):
+        """a use case that really isn't supported, nonetheless we can
+        guard against memleaks here so why not"""
+
+        m1 = MetaData()
+        t1 = Table('t1', m1, Column('id', Integer, primary_key=True))
+        t2 = Table(
+            't2', m1, Column('id', Integer, primary_key=True),
+            Column('t1id', ForeignKey('t1.id')))
+
+        class T1(object):
+            pass
+        t1_mapper = mapper(T1, t1)
+
+        @testing.emits_warning()
+        @profile_memory()
+        def go():
+            class T2(object):
+                pass
+            t2_mapper = mapper(T2, t2)
+            t1_mapper.add_property("bar", relationship(t2_mapper))
+            s1 = Session()
+            # this causes the path_registry to be invoked
+            s1.query(t1_mapper)._compile_context()
+        go()
+
     # fails on newer versions of pysqlite due to unusual memory behvior
     # in pysqlite itself. background at:
     # http://thread.gmane.org/gmane.comp.python.db.pysqlite.user/2290