From: Mike Bayer Date: Sun, 12 Dec 2021 16:23:07 +0000 (-0500) Subject: check for string_types, not str, for py2 support X-Git-Tag: rel_1_4_29~9^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8dafa1b19c0003b92eb9b81dd33e2989ae5e2ec2;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git check for string_types, not str, for py2 support Fixed regression in the :func:`_engine.make_url` function used to parse URL strings where the query string parsing would go into a recursion overflow if a Python 2 ``u''`` string were used. Fixes: #7446 Change-Id: I081275673e6240a52f71da7dfaaf04e6fe32cf48 --- diff --git a/doc/build/changelog/unreleased_14/7446.rst b/doc/build/changelog/unreleased_14/7446.rst new file mode 100644 index 0000000000..d92eb13a8d --- /dev/null +++ b/doc/build/changelog/unreleased_14/7446.rst @@ -0,0 +1,7 @@ +.. change:: + :tags: bug, engine, regression + :tickets: 7446 + + Fixed regression in the :func:`_engine.make_url` function used to parse URL + strings where the query string parsing would go into a recursion overflow + if a Python 2 ``u''`` string were used. diff --git a/lib/sqlalchemy/engine/url.py b/lib/sqlalchemy/engine/url.py index 320e69fbc3..a73b81a319 100644 --- a/lib/sqlalchemy/engine/url.py +++ b/lib/sqlalchemy/engine/url.py @@ -182,7 +182,7 @@ class URL( return util.EMPTY_DICT def _assert_value(val): - if isinstance(val, str): + if isinstance(val, compat.string_types): return val elif isinstance(val, collections_abc.Sequence): return tuple(_assert_value(elem) for elem in val) diff --git a/test/engine/test_parseconnect.py b/test/engine/test_parseconnect.py index f553b1dab5..28362ba2a1 100644 --- a/test/engine/test_parseconnect.py +++ b/test/engine/test_parseconnect.py @@ -6,6 +6,7 @@ from sqlalchemy import engine_from_config from sqlalchemy import exc from sqlalchemy import pool from sqlalchemy import testing +from sqlalchemy import util from sqlalchemy.dialects import plugins from sqlalchemy.dialects import registry from sqlalchemy.engine.default import DefaultDialect @@ -181,6 +182,17 @@ class URLTest(fixtures.TestBase): eq_(u.query, {"arg1=": "param1", "arg2": "param 2"}) eq_(str(u), test_url) + def test_query_string_py2_unicode(self): + url_str = u"dialect://user:pass@host/?arg1=param1&arg2=param2" + if util.py2k: + # just to make sure linters / formatters etc. don't erase the + # 'u' above + assert isinstance(url_str, unicode) # noqa + u = url.make_url(url_str) + eq_(u.query, {"arg1": "param1", "arg2": "param2"}) + eq_(u.database, "") + eq_(str(u), "dialect://user:pass@host/?arg1=param1&arg2=param2") + def test_comparison(self): common_url = ( "dbtype://username:password"