]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
change state.load_options to a tuple
authorMike Bayer <mike_mp@zzzcomputing.com>
Tue, 11 Jan 2022 03:11:50 +0000 (22:11 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Tue, 11 Jan 2022 14:27:58 +0000 (09:27 -0500)
having this be an immutable sequence is safer
and possibly lower overhead.

The change here went in with no issues save
for tests that asserted it was a set.
InstanceState.load_options is only referred
towards when the object is first loaded, and then
within the logic that emits an object refresh
as well as within a lazy loader.   it's only
accessed as a whole collection.

Fixes: #7558
Change-Id: Id1adbec0f93bcfbfc934ec9cd39e71e74727845d

lib/sqlalchemy/orm/context.py
lib/sqlalchemy/orm/state.py
lib/sqlalchemy/orm/strategies.py
test/orm/inheritance/test_poly_loading.py
test/orm/test_merge.py

index 8ec18b8651bc2b966899c5f9e45407b184736e02..cba7cf07dcc2d9378373acb03ee8d9a104fbd573 100644 (file)
@@ -103,7 +103,7 @@ class QueryContext:
         self.loaders_require_uniquing = False
         self.params = params
 
-        self.propagated_loader_options = {
+        self.propagated_loader_options = tuple(
             # issue 7447.
             # propagated loader options will be present on loaded InstanceState
             # objects under state.load_options and are typically used by
@@ -118,14 +118,14 @@ class QueryContext:
             cached_o
             for cached_o in compile_state.select_statement._with_options
             if cached_o.propagate_to_loaders and cached_o._is_compile_state
-        } | {
+        ) + tuple(
             # for user defined loader options that are not "compile state",
             # those just need to be present as they are
             uncached_o
             for uncached_o in statement._with_options
             if uncached_o.propagate_to_loaders
             and not uncached_o._is_compile_state
-        }
+        )
 
         self.attributes = dict(compile_state.attributes)
 
index e0eadefc4edc19a63a5bbf01905587b71dee508c..01ee16a13f4c1851038e0dcbb37d5352c8fdf6f9 100644 (file)
@@ -68,7 +68,7 @@ class InstanceState(interfaces.InspectionAttrInfo):
     session_id = None
     key = None
     runid = None
-    load_options = util.EMPTY_SET
+    load_options = ()
     load_path = PathRegistry.root
     insert_order = None
     _strong_obj = None
index a8a56395284fb2a816f30c645212386e2b41c38f..beaf649b785bea708d3e13ba4aa44de092c43060 100644 (file)
@@ -964,7 +964,7 @@ class LazyLoader(AbstractRelationshipLoader, util.MemoizedSlots):
         if state.load_options or (loadopt and loadopt._extra_criteria):
             effective_path = state.load_path[self.parent_property]
 
-            opts = tuple(state.load_options)
+            opts = state.load_options
 
             if loadopt and loadopt._extra_criteria:
                 use_get = False
index 517431e7052608d03a49d36116a697a4ee9ffe3f..5f8ff563958a3b891a2ce255905f84d8fc1afe79 100644 (file)
@@ -928,4 +928,4 @@ class LazyLoaderTransfersOptsTest(fixtures.DeclarativeMappedTest):
 
         u = sess.execute(select(User).options(*opts)).scalars().one()
         address = u.address
-        eq_(inspect(address).load_options, set(opts))
+        eq_(inspect(address).load_options, opts)
index 0f29cfc568075a321ffcff40d90c41d77b988687..dc04d4da65f6fd1abdedf63fac04eced696118aa 100644 (file)
@@ -1583,7 +1583,7 @@ class MergeTest(_fixtures.FixtureTest):
         for u in s1_users:
             ustate = attributes.instance_state(u)
             eq_(ustate.load_path.path, (umapper,))
-            eq_(ustate.load_options, set())
+            eq_(ustate.load_options, ())
 
         for u in s2_users:
             sess.merge(u)
@@ -1591,7 +1591,7 @@ class MergeTest(_fixtures.FixtureTest):
         for u in s1_users:
             ustate = attributes.instance_state(u)
             eq_(ustate.load_path.path, (umapper,))
-            eq_(ustate.load_options, set([opt2]))
+            eq_(ustate.load_options, (opt2,))
 
         # test 2.  present options are replaced by merge options
         sess = fixture_session()
@@ -1599,7 +1599,7 @@ class MergeTest(_fixtures.FixtureTest):
         for u in s1_users:
             ustate = attributes.instance_state(u)
             eq_(ustate.load_path.path, (umapper,))
-            eq_(ustate.load_options, set([opt1]))
+            eq_(ustate.load_options, (opt1,))
 
         for u in s2_users:
             sess.merge(u)
@@ -1607,7 +1607,7 @@ class MergeTest(_fixtures.FixtureTest):
         for u in s1_users:
             ustate = attributes.instance_state(u)
             eq_(ustate.load_path.path, (umapper,))
-            eq_(ustate.load_options, set([opt2]))
+            eq_(ustate.load_options, (opt2,))
 
     def test_resolve_conflicts_pending_doesnt_interfere_no_ident(self):
         User, Address, Order = (