From c4f28fb414c342ba362fdee8a68bd169f01aa7d2 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Andrzej=20Bartosi=C5=84ski?= Date: Sat, 19 Sep 2020 12:47:46 -0400 Subject: [PATCH] Stringify correctly for non-str exception argument MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Fixed issue where a non-string object sent to :class:`_exc.SQLAlchemyError` or a subclass, as occurs with some third party dialects, would fail to stringify correctly. Pull request courtesy Andrzej Bartosiński. Fixes: #5599 Closes: #5600 Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/5600 Pull-request-sha: cdccccc42a6ac8de771593a43ee8675bfd8dbeb6 Change-Id: Icd710d9015abc80f61a84893d75fbb33ee0fe46e --- doc/build/changelog/unreleased_13/5599.rst | 8 ++++++++ lib/sqlalchemy/exc.py | 12 ++++++++++-- test/engine/test_execute.py | 21 ++++++++++++++++++--- 3 files changed, 36 insertions(+), 5 deletions(-) create mode 100644 doc/build/changelog/unreleased_13/5599.rst diff --git a/doc/build/changelog/unreleased_13/5599.rst b/doc/build/changelog/unreleased_13/5599.rst new file mode 100644 index 0000000000..c5a5dcc3a7 --- /dev/null +++ b/doc/build/changelog/unreleased_13/5599.rst @@ -0,0 +1,8 @@ +.. change:: + :tags: bug, engine + :tickets: 5599 + + Fixed issue where a non-string object sent to + :class:`_exc.SQLAlchemyError` or a subclass, as occurs with some third + party dialects, would fail to stringify correctly. Pull request + courtesy Andrzej Bartosiński. diff --git a/lib/sqlalchemy/exc.py b/lib/sqlalchemy/exc.py index c2308a5ccc..b80bf9b011 100644 --- a/lib/sqlalchemy/exc.py +++ b/lib/sqlalchemy/exc.py @@ -56,10 +56,18 @@ class SQLAlchemyError(Exception): # if len(self.args) == 1: text = self.args[0] + if as_unicode and isinstance(text, compat.binary_types): - return compat.decode_backslashreplace(text, "utf-8") + text = compat.decode_backslashreplace(text, "utf-8") + # This is for when the argument is not a string of any sort. + # Otherwise, converting this exception to string would fail for + # non-string arguments. + elif compat.py3k or not as_unicode: + text = str(text) else: - return self.args[0] + text = compat.text_type(text) + + return text else: # this is not a normal case within SQLAlchemy but is here for # compatibility with Exception.args - the str() comes out as diff --git a/test/engine/test_execute.py b/test/engine/test_execute.py index 7e3893afdd..73681ee51c 100644 --- a/test/engine/test_execute.py +++ b/test/engine/test_execute.py @@ -58,6 +58,14 @@ class SomeException(Exception): pass +class Foo(object): + def __str__(self): + return "foo" + + def __unicode__(self): + return util.u("fóó") + + class ExecuteTest(fixtures.TablesTest): __backend__ = True @@ -382,7 +390,7 @@ class ExecuteTest(fixtures.TablesTest): eq_(str(err), message) # unicode accessor decodes to utf-8 - eq_(unicode(err), util.u("some message méil")) # noqa + eq_(unicode(err), util.u("some message méil")) # noqa F821 else: eq_(str(err), util.u("some message méil")) @@ -397,7 +405,7 @@ class ExecuteTest(fixtures.TablesTest): eq_(str(err), message) # unicode accessor decodes to utf-8 - eq_(unicode(err), util.u("some message m\\xe9il")) # noqa + eq_(unicode(err), util.u("some message m\\xe9il")) # noqa F821 else: eq_(str(err), util.u("some message m\\xe9il")) @@ -408,10 +416,17 @@ class ExecuteTest(fixtures.TablesTest): err = tsa.exc.SQLAlchemyError(message) if util.py2k: - eq_(unicode(err), util.u("some message méil")) # noqa + eq_(unicode(err), util.u("some message méil")) # noqa F821 else: eq_(str(err), util.u("some message méil")) + def test_stmt_exception_object_arg(self): + err = tsa.exc.SQLAlchemyError(Foo()) + eq_(str(err), "foo") + + if util.py2k: + eq_(unicode(err), util.u("fóó")) # noqa F821 + def test_stmt_exception_str_multi_args(self): err = tsa.exc.SQLAlchemyError("some message", 206) eq_(str(err), "('some message', 206)") -- 2.47.2