From 743e9d4589946f1a29cdec7f2f1a2e4ec0853db7 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Tue, 10 May 2016 11:05:30 -0400 Subject: Check for duplicate calls to register_attribute_impl Fixed bug whereby the event listeners used for backrefs could be inadvertently applied multiple times, when using a deep class inheritance hierarchy in conjunction with mutiple mapper configuration steps. Change-Id: I712beaf4674e2323bf5b282922658020a6d00b53 Fixes: #3710 --- test/orm/test_mapper.py | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'test') diff --git a/test/orm/test_mapper.py b/test/orm/test_mapper.py index 69a039681..e357a7e25 100644 --- a/test/orm/test_mapper.py +++ b/test/orm/test_mapper.py @@ -373,6 +373,47 @@ class MapperTest(_fixtures.FixtureTest, AssertsCompiledSQL): }) assert getattr(Foo().__class__, 'name').impl is not None + def test_class_hier_only_instrument_once_multiple_configure(self): + users, addresses = (self.tables.users, self.tables.addresses) + + class A(object): + pass + + class ASub(A): + pass + + class ASubSub(ASub): + pass + + class B(object): + pass + + from sqlalchemy.testing import mock + from sqlalchemy.orm.attributes import register_attribute_impl + + with mock.patch( + "sqlalchemy.orm.attributes.register_attribute_impl", + side_effect=register_attribute_impl + ) as some_mock: + + mapper(A, users, properties={ + 'bs': relationship(B) + }) + mapper(B, addresses) + + configure_mappers() + + mapper(ASub, inherits=A) + mapper(ASubSub, inherits=ASub) + + configure_mappers() + + b_calls = [ + c for c in some_mock.mock_calls if c[1][1] == 'bs' + ] + eq_(len(b_calls), 3) + + def test_check_descriptor_as_method(self): User, users = self.classes.User, self.tables.users -- cgit v1.2.1