legacy setstate for loader options not tested

Issue #4159 resolved
Michael Bayer
repo owner created an issue
diff --git a/test/orm/test_options.py b/test/orm/test_options.py
index 731aee1e5..9d3b8b702 100644
--- a/test/orm/test_options.py
+++ b/test/orm/test_options.py
@@ -890,6 +890,86 @@ class OptionsNoPropTest(_fixtures.FixtureTest):
                               joinedload(eager_option))


+class PickleTest(PathTest, QueryTest):
+
+    def _option_fixture(self, *arg):
+        return strategy_options._UnboundLoad._from_keys(
+            strategy_options._UnboundLoad.joinedload, arg, True, {})
+
+    def test_modern_opt_getstate(self):
+        User = self.classes.User
+
+        sess = Session()
+        q = sess.query(User)
+
+        opt = self._option_fixture(User.addresses)
+        eq_(
+            opt.__getstate__(),
+            {
+                '_is_chain_link': False,
+                'local_opts': {},
+                'is_class_strategy': False,
+                'path': [(User, 'addresses', None)],
+                'propagate_to_loaders': True,
+                '_to_bind': [opt],
+                'strategy': (('lazy', 'joined'),)}
+        )
+
+    def test_modern_opt_setstate(self):
+        User = self.classes.User
+
+        opt = strategy_options._UnboundLoad.__new__(
+            strategy_options._UnboundLoad)
+        state = {
+            '_is_chain_link': False,
+            'local_opts': {},
+            'is_class_strategy': False,
+            'path': [(User, 'addresses', None)],
+            'propagate_to_loaders': True,
+            '_to_bind': [opt],
+            'strategy': (('lazy', 'joined'),)}
+
+        opt.__setstate__(state)
+
+        query = create_session().query(User)
+        attr = {}
+        load = opt._bind_loader(
+            [ent.entity_zero for ent in query._mapper_entities],
+            query._current_path, attr, False)
+
+        eq_(
+            load.path,
+            inspect(User)._path_registry
+            [User.addresses.property][inspect(self.classes.Address)])
+
+    def test_legacy_opt_setstate(self):
+        User = self.classes.User
+
+        opt = strategy_options._UnboundLoad.__new__(
+            strategy_options._UnboundLoad)
+        state = {
+            '_is_chain_link': False,
+            'local_opts': {},
+            'is_class_strategy': False,
+            'path': [(User, 'addresses')],
+            'propagate_to_loaders': True,
+            '_to_bind': [opt],
+            'strategy': (('lazy', 'joined'),)}
+
+        opt.__setstate__(state)
+
+        query = create_session().query(User)
+        attr = {}
+        load = opt._bind_loader(
+            [ent.entity_zero for ent in query._mapper_entities],
+            query._current_path, attr, False)
+
+        eq_(
+            load.path,
+            inspect(User)._path_registry
+            [User.addresses.property][inspect(self.classes.Address)])
+
+
 class LocalOptsTest(PathTest, QueryTest):
     @classmethod
     def setup_class(cls):

Comments (2)

  1. Michael Bayer reporter

    Set up of_type variable for legacy loader option deserialize

    Fixed regression where pickle format of a Load / _UnboundLoad object (e.g. loader options) changed and __setstate__() was raising an UnboundLocalError for an object received from the legacy format, even though an attempt was made to do so. tests are now added to ensure this works.

    Change-Id: Idccf643e010776817dd32512facdefa263188814 Fixes: #4159

    → <<cset 4332b970c9ec>>

  2. Log in to comment