]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Add .info to InstanceState
authorMike Bayer <mike_mp@zzzcomputing.com>
Mon, 1 Oct 2018 20:34:50 +0000 (16:34 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Mon, 1 Oct 2018 20:35:27 +0000 (16:35 -0400)
Added ``.info`` dictionary to the :class:`.InstanceState` class, the object
that comes from calling :func:`.inspect` on a mapped object.

Fixes: #4257
Change-Id: I32d043f369edb708a17eec2e0b8876db0c1891b4

doc/build/changelog/migration_13.rst
doc/build/changelog/unreleased_13/4257.rst [new file with mode: 0644]
lib/sqlalchemy/orm/state.py
test/orm/test_inspect.py
test/orm/test_pickled.py

index 500062686921bfe818089bb21bc896bb4f376942..08f62bb02755374244060477e1e25c3ed463b4db 100644 (file)
@@ -20,6 +20,25 @@ potentially backwards-incompatible changes in behavior.
 New Features and Improvements - ORM
 ===================================
 
+.. _change_4257:
+
+info dictionary added to InstanceState
+--------------------------------------
+
+Added the ``.info`` dictionary to the :class:`.InstanceState` class, the object
+that comes from calling :func:`.inspect` on a mapped object.  This allows custom
+recipes to add additional information about an object that will be carried
+along with that object's full lifecycle in memory::
+
+    from sqlalchemy import inspect
+
+    u1 = User(id=7, name='ed')
+
+    inspect(u1).info['user_info'] = '7|ed'
+
+
+:ticket:`4257`
+
 Key Behavioral Changes - ORM
 =============================
 
diff --git a/doc/build/changelog/unreleased_13/4257.rst b/doc/build/changelog/unreleased_13/4257.rst
new file mode 100644 (file)
index 0000000..72cac1e
--- /dev/null
@@ -0,0 +1,10 @@
+.. change::
+   :tags: feature, orm
+   :tickets: 4257
+
+   Added ``.info`` dictionary to the :class:`.InstanceState` class, the object
+   that comes from calling :func:`.inspect` on a mapped object.
+
+   .. seealso::
+
+        :ref:`change_4257`
index 03d68ab820c1b1d42d69af4b703827be2c3eb174..935e7df19f77d2bcf052e8b4a9a9c738c52f276f 100644 (file)
@@ -24,7 +24,7 @@ from . import base
 
 
 @inspection._self_inspects
-class InstanceState(interfaces.InspectionAttr):
+class InstanceState(interfaces.InspectionAttrInfo):
     """tracks state information at the instance level.
 
     The :class:`.InstanceState` is a key object used by the
@@ -440,7 +440,7 @@ class InstanceState(interfaces.InspectionAttr):
             (k, self.__dict__[k]) for k in (
                 'committed_state', '_pending_mutations', 'modified',
                 'expired', 'callables', 'key', 'parents', 'load_options',
-                'class_', 'expired_attributes'
+                'class_', 'expired_attributes', 'info'
             ) if k in self.__dict__
         )
         if self.load_path:
@@ -467,6 +467,8 @@ class InstanceState(interfaces.InspectionAttr):
         self.parents = state_dict.get('parents', {})
         self.modified = state_dict.get('modified', False)
         self.expired = state_dict.get('expired', False)
+        if 'info' in state_dict:
+            self.info.update(state_dict['info'])
         if 'callables' in state_dict:
             self.callables = state_dict['callables']
 
index 37cafe599fb0ac4608b9504b98b3612d5dd57d97..0eaca3136a02cb693ac8ee89de2ba818e0d72477 100644 (file)
@@ -309,6 +309,13 @@ class TestORMInspection(_fixtures.FixtureTest):
         insp = inspect(u1)
         is_(insp, instance_state(u1))
 
+    def test_instance_state_info(self):
+        User = self.classes.User
+        u1 = User()
+        insp = inspect(u1)
+        insp.info['some_key'] = 'value'
+        eq_(inspect(u1).info['some_key'], 'value')
+
     def test_instance_state_attr(self):
         User = self.classes.User
         u1 = User(name='ed')
index d9c30f6bf0b902060486c203065532e12f0745c7..ff8b9e429c0b11ad496060682ebcfaa5362e385c 100644 (file)
@@ -333,6 +333,22 @@ class PickleTest(fixtures.MappedTest):
         eq_(state.identity_token, None)
         eq_(state.identity_key, (User, (1,), None))
 
+    def test_state_info_pickle(self):
+        users = self.tables.users
+        mapper(User, users)
+
+        u1 = User(id=1, name='ed')
+
+        sa.inspect(u1).info['some_key'] = 'value'
+
+        state_dict = sa.inspect(u1).__getstate__()
+
+        state = sa_state.InstanceState.__new__(sa_state.InstanceState)
+        state.__setstate__(state_dict)
+
+        u2 = state.obj()
+        eq_(sa.inspect(u2).info['some_key'], 'value')
+
     @testing.requires.non_broken_pickle
     def test_options_with_descriptors(self):
         users, addresses, dingalings = (self.tables.users,