From 853051c9225446b69f52b13ade78709ad2617f6d Mon Sep 17 00:00:00 2001 From: RamonWill Date: Sun, 26 Jul 2020 23:54:45 +0100 Subject: [PATCH] resolves #3858 --- doc/build/changelog/unreleased_14/3858.rst | 7 +++++++ lib/sqlalchemy/orm/attributes.py | 9 ++++++++- test/orm/test_attributes.py | 20 ++++++++++++++++++++ 3 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 doc/build/changelog/unreleased_14/3858.rst diff --git a/doc/build/changelog/unreleased_14/3858.rst b/doc/build/changelog/unreleased_14/3858.rst new file mode 100644 index 0000000000..62d57cc7e5 --- /dev/null +++ b/doc/build/changelog/unreleased_14/3858.rst @@ -0,0 +1,7 @@ +.. change:: + :tags: bug, orm + :tickets: 3858 + + An ``UnmappedInstanceError`` is now raised for :class:`.InstrumentedAttribute` + if an instance is an unmapped object. Prior to this an ``AttributeError`` + was raised. Pull request courtesy Ramon Williams. diff --git a/lib/sqlalchemy/orm/attributes.py b/lib/sqlalchemy/orm/attributes.py index 6dd95a5a90..96cef01ebd 100644 --- a/lib/sqlalchemy/orm/attributes.py +++ b/lib/sqlalchemy/orm/attributes.py @@ -325,7 +325,14 @@ class InstrumentedAttribute(QueryableAttribute): if self._supports_population and self.key in dict_: return dict_[self.key] else: - return self.impl.get(instance_state(instance), dict_) + try: + state = instance_state(instance) + except AttributeError as err: + util.raise_( + orm_exc.UnmappedInstanceError(instance), + replace_context=err, + ) + return self.impl.get(state, dict_) HasEntityNamespace = util.namedtuple( diff --git a/test/orm/test_attributes.py b/test/orm/test_attributes.py index 43a7d8dc83..671c75fa7c 100644 --- a/test/orm/test_attributes.py +++ b/test/orm/test_attributes.py @@ -361,6 +361,26 @@ class AttributesTest(fixtures.ORMTest): lambda: Foo().bars.append(Bar()), ) + def test_unmapped_instance_raises(self): + class User(object): + pass + + instrumentation.register_class(User) + attributes.register_attribute( + User, "user_name", uselist=False, useobject=False + ) + + class Blog(object): + name = User.user_name + + def go(): + b = Blog() + return b.name + + assert_raises( + orm_exc.UnmappedInstanceError, go, + ) + def test_del_scalar_nonobject(self): class Foo(object): pass -- 2.47.3