From: Mike Bayer Date: Thu, 18 Sep 2014 19:42:27 +0000 (-0400) Subject: - Fixed an unlikely race condition observed in some exotic end-user X-Git-Tag: rel_1_0_0b1~70^2~73 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c7ec21b29e926c40dd64eb2909d5f8b5e120ed94;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - 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 --- diff --git a/doc/build/changelog/changelog_09.rst b/doc/build/changelog/changelog_09.rst index 56be5b38e7..c0d13e16db 100644 --- a/doc/build/changelog/changelog_09.rst +++ b/doc/build/changelog/changelog_09.rst @@ -13,6 +13,17 @@ .. changelog:: :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 diff --git a/lib/sqlalchemy/ext/declarative/clsregistry.py b/lib/sqlalchemy/ext/declarative/clsregistry.py index 4595b857a8..3ef63a5aeb 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 "