summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorNate Clark <natec425@gmail.com>2019-02-20 12:58:18 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2019-02-20 18:56:47 -0500
commit8f318692d4443300c90c7be9dc44ae3c8707f818 (patch)
tree3b935eedfd1c31ae4c69c4996f3bae5adec2bd71 /test
parentd879bed8786b6387b470c148b412731456793653 (diff)
downloadsqlalchemy-8f318692d4443300c90c7be9dc44ae3c8707f818.tar.gz
Include newlines in StatementError formatting
Revised the formatting for :class:`.StatementError` when stringified. Each error detail is broken up over multiple newlines instead of spaced out on a single line. Additionally, the SQL representation now stringifies the SQL statement rather than using ``repr()``, so that newlines are rendered as is. Pull request courtesy Nate Clark. Fixes: #4500 Closes: #4501 Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/4501 Pull-request-sha: 60cc0ee68dc96b8f483a60d37bcb26b6c6d53efe Change-Id: I79d8418b7495e5691c9a56f41e79495c26a967ff
Diffstat (limited to 'test')
-rw-r--r--test/base/test_except.py80
-rw-r--r--test/engine/test_deprecations.py2
-rw-r--r--test/engine/test_execute.py10
-rw-r--r--test/engine/test_logging.py10
-rw-r--r--test/orm/test_session.py2
-rw-r--r--test/sql/test_insert_exec.py4
6 files changed, 65 insertions, 43 deletions
diff --git a/test/base/test_except.py b/test/base/test_except.py
index 58943902c..7dcfbb1f0 100644
--- a/test/base/test_except.py
+++ b/test/base/test_except.py
@@ -70,9 +70,26 @@ class WrapTest(fixtures.TestBase):
except sa_exceptions.DBAPIError as exc:
eq_(
str(exc),
- "(test.base.test_except.OperationalError) "
- "[SQL: 'this is a message'] (Background on this error at: "
- "http://sqlalche.me/e/e3q8)",
+ "(test.base.test_except.OperationalError) \n"
+ "[SQL: this is a message]\n"
+ "(Background on this error at: http://sqlalche.me/e/e3q8)",
+ )
+
+ def test_tostring_with_newlines(self):
+ try:
+ raise sa_exceptions.DBAPIError.instance(
+ "this is a message\nthis is the next line\nthe last line",
+ None,
+ OperationalError(),
+ DatabaseError,
+ )
+ except sa_exceptions.DBAPIError as exc:
+ eq_(
+ str(exc),
+ "(test.base.test_except.OperationalError) \n"
+ "[SQL: this is a message\nthis is the next line\n"
+ "the last line]\n"
+ "(Background on this error at: http://sqlalche.me/e/e3q8)",
)
def test_statement_error_no_code(self):
@@ -86,8 +103,8 @@ class WrapTest(fixtures.TestBase):
except sa_exceptions.StatementError as err:
eq_(
str(err),
- "(sqlalchemy.exc.InvalidRequestError) hello "
- "[SQL: 'select * from table'] [parameters: [{'x': 1}]]",
+ "(sqlalchemy.exc.InvalidRequestError) hello\n"
+ "[SQL: select * from table]\n[parameters: [{'x': 1}]]",
)
eq_(err.args, ("(sqlalchemy.exc.InvalidRequestError) hello",))
@@ -102,8 +119,9 @@ class WrapTest(fixtures.TestBase):
except sa_exceptions.StatementError as err:
eq_(
str(err),
- "(sqlalchemy.exc.InvalidRequestError) hello "
- "[SQL: 'select * from table'] [parameters: [{'x': 1}]] "
+ "(sqlalchemy.exc.InvalidRequestError) hello\n"
+ "[SQL: select * from table]\n"
+ "[parameters: [{'x': 1}]]\n"
"(Background on this error at: http://sqlalche.me/e/abcd)",
)
eq_(err.args, ("(sqlalchemy.exc.InvalidRequestError) hello",))
@@ -114,7 +132,7 @@ class WrapTest(fixtures.TestBase):
orig.args = [2006, "Test raise operational error"]
eq_(
str(orig),
- "(2006, 'Test raise operational error') "
+ "(2006, 'Test raise operational error')\n"
"(Background on this error at: http://sqlalche.me/e/dbapi)",
)
@@ -125,7 +143,7 @@ class WrapTest(fixtures.TestBase):
eq_(
compat.text_type(orig),
compat.u(
- "méil (Background on this error at: "
+ "méil\n(Background on this error at: "
"http://sqlalche.me/e/dbapi)"
),
)
@@ -153,8 +171,9 @@ class WrapTest(fixtures.TestBase):
)
except sa_exceptions.DBAPIError as exc:
assert str(exc).startswith(
- "(test.base.test_except.OperationalError) "
- "[SQL: 'this is a message'] [parameters: {"
+ "(test.base.test_except.OperationalError) \n"
+ "[SQL: this is a message]\n"
+ "[parameters: {"
)
def test_tostring_large_list(self):
@@ -165,10 +184,10 @@ class WrapTest(fixtures.TestBase):
OperationalError(),
DatabaseError,
)
- except sa_exceptions.DBAPIError as exc:
- assert str(exc).startswith(
- "(test.base.test_except.OperationalError) "
- "[SQL: 'this is a message'] [parameters: "
+ except sa_exceptions.DBAPIError as ex:
+ assert str(ex).startswith(
+ "(test.base.test_except.OperationalError) \n"
+ "[SQL: this is a message]\n[parameters: "
"[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]]"
)
@@ -194,11 +213,11 @@ class WrapTest(fixtures.TestBase):
except sa_exceptions.DBAPIError as exc:
eq_(
str(exc),
- "(test.base.test_except.OperationalError) sql error "
- "[SQL: 'this is a message'] [parameters: [{1: 1}, "
- "{1: 1}, {1: 1}, {1: 1}, {1: 1}, {1: 1}, {1: 1}, {1: "
- "1}, {1: 1}, {1: 1}]] (Background on this error at: "
- "http://sqlalche.me/e/e3q8)",
+ "(test.base.test_except.OperationalError) sql error\n"
+ "[SQL: this is a message]\n"
+ "[parameters: [{1: 1}, {1: 1}, {1: 1}, {1: 1}, {1: 1},"
+ " {1: 1}, {1: 1}, {1: 1}, {1: 1}, {1: 1}]]\n"
+ "(Background on this error at: http://sqlalche.me/e/e3q8)",
)
eq_(
exc.args,
@@ -226,11 +245,12 @@ class WrapTest(fixtures.TestBase):
except sa_exceptions.DBAPIError as exc:
eq_(
str(exc),
- "(test.base.test_except.OperationalError) "
- "[SQL: 'this is a message'] [parameters: [{1: 1}, "
+ "(test.base.test_except.OperationalError) \n"
+ "[SQL: this is a message]\n"
+ "[parameters: [{1: 1}, "
"{1: 1}, {1: 1}, {1: 1}, {1: 1}, {1: 1}, "
"{1: 1}, {1: 1} ... displaying 10 of 11 total "
- "bound parameter sets ... {1: 1}, {1: 1}]] "
+ "bound parameter sets ... {1: 1}, {1: 1}]]\n"
"(Background on this error at: http://sqlalche.me/e/e3q8)",
)
try:
@@ -244,9 +264,10 @@ class WrapTest(fixtures.TestBase):
except sa_exceptions.DBAPIError as exc:
eq_(
str(exc),
- "(test.base.test_except.OperationalError) "
- "[SQL: 'this is a message'] [parameters: [(1,), "
- "(1,), (1,), (1,), (1,), (1,), (1,), (1,), (1,), (1,)]] "
+ "(test.base.test_except.OperationalError) \n"
+ "[SQL: this is a message]\n"
+ "[parameters: [(1,), "
+ "(1,), (1,), (1,), (1,), (1,), (1,), (1,), (1,), (1,)]]\n"
"(Background on this error at: http://sqlalche.me/e/e3q8)",
)
try:
@@ -271,11 +292,12 @@ class WrapTest(fixtures.TestBase):
except sa_exceptions.DBAPIError as exc:
eq_(
str(exc),
- "(test.base.test_except.OperationalError) "
- "[SQL: 'this is a message'] [parameters: [(1,), "
+ "(test.base.test_except.OperationalError) \n"
+ "[SQL: this is a message]\n"
+ "[parameters: [(1,), "
"(1,), (1,), (1,), (1,), (1,), (1,), (1,) "
"... displaying 10 of 11 total bound "
- "parameter sets ... (1,), (1,)]] "
+ "parameter sets ... (1,), (1,)]]\n"
"(Background on this error at: http://sqlalche.me/e/e3q8)",
)
diff --git a/test/engine/test_deprecations.py b/test/engine/test_deprecations.py
index 35226a097..29bda0ac2 100644
--- a/test/engine/test_deprecations.py
+++ b/test/engine/test_deprecations.py
@@ -1114,7 +1114,7 @@ class HandleErrorTest(fixtures.TestBase):
with engine.connect() as conn:
assert_raises_message(
tsa.exc.StatementError,
- r"\(.*SomeException\) " r"nope \[SQL\: u?'SELECT 1 ",
+ r"\(.*SomeException\) " r"nope\n\[SQL\: u?SELECT 1 ",
conn.execute,
select([1]).where(column("foo") == literal("bar", MyType())),
)
diff --git a/test/engine/test_execute.py b/test/engine/test_execute.py
index ad9144a38..e18cdfad4 100644
--- a/test/engine/test_execute.py
+++ b/test/engine/test_execute.py
@@ -371,7 +371,7 @@ class ExecuteTest(fixtures.TestBase):
def _go(conn):
assert_raises_message(
tsa.exc.StatementError,
- r"\(.*.SomeException\) " r"nope \[SQL\: u?'SELECT 1 ",
+ r"\(.*.SomeException\) " r"nope\n\[SQL\: u?SELECT 1 ",
conn.execute,
select([1]).where(column("foo") == literal("bar", MyType())),
)
@@ -410,12 +410,12 @@ class ExecuteTest(fixtures.TestBase):
assert_raises_message(
tsa.exc.StatementError,
util.u(
- "A value is required for bind parameter 'uname'"
- r".*SELECT users.user_name AS .m\\xe9il."
+ "A value is required for bind parameter 'uname'\n"
+ r".*SELECT users.user_name AS .m\xe9il."
)
if util.py2k
else util.u(
- "A value is required for bind parameter 'uname'"
+ "A value is required for bind parameter 'uname'\n"
".*SELECT users.user_name AS .méil."
),
conn.execute,
@@ -2184,7 +2184,7 @@ class HandleErrorTest(fixtures.TestBase):
with engine.connect() as conn:
assert_raises_message(
tsa.exc.StatementError,
- r"\(.*.SomeException\) " r"nope \[SQL\: u?'SELECT 1 ",
+ r"\(.*.SomeException\) " r"nope\n\[SQL\: u?SELECT 1 ",
conn.execute,
select([1]).where(column("foo") == literal("bar", MyType())),
)
diff --git a/test/engine/test_logging.py b/test/engine/test_logging.py
index 8190a3fcd..bd425c940 100644
--- a/test/engine/test_logging.py
+++ b/test/engine/test_logging.py
@@ -103,7 +103,7 @@ class LogParamsTest(fixtures.TestBase):
exception = tsa.exc.IntegrityError("foo", {"x": "y"}, None)
eq_regex(
str(exception),
- r"\(.*.NoneType\) None \[SQL: 'foo'\] \[parameters: {'x': 'y'}\]",
+ r"\(.*.NoneType\) None\n\[SQL: foo\]\n\[parameters: {'x': 'y'}\]",
)
def test_exception_format_unexpected_parameter(self):
@@ -112,7 +112,7 @@ class LogParamsTest(fixtures.TestBase):
exception = tsa.exc.IntegrityError("foo", "bar", "bat")
eq_regex(
str(exception),
- r"\(.*.str\) bat \[SQL: 'foo'\] \[parameters: 'bar'\]",
+ r"\(.*.str\) bat\n\[SQL: foo\]\n\[parameters: 'bar'\]",
)
def test_exception_format_unexpected_member_parameter(self):
@@ -121,7 +121,7 @@ class LogParamsTest(fixtures.TestBase):
exception = tsa.exc.IntegrityError("foo", ["bar", "bat"], "hoho")
eq_regex(
str(exception),
- r"\(.*.str\) hoho \[SQL: 'foo'\] \[parameters: \['bar', 'bat'\]\]",
+ r"\(.*.str\) hoho\n\[SQL: foo\]\n\[parameters: \['bar', 'bat'\]\]",
)
def test_result_large_param(self):
@@ -169,7 +169,7 @@ class LogParamsTest(fixtures.TestBase):
def test_error_large_dict(self):
assert_raises_message(
tsa.exc.DBAPIError,
- r".*'INSERT INTO nonexistent \(data\) values \(:data\)'\] "
+ r".*INSERT INTO nonexistent \(data\) values \(:data\)\]\n"
r"\[parameters: "
r"\[{'data': '0'}, {'data': '1'}, {'data': '2'}, "
r"{'data': '3'}, {'data': '4'}, {'data': '5'}, "
@@ -186,7 +186,7 @@ class LogParamsTest(fixtures.TestBase):
assert_raises_message(
tsa.exc.DBAPIError,
r".*INSERT INTO nonexistent \(data\) values "
- r"\(\?\)'\] \[parameters: \[\('0',\), \('1',\), \('2',\), "
+ r"\(\?\)\]\n\[parameters: \[\('0',\), \('1',\), \('2',\), "
r"\('3',\), \('4',\), \('5',\), \('6',\), \('7',\) "
r"... displaying "
r"10 of 100 total bound parameter sets ... "
diff --git a/test/orm/test_session.py b/test/orm/test_session.py
index 2bc11398d..ad7ff2d35 100644
--- a/test/orm/test_session.py
+++ b/test/orm/test_session.py
@@ -1037,7 +1037,7 @@ class DeferredRelationshipExpressionTest(_fixtures.FixtureTest):
assert_raises_message(
sa.exc.StatementError,
"Can't resolve value for column users.id on object "
- ".User.*.; the object is detached and the value was expired ",
+ ".User.*.; the object is detached and the value was expired",
q.one,
)
diff --git a/test/sql/test_insert_exec.py b/test/sql/test_insert_exec.py
index fafe7cc9b..7905dc4bc 100644
--- a/test/sql/test_insert_exec.py
+++ b/test/sql/test_insert_exec.py
@@ -60,8 +60,8 @@ class InsertExecTest(fixtures.TablesTest):
exc.StatementError,
r"\(sqlalchemy.exc.InvalidRequestError\) A value is required for "
"bind parameter 'user_name', in "
- "parameter group 2 "
- r"\[SQL: u?'INSERT INTO users",
+ "parameter group 2\n"
+ r"\[SQL: u?INSERT INTO users",
users.insert().execute,
{"user_id": 7, "user_name": "jack"},
{"user_id": 8, "user_name": "ed"},