summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2020-02-29 14:40:45 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2020-03-02 17:24:19 -0500
commit57dc36a01b2b334a996f73f6a78b3bfbe4d9f2ec (patch)
tree77cbb0199ca91be3b0816e3a5bd4c217e36a7d1b /test
parent649de79950dcf952d7a44069faf36925c23c4e63 (diff)
downloadsqlalchemy-57dc36a01b2b334a996f73f6a78b3bfbe4d9f2ec.tar.gz
Ensure all nested exception throws have a cause
Applied an explicit "cause" to most if not all internally raised exceptions that are raised from within an internal exception catch, to avoid misleading stacktraces that suggest an error within the handling of an exception. While it would be preferable to suppress the internally caught exception in the way that the ``__suppress_context__`` attribute would, there does not as yet seem to be a way to do this without suppressing an enclosing user constructed context, so for now it exposes the internally caught exception as the cause so that full information about the context of the error is maintained. Fixes: #4849 Change-Id: I55a86b29023675d9e5e49bc7edc5a2dc0bcd4751
Diffstat (limited to 'test')
-rw-r--r--test/aaa_profiling/test_memusage.py14
-rw-r--r--test/aaa_profiling/test_resultset.py2
-rw-r--r--test/base/test_utils.py28
-rw-r--r--test/engine/test_execute.py13
-rw-r--r--test/engine/test_pool.py3
-rw-r--r--test/engine/test_reconnect.py5
-rw-r--r--test/engine/test_reflection.py10
-rw-r--r--test/sql/test_metadata.py11
8 files changed, 52 insertions, 34 deletions
diff --git a/test/aaa_profiling/test_memusage.py b/test/aaa_profiling/test_memusage.py
index 55890cd06..8f84acde8 100644
--- a/test/aaa_profiling/test_memusage.py
+++ b/test/aaa_profiling/test_memusage.py
@@ -1124,6 +1124,20 @@ class CycleTest(_fixtures.FixtureTest):
go()
+ def test_raise_from(self):
+ @assert_cycles()
+ def go():
+ try:
+ try:
+ raise KeyError("foo")
+ except KeyError as ke:
+
+ util.raise_(Exception("oops"), from_=ke)
+ except Exception as err: # noqa
+ pass
+
+ go()
+
def test_query_alias(self):
User, Address = self.classes("User", "Address")
configure_mappers()
diff --git a/test/aaa_profiling/test_resultset.py b/test/aaa_profiling/test_resultset.py
index 87908f016..73a1a8b6f 100644
--- a/test/aaa_profiling/test_resultset.py
+++ b/test/aaa_profiling/test_resultset.py
@@ -111,7 +111,7 @@ class ResultSetTest(fixtures.TestBase, AssertsExecutionResults):
"some other column", Integer
)
- @profiling.function_call_count()
+ @profiling.function_call_count(variance=0.10)
def go():
c1 in row
diff --git a/test/base/test_utils.py b/test/base/test_utils.py
index 48e464a01..183e157e5 100644
--- a/test/base/test_utils.py
+++ b/test/base/test_utils.py
@@ -3,7 +3,6 @@
import copy
import datetime
import inspect
-import sys
from sqlalchemy import exc
from sqlalchemy import sql
@@ -2899,20 +2898,29 @@ class ReraiseTest(fixtures.TestBase):
except MyException as err:
is_(err.__cause__, None)
- def test_reraise_disallow_same_cause(self):
+ def test_raise_from_cause_legacy(self):
class MyException(Exception):
pass
+ class MyOtherException(Exception):
+ pass
+
+ me = MyException("exc on")
+
def go():
try:
- raise MyException("exc one")
- except Exception as err:
- type_, value, tb = sys.exc_info()
- util.reraise(type_, err, tb, value)
+ raise me
+ except Exception:
+ util.raise_from_cause(MyOtherException("exc two"))
- assert_raises_message(AssertionError, "Same cause emitted", go)
+ try:
+ go()
+ assert False
+ except MyOtherException as moe:
+ if testing.requires.python3.enabled:
+ is_(moe.__cause__, me)
- def test_raise_from_cause(self):
+ def test_raise_from(self):
class MyException(Exception):
pass
@@ -2924,8 +2932,8 @@ class ReraiseTest(fixtures.TestBase):
def go():
try:
raise me
- except Exception:
- util.raise_from_cause(MyOtherException("exc two"))
+ except Exception as err:
+ util.raise_(MyOtherException("exc two"), from_=err)
try:
go()
diff --git a/test/engine/test_execute.py b/test/engine/test_execute.py
index 5acd14177..cf262a573 100644
--- a/test/engine/test_execute.py
+++ b/test/engine/test_execute.py
@@ -712,12 +712,13 @@ class ExecuteTest(fixtures.TestBase):
return super(MockCursor, self).execute(stmt, params, **kw)
eng = engines.proxying_engine(cursor_cls=MockCursor)
- assert_raises_message(
- tsa.exc.SAWarning,
- "Exception attempting to detect unicode returns",
- eng.connect,
- )
- assert eng.dialect.returns_unicode_strings in (True, False)
+ with testing.expect_warnings(
+ "Exception attempting to detect unicode returns"
+ ):
+ eng.connect()
+
+ # because plain varchar passed, we don't know the correct answer
+ eq_(eng.dialect.returns_unicode_strings, "conditional")
eng.dispose()
def test_works_after_dispose(self):
diff --git a/test/engine/test_pool.py b/test/engine/test_pool.py
index cfe20f5ec..72e0fa186 100644
--- a/test/engine/test_pool.py
+++ b/test/engine/test_pool.py
@@ -10,6 +10,7 @@ from sqlalchemy import pool
from sqlalchemy import select
from sqlalchemy import testing
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 eq_
from sqlalchemy.testing import fixtures
@@ -1256,7 +1257,7 @@ class QueuePoolTest(PoolTestBase):
eq_(p.checkedout(), 0)
eq_(p._overflow, 0)
dbapi.shutdown(True)
- assert_raises(Exception, p.connect)
+ assert_raises_context_ok(Exception, p.connect)
eq_(p._overflow, 0)
eq_(p.checkedout(), 0) # and not 1
diff --git a/test/engine/test_reconnect.py b/test/engine/test_reconnect.py
index 205c1fb31..000be1a70 100644
--- a/test/engine/test_reconnect.py
+++ b/test/engine/test_reconnect.py
@@ -14,6 +14,7 @@ from sqlalchemy import util
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 engines
from sqlalchemy.testing import eq_
from sqlalchemy.testing import expect_warnings
@@ -255,7 +256,7 @@ class PrePingMockTest(fixtures.TestBase):
self.dbapi.shutdown("execute", stop=True)
- assert_raises_message(
+ assert_raises_message_context_ok(
MockDisconnect, "database is stopped", pool.connect
)
@@ -835,7 +836,7 @@ class CursorErrTest(fixtures.TestBase):
def test_cursor_shutdown_in_initialize(self):
db = self._fixture(True, True)
- assert_raises_message(
+ assert_raises_message_context_ok(
exc.SAWarning, "Exception attempting to detect", db.connect
)
eq_(
diff --git a/test/engine/test_reflection.py b/test/engine/test_reflection.py
index 301614061..579f1aece 100644
--- a/test/engine/test_reflection.py
+++ b/test/engine/test_reflection.py
@@ -24,6 +24,7 @@ from sqlalchemy.testing import eq_regex
from sqlalchemy.testing import expect_warnings
from sqlalchemy.testing import fixtures
from sqlalchemy.testing import in_
+from sqlalchemy.testing import is_
from sqlalchemy.testing import is_false
from sqlalchemy.testing import is_true
from sqlalchemy.testing import mock
@@ -596,13 +597,10 @@ class ReflectionTest(fixtures.TestBase, ComparesTables):
testing.db.dialect.ischema_names = {}
try:
m2 = MetaData(testing.db)
- assert_raises(sa.exc.SAWarning, Table, "test", m2, autoload=True)
- @testing.emits_warning("Did not recognize type")
- def warns():
- m3 = MetaData(testing.db)
- t3 = Table("test", m3, autoload=True)
- assert t3.c.foo.type.__class__ == sa.types.NullType
+ with testing.expect_warnings("Did not recognize type"):
+ t3 = Table("test", m2, autoload_with=testing.db)
+ is_(t3.c.foo.type.__class__, sa.types.NullType)
finally:
testing.db.dialect.ischema_names = ischema_names
diff --git a/test/sql/test_metadata.py b/test/sql/test_metadata.py
index 3f4333750..8ef272a9e 100644
--- a/test/sql/test_metadata.py
+++ b/test/sql/test_metadata.py
@@ -4093,16 +4093,11 @@ class DialectKWArgTest(fixtures.TestBase):
def test_unknown_dialect_warning(self):
with self._fixture():
- assert_raises_message(
- exc.SAWarning,
+ with testing.expect_warnings(
"Can't validate argument 'unknown_y'; can't locate "
"any SQLAlchemy dialect named 'unknown'",
- Index,
- "a",
- "b",
- "c",
- unknown_y=True,
- )
+ ):
+ Index("a", "b", "c", unknown_y=True)
def test_participating_bad_kw(self):
with self._fixture():