]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- raise error when unpickling non-mapped state, [ticket:1610]
authorMike Bayer <mike_mp@zzzcomputing.com>
Sun, 17 Jan 2010 22:23:54 +0000 (22:23 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sun, 17 Jan 2010 22:23:54 +0000 (22:23 +0000)
- remove pickle language from regular unmapped class error

lib/sqlalchemy/orm/exc.py
lib/sqlalchemy/orm/state.py
test/orm/test_pickled.py

index ccb4feda2115655e4e95f2c1de67c02bdd1efbb2..8b52eec8ac35b2e34565f977cae4b1a7b9c64cc9 100644 (file)
@@ -33,10 +33,8 @@ class UnmappedInstanceError(UnmappedError):
                 mapper = sa.orm.class_mapper(type(obj))
                 name = _safe_cls_name(type(obj))
                 msg = ("Class %r is mapped, but this instance lacks "
-                       "instrumentation.  Possible causes: instance created "
-                       "before sqlalchemy.orm.mapper(%s) was called, or "
-                       "instance was pickled/depickled without instrumentation"
-                       "information." % (name, name))
+                       "instrumentation.  This occurs when the instance is created "
+                       "before sqlalchemy.orm.mapper(%s) was called." % (name, name))
             except UnmappedClassError:
                 msg = _default_unmapped(type(obj))
                 if isinstance(obj, type):
index 042f06710376a2c601b6d11700e9f6e36cc4ecd2..472d2c0817603f2d4ba459e220f4a653f39600ac 100644 (file)
@@ -1,9 +1,10 @@
 from sqlalchemy.util import EMPTY_SET
 import weakref
 from sqlalchemy import util
-from sqlalchemy.orm.attributes import PASSIVE_NO_RESULT, PASSIVE_OFF, NEVER_SET, NO_VALUE, manager_of_class, ATTR_WAS_SET
-from sqlalchemy.orm import attributes
-from sqlalchemy.orm import interfaces
+from sqlalchemy.orm.attributes import PASSIVE_NO_RESULT, PASSIVE_OFF, \
+                                        NEVER_SET, NO_VALUE, manager_of_class, \
+                                        ATTR_WAS_SET
+from sqlalchemy.orm import attributes, exc as orm_exc, interfaces
 
 class InstanceState(object):
     """tracks state information at the instance level."""
@@ -147,8 +148,14 @@ class InstanceState(object):
     def __setstate__(self, state):
         self.obj = weakref.ref(state['instance'], self._cleanup)
         self.class_ = state['instance'].__class__
-        self.manager = manager_of_class(self.class_)
-
+        self.manager = manager = manager_of_class(self.class_)
+        if manager is None:
+            raise orm_exc.UnmappedInstanceError(
+                        state['instance'],
+                        "Cannot deserialize object of type %r - no mapper() has"
+                        " been configured for this class within the current Python process!" %
+                        self.class_)
+        
         self.committed_state = state.get('committed_state', {})
         self.pending = state.get('pending', {})
         self.parents = state.get('parents', {})
index 0285f4d0b2b883d4600f3a6b61ed5b023587f764..62caa49dae07c68d096e62757f48fc2ac1ebcc64 100644 (file)
@@ -2,9 +2,12 @@ from sqlalchemy.test.testing import eq_
 import pickle
 import sqlalchemy as sa
 from sqlalchemy.test import testing
-from sqlalchemy import Integer, String, ForeignKey
+from sqlalchemy.test.testing import assert_raises_message
+from sqlalchemy import Integer, String, ForeignKey, exc
 from sqlalchemy.test.schema import Table, Column
-from sqlalchemy.orm import mapper, relation, create_session, sessionmaker, attributes, interfaces
+from sqlalchemy.orm import mapper, relation, create_session, \
+                            sessionmaker, attributes, interfaces,\
+                            clear_mappers, exc as orm_exc
 from test.orm import _base, _fixtures
 
 
@@ -32,6 +35,20 @@ class PickleTest(_fixtures.FixtureTest):
 
         eq_(u1, sess.query(User).get(u2.id))
 
+    @testing.resolve_artifact_names
+    def test_no_mappers(self):
+        
+        umapper = mapper(User, users)
+        u1 = User(name='ed')
+        u1_pickled = pickle.dumps(u1, -1)
+
+        clear_mappers()
+
+        assert_raises_message(
+            orm_exc.UnmappedInstanceError,
+            "Cannot deserialize object of type <class 'test.orm._fixtures.User'> - no mapper()",
+            pickle.loads, u1_pickled)
+        
     @testing.resolve_artifact_names
     def test_serialize_path(self):
         umapper = mapper(User, users, properties={