summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authormike bayer <mike_mp@zzzcomputing.com>2021-03-23 18:28:33 +0000
committerGerrit Code Review <gerrit@ci3.zzzcomputing.com>2021-03-23 18:28:33 +0000
commit51bedc6751b440b51715420ca39c36fc6aea5349 (patch)
tree39d945c406dbe1918a6382e82997e524e19b00fe /lib
parent65c577583215d98423946d8d9bf377b63fc65e43 (diff)
parent9ec860e7a5c944799f9ef4de9069d707cfc1ed27 (diff)
downloadsqlalchemy-51bedc6751b440b51715420ca39c36fc6aea5349.tar.gz
Merge "Remove internal use of string attr in loader option"
Diffstat (limited to 'lib')
-rw-r--r--lib/sqlalchemy/orm/interfaces.py1
-rw-r--r--lib/sqlalchemy/orm/strategies.py2
-rw-r--r--lib/sqlalchemy/orm/strategy_options.py136
-rw-r--r--lib/sqlalchemy/testing/assertions.py17
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: