diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2014-09-18 15:42:27 -0400 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2014-09-18 15:42:27 -0400 |
commit | c7ec21b29e926c40dd64eb2909d5f8b5e120ed94 (patch) | |
tree | 434daf9f360295f6e3d8e0348639006e7f9281f4 | |
parent | 9ae4db27b993fbd4666907cd11c2de3a41aee02f (diff) | |
download | sqlalchemy-c7ec21b29e926c40dd64eb2909d5f8b5e120ed94.tar.gz |
- Fixed an unlikely race condition observed in some exotic end-user
setups, where the attempt to check for "duplicate class name" in
declarative would hit upon a not-totally-cleaned-up weak reference
related to some other class being removed; the check here now ensures
the weakref still references an object before calling upon it further.
fixes #3208
-rw-r--r-- | doc/build/changelog/changelog_09.rst | 11 | ||||
-rw-r--r-- | lib/sqlalchemy/ext/declarative/clsregistry.py | 7 |
2 files changed, 17 insertions, 1 deletions
diff --git a/doc/build/changelog/changelog_09.rst b/doc/build/changelog/changelog_09.rst index 56be5b38e..c0d13e16d 100644 --- a/doc/build/changelog/changelog_09.rst +++ b/doc/build/changelog/changelog_09.rst @@ -14,6 +14,17 @@ :version: 0.9.8 .. change:: + :tags: bug, declarative + :versions: 1.0.0 + :tickets: 3208 + + Fixed an unlikely race condition observed in some exotic end-user + setups, where the attempt to check for "duplicate class name" in + declarative would hit upon a not-totally-cleaned-up weak reference + related to some other class being removed; the check here now ensures + the weakref still references an object before calling upon it further. + + .. change:: :tags: bug, orm :versions: 1.0.0 :tickets: 3199 diff --git a/lib/sqlalchemy/ext/declarative/clsregistry.py b/lib/sqlalchemy/ext/declarative/clsregistry.py index 4595b857a..3ef63a5ae 100644 --- a/lib/sqlalchemy/ext/declarative/clsregistry.py +++ b/lib/sqlalchemy/ext/declarative/clsregistry.py @@ -103,7 +103,12 @@ class _MultipleClassMarker(object): self.on_remove() def add_item(self, item): - modules = set([cls().__module__ for cls in self.contents]) + # protect against class registration race condition against + # asynchronous garbage collection calling _remove_item, + # [ticket:3208] + modules = set([ + cls.__module__ for cls in + [ref() for ref in self.contents] if cls is not None]) if item.__module__ in modules: util.warn( "This declarative base already contains a class with the " |