]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
resolves #3858 5478/head
authorRamonWill <ramonwilliams@hotmail.co.uk>
Sun, 26 Jul 2020 22:54:45 +0000 (23:54 +0100)
committerRamonWill <ramonwilliams@hotmail.co.uk>
Sun, 26 Jul 2020 22:54:45 +0000 (23:54 +0100)
doc/build/changelog/unreleased_14/3858.rst [new file with mode: 0644]
lib/sqlalchemy/orm/attributes.py
test/orm/test_attributes.py

diff --git a/doc/build/changelog/unreleased_14/3858.rst b/doc/build/changelog/unreleased_14/3858.rst
new file mode 100644 (file)
index 0000000..62d57cc
--- /dev/null
@@ -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.
index 6dd95a5a90f0b9d379b18e019390e452c5a66869..96cef01ebd4b394b1333ebe3394e3ee670857441 100644 (file)
@@ -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(
index 43a7d8dc83f7408ef0491549faad65cc64dd7040..671c75fa7ce2552eb512cfd6537b3fd04e3cb2ce 100644 (file)
@@ -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