From 5a10b6a455f9ad7be752469cbaa503857ae9fda2 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Mon, 6 Oct 2014 18:33:05 -0400 Subject: [PATCH] - Fixed "'NoneType' object has no attribute 'concrete'" error when using :class:`.AbstractConcreteBase` in conjunction with a subclass that declares ``__abstract__``. fixes #3185 --- doc/build/changelog/changelog_09.rst | 9 ++++++++ lib/sqlalchemy/ext/declarative/api.py | 2 +- test/ext/declarative/test_inheritance.py | 29 ++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/doc/build/changelog/changelog_09.rst b/doc/build/changelog/changelog_09.rst index 7dd50739e0..692c6e3925 100644 --- a/doc/build/changelog/changelog_09.rst +++ b/doc/build/changelog/changelog_09.rst @@ -13,6 +13,15 @@ .. changelog:: :version: 0.9.8 + .. change:: + :tags: bug, declarative, orm + :versions: 1.0.0 + :tickets: 3185 + + Fixed "'NoneType' object has no attribute 'concrete'" error + when using :class:`.AbstractConcreteBase` in conjunction with + a subclass that declares ``__abstract__``. + .. change:: :tags: bug, engine :versions: 1.0.0 diff --git a/lib/sqlalchemy/ext/declarative/api.py b/lib/sqlalchemy/ext/declarative/api.py index e84b21ad23..66fe05fd0e 100644 --- a/lib/sqlalchemy/ext/declarative/api.py +++ b/lib/sqlalchemy/ext/declarative/api.py @@ -547,7 +547,7 @@ class AbstractConcreteBase(ConcreteBase): for scls in cls.__subclasses__(): sm = _mapper_or_none(scls) - if sm.concrete and cls in scls.__bases__: + if sm and sm.concrete and cls in scls.__bases__: sm._set_concrete_base(m) diff --git a/test/ext/declarative/test_inheritance.py b/test/ext/declarative/test_inheritance.py index 5a99c9c5a7..6ea37e4d3b 100644 --- a/test/ext/declarative/test_inheritance.py +++ b/test/ext/declarative/test_inheritance.py @@ -1388,3 +1388,32 @@ class ConcreteExtensionConfigTest( "WHERE something.id = pjoin.something_id AND something.id = :id_1)" ) + def test_abstract_in_hierarchy(self): + class Document(Base, AbstractConcreteBase): + doctype = Column(String) + + class ContactDocument(Document): + __abstract__ = True + + send_method = Column(String) + + class ActualDocument(ContactDocument): + __tablename__ = 'actual_documents' + __mapper_args__ = { + 'concrete': True, + 'polymorphic_identity': 'actual'} + + id = Column(Integer, primary_key=True) + + configure_mappers() + session = Session() + self.assert_compile( + session.query(Document), + "SELECT pjoin.doctype AS pjoin_doctype, " + "pjoin.send_method AS pjoin_send_method, " + "pjoin.id AS pjoin_id, pjoin.type AS pjoin_type " + "FROM (SELECT actual_documents.doctype AS doctype, " + "actual_documents.send_method AS send_method, " + "actual_documents.id AS id, 'actual' AS type " + "FROM actual_documents) AS pjoin" + ) \ No newline at end of file -- 2.47.2