From cc57ea495f6460dd56daa6de57e40047ed999369 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Wed, 5 Aug 2020 16:42:26 -0400 Subject: Robustness for lambdas, lambda statements in order to accommodate relationship loaders with lambda caching, a lot more is needed. This is a full refactor of the lambda system such that it now has two levels of caching; the first level caches what can be known from the __code__ element, then the next level of caching is against the lambda itself and the contents of __closure__. This allows for the elements inside the lambdas, like columns and entities, to change and then be part of the cache key. Lazy/selectinloads' use of baked queries had to add distinct cache key elements, which was attempted here but overall things needed to be more robust than that. This commit is broken out from the very long and sprawling commit at Id6b5c03b1ce9ddb7b280f66792212a0ef0a1c541 . Change-Id: I29a513c98917b1d503abfdd61e6b6e8800851aa8 --- lib/sqlalchemy/util/_collections.py | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) (limited to 'lib/sqlalchemy/util/_collections.py') diff --git a/lib/sqlalchemy/util/_collections.py b/lib/sqlalchemy/util/_collections.py index 605686494..7c109b358 100644 --- a/lib/sqlalchemy/util/_collections.py +++ b/lib/sqlalchemy/util/_collections.py @@ -49,13 +49,25 @@ def _immutabledict_py_fallback(): def __reduce__(self): return _immutabledict_reconstructor, (dict(self),) - def union(self, d): - if not d: + def union(self, __d=None): + if not __d: return self new = dict.__new__(self.__class__) dict.__init__(new, self) - dict.update(new, d) + dict.update(new, __d) + return new + + def _union_w_kw(self, __d=None, **kw): + # not sure if C version works correctly w/ this yet + if not __d and not kw: + return self + + new = dict.__new__(self.__class__) + dict.__init__(new, self) + if __d: + dict.update(new, __d) + dict.update(new, kw) return new def merge_with(self, *dicts): @@ -90,6 +102,18 @@ except ImportError: return immutabledict(*arg) +def coerce_to_immutabledict(d): + if not d: + return EMPTY_DICT + elif isinstance(d, immutabledict): + return d + else: + return immutabledict(d) + + +EMPTY_DICT = immutabledict() + + class FacadeDict(ImmutableContainer, dict): """A dictionary that is not publicly mutable.""" -- cgit v1.2.1