From 48a655e728e978f665590aa17ff22eb2646cb25f Mon Sep 17 00:00:00 2001 From: Dan Allan Date: Wed, 11 Sep 2024 16:33:28 -0400 Subject: [PATCH 1/9] Automatically set SQL driver if unset. --- tiled/_tests/conftest.py | 3 ++- tiled/_tests/utils.py | 3 ++- tiled/authn_database/connection_pool.py | 5 ++++- tiled/catalog/adapter.py | 6 +++++- tiled/commandline/_admin.py | 9 ++++++--- tiled/commandline/_catalog.py | 10 ++++++---- tiled/commandline/_serve.py | 6 ++++-- tiled/utils.py | 25 +++++++++++++++++++++++++ 8 files changed, 54 insertions(+), 13 deletions(-) diff --git a/tiled/_tests/conftest.py b/tiled/_tests/conftest.py index 434741217..f9632ea46 100644 --- a/tiled/_tests/conftest.py +++ b/tiled/_tests/conftest.py @@ -13,6 +13,7 @@ from ..catalog import from_uri, in_memory from ..client.base import BaseClient from ..server.settings import get_settings +from ..utils import ensure_specified_sql_driver from .utils import enter_username_password as utils_enter_uname_passwd from .utils import temp_postgres @@ -152,7 +153,7 @@ async def postgresql_with_example_data_adapter(request, tmpdir): if uri.endswith("/"): uri = uri[:-1] uri_with_database_name = f"{uri}/{DATABASE_NAME}" - engine = create_async_engine(uri_with_database_name) + engine = create_async_engine(ensure_specified_sql_driver(uri_with_database_name)) try: async with engine.connect(): pass diff --git a/tiled/_tests/utils.py b/tiled/_tests/utils.py index b3a4bc9df..25bad3929 100644 --- a/tiled/_tests/utils.py +++ b/tiled/_tests/utils.py @@ -14,6 +14,7 @@ from ..client import context from ..client.base import BaseClient +from ..utils import ensure_specified_sql_driver if sys.version_info < (3, 9): import importlib_resources as resources @@ -33,7 +34,7 @@ async def temp_postgres(uri): if uri.endswith("/"): uri = uri[:-1] # Create a fresh database. - engine = create_async_engine(uri) + engine = create_async_engine(ensure_specified_sql_driver(uri)) database_name = f"tiled_test_disposable_{uuid.uuid4().hex}" async with engine.connect() as connection: await connection.execute( diff --git a/tiled/authn_database/connection_pool.py b/tiled/authn_database/connection_pool.py index 652261865..4eae74b83 100644 --- a/tiled/authn_database/connection_pool.py +++ b/tiled/authn_database/connection_pool.py @@ -2,6 +2,7 @@ from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine from ..server.settings import get_settings +from ..utils import ensure_specified_sql_driver # A given process probably only has one of these at a time, but we # key on database_settings just case in some testing context or something @@ -16,7 +17,9 @@ def open_database_connection_pool(database_settings): # kwargs["pool_pre_ping"] = database_settings.pool_pre_ping # kwargs["max_overflow"] = database_settings.max_overflow engine = create_async_engine( - database_settings.uri, connect_args=connect_args, **kwargs + ensure_specified_sql_driver(database_settings.uri), + connect_args=connect_args, + **kwargs, ) _connection_pools[database_settings] = engine return engine diff --git a/tiled/catalog/adapter.py b/tiled/catalog/adapter.py index b3b407955..224e3b055 100644 --- a/tiled/catalog/adapter.py +++ b/tiled/catalog/adapter.py @@ -70,6 +70,7 @@ OneShotCachedMap, UnsupportedQueryType, ensure_awaitable, + ensure_specified_sql_driver, ensure_uri, import_object, path_from_uri, @@ -1381,7 +1382,10 @@ def from_uri( else: poolclass = None # defer to sqlalchemy default engine = create_async_engine( - uri, echo=echo, json_serializer=json_serializer, poolclass=poolclass + ensure_specified_sql_driver(uri), + echo=echo, + json_serializer=json_serializer, + poolclass=poolclass, ) if engine.dialect.name == "sqlite": event.listens_for(engine.sync_engine, "connect")(_set_sqlite_pragma) diff --git a/tiled/commandline/_admin.py b/tiled/commandline/_admin.py index 19a5c4037..fd7afffa5 100644 --- a/tiled/commandline/_admin.py +++ b/tiled/commandline/_admin.py @@ -27,9 +27,10 @@ def initialize_database(database_uri: str): REQUIRED_REVISION, initialize_database, ) + from ..utils import ensure_specified_sql_driver async def do_setup(): - engine = create_async_engine(database_uri) + engine = create_async_engine(ensure_specified_sql_driver(database_uri)) redacted_url = engine.url._replace(password="[redacted]") try: await check_database(engine, REQUIRED_REVISION, ALL_REVISIONS) @@ -71,9 +72,10 @@ def upgrade_database( ALEMBIC_INI_TEMPLATE_PATH, ) from ..authn_database.core import ALL_REVISIONS + from ..utils import ensure_specified_sql_driver async def do_setup(): - engine = create_async_engine(database_uri) + engine = create_async_engine(ensure_specified_sql_driver(database_uri)) redacted_url = engine.url._replace(password="[redacted]") current_revision = await get_current_revision(engine, ALL_REVISIONS) await engine.dispose() @@ -107,9 +109,10 @@ def downgrade_database( ALEMBIC_INI_TEMPLATE_PATH, ) from ..authn_database.core import ALL_REVISIONS + from ..utils import ensure_specified_sql_driver async def do_setup(): - engine = create_async_engine(database_uri) + engine = create_async_engine(ensure_specified_sql_driver(database_uri)) redacted_url = engine.url._replace(password="[redacted]") current_revision = await get_current_revision(engine, ALL_REVISIONS) if current_revision is None: diff --git a/tiled/commandline/_catalog.py b/tiled/commandline/_catalog.py index 5cc5f8998..b1fd5215e 100644 --- a/tiled/commandline/_catalog.py +++ b/tiled/commandline/_catalog.py @@ -44,14 +44,14 @@ def init( from ..alembic_utils import UninitializedDatabase, check_database, stamp_head from ..catalog.alembic_constants import ALEMBIC_DIR, ALEMBIC_INI_TEMPLATE_PATH from ..catalog.core import ALL_REVISIONS, REQUIRED_REVISION, initialize_database - from ..utils import SCHEME_PATTERN + from ..utils import SCHEME_PATTERN, ensure_specified_sql_driver if not SCHEME_PATTERN.match(database): # Interpret URI as filepath. database = f"sqlite+aiosqlite:///{database}" async def do_setup(): - engine = create_async_engine(database) + engine = create_async_engine(ensure_specified_sql_driver(database)) redacted_url = engine.url._replace(password="[redacted]") try: await check_database(engine, REQUIRED_REVISION, ALL_REVISIONS) @@ -94,9 +94,10 @@ def upgrade_database( from ..alembic_utils import get_current_revision, upgrade from ..catalog.alembic_constants import ALEMBIC_DIR, ALEMBIC_INI_TEMPLATE_PATH from ..catalog.core import ALL_REVISIONS + from ..utils import ensure_specified_sql_driver async def do_setup(): - engine = create_async_engine(database_uri) + engine = create_async_engine(ensure_specified_sql_driver(database_uri)) redacted_url = engine.url._replace(password="[redacted]") current_revision = await get_current_revision(engine, ALL_REVISIONS) await engine.dispose() @@ -127,9 +128,10 @@ def downgrade_database( from ..alembic_utils import downgrade, get_current_revision from ..catalog.alembic_constants import ALEMBIC_DIR, ALEMBIC_INI_TEMPLATE_PATH from ..catalog.core import ALL_REVISIONS + from ..utils import ensure_specified_sql_driver async def do_setup(): - engine = create_async_engine(database_uri) + engine = create_async_engine(ensure_specified_sql_driver(database_uri)) redacted_url = engine.url._replace(password="[redacted]") current_revision = await get_current_revision(engine, ALL_REVISIONS) if current_revision is None: diff --git a/tiled/commandline/_serve.py b/tiled/commandline/_serve.py index 17ef6f971..2fb7754cf 100644 --- a/tiled/commandline/_serve.py +++ b/tiled/commandline/_serve.py @@ -129,8 +129,9 @@ def serve_directory( from ..alembic_utils import stamp_head from ..catalog.alembic_constants import ALEMBIC_DIR, ALEMBIC_INI_TEMPLATE_PATH from ..catalog.core import initialize_database + from ..utils import ensure_specified_sql_driver - engine = create_async_engine(database) + engine = create_async_engine(ensure_specified_sql_driver(database)) asyncio.run(initialize_database(engine)) stamp_head(ALEMBIC_INI_TEMPLATE_PATH, ALEMBIC_DIR, database) @@ -389,8 +390,9 @@ def serve_catalog( from ..alembic_utils import stamp_head from ..catalog.alembic_constants import ALEMBIC_DIR, ALEMBIC_INI_TEMPLATE_PATH from ..catalog.core import initialize_database + from ..utils import ensure_specified_sql_driver - engine = create_async_engine(database) + engine = create_async_engine(ensure_specified_sql_driver(database)) asyncio.run(initialize_database(engine)) stamp_head(ALEMBIC_INI_TEMPLATE_PATH, ALEMBIC_DIR, database) diff --git a/tiled/utils.py b/tiled/utils.py index 105c7601e..c9744f320 100644 --- a/tiled/utils.py +++ b/tiled/utils.py @@ -721,6 +721,31 @@ def ensure_uri(uri_or_path) -> str: return str(uri_str) +SCHEME_TO_SCHEME_PLUS_DRIVER = { + "postgresql": "postgresql+asyncpg", + "sqlite": "sqlite+aiosqlite", +} + + +def ensure_specified_sql_driver(uri: str) -> str: + """ + Given a URI without a driver in the scheme, add Tiled's preferred driver. + + If a driver is already specified, the specified one will be used; it + will NOT be overriden by this function. + + 'postgresql://...' -> 'postgresql+asynpg://...' + 'sqlite://...' -> 'sqlite+aiosqlite://...' + 'postgresql+asyncpg://...' -> 'postgresql+asynpg://...' + 'postgresql+my_custom_driver://...' -> 'postgresql+my_custom_driver://...' + """ + parsed_uri = urlparse(uri) + scheme = parsed_uri.scheme + new_scheme = SCHEME_TO_SCHEME_PLUS_DRIVER.get(scheme, scheme) + updated_uri = urlunparse(parsed_uri._replace(scheme=new_scheme)) + return updated_uri + + class catch_warning_msg(warnings.catch_warnings): """Backward compatible version of catch_warnings for python <3.11. From bfd540f6555df6c64acae2128b9b78cce2fda43e Mon Sep 17 00:00:00 2001 From: Dan Allan Date: Wed, 11 Sep 2024 17:14:23 -0400 Subject: [PATCH 2/9] Handle special SQLite URIs --- tiled/_tests/test_utils.py | 61 ++++++++++++++++++++++++++++++++++++++ tiled/utils.py | 6 ++-- 2 files changed, 63 insertions(+), 4 deletions(-) create mode 100644 tiled/_tests/test_utils.py diff --git a/tiled/_tests/test_utils.py b/tiled/_tests/test_utils.py new file mode 100644 index 000000000..f31fe86b1 --- /dev/null +++ b/tiled/_tests/test_utils.py @@ -0,0 +1,61 @@ +from ..utils import ensure_specified_sql_driver + + +def test_ensure_specified_sql_driver(): + # Postgres + # Default driver is added if missing. + assert ( + ensure_specified_sql_driver( + "postgresql://user:password@localhost:5432/database" + ) + == "postgresql+asyncpg://user:password@localhost:5432/database" + ) + # Default driver passes through if specified. + assert ( + ensure_specified_sql_driver( + "postgresql+asyncpg://user:password@localhost:5432/database" + ) + == "postgresql+asyncpg://user:password@localhost:5432/database" + ) + # Do not override user-provided. + assert ( + ensure_specified_sql_driver( + "postgresql+custom://user:password@localhost:5432/database" + ) + == "postgresql+custom://user:password@localhost:5432/database" + ) + + # SQLite + # Default driver is added if missing. + assert ( + ensure_specified_sql_driver("sqlite:////test.db") + == "sqlite+aiosqlite:////test.db" + ) + # Default driver passes through if specified. + assert ( + ensure_specified_sql_driver("sqlite+aiosqlite:////test.db") + == "sqlite+aiosqlite:////test.db" + ) + # Do not override user-provided. + assert ( + ensure_specified_sql_driver("sqlite+custom:////test.db") + == "sqlite+custom:////test.db" + ) + # Handle SQLite :memory: URIs + assert ( + ensure_specified_sql_driver("sqlite+aiosqlite://:memory:") + == "sqlite+aiosqlite://:memory:" + ) + assert ( + ensure_specified_sql_driver("sqlite://:memory:") + == "sqlite+aiosqlite://:memory:" + ) + # Handle SQLite relative URIs + assert ( + ensure_specified_sql_driver("sqlite+aiosqlite:///test.db") + == "sqlite+aiosqlite:///test.db" + ) + assert ( + ensure_specified_sql_driver("sqlite:///test.db") + == "sqlite+aiosqlite:///test.db" + ) diff --git a/tiled/utils.py b/tiled/utils.py index c9744f320..eefdc9529 100644 --- a/tiled/utils.py +++ b/tiled/utils.py @@ -739,11 +739,9 @@ def ensure_specified_sql_driver(uri: str) -> str: 'postgresql+asyncpg://...' -> 'postgresql+asynpg://...' 'postgresql+my_custom_driver://...' -> 'postgresql+my_custom_driver://...' """ - parsed_uri = urlparse(uri) - scheme = parsed_uri.scheme + scheme, rest = uri.split(":", 1) new_scheme = SCHEME_TO_SCHEME_PLUS_DRIVER.get(scheme, scheme) - updated_uri = urlunparse(parsed_uri._replace(scheme=new_scheme)) - return updated_uri + return ":".join([new_scheme, rest]) class catch_warning_msg(warnings.catch_warnings): From 02e702cc908896d66bcd57e230e3e5fcd7556fda Mon Sep 17 00:00:00 2001 From: Dan Allan Date: Tue, 1 Oct 2024 10:59:26 -0400 Subject: [PATCH 3/9] Consistently use database URI with schema. --- tiled/commandline/_catalog.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/tiled/commandline/_catalog.py b/tiled/commandline/_catalog.py index b1fd5215e..68e50dc70 100644 --- a/tiled/commandline/_catalog.py +++ b/tiled/commandline/_catalog.py @@ -49,9 +49,10 @@ def init( if not SCHEME_PATTERN.match(database): # Interpret URI as filepath. database = f"sqlite+aiosqlite:///{database}" + database = ensure_specified_sql_driver(database) async def do_setup(): - engine = create_async_engine(ensure_specified_sql_driver(database)) + engine = create_async_engine(database) redacted_url = engine.url._replace(password="[redacted]") try: await check_database(engine, REQUIRED_REVISION, ALL_REVISIONS) @@ -96,8 +97,10 @@ def upgrade_database( from ..catalog.core import ALL_REVISIONS from ..utils import ensure_specified_sql_driver + database_uri = ensure_specified_sql_driver(database_uri) + async def do_setup(): - engine = create_async_engine(ensure_specified_sql_driver(database_uri)) + engine = create_async_engine(database_uri) redacted_url = engine.url._replace(password="[redacted]") current_revision = await get_current_revision(engine, ALL_REVISIONS) await engine.dispose() @@ -130,8 +133,10 @@ def downgrade_database( from ..catalog.core import ALL_REVISIONS from ..utils import ensure_specified_sql_driver + database_uri = ensure_specified_sql_driver(database_uri) + async def do_setup(): - engine = create_async_engine(ensure_specified_sql_driver(database_uri)) + engine = create_async_engine(database_uri) redacted_url = engine.url._replace(password="[redacted]") current_revision = await get_current_revision(engine, ALL_REVISIONS) if current_revision is None: From 54c07f2b9c54af2b411ad2c484c2df99f628eaaa Mon Sep 17 00:00:00 2001 From: Dan Allan Date: Wed, 2 Oct 2024 09:14:56 -0400 Subject: [PATCH 4/9] Interpret filepaths as SQLite URIs. --- tiled/_tests/test_utils.py | 10 ++++++++++ tiled/catalog/adapter.py | 4 ---- tiled/commandline/_catalog.py | 5 +---- tiled/utils.py | 4 ++++ 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/tiled/_tests/test_utils.py b/tiled/_tests/test_utils.py index f31fe86b1..ab688d2b7 100644 --- a/tiled/_tests/test_utils.py +++ b/tiled/_tests/test_utils.py @@ -59,3 +59,13 @@ def test_ensure_specified_sql_driver(): ensure_specified_sql_driver("sqlite:///test.db") == "sqlite+aiosqlite:///test.db" ) + # Filepaths are implicitly SQLite databases. + # Relative path + assert ensure_specified_sql_driver("test.db") == "sqlite+aiosqlite:///test.db" + # Relative path anchored to . + assert ensure_specified_sql_driver("./test.db") == "sqlite+aiosqlite:///test.db" + # Absolute path + assert ( + ensure_specified_sql_driver("/tmp/test.db") + == "sqlite+aiosqlite:////tmp/test.db" + ) diff --git a/tiled/catalog/adapter.py b/tiled/catalog/adapter.py index 224e3b055..ee4c42ae5 100644 --- a/tiled/catalog/adapter.py +++ b/tiled/catalog/adapter.py @@ -64,7 +64,6 @@ from ..server.schemas import Asset, DataSource, Management, Revision, Spec from ..structures.core import StructureFamily from ..utils import ( - SCHEME_PATTERN, UNCHANGED, Conflicts, OneShotCachedMap, @@ -1367,9 +1366,6 @@ def from_uri( stderr = process.stderr.decode() logging.info(f"Subprocess stdout: {stdout}") logging.error(f"Subprocess stderr: {stderr}") - if not SCHEME_PATTERN.match(uri): - # Interpret URI as filepath. - uri = f"sqlite+aiosqlite:///{uri}" parsed_url = make_url(uri) if (parsed_url.get_dialect().name == "sqlite") and ( diff --git a/tiled/commandline/_catalog.py b/tiled/commandline/_catalog.py index 68e50dc70..2de6849b7 100644 --- a/tiled/commandline/_catalog.py +++ b/tiled/commandline/_catalog.py @@ -44,11 +44,8 @@ def init( from ..alembic_utils import UninitializedDatabase, check_database, stamp_head from ..catalog.alembic_constants import ALEMBIC_DIR, ALEMBIC_INI_TEMPLATE_PATH from ..catalog.core import ALL_REVISIONS, REQUIRED_REVISION, initialize_database - from ..utils import SCHEME_PATTERN, ensure_specified_sql_driver + from ..utils import ensure_specified_sql_driver - if not SCHEME_PATTERN.match(database): - # Interpret URI as filepath. - database = f"sqlite+aiosqlite:///{database}" database = ensure_specified_sql_driver(database) async def do_setup(): diff --git a/tiled/utils.py b/tiled/utils.py index eefdc9529..e404b97f3 100644 --- a/tiled/utils.py +++ b/tiled/utils.py @@ -738,7 +738,11 @@ def ensure_specified_sql_driver(uri: str) -> str: 'sqlite://...' -> 'sqlite+aiosqlite://...' 'postgresql+asyncpg://...' -> 'postgresql+asynpg://...' 'postgresql+my_custom_driver://...' -> 'postgresql+my_custom_driver://...' + '/path/to/file.db' -> 'sqlite+aiosqlite:////path/to/file.db' """ + if not SCHEME_PATTERN.match(uri): + # Interpret URI as filepath. + uri = f"sqlite+aiosqlite:///{Path(uri)}" scheme, rest = uri.split(":", 1) new_scheme = SCHEME_TO_SCHEME_PLUS_DRIVER.get(scheme, scheme) return ":".join([new_scheme, rest]) From c70eed225e71407f0b3e0e108273fd0c9fc4a6b1 Mon Sep 17 00:00:00 2001 From: Dan Allan Date: Fri, 4 Oct 2024 12:49:47 -0400 Subject: [PATCH 5/9] Parse uri earlier. --- tiled/catalog/adapter.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tiled/catalog/adapter.py b/tiled/catalog/adapter.py index ee4c42ae5..78a0fdb1a 100644 --- a/tiled/catalog/adapter.py +++ b/tiled/catalog/adapter.py @@ -1347,7 +1347,7 @@ def from_uri( echo=DEFAULT_ECHO, adapters_by_mimetype=None, ): - uri = str(uri) + uri = ensure_specified_sql_driver(uri) if init_if_not_exists: # The alembic stamping can only be does synchronously. # The cleanest option available is to start a subprocess @@ -1378,7 +1378,6 @@ def from_uri( else: poolclass = None # defer to sqlalchemy default engine = create_async_engine( - ensure_specified_sql_driver(uri), echo=echo, json_serializer=json_serializer, poolclass=poolclass, From fe28a8aee9dfa0b01f519f0aa07abff1f3060b3b Mon Sep 17 00:00:00 2001 From: Dan Allan Date: Mon, 4 Nov 2024 18:14:57 -0500 Subject: [PATCH 6/9] Update CHANGELOG --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e384cb8a..1c07cab4d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,8 @@ Write the date in place of the "Unreleased" in the case a new version is release - Drop support for Python 3.8, which is reached end of life upstream on 7 October 2024. +- Do not require SQL database URIs to specify a "driver" (Python + library to be used for connecting). ## v0.1.0b10 (2024-10-11) From 0b1181ad6c4e8c4f0f70e67c78ce800ee20e3f11 Mon Sep 17 00:00:00 2001 From: Dan Allan Date: Tue, 5 Nov 2024 10:28:26 -0500 Subject: [PATCH 7/9] Fix missing arg in refactor. --- tiled/catalog/adapter.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tiled/catalog/adapter.py b/tiled/catalog/adapter.py index 78a0fdb1a..2844bcdef 100644 --- a/tiled/catalog/adapter.py +++ b/tiled/catalog/adapter.py @@ -1378,6 +1378,7 @@ def from_uri( else: poolclass = None # defer to sqlalchemy default engine = create_async_engine( + uri, echo=echo, json_serializer=json_serializer, poolclass=poolclass, From 2aed6f48f7b5868e5593bd3de210b6be68a58efb Mon Sep 17 00:00:00 2001 From: Dan Allan Date: Tue, 5 Nov 2024 10:51:41 -0500 Subject: [PATCH 8/9] Make utility accept Path-like objects. --- tiled/_tests/test_utils.py | 4 ++++ tiled/utils.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/tiled/_tests/test_utils.py b/tiled/_tests/test_utils.py index ab688d2b7..e6671f20c 100644 --- a/tiled/_tests/test_utils.py +++ b/tiled/_tests/test_utils.py @@ -1,3 +1,5 @@ +from pathlib import Path + from ..utils import ensure_specified_sql_driver @@ -62,6 +64,8 @@ def test_ensure_specified_sql_driver(): # Filepaths are implicitly SQLite databases. # Relative path assert ensure_specified_sql_driver("test.db") == "sqlite+aiosqlite:///test.db" + # Path object + assert ensure_specified_sql_driver(Path("test.db")) == "sqlite+aiosqlite:///test.db" # Relative path anchored to . assert ensure_specified_sql_driver("./test.db") == "sqlite+aiosqlite:///test.db" # Absolute path diff --git a/tiled/utils.py b/tiled/utils.py index e404b97f3..732424c35 100644 --- a/tiled/utils.py +++ b/tiled/utils.py @@ -740,7 +740,7 @@ def ensure_specified_sql_driver(uri: str) -> str: 'postgresql+my_custom_driver://...' -> 'postgresql+my_custom_driver://...' '/path/to/file.db' -> 'sqlite+aiosqlite:////path/to/file.db' """ - if not SCHEME_PATTERN.match(uri): + if not SCHEME_PATTERN.match(str(uri)): # Interpret URI as filepath. uri = f"sqlite+aiosqlite:///{Path(uri)}" scheme, rest = uri.split(":", 1) From 639cc266c30e1e1fdea2d45e4bcabef8cd6cc1ac Mon Sep 17 00:00:00 2001 From: Dan Allan Date: Tue, 5 Nov 2024 12:13:36 -0500 Subject: [PATCH 9/9] Deal with Windows paths in test case --- tiled/_tests/test_utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tiled/_tests/test_utils.py b/tiled/_tests/test_utils.py index e6671f20c..2e39725e7 100644 --- a/tiled/_tests/test_utils.py +++ b/tiled/_tests/test_utils.py @@ -70,6 +70,6 @@ def test_ensure_specified_sql_driver(): assert ensure_specified_sql_driver("./test.db") == "sqlite+aiosqlite:///test.db" # Absolute path assert ( - ensure_specified_sql_driver("/tmp/test.db") - == "sqlite+aiosqlite:////tmp/test.db" + ensure_specified_sql_driver(Path("/tmp/test.db")) + == f"sqlite+aiosqlite:///{Path('/tmp/test.db')}" )