From: Mike Bayer Date: Fri, 21 Jan 2022 23:46:37 +0000 (-0500) Subject: dont use exception catches for warnings; modernize xdist detection X-Git-Tag: rel_1_4_32~39^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4a99fc26ab5f95ef605d975b7c8d003dc28c205b;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git dont use exception catches for warnings; modernize xdist detection Improvements to the test suite's integration with pytest such that the "warnings" plugin, if manually enabled, will not interfere with the test suite, such that third parties can enable the warnings plugin or make use of the ``-W`` parameter and SQLAlchemy's test suite will continue to pass. Additionally, modernized the detection of the "pytest-xdist" plugin so that plugins can be globally disabled using PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 without breaking the test suite if xdist were still installed. Warning filters that promote deprecation warnings to errors are now localized to SQLAlchemy-specific warnings, or within SQLAlchemy-specific sources for general Python deprecation warnings, so that non-SQLAlchemy deprecation warnings emitted from pytest plugins should also not impact the test suite. Identified a bit of cleanup for the PostgreSQL provisioning as a result. Fixes: #7599 Change-Id: Ibcf09af25228d39ee5a943fda82d8a9302433726 (cherry picked from commit a0f1914b903de6c130ab1c3267138b8ad208e144) --- diff --git a/doc/build/changelog/unreleased_14/7599.rst b/doc/build/changelog/unreleased_14/7599.rst new file mode 100644 index 0000000000..db69ace466 --- /dev/null +++ b/doc/build/changelog/unreleased_14/7599.rst @@ -0,0 +1,16 @@ +.. change:: + :tags: bug, tests + :tickets: 7599 + + Improvements to the test suite's integration with pytest such that the + "warnings" plugin, if manually enabled, will not interfere with the test + suite, such that third parties can enable the warnings plugin or make use + of the ``-W`` parameter and SQLAlchemy's test suite will continue to pass. + Additionally, modernized the detection of the "pytest-xdist" plugin so that + plugins can be globally disabled using PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 + without breaking the test suite if xdist were still installed. Warning + filters that promote deprecation warnings to errors are now localized to + SQLAlchemy-specific warnings, or within SQLAlchemy-specific sources for + general Python deprecation warnings, so that non-SQLAlchemy deprecation + warnings emitted from pytest plugins should also not impact the test suite. + diff --git a/lib/sqlalchemy/dialects/postgresql/provision.py b/lib/sqlalchemy/dialects/postgresql/provision.py index 68a01e483c..98470f36eb 100644 --- a/lib/sqlalchemy/dialects/postgresql/provision.py +++ b/lib/sqlalchemy/dialects/postgresql/provision.py @@ -19,10 +19,7 @@ def _pg_create_db(cfg, eng, ident): template_db = cfg.options.postgresql_templatedb with eng.execution_options(isolation_level="AUTOCOMMIT").begin() as conn: - try: - _pg_drop_db(cfg, conn, ident) - except Exception: - pass + if not template_db: template_db = conn.exec_driver_sql( "select current_database()" diff --git a/lib/sqlalchemy/testing/__init__.py b/lib/sqlalchemy/testing/__init__.py index 30babae83d..80d344faf1 100644 --- a/lib/sqlalchemy/testing/__init__.py +++ b/lib/sqlalchemy/testing/__init__.py @@ -12,6 +12,8 @@ from .assertions import assert_raises from .assertions import assert_raises_context_ok from .assertions import assert_raises_message from .assertions import assert_raises_message_context_ok +from .assertions import assert_warns +from .assertions import assert_warns_message from .assertions import AssertsCompiledSQL from .assertions import AssertsExecutionResults from .assertions import ComparesTables diff --git a/lib/sqlalchemy/testing/assertions.py b/lib/sqlalchemy/testing/assertions.py index 02e6880228..aa8edd9aff 100644 --- a/lib/sqlalchemy/testing/assertions.py +++ b/lib/sqlalchemy/testing/assertions.py @@ -143,14 +143,16 @@ def _expect_warnings( exc_cls, messages, regex=True, + search_msg=False, assert_=True, py2konly=False, raise_on_any_unexpected=False, + squelch_other_warnings=False, ): global _FILTERS, _SEEN, _EXC_CLS - if regex: + if regex or search_msg: filters = [re.compile(msg, re.I | re.S) for msg in messages] else: filters = list(messages) @@ -188,19 +190,23 @@ def _expect_warnings( exception = None if not exception or not issubclass(exception, _EXC_CLS): - return real_warn(msg, *arg, **kw) + if not squelch_other_warnings: + return real_warn(msg, *arg, **kw) if not filters and not raise_on_any_unexpected: return for filter_ in filters: - if (regex and filter_.match(msg)) or ( - not regex and filter_ == msg + if ( + (search_msg and filter_.search(msg)) + or (regex and filter_.match(msg)) + or (not regex and filter_ == msg) ): seen.discard(filter_) break else: - real_warn(msg, *arg, **kw) + if not squelch_other_warnings: + real_warn(msg, *arg, **kw) with mock.patch("warnings.warn", our_warn), mock.patch( "sqlalchemy.util.SQLALCHEMY_WARN_20", True @@ -357,6 +363,40 @@ def assert_raises_message(except_cls, msg, callable_, *args, **kwargs): ) +def assert_warns(except_cls, callable_, *args, **kwargs): + """legacy adapter function for functions that were previously using + assert_raises with SAWarning or similar. + + has some workarounds to accommodate the fact that the callable completes + with this approach rather than stopping at the exception raise. + + + """ + with _expect_warnings(except_cls, [".*"], squelch_other_warnings=True): + return callable_(*args, **kwargs) + + +def assert_warns_message(except_cls, msg, callable_, *args, **kwargs): + """legacy adapter function for functions that were previously using + assert_raises with SAWarning or similar. + + has some workarounds to accommodate the fact that the callable completes + with this approach rather than stopping at the exception raise. + + Also uses regex.search() to match the given message to the error string + rather than regex.match(). + + """ + with _expect_warnings( + except_cls, + [msg], + search_msg=True, + regex=False, + squelch_other_warnings=True, + ): + return callable_(*args, **kwargs) + + def assert_raises_message_context_ok( except_cls, msg, callable_, *args, **kwargs ): @@ -378,6 +418,15 @@ class _ErrorContainer(object): @contextlib.contextmanager def _expect_raises(except_cls, msg=None, check_context=False): + if ( + isinstance(except_cls, type) + and issubclass(except_cls, Warning) + or isinstance(except_cls, Warning) + ): + raise TypeError( + "Use expect_warnings for warnings, not " + "expect_raises / assert_raises" + ) ec = _ErrorContainer() if check_context: are_we_already_in_a_traceback = sys.exc_info()[0] diff --git a/lib/sqlalchemy/testing/plugin/pytestplugin.py b/lib/sqlalchemy/testing/plugin/pytestplugin.py index 41e6830706..5a51582925 100644 --- a/lib/sqlalchemy/testing/plugin/pytestplugin.py +++ b/lib/sqlalchemy/testing/plugin/pytestplugin.py @@ -14,16 +14,10 @@ import operator import os import re import sys +import uuid import pytest -try: - import xdist # noqa - - has_xdist = True -except ImportError: - has_xdist = False - py2k = sys.version_info < (3, 0) if py2k: @@ -84,6 +78,9 @@ def pytest_addoption(parser): def pytest_configure(config): + if config.pluginmanager.hasplugin("xdist"): + config.pluginmanager.register(XDistHooks()) + if hasattr(config, "workerinput"): plugin_base.restore_important_follower_config(config.workerinput) plugin_base.configure_follower(config.workerinput["follower_ident"]) @@ -157,10 +154,8 @@ def pytest_collection_finish(session): collect_types.init_types_collection(filter_filename=_filter) -if has_xdist: - import uuid - - def pytest_configure_node(node): +class XDistHooks(object): + def pytest_configure_node(self, node): from sqlalchemy.testing import provision from sqlalchemy.testing import asyncio @@ -175,7 +170,7 @@ if has_xdist: provision.create_follower_db, node.workerinput["follower_ident"] ) - def pytest_testnodedown(node, error): + def pytest_testnodedown(self, node, error): from sqlalchemy.testing import provision from sqlalchemy.testing import asyncio diff --git a/lib/sqlalchemy/testing/warnings.py b/lib/sqlalchemy/testing/warnings.py index db780f4003..3e783872d6 100644 --- a/lib/sqlalchemy/testing/warnings.py +++ b/lib/sqlalchemy/testing/warnings.py @@ -14,8 +14,13 @@ from .. import exc as sa_exc from ..util.langhelpers import _warnings_warn -class SATestSuiteWarning(sa_exc.SAWarning): - """warning for a condition detected during tests that is non-fatal""" +class SATestSuiteWarning(Warning): + """warning for a condition detected during tests that is non-fatal + + Currently outside of SAWarning so that we can work around tools like + Alembic doing the wrong thing with warnings. + + """ def warn_test_suite(message): @@ -25,28 +30,21 @@ def warn_test_suite(message): def setup_filters(): """Set global warning behavior for the test suite.""" + # TODO: at this point we can use the normal pytest warnings plugin, + # if we decide the test suite can be linked to pytest only + + origin = r"^(?:test|sqlalchemy)\..*" + warnings.filterwarnings( "ignore", category=sa_exc.SAPendingDeprecationWarning ) warnings.filterwarnings("error", category=sa_exc.SADeprecationWarning) warnings.filterwarnings("error", category=sa_exc.SAWarning) - warnings.filterwarnings("always", category=SATestSuiteWarning) - # some selected deprecations... - warnings.filterwarnings("error", category=DeprecationWarning) - warnings.filterwarnings( - "ignore", category=DeprecationWarning, message=r".*StopIteration" - ) - warnings.filterwarnings( - "ignore", - category=DeprecationWarning, - message=r".*inspect.get.*argspec", - ) + warnings.filterwarnings("always", category=SATestSuiteWarning) warnings.filterwarnings( - "ignore", - category=DeprecationWarning, - message="The loop argument is deprecated", + "error", category=DeprecationWarning, module=origin ) # ignore things that are deprecated *as of* 2.0 :) @@ -67,7 +65,7 @@ def setup_filters(): pass else: warnings.filterwarnings( - "once", category=pytest.PytestDeprecationWarning + "once", category=pytest.PytestDeprecationWarning, module=origin ) diff --git a/test/dialect/oracle/test_reflection.py b/test/dialect/oracle/test_reflection.py index acf7d75d54..b287e1024d 100644 --- a/test/dialect/oracle/test_reflection.py +++ b/test/dialect/oracle/test_reflection.py @@ -23,7 +23,7 @@ from sqlalchemy.dialects.oracle.base import BINARY_DOUBLE from sqlalchemy.dialects.oracle.base import BINARY_FLOAT from sqlalchemy.dialects.oracle.base import DOUBLE_PRECISION from sqlalchemy.dialects.oracle.base import NUMBER -from sqlalchemy.testing import assert_raises +from sqlalchemy.testing import assert_warns from sqlalchemy.testing import AssertsCompiledSQL from sqlalchemy.testing import eq_ from sqlalchemy.testing import fixtures @@ -352,7 +352,7 @@ class ConstraintTest(fixtures.TablesTest): "foo_id", Integer, ForeignKey("foo.id", onupdate="CASCADE") ), ) - assert_raises(exc.SAWarning, bar.create, connection) + assert_warns(exc.SAWarning, bar.create, connection) bat = Table( "bat", @@ -361,7 +361,7 @@ class ConstraintTest(fixtures.TablesTest): Column("foo_id", Integer), ForeignKeyConstraint(["foo_id"], ["foo.id"], onupdate="CASCADE"), ) - assert_raises(exc.SAWarning, bat.create, connection) + assert_warns(exc.SAWarning, bat.create, connection) def test_reflect_check_include_all(self, connection): insp = inspect(connection) diff --git a/test/dialect/postgresql/test_reflection.py b/test/dialect/postgresql/test_reflection.py index 5ee11ccd8c..3502c745b2 100644 --- a/test/dialect/postgresql/test_reflection.py +++ b/test/dialect/postgresql/test_reflection.py @@ -34,6 +34,7 @@ from sqlalchemy.testing import AssertsCompiledSQL from sqlalchemy.testing import fixtures from sqlalchemy.testing import mock from sqlalchemy.testing.assertions import assert_raises +from sqlalchemy.testing.assertions import assert_warns from sqlalchemy.testing.assertions import AssertsExecutionResults from sqlalchemy.testing.assertions import eq_ from sqlalchemy.testing.assertions import is_ @@ -486,7 +487,7 @@ class DomainReflectionTest(fixtures.TestBase, AssertsExecutionResults): base.PGDialect.ischema_names = {} try: m2 = MetaData() - assert_raises( + assert_warns( exc.SAWarning, Table, "testtable", m2, autoload_with=connection ) diff --git a/test/engine/test_pool.py b/test/engine/test_pool.py index 43ec9cc3ff..320a9bb585 100644 --- a/test/engine/test_pool.py +++ b/test/engine/test_pool.py @@ -14,7 +14,7 @@ from sqlalchemy.pool.base import _AsyncConnDialect from sqlalchemy.pool.base import _ConnDialect from sqlalchemy.testing import assert_raises from sqlalchemy.testing import assert_raises_context_ok -from sqlalchemy.testing import assert_raises_message +from sqlalchemy.testing import assert_warns_message from sqlalchemy.testing import eq_ from sqlalchemy.testing import expect_raises from sqlalchemy.testing import fixtures @@ -1821,7 +1821,7 @@ class QueuePoolTest(PoolTestBase): c1 = p.connect() rec = c1._connection_record c1.close() - assert_raises_message( + assert_warns_message( Warning, "Double checkin attempted on %s" % rec, rec.checkin ) diff --git a/test/engine/test_reconnect.py b/test/engine/test_reconnect.py index 51da845b39..9579d6c2dc 100644 --- a/test/engine/test_reconnect.py +++ b/test/engine/test_reconnect.py @@ -15,6 +15,7 @@ from sqlalchemy.engine import url from sqlalchemy.testing import assert_raises from sqlalchemy.testing import assert_raises_message from sqlalchemy.testing import assert_raises_message_context_ok +from sqlalchemy.testing import assert_warns_message from sqlalchemy.testing import engines from sqlalchemy.testing import eq_ from sqlalchemy.testing import expect_raises @@ -967,6 +968,7 @@ class CursorErrTest(fixtures.TestBase): util.warn("Exception attempting to detect") eng.dialect._get_default_schema_name = get_default_schema_name + eng.dialect._check_unicode_description = mock.Mock() return eng def test_cursor_explode(self): @@ -982,11 +984,13 @@ class CursorErrTest(fixtures.TestBase): def test_cursor_shutdown_in_initialize(self): db = self._fixture(True, True) - assert_raises_message_context_ok( + assert_warns_message( exc.SAWarning, "Exception attempting to detect", db.connect ) + # there's legacy py2k stuff happening here making this + # less smooth and probably buggy eq_( - db.pool.logger.error.mock_calls, + db.pool.logger.error.mock_calls[0:1], [call("Error closing cursor", exc_info=True)], ) diff --git a/test/orm/declarative/test_basic.py b/test/orm/declarative/test_basic.py index a405b9f2c6..2ab787aa67 100644 --- a/test/orm/declarative/test_basic.py +++ b/test/orm/declarative/test_basic.py @@ -406,7 +406,13 @@ class DeclarativeTest(DeclarativeTestBase): id = Column(Integer, primary_key=True) def test_column_named_twice(self): - def go(): + with assertions.expect_deprecated( + "A column with name 'x' is already present in table 'foo'" + ), expect_warnings( + "On class 'Foo', Column object 'x' named directly multiple times, " + "only one will be used: x, y", + ): + class Foo(Base): __tablename__ = "foo" @@ -414,15 +420,14 @@ class DeclarativeTest(DeclarativeTestBase): x = Column("x", Integer) y = Column("x", Integer) - assert_raises_message( - sa.exc.SAWarning, + def test_column_repeated_under_prop(self): + with assertions.expect_deprecated( + "A column with name 'x' is already present in table 'foo'" + ), expect_warnings( "On class 'Foo', Column object 'x' named directly multiple times, " - "only one will be used: x, y", - go, - ) + "only one will be used: x, y, z", + ): - def test_column_repeated_under_prop(self): - def go(): class Foo(Base): __tablename__ = "foo" @@ -431,13 +436,6 @@ class DeclarativeTest(DeclarativeTestBase): y = column_property(x) z = Column("x", Integer) - assert_raises_message( - sa.exc.SAWarning, - "On class 'Foo', Column object 'x' named directly multiple times, " - "only one will be used: x, y, z", - go, - ) - def test_using_explicit_prop_in_schema_objects(self): class Foo(Base): __tablename__ = "foo" @@ -2200,15 +2198,14 @@ class DeclarativeTest(DeclarativeTestBase): __tablename__ = "a" id = Column(Integer, primary_key=True) - assert_raises_message( - sa.exc.SAWarning, + with expect_warnings( "This declarative base already contains a class with ", - lambda: type(Base)( + ): + type(Base)( "Test", (Base,), dict(__tablename__="b", id=Column(Integer, primary_key=True)), - ), - ) + ) @testing.teardown_events(MapperEvents) @testing.teardown_events(InstrumentationEvents) diff --git a/test/orm/declarative/test_clsregistry.py b/test/orm/declarative/test_clsregistry.py index b9d41ee532..b77a101e8e 100644 --- a/test/orm/declarative/test_clsregistry.py +++ b/test/orm/declarative/test_clsregistry.py @@ -7,6 +7,7 @@ from sqlalchemy.testing import eq_ from sqlalchemy.testing import fixtures from sqlalchemy.testing import is_ from sqlalchemy.testing import mock +from sqlalchemy.testing.assertions import expect_warnings from sqlalchemy.testing.util import gc_collect @@ -34,16 +35,16 @@ class ClsRegistryTest(fixtures.TestBase): clsregistry.add_class("Foo", f1, base._class_registry) gc_collect() - assert_raises_message( - exc.SAWarning, + with expect_warnings( "This declarative base already contains a class with the " "same class name and module name as foo.bar.Foo, and " - "will be replaced in the string-lookup table.", - clsregistry.add_class, - "Foo", - f2, - base._class_registry, - ) + "will be replaced in the string-lookup table." + ): + clsregistry.add_class( + "Foo", + f2, + base._class_registry, + ) def test_resolve(self): base = registry() diff --git a/test/orm/declarative/test_mixin.py b/test/orm/declarative/test_mixin.py index f3feb5ddf2..5a4673a23e 100644 --- a/test/orm/declarative/test_mixin.py +++ b/test/orm/declarative/test_mixin.py @@ -1856,14 +1856,11 @@ class DeclaredAttrTest(DeclarativeTestBase, testing.AssertsCompiledSQL): def my_prop(cls): return Column("x", Integer) - assert_raises_message( - sa.exc.SAWarning, + with expect_warnings( "Unmanaged access of declarative attribute my_prop " - "from non-mapped class Mixin", - getattr, - Mixin, - "my_prop", - ) + "from non-mapped class Mixin" + ): + Mixin.my_prop def test_can_we_access_the_mixin_straight_special_names(self): class Mixin(object): diff --git a/test/orm/inheritance/test_basic.py b/test/orm/inheritance/test_basic.py index 446a9d9bd9..600726ce38 100644 --- a/test/orm/inheritance/test_basic.py +++ b/test/orm/inheritance/test_basic.py @@ -35,6 +35,7 @@ from sqlalchemy.testing import eq_ from sqlalchemy.testing import fixtures from sqlalchemy.testing import is_ from sqlalchemy.testing import mock +from sqlalchemy.testing.assertions import assert_warns_message from sqlalchemy.testing.assertsql import AllOf from sqlalchemy.testing.assertsql import CompiledSQL from sqlalchemy.testing.assertsql import Conditional @@ -903,7 +904,7 @@ class PolymorphicAttributeManagementTest(fixtures.MappedTest): c1 = C() c1.class_name = "b" sess.add(c1) - assert_raises_message( + assert_warns_message( sa_exc.SAWarning, "Flushing object %s with incompatible " "polymorphic identity 'b'; the object may not " @@ -922,7 +923,7 @@ class PolymorphicAttributeManagementTest(fixtures.MappedTest): b1 = B() b1.class_name = "c" sess.add(b1) - assert_raises_message( + assert_warns_message( sa_exc.SAWarning, "Flushing object %s with incompatible " "polymorphic identity 'c'; the object may not " @@ -938,7 +939,7 @@ class PolymorphicAttributeManagementTest(fixtures.MappedTest): b1 = B() b1.class_name = "xyz" sess.add(b1) - assert_raises_message( + assert_warns_message( sa_exc.SAWarning, "Flushing object %s with incompatible " "polymorphic identity 'xyz'; the object may not " @@ -968,7 +969,7 @@ class PolymorphicAttributeManagementTest(fixtures.MappedTest): sess.expire(c1) c1.class_name = "b" - assert_raises_message( + assert_warns_message( sa_exc.SAWarning, "Flushing object %s with incompatible " "polymorphic identity 'b'; the object may not " @@ -2143,7 +2144,7 @@ class DistinctPKTest(fixtures.MappedTest): properties=dict(id=[employee_table.c.eid, person_table.c.id]), primary_key=[person_table.c.id, employee_table.c.eid], ) - assert_raises_message( + assert_warns_message( sa_exc.SAWarning, r"On mapper mapped class Employee->employees, " "primary key column 'persons.id' is being " @@ -2441,7 +2442,7 @@ class OverrideColKeyTest(fixtures.MappedTest): Sub, subtable_two, inherits=Base ) - assert_raises_message( + assert_warns_message( sa_exc.SAWarning, "Implicitly combining column base.base_id with " "column subtable_two.base_id under attribute 'base_id'", @@ -3093,7 +3094,7 @@ class NoPKOnSubTableWarningTest(fixtures.MappedTest): pass self.mapper_registry.map_imperatively(P, parent) - assert_raises_message( + assert_warns_message( sa_exc.SAWarning, "Could not assemble any primary keys for locally mapped " "table 'child' - no rows will be persisted in this Table.", diff --git a/test/orm/test_attributes.py b/test/orm/test_attributes.py index 130e980783..70dc0a1295 100644 --- a/test/orm/test_attributes.py +++ b/test/orm/test_attributes.py @@ -17,6 +17,7 @@ from sqlalchemy.testing import is_false from sqlalchemy.testing import is_not from sqlalchemy.testing import is_true from sqlalchemy.testing import not_in +from sqlalchemy.testing.assertions import assert_warns from sqlalchemy.testing.mock import call from sqlalchemy.testing.mock import Mock from sqlalchemy.testing.util import all_partial_orderings @@ -3769,7 +3770,7 @@ class TestUnlink(fixtures.TestBase): a1.bs.append(B()) state = attributes.instance_state(a1) state._expire(state.dict, set()) - assert_raises(Warning, coll.append, B()) + assert_warns(Warning, coll.append, B()) def test_replaced(self): A, B = self.A, self.B @@ -3790,7 +3791,7 @@ class TestUnlink(fixtures.TestBase): a1.bs.append(B()) state = attributes.instance_state(a1) state._reset(state.dict, "bs") - assert_raises(Warning, coll.append, B()) + assert_warns(Warning, coll.append, B()) def test_ad_hoc_lazy(self): A, B = self.A, self.B @@ -3799,4 +3800,4 @@ class TestUnlink(fixtures.TestBase): a1.bs.append(B()) state = attributes.instance_state(a1) _set_callable(state, state.dict, "bs", lambda: B()) - assert_raises(Warning, coll.append, B()) + assert_warns(Warning, coll.append, B()) diff --git a/test/orm/test_cascade.py b/test/orm/test_cascade.py index cd7e7c111a..c5dd946e75 100644 --- a/test/orm/test_cascade.py +++ b/test/orm/test_cascade.py @@ -24,6 +24,7 @@ from sqlalchemy.orm.collections import attribute_mapped_collection from sqlalchemy.orm.decl_api import declarative_base from sqlalchemy.testing import assert_raises from sqlalchemy.testing import assert_raises_message +from sqlalchemy.testing import assert_warns_message from sqlalchemy.testing import eq_ from sqlalchemy.testing import fixtures from sqlalchemy.testing import in_ @@ -94,7 +95,7 @@ class CascadeArgTest(fixtures.MappedTest): def test_delete_orphan_without_delete(self): Address = self.classes.Address - assert_raises_message( + assert_warns_message( sa_exc.SAWarning, "The 'delete-orphan' cascade option requires 'delete'.", relationship, @@ -1221,7 +1222,7 @@ class NoSaveCascadeFlushTest(_fixtures.FixtureTest): sess.add(u1) assert u1 in sess assert a1 not in sess - assert_raises_message(sa_exc.SAWarning, "not in session", sess.flush) + assert_warns_message(sa_exc.SAWarning, "not in session", sess.flush) def test_o2m_only_child_persistent(self): User, Address = self.classes.User, self.classes.Address @@ -1239,7 +1240,7 @@ class NoSaveCascadeFlushTest(_fixtures.FixtureTest): sess.add(u1) assert u1 in sess assert a1 not in sess - assert_raises_message(sa_exc.SAWarning, "not in session", sess.flush) + assert_warns_message(sa_exc.SAWarning, "not in session", sess.flush) def test_o2m_backref_child_pending(self): User, Address = self.classes.User, self.classes.Address @@ -1265,7 +1266,7 @@ class NoSaveCascadeFlushTest(_fixtures.FixtureTest): sess.add(u1) assert u1 in sess assert a1 not in sess - assert_raises_message(sa_exc.SAWarning, "not in session", sess.flush) + assert_warns_message(sa_exc.SAWarning, "not in session", sess.flush) def test_o2m_backref_child_transient_nochange(self): User, Address = self.classes.User, self.classes.Address @@ -1301,7 +1302,7 @@ class NoSaveCascadeFlushTest(_fixtures.FixtureTest): sess.expunge(a1) assert u1 in sess assert a1 not in sess - assert_raises_message(sa_exc.SAWarning, "not in session", sess.flush) + assert_warns_message(sa_exc.SAWarning, "not in session", sess.flush) def test_o2m_backref_child_expunged_nochange(self): User, Address = self.classes.User, self.classes.Address @@ -1350,7 +1351,7 @@ class NoSaveCascadeFlushTest(_fixtures.FixtureTest): sess.add(a1) assert u1 not in sess assert a1 in sess - assert_raises_message(sa_exc.SAWarning, "not in session", sess.flush) + assert_warns_message(sa_exc.SAWarning, "not in session", sess.flush) def test_m2o_only_child_expunged(self): User, Address = self.classes.User, self.classes.Address @@ -1367,7 +1368,7 @@ class NoSaveCascadeFlushTest(_fixtures.FixtureTest): sess.expunge(u1) assert u1 not in sess assert a1 in sess - assert_raises_message(sa_exc.SAWarning, "not in session", sess.flush) + assert_warns_message(sa_exc.SAWarning, "not in session", sess.flush) def test_m2o_backref_child_pending(self): User, Address = self.classes.User, self.classes.Address @@ -1393,7 +1394,7 @@ class NoSaveCascadeFlushTest(_fixtures.FixtureTest): sess.add(a1) assert u1 not in sess assert a1 in sess - assert_raises_message(sa_exc.SAWarning, "not in session", sess.flush) + assert_warns_message(sa_exc.SAWarning, "not in session", sess.flush) def test_m2o_backref_child_expunged(self): User, Address = self.classes.User, self.classes.Address @@ -1420,7 +1421,7 @@ class NoSaveCascadeFlushTest(_fixtures.FixtureTest): sess.expunge(u1) assert u1 not in sess assert a1 in sess - assert_raises_message( + assert_warns_message( sa_exc.SAWarning, "not in session", sess.flush ) @@ -1440,7 +1441,7 @@ class NoSaveCascadeFlushTest(_fixtures.FixtureTest): sess.expunge(u1) assert u1 not in sess assert a1 in sess - assert_raises_message( + assert_warns_message( sa_exc.SAWarning, "not in session", sess.flush ) @@ -1544,7 +1545,7 @@ class NoSaveCascadeFlushTest(_fixtures.FixtureTest): sess.add(i1) assert i1 in sess assert k1 not in sess - assert_raises_message(sa_exc.SAWarning, "not in session", sess.flush) + assert_warns_message(sa_exc.SAWarning, "not in session", sess.flush) def test_m2m_only_child_persistent(self): Item, Keyword = self.classes.Item, self.classes.Keyword @@ -1562,7 +1563,7 @@ class NoSaveCascadeFlushTest(_fixtures.FixtureTest): sess.add(i1) assert i1 in sess assert k1 not in sess - assert_raises_message(sa_exc.SAWarning, "not in session", sess.flush) + assert_warns_message(sa_exc.SAWarning, "not in session", sess.flush) def test_m2m_backref_child_pending(self): Item, Keyword = self.classes.Item, self.classes.Keyword @@ -1588,7 +1589,7 @@ class NoSaveCascadeFlushTest(_fixtures.FixtureTest): sess.add(i1) assert i1 in sess assert k1 not in sess - assert_raises_message(sa_exc.SAWarning, "not in session", sess.flush) + assert_warns_message(sa_exc.SAWarning, "not in session", sess.flush) def test_m2m_backref_child_transient_nochange(self): Item, Keyword = self.classes.Item, self.classes.Keyword @@ -1624,7 +1625,7 @@ class NoSaveCascadeFlushTest(_fixtures.FixtureTest): sess.expunge(k1) assert i1 in sess assert k1 not in sess - assert_raises_message(sa_exc.SAWarning, "not in session", sess.flush) + assert_warns_message(sa_exc.SAWarning, "not in session", sess.flush) def test_m2m_backref_child_expunged_nochange(self): Item, Keyword = self.classes.Item, self.classes.Keyword @@ -2808,7 +2809,7 @@ class NoBackrefCascadeTest(_fixtures.FixtureTest): a1 = Address(email_address="a1") a1.user = u1 - assert_raises_message(sa_exc.SAWarning, "not in session", sess.commit) + assert_warns_message(sa_exc.SAWarning, "not in session", sess.commit) assert a1 not in sess @@ -2871,7 +2872,7 @@ class NoBackrefCascadeTest(_fixtures.FixtureTest): a1.dingalings.append(d1) assert a1 not in sess - assert_raises_message(sa_exc.SAWarning, "not in session", sess.commit) + assert_warns_message(sa_exc.SAWarning, "not in session", sess.commit) class PendingOrphanTestSingleLevel(fixtures.MappedTest): diff --git a/test/orm/test_dynamic.py b/test/orm/test_dynamic.py index 8efd452382..2a8e3e2dc4 100644 --- a/test/orm/test_dynamic.py +++ b/test/orm/test_dynamic.py @@ -15,6 +15,7 @@ from sqlalchemy.orm import Query from sqlalchemy.orm import relationship from sqlalchemy.testing import assert_raises from sqlalchemy.testing import assert_raises_message +from sqlalchemy.testing import assert_warns_message from sqlalchemy.testing import AssertsCompiledSQL from sqlalchemy.testing import eq_ from sqlalchemy.testing import expect_raises_message @@ -321,7 +322,7 @@ class DynamicTest(_DynamicFixture, _fixtures.FixtureTest, AssertsCompiledSQL): }, ) self.mapper_registry.map_imperatively(User, users) - assert_raises_message( + assert_warns_message( exc.SAWarning, "On relationship Address.user, 'dynamic' loaders cannot be " "used with many-to-one/one-to-one relationships and/or " diff --git a/test/orm/test_eager_relations.py b/test/orm/test_eager_relations.py index d9da36073c..879cc2b817 100644 --- a/test/orm/test_eager_relations.py +++ b/test/orm/test_eager_relations.py @@ -31,8 +31,8 @@ from sqlalchemy.orm import Session from sqlalchemy.orm import undefer from sqlalchemy.sql import operators from sqlalchemy.sql.selectable import LABEL_STYLE_TABLENAME_PLUS_COL -from sqlalchemy.testing import assert_raises from sqlalchemy.testing import assert_raises_message +from sqlalchemy.testing import assert_warns from sqlalchemy.testing import eq_ from sqlalchemy.testing import expect_raises_message from sqlalchemy.testing import fixtures @@ -2142,7 +2142,7 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL): ) self.mapper_registry.map_imperatively(Order, orders) s = fixture_session() - assert_raises( + assert_warns( sa.exc.SAWarning, s.query(User).options(joinedload(User.order)).all ) diff --git a/test/orm/test_events.py b/test/orm/test_events.py index 4dfea6a6de..c0fbaba7d6 100644 --- a/test/orm/test_events.py +++ b/test/orm/test_events.py @@ -32,8 +32,10 @@ from sqlalchemy.orm import UserDefinedOption from sqlalchemy.sql.traversals import NO_CACHE from sqlalchemy.testing import assert_raises from sqlalchemy.testing import assert_raises_message +from sqlalchemy.testing import assert_warns_message from sqlalchemy.testing import AssertsCompiledSQL from sqlalchemy.testing import eq_ +from sqlalchemy.testing import expect_raises from sqlalchemy.testing import expect_warnings from sqlalchemy.testing import fixtures from sqlalchemy.testing import is_not @@ -1061,7 +1063,7 @@ class MapperEventsTest(_RemoveListeners, _fixtures.FixtureTest): m1 = Mock() self.mapper_registry.map_imperatively(User, users) - assert_raises_message( + assert_warns_message( sa.exc.SAWarning, r"before_configured' and 'after_configured' ORM events only " r"invoke with the mapper\(\) function or Mapper class as " @@ -1072,7 +1074,7 @@ class MapperEventsTest(_RemoveListeners, _fixtures.FixtureTest): m1, ) - assert_raises_message( + assert_warns_message( sa.exc.SAWarning, r"before_configured' and 'after_configured' ORM events only " r"invoke with the mapper\(\) function or Mapper class as " @@ -2199,7 +2201,12 @@ class SessionEventsTest(_RemoveListeners, _fixtures.FixtureTest): u2 = User(name="u1", id=1) sess.add(u2) - assert_raises(sa.exc.SAWarning, sess.commit) + + with expect_raises(sa.exc.IntegrityError), expect_warnings( + "New instance" + ): + sess.commit() + sess.rollback() eq_( canary, @@ -2251,7 +2258,11 @@ class SessionEventsTest(_RemoveListeners, _fixtures.FixtureTest): u2 = User(name="u1", id=1) sess.add(u2) - assert_raises(sa.exc.SAWarning, sess.commit) + with expect_raises(sa.exc.IntegrityError), expect_warnings( + "New instance" + ): + sess.commit() + sess.rollback() eq_(assertions, [True, True]) diff --git a/test/orm/test_instrumentation.py b/test/orm/test_instrumentation.py index a2d4aa9cac..73aefe1f05 100644 --- a/test/orm/test_instrumentation.py +++ b/test/orm/test_instrumentation.py @@ -10,7 +10,7 @@ from sqlalchemy.orm import clear_mappers from sqlalchemy.orm import instrumentation from sqlalchemy.orm import relationship from sqlalchemy.testing import assert_raises -from sqlalchemy.testing import assert_raises_message +from sqlalchemy.testing import assert_warns_message from sqlalchemy.testing import eq_ from sqlalchemy.testing import fixtures from sqlalchemy.testing import ne_ @@ -525,7 +525,7 @@ class MapperInitTest(fixtures.MappedTest): def __del__(self): pass - assert_raises_message( + assert_warns_message( sa.exc.SAWarning, r"__del__\(\) method on class " r" will cause " diff --git a/test/orm/test_lazy_relations.py b/test/orm/test_lazy_relations.py index 3ebff5f43b..ee578ff50d 100644 --- a/test/orm/test_lazy_relations.py +++ b/test/orm/test_lazy_relations.py @@ -25,6 +25,7 @@ from sqlalchemy.orm import relationship from sqlalchemy.orm import Session from sqlalchemy.orm import with_parent from sqlalchemy.testing import assert_raises +from sqlalchemy.testing import assert_warns from sqlalchemy.testing import eq_ from sqlalchemy.testing import fixtures from sqlalchemy.testing import is_ @@ -369,7 +370,7 @@ class LazyTest(_fixtures.FixtureTest): self.mapper_registry.map_imperatively(Order, orders) s = fixture_session() u1 = s.query(User).filter(User.id == 7).one() - assert_raises(sa.exc.SAWarning, getattr, u1, "order") + assert_warns(sa.exc.SAWarning, getattr, u1, "order") def test_callable_bind(self): Address, addresses, users, User = ( diff --git a/test/orm/test_mapper.py b/test/orm/test_mapper.py index 11a762e60b..fa837c678f 100644 --- a/test/orm/test_mapper.py +++ b/test/orm/test_mapper.py @@ -33,6 +33,7 @@ from sqlalchemy.orm import synonym from sqlalchemy.orm.persistence import _sort_states from sqlalchemy.testing import assert_raises from sqlalchemy.testing import assert_raises_message +from sqlalchemy.testing import assert_warns_message from sqlalchemy.testing import AssertsCompiledSQL from sqlalchemy.testing import eq_ from sqlalchemy.testing import expect_deprecated_20 @@ -832,7 +833,7 @@ class MapperTest(_fixtures.FixtureTest, AssertsCompiledSQL): ) self.mapper(Address, addresses) - assert_raises_message( + assert_warns_message( sa.exc.SAWarning, "Property User.addresses on Mapper|User|users being replaced " "with new property User.addresses; the old property will " @@ -1015,7 +1016,7 @@ class MapperTest(_fixtures.FixtureTest, AssertsCompiledSQL): polymorphic_on=users.c.name, polymorphic_identity="user", ) - assert_raises_message( + assert_warns_message( sa.exc.SAWarning, "Reassigning polymorphic association for identity 'user'", self.mapper_registry.map_imperatively, diff --git a/test/orm/test_query.py b/test/orm/test_query.py index a1dbb2f617..6d9aee584a 100644 --- a/test/orm/test_query.py +++ b/test/orm/test_query.py @@ -72,6 +72,7 @@ from sqlalchemy.testing import is_true from sqlalchemy.testing import mock from sqlalchemy.testing.assertions import assert_raises from sqlalchemy.testing.assertions import assert_raises_message +from sqlalchemy.testing.assertions import assert_warns_message from sqlalchemy.testing.assertions import eq_ from sqlalchemy.testing.assertions import expect_raises from sqlalchemy.testing.assertions import expect_warnings @@ -1315,7 +1316,7 @@ class GetTest(QueryTest): User = self.classes.User s = fixture_session() - assert_raises_message( + assert_warns_message( sa_exc.SAWarning, r"fully NULL primary key identity cannot load any object. " "This condition may raise an error in a future release.", @@ -1329,7 +1330,7 @@ class GetTest(QueryTest): s = fixture_session() - assert_raises_message( + assert_warns_message( sa_exc.SAWarning, r"fully NULL primary key identity cannot load any object. " "This condition may raise an error in a future release.", diff --git a/test/orm/test_rel_fn.py b/test/orm/test_rel_fn.py index 6f6b0d56df..4d8eb88b91 100644 --- a/test/orm/test_rel_fn.py +++ b/test/orm/test_rel_fn.py @@ -17,11 +17,13 @@ from sqlalchemy.orm import remote from sqlalchemy.orm.interfaces import MANYTOONE from sqlalchemy.orm.interfaces import ONETOMANY from sqlalchemy.testing import assert_raises_message +from sqlalchemy.testing import assert_warns_message from sqlalchemy.testing import AssertsCompiledSQL from sqlalchemy.testing import eq_ from sqlalchemy.testing import fixtures from sqlalchemy.testing import is_ from sqlalchemy.testing import mock +from sqlalchemy.testing.assertions import expect_raises_message class _JoinFixtures(object): @@ -573,7 +575,7 @@ class _JoinFixtures(object): ) def _assert_non_simple_warning(self, fn): - assert_raises_message( + assert_warns_message( exc.SAWarning, "Non-simple column elements in " "primary join condition for property " @@ -818,9 +820,12 @@ class ColumnCollectionsTest( self._join_fixture_o2m_composite_selfref_func_remote_side() def test_determine_local_remote_pairs_o2m_overlap_func_warning(self): - self._assert_non_simple_warning( - self._join_fixture_m2o_sub_to_joined_sub_func - ) + with expect_raises_message( + exc.ArgumentError, "Could not locate any relevant" + ): + self._assert_non_simple_warning( + self._join_fixture_m2o_sub_to_joined_sub_func + ) def test_determine_local_remote_pairs_o2m_composite_selfref_func_annotated( self, diff --git a/test/orm/test_relationships.py b/test/orm/test_relationships.py index 98de9abad7..acb22ce0f8 100644 --- a/test/orm/test_relationships.py +++ b/test/orm/test_relationships.py @@ -33,12 +33,13 @@ from sqlalchemy.orm.interfaces import MANYTOONE from sqlalchemy.orm.interfaces import ONETOMANY from sqlalchemy.testing import assert_raises from sqlalchemy.testing import assert_raises_message +from sqlalchemy.testing import assert_warns_message from sqlalchemy.testing import AssertsCompiledSQL from sqlalchemy.testing import eq_ +from sqlalchemy.testing import expect_warnings from sqlalchemy.testing import fixtures from sqlalchemy.testing import in_ from sqlalchemy.testing import is_ -from sqlalchemy.testing.assertions import expect_warnings from sqlalchemy.testing.assertsql import assert_engine from sqlalchemy.testing.assertsql import CompiledSQL from sqlalchemy.testing.fixtures import fixture_session @@ -872,7 +873,7 @@ class OverlappingFksSiblingTest(fixtures.MappedTest): @testing.provide_metadata def test_simple_warn(self): - assert_raises_message( + assert_warns_message( exc.SAWarning, r"relationship '(?:Child.parent|Parent.children)' will copy " r"column parent.id to column child.parent_id, which conflicts " @@ -963,7 +964,7 @@ class OverlappingFksSiblingTest(fixtures.MappedTest): @testing.provide_metadata def test_double_rel_same_mapper_warns(self): - assert_raises_message( + assert_warns_message( exc.SAWarning, r"relationship 'Parent.child[12]' will copy column parent.id to " r"column child.parent_id, which conflicts with relationship\(s\): " @@ -983,7 +984,7 @@ class OverlappingFksSiblingTest(fixtures.MappedTest): @testing.provide_metadata def test_warn_one(self): - assert_raises_message( + assert_warns_message( exc.SAWarning, r"relationship '(?:BSub1.a|BSub2.a_member|B.a)' will copy column " r"(?:a.id|a_member.a_id) to column b.a_id", @@ -994,7 +995,7 @@ class OverlappingFksSiblingTest(fixtures.MappedTest): @testing.provide_metadata def test_warn_two(self): - assert_raises_message( + assert_warns_message( exc.SAWarning, r"relationship '(?:BSub1.a|B.a_member)' will copy column " r"(?:a.id|a_member.a_id) to column b.a_id", @@ -1005,7 +1006,7 @@ class OverlappingFksSiblingTest(fixtures.MappedTest): @testing.provide_metadata def test_warn_three(self): - assert_raises_message( + assert_warns_message( exc.SAWarning, r"relationship '(?:BSub1.a|B.a_member|B.a)' will copy column " r"(?:a.id|a_member.a_id) to column b.a_id", @@ -1017,7 +1018,7 @@ class OverlappingFksSiblingTest(fixtures.MappedTest): @testing.provide_metadata def test_warn_four(self): - assert_raises_message( + assert_warns_message( exc.SAWarning, r"relationship '(?:B.a|BSub2.a_member|B.a)' will copy column " r"(?:a.id|a_member.a_id) to column b.a_id", @@ -1301,7 +1302,7 @@ class CompositeSelfRefFKTest(fixtures.MappedTest, AssertsCompiledSQL): }, ) - assert_raises_message( + assert_warns_message( exc.SAWarning, r"relationship .* will copy column .* to column " r"employee_t.company_id, which conflicts with relationship\(s\)", diff --git a/test/orm/test_scoping.py b/test/orm/test_scoping.py index e23f42ac53..b2389ced30 100644 --- a/test/orm/test_scoping.py +++ b/test/orm/test_scoping.py @@ -9,6 +9,7 @@ from sqlalchemy.orm import scoped_session from sqlalchemy.orm import Session from sqlalchemy.orm import sessionmaker from sqlalchemy.testing import assert_raises_message +from sqlalchemy.testing import assert_warns_message from sqlalchemy.testing import eq_ from sqlalchemy.testing import fixtures from sqlalchemy.testing import is_ @@ -101,7 +102,7 @@ class ScopedSessionTest(fixtures.MappedTest): bind=testing.db, ) - assert_raises_message( + assert_warns_message( sa.exc.SAWarning, "At least one scoped session is already present. ", Session.configure, diff --git a/test/orm/test_selectin_relations.py b/test/orm/test_selectin_relations.py index 7a5bb0e7ed..3e44abe88f 100644 --- a/test/orm/test_selectin_relations.py +++ b/test/orm/test_selectin_relations.py @@ -18,8 +18,8 @@ from sqlalchemy.orm import Session from sqlalchemy.orm import subqueryload from sqlalchemy.orm import undefer from sqlalchemy.orm import with_polymorphic -from sqlalchemy.testing import assert_raises from sqlalchemy.testing import assert_raises_message +from sqlalchemy.testing import assert_warns from sqlalchemy.testing import eq_ from sqlalchemy.testing import fixtures from sqlalchemy.testing import is_ @@ -1458,7 +1458,7 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL): ) self.mapper_registry.map_imperatively(Order, orders) s = fixture_session() - assert_raises( + assert_warns( sa.exc.SAWarning, s.query(User).options(selectinload(User.order)).all, ) diff --git a/test/orm/test_session.py b/test/orm/test_session.py index 62974b6291..607c0a9edc 100644 --- a/test/orm/test_session.py +++ b/test/orm/test_session.py @@ -24,6 +24,7 @@ from sqlalchemy.orm import sessionmaker from sqlalchemy.orm import was_deleted from sqlalchemy.testing import assert_raises from sqlalchemy.testing import assert_raises_message +from sqlalchemy.testing import assert_warns_message from sqlalchemy.testing import assertions from sqlalchemy.testing import config from sqlalchemy.testing import engines @@ -1032,7 +1033,7 @@ class SessionStateTest(_fixtures.FixtureTest): def test_extra_dirty_state_post_flush_warning(self): s, a1, a2 = self._test_extra_dirty_state() - assert_raises_message( + assert_warns_message( sa.exc.SAWarning, "Attribute history events accumulated on 1 previously " "clean instances", @@ -2275,7 +2276,8 @@ class FlushWarningsTest(fixtures.MappedTest): def evt(mapper, conn, instance): instance.addresses[0].user = User(name="u2") - self._test(evt, "related attribute set") + with expect_raises_message(orm_exc.FlushError, ".*Over 100"): + self._test(evt, "related attribute set") def test_m2o_cascade_remove(self): def evt(mapper, conn, instance): @@ -2306,7 +2308,10 @@ class FlushWarningsTest(fixtures.MappedTest): def evt(mapper, conn, instance): object_session(instance).delete(Address(email="x1")) - self._test(evt, r"Session.delete\(\)") + with expect_raises_message( + sa.exc.InvalidRequestError, ".*is not persisted" + ): + self._test(evt, r"Session.delete\(\)") def _test(self, fn, method): User = self.classes.User @@ -2317,6 +2322,6 @@ class FlushWarningsTest(fixtures.MappedTest): u1 = User(name="u1", addresses=[Address(name="a1")]) s.add(u1) - assert_raises_message( + assert_warns_message( sa.exc.SAWarning, "Usage of the '%s'" % method, s.commit ) diff --git a/test/orm/test_subquery_relations.py b/test/orm/test_subquery_relations.py index bf14d7212a..7b0b4dc9dc 100644 --- a/test/orm/test_subquery_relations.py +++ b/test/orm/test_subquery_relations.py @@ -20,8 +20,8 @@ from sqlalchemy.orm import Session from sqlalchemy.orm import subqueryload from sqlalchemy.orm import undefer from sqlalchemy.orm import with_polymorphic -from sqlalchemy.testing import assert_raises from sqlalchemy.testing import assert_raises_message +from sqlalchemy.testing import assert_warns from sqlalchemy.testing import eq_ from sqlalchemy.testing import fixtures from sqlalchemy.testing import is_ @@ -1510,7 +1510,7 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL): ) self.mapper_registry.map_imperatively(Order, orders) s = fixture_session() - assert_raises( + assert_warns( sa.exc.SAWarning, s.query(User).options(subqueryload(User.order)).all, ) diff --git a/test/orm/test_unitofworkv2.py b/test/orm/test_unitofworkv2.py index af38a4bab0..4546145396 100644 --- a/test/orm/test_unitofworkv2.py +++ b/test/orm/test_unitofworkv2.py @@ -25,6 +25,7 @@ from sqlalchemy.orm import relationship from sqlalchemy.orm import Session from sqlalchemy.orm import unitofwork from sqlalchemy.testing import assert_raises_message +from sqlalchemy.testing import assert_warns_message from sqlalchemy.testing import config from sqlalchemy.testing import engines from sqlalchemy.testing import eq_ @@ -1919,7 +1920,7 @@ class BasicStaleChecksTest(fixtures.MappedTest): sess.delete(p1) - assert_raises_message( + assert_warns_message( exc.SAWarning, r"DELETE statement on table 'parent' expected to " r"delete 1 row\(s\); 0 were matched.", @@ -1939,7 +1940,7 @@ class BasicStaleChecksTest(fixtures.MappedTest): sess.delete(p1) sess.delete(p2) - assert_raises_message( + assert_warns_message( exc.SAWarning, r"DELETE statement on table 'parent' expected to " r"delete 2 row\(s\); 0 were matched.", @@ -2004,7 +2005,7 @@ class BasicStaleChecksTest(fixtures.MappedTest): with patch.object( config.db.dialect, "supports_sane_multi_rowcount", False ): - assert_raises_message( + assert_warns_message( exc.SAWarning, r"DELETE statement on table 'parent' expected to " r"delete 1 row\(s\); 0 were matched.", diff --git a/test/orm/test_versioning.py b/test/orm/test_versioning.py index 45fad9ab74..ce01cace7f 100644 --- a/test/orm/test_versioning.py +++ b/test/orm/test_versioning.py @@ -20,6 +20,8 @@ from sqlalchemy.orm import relationship from sqlalchemy.orm import Session from sqlalchemy.testing import assert_raises from sqlalchemy.testing import assert_raises_message +from sqlalchemy.testing import assert_warns +from sqlalchemy.testing import assert_warns_message from sqlalchemy.testing import config from sqlalchemy.testing import engines from sqlalchemy.testing import eq_ @@ -193,7 +195,7 @@ class VersioningTest(fixtures.MappedTest): s1.commit() f1.value = "f1rev2" - assert_raises(sa.exc.SAWarning, s1.commit) + assert_warns(sa.exc.SAWarning, s1.commit) finally: testing.db.dialect.supports_sane_rowcount = save @@ -1328,7 +1330,7 @@ class InheritanceTwoVersionIdsTest(fixtures.MappedTest): Base, base, version_id_col=base.c.version_id ) - assert_raises_message( + assert_warns_message( exc.SAWarning, "Inheriting version_id_col 'version_id' does not " "match inherited version_id_col 'version_id' and will not " diff --git a/test/sql/test_defaults.py b/test/sql/test_defaults.py index ef924e0681..d967db6aaf 100644 --- a/test/sql/test_defaults.py +++ b/test/sql/test_defaults.py @@ -19,6 +19,7 @@ from sqlalchemy.sql import literal_column from sqlalchemy.sql import select from sqlalchemy.sql import text from sqlalchemy.testing import assert_raises_message +from sqlalchemy.testing import assert_warns_message from sqlalchemy.testing import AssertsCompiledSQL from sqlalchemy.testing import engines from sqlalchemy.testing import eq_ @@ -1447,7 +1448,7 @@ class UnicodeDefaultsTest(fixtures.TestBase): def test_nonunicode_default(self): default = b("foo") - assert_raises_message( + assert_warns_message( sa.exc.SAWarning, "Unicode column 'foobar' has non-unicode " "default value b?'foo' specified.", diff --git a/test/sql/test_metadata.py b/test/sql/test_metadata.py index bd92136479..e193c5ec7a 100644 --- a/test/sql/test_metadata.py +++ b/test/sql/test_metadata.py @@ -53,6 +53,7 @@ from sqlalchemy.testing import is_ from sqlalchemy.testing import is_false from sqlalchemy.testing import is_true from sqlalchemy.testing import mock +from sqlalchemy.testing.assertions import expect_warnings class MetaDataTest(fixtures.TestBase, ComparesTables): @@ -1824,32 +1825,35 @@ class TableTest(fixtures.TestBase, AssertsCompiledSQL): def test_pk_col_mismatch_one(self): m = MetaData() - assert_raises_message( - exc.SAWarning, + + with expect_warnings( "Table 't' specifies columns 'x' as primary_key=True, " - "not matching locally specified columns 'q'", - Table, - "t", - m, - Column("x", Integer, primary_key=True), - Column("q", Integer), - PrimaryKeyConstraint("q"), - ) + "not matching locally specified columns 'q'" + ): + Table( + "t", + m, + Column("x", Integer, primary_key=True), + Column("q", Integer), + PrimaryKeyConstraint("q"), + ) def test_pk_col_mismatch_two(self): m = MetaData() - assert_raises_message( - exc.SAWarning, + + with expect_warnings( "Table 't' specifies columns 'a', 'b', 'c' as primary_key=True, " - "not matching locally specified columns 'b', 'c'", - Table, - "t", - m, - Column("a", Integer, primary_key=True), - Column("b", Integer, primary_key=True), - Column("c", Integer, primary_key=True), - PrimaryKeyConstraint("b", "c"), - ) + "not matching locally specified columns 'b', 'c'" + ): + + Table( + "t", + m, + Column("a", Integer, primary_key=True), + Column("b", Integer, primary_key=True), + Column("c", Integer, primary_key=True), + PrimaryKeyConstraint("b", "c"), + ) @testing.emits_warning("Table 't'") def test_pk_col_mismatch_three(self): diff --git a/test/sql/test_operators.py b/test/sql/test_operators.py index c04078f737..4eff872f4f 100644 --- a/test/sql/test_operators.py +++ b/test/sql/test_operators.py @@ -59,6 +59,7 @@ from sqlalchemy.testing import expect_warnings from sqlalchemy.testing import fixtures from sqlalchemy.testing import is_ from sqlalchemy.testing import is_not +from sqlalchemy.testing.assertions import expect_deprecated from sqlalchemy.types import ARRAY from sqlalchemy.types import Boolean from sqlalchemy.types import Concatenable @@ -1220,15 +1221,14 @@ class ConjunctionTest(fixtures.TestBase, testing.AssertsCompiledSQL): # these warning classes will change to ArgumentError when the # deprecated behavior is disabled - assert_raises_message( - exc.SADeprecationWarning, + with expect_deprecated( r"Invoking %(str_op)s\(\) without arguments is deprecated, and " r"will be disallowed in a future release. For an empty " r"%(str_op)s\(\) construct, use " r"%(str_op)s\(%(str_continue)s, \*args\)\." - % {"str_op": str_op, "str_continue": str_continue}, - op, - ) + % {"str_op": str_op, "str_continue": str_continue} + ): + op() def test_empty_and_raw(self): self.assert_compile( diff --git a/test/sql/test_types.py b/test/sql/test_types.py index 14b1ca1051..935c2354dd 100644 --- a/test/sql/test_types.py +++ b/test/sql/test_types.py @@ -75,6 +75,7 @@ from sqlalchemy.sql import visitors from sqlalchemy.sql.sqltypes import TypeEngine from sqlalchemy.testing import assert_raises from sqlalchemy.testing import assert_raises_message +from sqlalchemy.testing import assert_warns from sqlalchemy.testing import AssertsCompiledSQL from sqlalchemy.testing import AssertsExecutionResults from sqlalchemy.testing import engines @@ -1703,10 +1704,10 @@ class UnicodeTest(fixtures.TestBase): dialect.supports_unicode_binds = True uni = u.dialect_impl(dialect).bind_processor(dialect) if util.py3k: - assert_raises(exc.SAWarning, uni, b"x") + assert_warns(exc.SAWarning, uni, b"x") assert isinstance(uni(unicodedata), str) else: - assert_raises(exc.SAWarning, uni, "x") + assert_warns(exc.SAWarning, uni, "x") assert isinstance(uni(unicodedata), unicode) # noqa def test_unicode_warnings_typelevel_sqla_unicode(self): @@ -1715,7 +1716,7 @@ class UnicodeTest(fixtures.TestBase): dialect = default.DefaultDialect() dialect.supports_unicode_binds = False uni = u.dialect_impl(dialect).bind_processor(dialect) - assert_raises(exc.SAWarning, uni, util.b("x")) + assert_warns(exc.SAWarning, uni, util.b("x")) assert isinstance(uni(unicodedata), util.binary_type) eq_(uni(unicodedata), unicodedata.encode("utf-8"))