--- /dev/null
+.. change::
+ :tags: bug, regression, ext
+ :tickets: 6390
+
+ Fixed regression in the ``sqlalchemy.ext.instrumentation`` extension that
+ prevented instrumentation disposal from working completely. This fix
+ includes both a 1.4 regression fix as well as a fix for a related issue
+ that existed in 1.3 also. As part of this change, the
+ :class:`sqlalchemy.ext.instrumentation.InstrumentationManager` class now
+ has a new method ``unregister()``, which replaces the previous method
+ ``dispose()``, which was not called as of version 1.4.
+
return factories
def unregister(self, class_):
+ super(ExtendedInstrumentationRegistry, self).unregister(class_)
if class_ in self._manager_finders:
del self._manager_finders[class_]
del self._state_finders[class_]
del self._dict_finders[class_]
- super(ExtendedInstrumentationRegistry, self).unregister(class_)
def manager_of_class(self, cls):
if cls is None:
def manage(self, class_, manager):
setattr(class_, "_default_class_manager", manager)
- def dispose(self, class_, manager):
+ def unregister(self, class_, manager):
delattr(class_, "_default_class_manager")
def manager_getter(self, class_):
def manage(self):
self._adapted.manage(self.class_, self)
- def dispose(self):
- self._adapted.dispose(self.class_)
+ def unregister(self):
+ self._adapted.unregister(self.class_, self)
def manager_getter(self):
return self._adapted.manager_getter(self.class_)
import sqlalchemy as sa
+from sqlalchemy import Column
from sqlalchemy import event
+from sqlalchemy import Integer
+from sqlalchemy import Table
from sqlalchemy import util
from sqlalchemy.ext import instrumentation
from sqlalchemy.orm import attributes
from sqlalchemy.testing import assert_raises_message
from sqlalchemy.testing import eq_
from sqlalchemy.testing import fixtures
+from sqlalchemy.testing import is_
+from sqlalchemy.testing import is_not
from sqlalchemy.testing import ne_
from sqlalchemy.testing.util import decorator
MyBaseClass, MyClass = None, None
+class DisposeTest(_ExtBase, fixtures.TestBase):
+ def test_unregister(self, registry):
+ class MyClassState(instrumentation.InstrumentationManager):
+ def manage(self, class_, manager):
+ setattr(class_, "xyz", manager)
+
+ def unregister(self, class_, manager):
+ delattr(class_, "xyz")
+
+ def manager_getter(self, class_):
+ def get(cls):
+ return cls.xyz
+
+ return get
+
+ class MyClass(object):
+ __sa_instrumentation_manager__ = MyClassState
+
+ assert attributes.manager_of_class(MyClass) is None
+
+ t = Table(
+ "my_table",
+ registry.metadata,
+ Column("id", Integer, primary_key=True),
+ )
+
+ registry.map_imperatively(MyClass, t)
+
+ manager = attributes.manager_of_class(MyClass)
+ is_not(manager, None)
+ is_(manager, MyClass.xyz)
+
+ registry.configure()
+
+ registry.dispose()
+
+ manager = attributes.manager_of_class(MyClass)
+ is_(manager, None)
+
+ assert not hasattr(MyClass, "xyz")
+
+
class UserDefinedExtensionTest(_ExtBase, fixtures.ORMTest):
@classmethod
def setup_test_class(cls):