diff options
| author | mike bayer <mike_mp@zzzcomputing.com> | 2018-02-19 18:19:01 -0500 |
|---|---|---|
| committer | Gerrit Code Review <gerrit@ci.zzzcomputing.com> | 2018-02-19 18:19:01 -0500 |
| commit | 191dd0055c05f51fa985d4e24f107faa58743022 (patch) | |
| tree | 1d928bbf065922644d3fe1536f1fa35369dcc5bc | |
| parent | 5cb5b8b5f7a5b4488fb5df82c53861d565537405 (diff) | |
| parent | 1393eac44c49299e733a5181f387ba140aaa3e44 (diff) | |
| download | sqlalchemy-191dd0055c05f51fa985d4e24f107faa58743022.tar.gz | |
Merge "Implement remove() for _empty_collection"
| -rw-r--r-- | doc/build/changelog/unreleased_12/4190.rst | 9 | ||||
| -rw-r--r-- | lib/sqlalchemy/event/attr.py | 3 | ||||
| -rw-r--r-- | test/base/test_events.py | 58 | ||||
| -rw-r--r-- | test/engine/test_execute.py | 9 |
4 files changed, 79 insertions, 0 deletions
diff --git a/doc/build/changelog/unreleased_12/4190.rst b/doc/build/changelog/unreleased_12/4190.rst new file mode 100644 index 000000000..0969ea3a2 --- /dev/null +++ b/doc/build/changelog/unreleased_12/4190.rst @@ -0,0 +1,9 @@ +.. change:: + :tags: bug, engine + :tickets: 4190 + + Fixed regression caused in 1.2.3 due to fix from :ticket:`4181` where + the changes to the event system involving :class:`.Engine` and + :class:`.OptionEngine` did not accommodate for event removals, which + would raise an ``AttributeError`` when invoked at the class + level. diff --git a/lib/sqlalchemy/event/attr.py b/lib/sqlalchemy/event/attr.py index efa8fab42..c33ec82ff 100644 --- a/lib/sqlalchemy/event/attr.py +++ b/lib/sqlalchemy/event/attr.py @@ -54,6 +54,9 @@ class _empty_collection(object): def extend(self, other): pass + def remove(self, element): + pass + def __iter__(self): return iter([]) diff --git a/test/base/test_events.py b/test/base/test_events.py index b502a0348..288c6091f 100644 --- a/test/base/test_events.py +++ b/test/base/test_events.py @@ -1033,6 +1033,64 @@ class JoinTest(fixtures.TestBase): ) +class DisableClsPropagateTest(fixtures.TestBase): + + def setUp(self): + class TargetEvents(event.Events): + def event_one(self, target, arg): + pass + + class BaseTarget(object): + dispatch = event.dispatcher(TargetEvents) + + class SubTarget(BaseTarget): + _sa_propagate_class_events = False + + def __init__(self, parent): + self.dispatch = self.dispatch._join(parent.dispatch) + + self.BaseTarget = BaseTarget + self.SubTarget = SubTarget + + def tearDown(self): + for cls in (self.SubTarget, self.BaseTarget): + if 'dispatch' in cls.__dict__: + event.base._remove_dispatcher(cls.__dict__['dispatch'].events) + + def test_listen_invoke_clslevel(self): + canary = Mock() + + event.listen(self.BaseTarget, "event_one", canary) + + s1 = self.SubTarget(self.BaseTarget()) + s1.dispatch.event_one() + + eq_(canary.mock_calls, [call.event_one()]) + + def test_insert_invoke_clslevel(self): + canary = Mock() + + event.listen(self.BaseTarget, "event_one", canary, insert=True) + + s1 = self.SubTarget(self.BaseTarget()) + s1.dispatch.event_one() + + eq_(canary.mock_calls, [call.event_one()]) + + def test_remove_invoke_clslevel(self): + canary = Mock() + + event.listen(self.BaseTarget, "event_one", canary) + + s1 = self.SubTarget(self.BaseTarget()) + + event.remove(self.BaseTarget, "event_one", canary) + + s1.dispatch.event_one() + + eq_(canary.mock_calls, []) + + class RemovalTest(fixtures.TestBase): def _fixture(self): class TargetEvents(event.Events): diff --git a/test/engine/test_execute.py b/test/engine/test_execute.py index e0727f770..2d602fa12 100644 --- a/test/engine/test_execute.py +++ b/test/engine/test_execute.py @@ -1399,6 +1399,15 @@ class EngineEventsTest(fixtures.TestBase): eq_(canary, ["l1", "l2", "l3", "l4", "l1", "l2", "l3"]) + canary[:] = [] + + event.remove(Engine, "before_execute", l1) + event.remove(eng1, "before_execute", l4) + event.remove(eng, "before_execute", l3) + + eng1.execute(select([1])).close() + eq_(canary, ["l2"]) + @testing.requires.ad_hoc_engines def test_cant_listen_to_option_engine(self): from sqlalchemy.engine import base |
