]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
added an extra check for the correct class when __init__ is called,
authorMike Bayer <mike_mp@zzzcomputing.com>
Thu, 8 Jul 2010 14:50:13 +0000 (10:50 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Thu, 8 Jul 2010 14:50:13 +0000 (10:50 -0400)
to fix the second half of [ticket:1846]

lib/sqlalchemy/orm/attributes.py
test/orm/test_mapper.py

index e9874028717efe93c27a518519e5e2554dd2751d..2405d91c0b33305a63e6547a699386c443ed77ad 100644 (file)
@@ -1118,6 +1118,15 @@ class ClassManager(dict):
         """
         if hasattr(instance, self.STATE_ATTR):
             return False
+        elif self.class_ is not instance.__class__ and \
+                self.is_mapped:
+            # this will create a new ClassManager for the
+            # subclass, without a mapper.  This is likely a
+            # user error situation but allow the object
+            # to be constructed, so that it is usable
+            # in a non-ORM context at least.
+            return self._subclass_manager(instance.__class__).\
+                        _new_state_if_none(instance)
         else:
             state = self._create_instance_state(instance)
             setattr(instance, self.STATE_ATTR, state)
index 2de77fd2c5fe7d1d7eb246e15653b0d11de9860f..be135316d5fd3548dac30161ad7d8b45be424377 100644 (file)
@@ -1076,7 +1076,7 @@ class MapperTest(_fixtures.FixtureTest):
         assert_raises(sa.orm.exc.UnmappedClassError, sa.orm.compile_mappers)
 
     @testing.resolve_artifact_names
-    def test_unmapped_subclass_error(self):
+    def test_unmapped_subclass_error_postmap(self):
         class Base(object):
             pass
         class Sub(Base):
@@ -1084,9 +1084,44 @@ class MapperTest(_fixtures.FixtureTest):
         
         mapper(Base, users)
         sa.orm.compile_mappers()
+
+        # we can create new instances, set attributes.
+        s = Sub()
+        s.name = 'foo'
+        eq_(s.name, 'foo')
+        eq_(
+            attributes.get_history(s, 'name'),
+            (['foo'], (), ())
+        )
+
+        # using it with an ORM operation, raises
         assert_raises(sa.orm.exc.UnmappedClassError,
                         create_session().add, Sub())
+
+    @testing.resolve_artifact_names
+    def test_unmapped_subclass_error_premap(self):
+        class Base(object):
+            pass
+            
+        mapper(Base, users)
         
+        class Sub(Base):
+            pass
+
+        sa.orm.compile_mappers()
+        
+        # we can create new instances, set attributes.
+        s = Sub()
+        s.name = 'foo'
+        eq_(s.name, 'foo')
+        eq_(
+            attributes.get_history(s, 'name'),
+            (['foo'], (), ())
+        )
+        
+        # using it with an ORM operation, raises
+        assert_raises(sa.orm.exc.UnmappedClassError,
+                        create_session().add, Sub())
         
     @testing.resolve_artifact_names
     def test_oldstyle_mixin(self):