From: Mike Bayer Date: Tue, 25 Oct 2022 14:22:14 +0000 (-0400) Subject: raise for non-Load opt passed to options() X-Git-Tag: rel_1_4_43~17 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=dbae24ab4c5f1e02e81d7211c94e1c7d9fc3562f;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git raise for non-Load opt passed to options() Fixed the exception that's raised when the :func:`_orm.with_loader_criteria` option is attempted to be used within a specific loader path, like in loader.options(). :func:`_orm.with_loader_criteria` is only intended to be used at the top level. Fixes: #8711 Change-Id: Iaa7b13956b808761e618a6be6406e5c82df1c65c (cherry picked from commit eae9d1420bbfde4dbd835b654e80653cd5ac2155) --- diff --git a/doc/build/changelog/unreleased_14/8711.rst b/doc/build/changelog/unreleased_14/8711.rst new file mode 100644 index 0000000000..82e68bbc43 --- /dev/null +++ b/doc/build/changelog/unreleased_14/8711.rst @@ -0,0 +1,9 @@ +.. change:: + :tags: bug, orm + :tickets: 8711 + + Fixed the exception that's raised when the + :func:`_orm.with_loader_criteria` option is attempted to be used within a + specific loader path, like in loader.options(). + :func:`_orm.with_loader_criteria` is only intended to be used at the top + level. diff --git a/lib/sqlalchemy/orm/strategy_options.py b/lib/sqlalchemy/orm/strategy_options.py index 1b5e762eb2..ce67286ee0 100644 --- a/lib/sqlalchemy/orm/strategy_options.py +++ b/lib/sqlalchemy/orm/strategy_options.py @@ -518,7 +518,19 @@ class Load(Generative, LoaderOption): "for 'unbound' loader options" ) for opt in opts: - opt._apply_to_parent(self, apply_cache, bound) + try: + opt._apply_to_parent(self, apply_cache, bound) + except AttributeError as ae: + if not isinstance(opt, Load): + util.raise_( + sa_exc.ArgumentError( + "Loader option %s is not compatible with the " + "Load.options() method." % (opt,) + ), + from_=ae, + ) + else: + raise @_generative def set_relationship_strategy( diff --git a/test/orm/test_relationship_criteria.py b/test/orm/test_relationship_criteria.py index 7a347cd55b..97650f53c7 100644 --- a/test/orm/test_relationship_criteria.py +++ b/test/orm/test_relationship_criteria.py @@ -26,6 +26,7 @@ from sqlalchemy.orm import subqueryload from sqlalchemy.orm import with_loader_criteria from sqlalchemy.orm.decl_api import declared_attr from sqlalchemy.testing import eq_ +from sqlalchemy.testing import expect_raises_message from sqlalchemy.testing.assertions import expect_raises from sqlalchemy.testing.assertsql import CompiledSQL from sqlalchemy.testing.fixtures import fixture_session @@ -231,6 +232,22 @@ class LoaderCriteriaTest(_Fixtures, testing.AssertsCompiledSQL): "FROM users WHERE users.name != :name_1", ) + def test_err_given_in_pathed(self, user_address_fixture): + User, Address = user_address_fixture + + with expect_raises_message( + sa_exc.ArgumentError, + r"Loader option <.*LoaderCriteriaOption.*> is not compatible " + r"with the Load.options\(\) method.", + ): + select(User).options( + selectinload(User.addresses).options( + with_loader_criteria( + Address, Address.email_address != "foo" + ) + ) + ) + def test_criteria_post_replace(self, user_address_fixture): User, Address = user_address_fixture