From: Mike Bayer Date: Mon, 29 Nov 2010 23:38:44 +0000 (-0500) Subject: - use class name by itself in flush warnings to prevent overflow of warnings registry X-Git-Tag: rel_0_7b1~216 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=79fc3cdc1b0be99e138580905290823463766944;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - use class name by itself in flush warnings to prevent overflow of warnings registry - test suite swaps out warnings.warn with warnings.warn_explicit, to solve warnings registry issue - explicitly disallow functions from inside test.bootstrap, test.lib being interpreted as tests --- diff --git a/lib/sqlalchemy/orm/dependency.py b/lib/sqlalchemy/orm/dependency.py index e57b1575ac..b9958f7758 100644 --- a/lib/sqlalchemy/orm/dependency.py +++ b/lib/sqlalchemy/orm/dependency.py @@ -727,9 +727,9 @@ class ManyToOneDP(DependencyProcessor): child is not None and \ not uowcommit.session._contains_state(child): util.warn( - "Child %s not in session, %s " + "Object of type %s not in session, %s " "operation along '%s' won't proceed" % - (mapperutil.state_str(child), operation, self.prop)) + (mapperutil.state_class_str(child), operation, self.prop)) return if clearkeys or child is None: @@ -1097,9 +1097,9 @@ class ManyToManyDP(DependencyProcessor): if child is not None and not uowcommit.session._contains_state(child): if not child.deleted: util.warn( - "Child %s not in session, %s " + "Object of type %s not in session, %s " "operation along '%s' won't proceed" % - (mapperutil.state_str(child), operation, self.prop)) + (mapperutil.state_class_str(child), operation, self.prop)) return False self._verify_canload(child) diff --git a/lib/sqlalchemy/orm/unitofwork.py b/lib/sqlalchemy/orm/unitofwork.py index 8f7475c4b7..db20acb90b 100644 --- a/lib/sqlalchemy/orm/unitofwork.py +++ b/lib/sqlalchemy/orm/unitofwork.py @@ -180,9 +180,9 @@ class UOWTransaction(object): operation=None, prop=None): if not self.session._contains_state(state): if not state.deleted and operation is not None: - util.warn("Object %s not in session, %s operation " + util.warn("Object of type %s not in session, %s operation " "along '%s' will not proceed" % - (mapperutil.state_str(state), operation, prop)) + (mapperutil.state_class_str(state), operation, prop)) return False if state not in self.states: diff --git a/lib/sqlalchemy/orm/util.py b/lib/sqlalchemy/orm/util.py index 4661b4b000..23154bd4e1 100644 --- a/lib/sqlalchemy/orm/util.py +++ b/lib/sqlalchemy/orm/util.py @@ -595,6 +595,14 @@ def state_str(state): else: return '<%s at 0x%x>' % (state.class_.__name__, id(state.obj())) +def state_class_str(state): + """Return a string describing an instance's class via its InstanceState.""" + + if state is None: + return "None" + else: + return '<%s>' % (state.class_.__name__, ) + def attribute_str(instance, attribute): return instance_str(instance) + "." + attribute diff --git a/lib/sqlalchemy/util/langhelpers.py b/lib/sqlalchemy/util/langhelpers.py index 5c12cf67be..68d9709f82 100644 --- a/lib/sqlalchemy/util/langhelpers.py +++ b/lib/sqlalchemy/util/langhelpers.py @@ -684,6 +684,17 @@ def warn_exception(func, *args, **kwargs): def warn(msg, stacklevel=3): + """Issue a warning. + + If msg is a string, :class:`.exc.SAWarning` is used as + the category. + + .. note:: This function is swapped out when the test suite + runs, with a compatible version that uses + warnings.warn_explicit, so that the warnings registry can + be controlled. + + """ if isinstance(msg, basestring): warnings.warn(msg, exc.SAWarning, stacklevel=stacklevel) else: diff --git a/test/bootstrap/noseplugin.py b/test/bootstrap/noseplugin.py index c2a152aa6e..838ad0042a 100644 --- a/test/bootstrap/noseplugin.py +++ b/test/bootstrap/noseplugin.py @@ -94,7 +94,12 @@ class NoseSQLAlchemy(Plugin): def describeTest(self, test): return "" - + + def wantFunction(self, fn): + if fn.__module__.startswith('test.lib') or \ + fn.__module__.startswith('test.bootstrap'): + return False + def wantClass(self, cls): """Return true if you want the main test selector to collect tests from this class, false if you don't, and None if you don't diff --git a/test/lib/testing.py b/test/lib/testing.py index da2a3dfd30..00b65c6e3a 100644 --- a/test/lib/testing.py +++ b/test/lib/testing.py @@ -13,7 +13,8 @@ from test.lib import assertsql, util as testutil from sqlalchemy.util import function_named, py3k from engines import drop_all_tables -from sqlalchemy import exc as sa_exc, util, types as sqltypes, schema, pool, orm +from sqlalchemy import exc as sa_exc, util, types as sqltypes, schema, \ + pool, orm from sqlalchemy.engine import default from nose import SkipTest @@ -333,7 +334,6 @@ def emits_warning(*messages): strings; these will be matched to the root of the warning description by warnings.filterwarnings(). """ - # TODO: it would be nice to assert that a named warning was # emitted. should work with some monkeypatching of warnings, # and may work on non-CPython if they keep to the spirit of @@ -427,16 +427,26 @@ def uses_deprecated(*messages): return function_named(safe, fn.__name__) return decorate +def testing_warn(msg, stacklevel=3): + """Replaces sqlalchemy.util.warn during tests.""" + + filename = "test.lib.testing" + lineno = 1 + if isinstance(msg, basestring): + warnings.warn_explicit(msg, sa_exc.SAWarning, filename, lineno) + else: + warnings.warn_explicit(msg, filename, lineno) + def resetwarnings(): """Reset warning behavior to testing defaults.""" - + + util.warn = util.langhelpers.warn = testing_warn + warnings.filterwarnings('ignore', category=sa_exc.SAPendingDeprecationWarning) warnings.filterwarnings('error', category=sa_exc.SADeprecationWarning) warnings.filterwarnings('error', category=sa_exc.SAWarning) -# warnings.simplefilter('error') - def global_cleanup_assertions(): """Check things that have to be finalized at the end of a test suite.