summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2020-12-01 16:03:35 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2020-12-01 16:04:06 -0500
commit14c08d18885e16611b884bd76ba2811375de1731 (patch)
tree66cd6a944896bcb65377c74552cfcc4b08da6a93
parent1de02c9f3f5085e125a6f79230ee7b98f0e30ddb (diff)
downloadsqlalchemy-14c08d18885e16611b884bd76ba2811375de1731.tar.gz
Pass along other keyword args in _EventsHold.populate
Fixed bug involving the ``restore_load_context`` option of ORM events such as :meth:`_orm.InstanceEvents.load` such that the flag would not be carried along to subclasses which were mapped after the event handler were first established. Fixes: #5737 Change-Id: Ie65fbeac7ab223d24993cff0b34094d4928ff113
-rw-r--r--doc/build/changelog/unreleased_13/5737.rst11
-rw-r--r--lib/sqlalchemy/orm/events.py18
-rw-r--r--test/orm/test_events.py26
3 files changed, 52 insertions, 3 deletions
diff --git a/doc/build/changelog/unreleased_13/5737.rst b/doc/build/changelog/unreleased_13/5737.rst
new file mode 100644
index 000000000..7a1c3b527
--- /dev/null
+++ b/doc/build/changelog/unreleased_13/5737.rst
@@ -0,0 +1,11 @@
+.. change::
+ :tags: bug, orm
+ :tickets: 5737
+ :versions: 1.4.0b2
+
+ Fixed bug involving the ``restore_load_context`` option of ORM events such
+ as :meth:`_orm.InstanceEvents.load` such that the flag would not be carried
+ along to subclasses which were mapped after the event handler were first
+ established.
+
+
diff --git a/lib/sqlalchemy/orm/events.py b/lib/sqlalchemy/orm/events.py
index a0e100a81..9f9ebd461 100644
--- a/lib/sqlalchemy/orm/events.py
+++ b/lib/sqlalchemy/orm/events.py
@@ -550,7 +550,13 @@ class _EventsHold(event.RefCollection):
collection = target.all_holds[target.class_] = {}
event.registry._stored_in_collection(event_key, target)
- collection[event_key._key] = (event_key, raw, propagate, retval)
+ collection[event_key._key] = (
+ event_key,
+ raw,
+ propagate,
+ retval,
+ kw,
+ )
if propagate:
stack = list(target.class_.__subclasses__())
@@ -577,7 +583,13 @@ class _EventsHold(event.RefCollection):
for subclass in class_.__mro__:
if subclass in cls.all_holds:
collection = cls.all_holds[subclass]
- for event_key, raw, propagate, retval in collection.values():
+ for (
+ event_key,
+ raw,
+ propagate,
+ retval,
+ kw,
+ ) in collection.values():
if propagate or subclass is class_:
# since we can't be sure in what order different
# classes in a hierarchy are triggered with
@@ -585,7 +597,7 @@ class _EventsHold(event.RefCollection):
# assignment, instead of using the generic propagate
# flag.
event_key.with_dispatch_target(subject).listen(
- raw=raw, propagate=False, retval=retval
+ raw=raw, propagate=False, retval=retval, **kw
)
diff --git a/test/orm/test_events.py b/test/orm/test_events.py
index 285162241..f8600894f 100644
--- a/test/orm/test_events.py
+++ b/test/orm/test_events.py
@@ -900,6 +900,32 @@ class RestoreLoadContextTest(fixtures.DeclarativeMappedTest):
s.query(A).all()
s.close()
+ @testing.combinations(
+ ("load", lambda instance, context: instance.unloaded),
+ (
+ "refresh",
+ lambda instance, context, attrs: instance.unloaded,
+ ),
+ )
+ def test_flag_resolves_existing_for_subclass(self, event_name, fn):
+ Base = declarative_base()
+
+ event.listen(
+ Base, event_name, fn, propagate=True, restore_load_context=True
+ )
+
+ class A(Base):
+ __tablename__ = "a"
+ id = Column(Integer, primary_key=True)
+ unloaded = deferred(Column(String(50)))
+
+ s = Session(testing.db)
+
+ a1 = s.query(A).all()[0]
+ if event_name == "refresh":
+ s.refresh(a1)
+ s.close()
+
@_combinations
def test_flag_resolves(self, target, event_name, fn):
A = self.classes.A