diff options
| author | mike bayer <mike_mp@zzzcomputing.com> | 2021-03-23 18:28:33 +0000 |
|---|---|---|
| committer | Gerrit Code Review <gerrit@ci3.zzzcomputing.com> | 2021-03-23 18:28:33 +0000 |
| commit | 51bedc6751b440b51715420ca39c36fc6aea5349 (patch) | |
| tree | 39d945c406dbe1918a6382e82997e524e19b00fe /lib | |
| parent | 65c577583215d98423946d8d9bf377b63fc65e43 (diff) | |
| parent | 9ec860e7a5c944799f9ef4de9069d707cfc1ed27 (diff) | |
| download | sqlalchemy-51bedc6751b440b51715420ca39c36fc6aea5349.tar.gz | |
Merge "Remove internal use of string attr in loader option"
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/sqlalchemy/orm/interfaces.py | 1 | ||||
| -rw-r--r-- | lib/sqlalchemy/orm/strategies.py | 2 | ||||
| -rw-r--r-- | lib/sqlalchemy/orm/strategy_options.py | 136 | ||||
| -rw-r--r-- | lib/sqlalchemy/testing/assertions.py | 17 |
4 files changed, 87 insertions, 69 deletions
diff --git a/lib/sqlalchemy/orm/interfaces.py b/lib/sqlalchemy/orm/interfaces.py index 7aae9ec37..a660d7e1a 100644 --- a/lib/sqlalchemy/orm/interfaces.py +++ b/lib/sqlalchemy/orm/interfaces.py @@ -83,6 +83,7 @@ class ORMFromClauseRole(roles.StrictFromClauseRole): _role_name = "ORM mapped entity, aliased entity, or FROM expression" +@inspection._self_inspects class MapperProperty( HasCacheKey, _MappedAttribute, InspectionAttr, util.MemoizedSlots ): diff --git a/lib/sqlalchemy/orm/strategies.py b/lib/sqlalchemy/orm/strategies.py index 339a5bcf1..b11758090 100644 --- a/lib/sqlalchemy/orm/strategies.py +++ b/lib/sqlalchemy/orm/strategies.py @@ -992,7 +992,7 @@ class LazyLoader(AbstractRelationshipLoader, util.MemoizedSlots): compile_context.compile_options._current_path[ rev.parent ] - ).lazyload(rev.key).process_compile_state(compile_context) + ).lazyload(rev).process_compile_state(compile_context) stmt = stmt.add_criteria( lambda stmt: stmt._add_context_option( diff --git a/lib/sqlalchemy/orm/strategy_options.py b/lib/sqlalchemy/orm/strategy_options.py index 932c4a37d..ba4e5c466 100644 --- a/lib/sqlalchemy/orm/strategy_options.py +++ b/lib/sqlalchemy/orm/strategy_options.py @@ -234,84 +234,90 @@ class Load(Generative, LoaderOption): raise path = path[attr] - elif _is_mapped_class(attr): - # TODO: this does not appear to be a valid codepath. "attr" - # would never be a mapper. This block is present in 1.2 - # as well however does not seem to be accessed in any tests. - if not orm_util._entity_corresponds_to_use_path_impl( - attr.parent, path[-1] - ): - if raiseerr: - raise sa_exc.ArgumentError( - "Attribute '%s' does not " - "link from element '%s'" % (attr, path.entity) - ) - else: - return None else: - prop = found_property = attr.property - - if not orm_util._entity_corresponds_to_use_path_impl( - attr.parent, path[-1] - ): - if raiseerr: - raise sa_exc.ArgumentError( - 'Attribute "%s" does not ' - 'link from element "%s".%s' - % ( - attr, - path.entity, - ( - " Did you mean to use " - "%s.of_type(%s)?" - % (path[-2], attr.class_.__name__) - if len(path) > 1 - and path.entity.is_mapper - and attr.parent.is_aliased_class - else "" - ), + insp = inspect(attr) + + if insp.is_mapper or insp.is_aliased_class: + # TODO: this does not appear to be a valid codepath. "attr" + # would never be a mapper. This block is present in 1.2 + # as well however does not seem to be accessed in any tests. + if not orm_util._entity_corresponds_to_use_path_impl( + attr.parent, path[-1] + ): + if raiseerr: + raise sa_exc.ArgumentError( + "Attribute '%s' does not " + "link from element '%s'" % (attr, path.entity) ) - ) - else: - return None + else: + return None + elif insp.is_property: + prop = found_property = attr + path = path[prop] + elif insp.is_attribute: + prop = found_property = attr.property - if attr._extra_criteria: - self._extra_criteria = attr._extra_criteria + if not orm_util._entity_corresponds_to_use_path_impl( + attr.parent, path[-1] + ): + if raiseerr: + raise sa_exc.ArgumentError( + 'Attribute "%s" does not ' + 'link from element "%s".%s' + % ( + attr, + path.entity, + ( + " Did you mean to use " + "%s.of_type(%s)?" + % (path[-2], attr.class_.__name__) + if len(path) > 1 + and path.entity.is_mapper + and attr.parent.is_aliased_class + else "" + ), + ) + ) + else: + return None - if getattr(attr, "_of_type", None): - ac = attr._of_type - ext_info = of_type_info = inspect(ac) + if attr._extra_criteria: + self._extra_criteria = attr._extra_criteria - if polymorphic_entity_context is None: - polymorphic_entity_context = self.context + if getattr(attr, "_of_type", None): + ac = attr._of_type + ext_info = of_type_info = inspect(ac) - existing = path.entity_path[prop].get( - polymorphic_entity_context, "path_with_polymorphic" - ) + if polymorphic_entity_context is None: + polymorphic_entity_context = self.context - if not ext_info.is_aliased_class: - ac = orm_util.with_polymorphic( - ext_info.mapper.base_mapper, - ext_info.mapper, - aliased=True, - _use_mapper_path=True, - _existing_alias=inspect(existing) - if existing is not None - else None, + existing = path.entity_path[prop].get( + polymorphic_entity_context, "path_with_polymorphic" ) - ext_info = inspect(ac) + if not ext_info.is_aliased_class: + ac = orm_util.with_polymorphic( + ext_info.mapper.base_mapper, + ext_info.mapper, + aliased=True, + _use_mapper_path=True, + _existing_alias=inspect(existing) + if existing is not None + else None, + ) - path.entity_path[prop].set( - polymorphic_entity_context, "path_with_polymorphic", ac - ) + ext_info = inspect(ac) - path = path[prop][ext_info] + path.entity_path[prop].set( + polymorphic_entity_context, "path_with_polymorphic", ac + ) - self._of_type = of_type_info + path = path[prop][ext_info] - else: - path = path[prop] + self._of_type = of_type_info + + else: + path = path[prop] if for_strategy is not None: found_property._get_strategy(for_strategy) diff --git a/lib/sqlalchemy/testing/assertions.py b/lib/sqlalchemy/testing/assertions.py index 289ac9a0a..02137474b 100644 --- a/lib/sqlalchemy/testing/assertions.py +++ b/lib/sqlalchemy/testing/assertions.py @@ -135,7 +135,12 @@ def uses_deprecated(*messages): @contextlib.contextmanager def _expect_warnings( - exc_cls, messages, regex=True, assert_=True, py2konly=False + exc_cls, + messages, + regex=True, + assert_=True, + py2konly=False, + raise_on_any_unexpected=False, ): if regex: @@ -145,7 +150,13 @@ def _expect_warnings( seen = set(filters) - real_warn = warnings.warn + if raise_on_any_unexpected: + + def real_warn(msg, *arg, **kw): + raise AssertionError("Got unexpected warning: %r" % msg) + + else: + real_warn = warnings.warn def our_warn(msg, *arg, **kw): if isinstance(msg, exc_cls): @@ -159,7 +170,7 @@ def _expect_warnings( if not exception or not issubclass(exception, exc_cls): return real_warn(msg, *arg, **kw) - if not filters: + if not filters and not raise_on_any_unexpected: return for filter_ in filters: |
