From: Mike Bayer Date: Sun, 6 Jun 2021 14:12:05 +0000 (-0400) Subject: Pass URL object, not the string, to on_connect_url X-Git-Tag: rel_1_4_18~10^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=03633a6462ee16a1348acb98fe0323c74eb9ba85;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git Pass URL object, not the string, to on_connect_url The fix for pysqlcipher released in version 1.4.3 :ticket:`5848` was unfortunately non-working, in that the new ``on_connect_url`` hook was erroneously not receiving a ``URL`` object under normal usage of :func:`_sa.create_engine` and instead received a string that was unhandled; the test suite failed to fully set up the actual conditions under which this hook is called. This has been fixed. Fixes: #6586 Change-Id: I3bf738daec35877a10fdad740f08dca9e7420829 --- diff --git a/doc/build/changelog/unreleased_14/6586.rst b/doc/build/changelog/unreleased_14/6586.rst new file mode 100644 index 0000000000..027f1b01db --- /dev/null +++ b/doc/build/changelog/unreleased_14/6586.rst @@ -0,0 +1,10 @@ +.. change:: + :tags: bug, sqlite, regression + :tickets: 6586 + + The fix for pysqlcipher released in version 1.4.3 :ticket:`5848` was + unfortunately non-working, in that the new ``on_connect_url`` hook was + erroneously not receiving a ``URL`` object under normal usage of + :func:`_sa.create_engine` and instead received a string that was unhandled; + the test suite failed to fully set up the actual conditions under which + this hook is called. This has been fixed. diff --git a/lib/sqlalchemy/dialects/sqlite/pysqlcipher.py b/lib/sqlalchemy/dialects/sqlite/pysqlcipher.py index ff02d4dee8..1a9337671e 100644 --- a/lib/sqlalchemy/dialects/sqlite/pysqlcipher.py +++ b/lib/sqlalchemy/dialects/sqlite/pysqlcipher.py @@ -9,7 +9,7 @@ .. dialect:: sqlite+pysqlcipher :name: pysqlcipher :dbapi: sqlcipher 3 or pysqlcipher - :connectstring: sqlite+pysqlcipher://:passphrase/file_path[?kdf_iter=] + :connectstring: sqlite+pysqlcipher://:passphrase@/file_path[?kdf_iter=] Dialect for support of DBAPIs that make use of the `SQLCipher `_ backend. diff --git a/lib/sqlalchemy/engine/create.py b/lib/sqlalchemy/engine/create.py index 0351f2ebcc..3cf339cfcd 100644 --- a/lib/sqlalchemy/engine/create.py +++ b/lib/sqlalchemy/engine/create.py @@ -649,8 +649,7 @@ def create_engine(url, **kwargs): engine = engineclass(pool, dialect, u, **engine_args) if _initialize: - - do_on_connect = dialect.on_connect_url(url) + do_on_connect = dialect.on_connect_url(u) if do_on_connect: if _wrap_do_on_connect: do_on_connect = _wrap_do_on_connect(do_on_connect) diff --git a/test/dialect/test_sqlite.py b/test/dialect/test_sqlite.py index 95dbecdc8c..9285041df9 100644 --- a/test/dialect/test_sqlite.py +++ b/test/dialect/test_sqlite.py @@ -596,6 +596,15 @@ class DialectTest( ) ) + @testing.only_on("sqlite+pysqlcipher") + def test_pysqlcipher_connects(self): + """test #6586""" + str_url = str(testing.db.url) + e = create_engine(str_url) + + with e.connect() as conn: + eq_(conn.scalar(text("select 1")), 1) + @testing.provide_metadata def test_extra_reserved_words(self, connection): """Tests reserved words in identifiers. diff --git a/test/engine/test_parseconnect.py b/test/engine/test_parseconnect.py index 5e8fbfb5fa..ea949dfd64 100644 --- a/test/engine/test_parseconnect.py +++ b/test/engine/test_parseconnect.py @@ -485,6 +485,39 @@ class CreateEngineTest(fixtures.TestBase): eq_(e.dialect.foobar, 5) eq_(e.dialect.bathoho, False) + def test_on_connect_url(self): + """test #6586""" + + tokens = __name__.split(".") + + canary = mock.Mock() + + class MyDialect(MockDialect): + def on_connect_url(self, url): + canary.on_connect_url(url) + + global dialect + dialect = MyDialect + registry.register( + "mockdialect.ocu", ".".join(tokens[0:-1]), tokens[-1] + ) + + create_engine("mockdialect+ocu://foo:bar@host/test") + eq_( + canary.mock_calls, + [ + mock.call.on_connect_url( + url.URL.create( + drivername="mockdialect+ocu", + username="foo", + password="bar", + host="host", + database="test", + ) + ) + ], + ) + def test_custom(self): dbapi = MockDBAPI( foober=12, lala=18, hoho={"this": "dict"}, fooz="somevalue"