From 36241638ba1ce07725996f8b301eef989cab6d9b Mon Sep 17 00:00:00 2001 From: ptiurin Date: Mon, 28 Jul 2025 13:39:15 +0100 Subject: [PATCH 1/6] build: Remove python 3.8 support --- .github/workflows/code-check.yml | 6 +++--- .github/workflows/integration-tests-v1.yml | 4 ++-- .github/workflows/integration-tests-v2.yml | 4 ++-- .github/workflows/nightly-v1.yml | 2 +- .github/workflows/nightly-v2.yml | 2 +- .github/workflows/unit-tests.yml | 4 ++-- docsrc/index.rst | 2 +- setup.cfg | 3 +-- 8 files changed, 13 insertions(+), 14 deletions(-) diff --git a/.github/workflows/code-check.yml b/.github/workflows/code-check.yml index 9a78a206e0..a784fad114 100644 --- a/.github/workflows/code-check.yml +++ b/.github/workflows/code-check.yml @@ -19,11 +19,11 @@ jobs: with: ref: ${{ inputs.branch }} - - name: Set up Python 3.8 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: 3.8 - + python-version: 3.9 + - name: Install dependencies run: | python -m pip install --upgrade pip diff --git a/.github/workflows/integration-tests-v1.yml b/.github/workflows/integration-tests-v1.yml index 0b8f131c48..f40ba6e888 100644 --- a/.github/workflows/integration-tests-v1.yml +++ b/.github/workflows/integration-tests-v1.yml @@ -18,10 +18,10 @@ jobs: - name: Check out code uses: actions/checkout@v2 - - name: Set up Python 3.8 + - name: Set up Python 3.9 uses: actions/setup-python@v2 with: - python-version: 3.8 + python-version: 3.9 - name: Install dependencies run: | diff --git a/.github/workflows/integration-tests-v2.yml b/.github/workflows/integration-tests-v2.yml index df881134a5..bd40a85686 100644 --- a/.github/workflows/integration-tests-v2.yml +++ b/.github/workflows/integration-tests-v2.yml @@ -27,10 +27,10 @@ jobs: with: repository: 'firebolt-db/firebolt-python-sdk' - - name: Set up Python 3.8 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: 3.8 + python-version: 3.9 - name: Install dependencies run: | diff --git a/.github/workflows/nightly-v1.yml b/.github/workflows/nightly-v1.yml index f52179077d..fc9c692fa3 100644 --- a/.github/workflows/nightly-v1.yml +++ b/.github/workflows/nightly-v1.yml @@ -36,7 +36,7 @@ jobs: max-parallel: 2 matrix: os: ['ubuntu-latest', 'macos-latest', 'windows-latest'] - python-version: ['3.8', '3.9', '3.10'] + python-version: ['3.9', '3.10', '3.11'] steps: - name: Check out code uses: actions/checkout@v2 diff --git a/.github/workflows/nightly-v2.yml b/.github/workflows/nightly-v2.yml index 9448e863b0..ec89f3f973 100644 --- a/.github/workflows/nightly-v2.yml +++ b/.github/workflows/nightly-v2.yml @@ -36,7 +36,7 @@ jobs: max-parallel: 2 matrix: os: ['ubuntu-latest', 'macos-latest', 'windows-latest'] - python-version: ['3.8', '3.9', '3.10'] + python-version: ['3.9', '3.10', '3.11'] steps: - name: Check out code uses: actions/checkout@v2 diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index d61ff2f33d..12e1c15fe1 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -27,10 +27,10 @@ jobs: with: ref: ${{ inputs.branch }} - - name: Set up Python 3.8 + - name: Set up Python 3.9 uses: actions/setup-python@v2 with: - python-version: 3.8 + python-version: 3.9 - name: Install dependencies run: | diff --git a/docsrc/index.rst b/docsrc/index.rst index e55a3dd56b..337f28a782 100644 --- a/docsrc/index.rst +++ b/docsrc/index.rst @@ -14,7 +14,7 @@ executing queries using a library of Python classes and functions. Prerequisites ======================== -* Python version 3.8 or later along with the pip package installer. For more information, +* Python version 3.9 or later along with the pip package installer. For more information, see the `Python `_ web page. * A Firebolt account and login credentials. diff --git a/setup.cfg b/setup.cfg index d2c5a97585..64bcfd4547 100755 --- a/setup.cfg +++ b/setup.cfg @@ -14,7 +14,6 @@ classifiers = Operating System :: OS Independent Programming Language :: Python :: 3 Programming Language :: Python :: 3 :: Only - Programming Language :: Python :: 3.8 Programming Language :: Python :: 3.9 Programming Language :: Python :: 3.10 Programming Language :: Python :: 3.11 @@ -40,7 +39,7 @@ install_requires = sqlparse>=0.4.2 trio>=0.22.0 truststore>=0.10;python_version>="3.10" -python_requires = >=3.8 +python_requires = >=3.9 include_package_data = True package_dir = = src From b6ea9d15880d7a64c5d7607b7d1ae0602f3d2557 Mon Sep 17 00:00:00 2001 From: ptiurin Date: Mon, 28 Jul 2025 14:18:02 +0100 Subject: [PATCH 2/6] attempt to fix tests --- tests/integration/dbapi/async/V2/test_queries_async.py | 6 +++--- tests/integration/dbapi/sync/V2/test_queries.py | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/integration/dbapi/async/V2/test_queries_async.py b/tests/integration/dbapi/async/V2/test_queries_async.py index e6e16a280a..c0c93066f9 100644 --- a/tests/integration/dbapi/async/V2/test_queries_async.py +++ b/tests/integration/dbapi/async/V2/test_queries_async.py @@ -265,16 +265,16 @@ async def test_empty_query(c: Cursor, query: str, params: tuple) -> None: async def test_parameterized_query_with_special_chars(connection: Connection) -> None: """Query parameters are handled properly.""" async with connection.cursor() as c: - params = ["text with 'quote'", "text with \\slashes"] + parameters = ["text with 'quote'", "text with \\slashes"] await c.execute( "SELECT ? as one, ? as two", - params, + parameters, ) result = await c.fetchall() assert result == [ - [params[0], params[1]] + [parameters[0], parameters[1]] ], "Invalid data in table after parameterized insert" diff --git a/tests/integration/dbapi/sync/V2/test_queries.py b/tests/integration/dbapi/sync/V2/test_queries.py index ff07b49012..869e093cc6 100644 --- a/tests/integration/dbapi/sync/V2/test_queries.py +++ b/tests/integration/dbapi/sync/V2/test_queries.py @@ -17,7 +17,7 @@ VALS_TO_INSERT = ",".join([f"({i},'{val}')" for (i, val) in enumerate(range(1, 360))]) LONG_INSERT = f"INSERT INTO test_tbl VALUES {VALS_TO_INSERT}" LONG_SELECT = ( - "SELECT checksum(*) FROM GENERATE_SERIES(1, 400000000000)" # approx 6m runtime + "SELECT checksum(*) FROM GENERATE_SERIES(1, 350000000000)" # approx 6m runtime ) @@ -214,16 +214,16 @@ def test_empty_query(c: Cursor, query: str) -> None: def test_parameterized_query_with_special_chars(connection: Connection) -> None: """Query parameters are handled properly.""" with connection.cursor() as c: - params = ["text with 'quote'", "text with \\slashes"] + parameters = ["text with 'quote'", "text with \\slashes"] c.execute( "SELECT ? as one, ? as two", - params, + parameters, ) result = c.fetchall() assert result == [ - [params[0], params[1]] + [parameters[0], parameters[1]] ], "Invalid data in table after parameterized insert" From 7a3496e65481434f0a79168b709afecdf17ec85d Mon Sep 17 00:00:00 2001 From: ptiurin Date: Tue, 29 Jul 2025 11:34:33 +0100 Subject: [PATCH 3/6] use variable for long tests --- .github/workflows/integration-tests-v1.yml | 1 + .github/workflows/integration-tests-v2.yml | 1 + .github/workflows/nightly-v1.yml | 1 + .github/workflows/nightly-v2.yml | 1 + .../dbapi/async/V1/test_queries_async.py | 8 ++++++-- .../dbapi/async/V2/test_queries_async.py | 8 ++++++-- tests/integration/dbapi/conftest.py | 14 ++++++++++++++ tests/integration/dbapi/sync/V1/test_queries.py | 11 ++++++++--- tests/integration/dbapi/sync/V2/test_queries.py | 8 ++++++-- 9 files changed, 44 insertions(+), 9 deletions(-) diff --git a/.github/workflows/integration-tests-v1.yml b/.github/workflows/integration-tests-v1.yml index f40ba6e888..d6be6a6a35 100644 --- a/.github/workflows/integration-tests-v1.yml +++ b/.github/workflows/integration-tests-v1.yml @@ -58,6 +58,7 @@ jobs: STOPPED_ENGINE_URL: ${{ steps.setup.outputs.stopped_engine_url }} API_ENDPOINT: "api.staging.firebolt.io" ACCOUNT_NAME: "firebolt" + LONG_TEST_VALUE: ${{ vars.LONG_TEST_VALUE_V1 }} run: | pytest --last-failed -n 6 --dist loadgroup --timeout_method "signal" -o log_cli=true -o log_cli_level=INFO tests/integration -k "not V2 and not core" --runslow diff --git a/.github/workflows/integration-tests-v2.yml b/.github/workflows/integration-tests-v2.yml index bd40a85686..9238242894 100644 --- a/.github/workflows/integration-tests-v2.yml +++ b/.github/workflows/integration-tests-v2.yml @@ -56,6 +56,7 @@ jobs: STOPPED_ENGINE_NAME: ${{ steps.setup.outputs.stopped_engine_name }} API_ENDPOINT: "api.staging.firebolt.io" ACCOUNT_NAME: ${{ vars.FIREBOLT_ACCOUNT }} + LONG_TEST_VALUE: ${{ vars.LONG_TEST_VALUE_V2 }} run: | pytest -n 6 --dist loadgroup --timeout_method "signal" -o log_cli=true -o log_cli_level=WARNING tests/integration -k "not V1 and not core" --runslow --alluredir=allure-results diff --git a/.github/workflows/nightly-v1.yml b/.github/workflows/nightly-v1.yml index fc9c692fa3..ada5e5c1a8 100644 --- a/.github/workflows/nightly-v1.yml +++ b/.github/workflows/nightly-v1.yml @@ -78,6 +78,7 @@ jobs: STOPPED_ENGINE_URL: ${{ steps.setup.outputs.stopped_engine_url }} ACCOUNT_NAME: "firebolt" API_ENDPOINT: "api.staging.firebolt.io" + LONG_TEST_VALUE: ${{ vars.LONG_TEST_VALUE_V1 }} run: | pytest --timeout_method "thread" -o log_cli=true -o log_cli_level=WARNING --junit-xml=report/junit.xml tests/integration -k "not V2 and not core" diff --git a/.github/workflows/nightly-v2.yml b/.github/workflows/nightly-v2.yml index ec89f3f973..a971ca7c4d 100644 --- a/.github/workflows/nightly-v2.yml +++ b/.github/workflows/nightly-v2.yml @@ -74,6 +74,7 @@ jobs: STOPPED_ENGINE_NAME: ${{ steps.setup.outputs.stopped_engine_name }} ACCOUNT_NAME: ${{ vars.FIREBOLT_ACCOUNT }} API_ENDPOINT: "api.staging.firebolt.io" + LONG_TEST_VALUE: ${{ vars.LONG_TEST_VALUE_V2 }} run: | pytest --timeout_method "thread" -o log_cli=true -o log_cli_level=WARNING --junit-xml=report/junit.xml tests/integration -k "not V1 and not core" diff --git a/tests/integration/dbapi/async/V1/test_queries_async.py b/tests/integration/dbapi/async/V1/test_queries_async.py index d8d5906c47..cc4e9f04f5 100644 --- a/tests/integration/dbapi/async/V1/test_queries_async.py +++ b/tests/integration/dbapi/async/V1/test_queries_async.py @@ -9,13 +9,14 @@ from firebolt.async_db import Binary, Connection, Cursor, OperationalError from firebolt.common._types import ColType from firebolt.common.row_set.types import Column +from tests.integration.dbapi.conftest import LONG_SELECT_DEFAULT_V1 VALS_TO_INSERT_2 = ",".join( [f"({i}, {i-3}, '{val}')" for (i, val) in enumerate(range(4, 1000))] ) LONG_INSERT = f'INSERT INTO "test_tbl" VALUES {VALS_TO_INSERT_2}' LONG_SELECT = ( - "SELECT checksum(*) FROM GENERATE_SERIES(1, 250000000000)" # approx 6m runtime + "SELECT checksum(*) FROM GENERATE_SERIES(1, {long_value})" # approx 6m runtime ) CREATE_EXTERNAL_TABLE = """CREATE EXTERNAL TABLE IF NOT EXISTS "ex_lineitem" ( @@ -174,6 +175,7 @@ async def test_select_nan(connection: Connection) -> None: async def test_long_query( connection: Connection, minimal_time: Callable[[float], None], + long_test_value: int, ) -> None: """AWS ALB TCP timeout set to 350; make sure we handle the keepalive correctly.""" @@ -181,7 +183,9 @@ async def test_long_query( minimal_time(350) async with connection.cursor() as c: - await c.execute(LONG_SELECT) + await c.execute( + LONG_SELECT.format(long_value=long_test_value(LONG_SELECT_DEFAULT_V1)) + ) data = await c.fetchall() assert len(data) == 1, "Invalid data size returned by fetchall" diff --git a/tests/integration/dbapi/async/V2/test_queries_async.py b/tests/integration/dbapi/async/V2/test_queries_async.py index c0c93066f9..fa8dc0ab12 100644 --- a/tests/integration/dbapi/async/V2/test_queries_async.py +++ b/tests/integration/dbapi/async/V2/test_queries_async.py @@ -12,6 +12,7 @@ from firebolt.common._types import ColType from firebolt.common.row_set.types import Column from firebolt.utils.exception import FireboltStructuredError +from tests.integration.dbapi.conftest import LONG_SELECT_DEFAULT_V2 from tests.integration.dbapi.utils import assert_deep_eq VALS_TO_INSERT_2 = ",".join( @@ -19,7 +20,7 @@ ) LONG_INSERT = f'INSERT INTO "test_tbl" VALUES {VALS_TO_INSERT_2}' LONG_SELECT = ( - "SELECT checksum(*) FROM GENERATE_SERIES(1, 400000000000)" # approx 6m runtime + "SELECT checksum(*) FROM GENERATE_SERIES(1, {long_value})" # approx 6m runtime ) @@ -102,13 +103,16 @@ async def test_select_nan(connection: Connection) -> None: async def test_long_query( connection: Connection, minimal_time: Callable[[float], None], + long_test_value: Callable[[int], int], ) -> None: """AWS ALB TCP timeout set to 350; make sure we handle the keepalive correctly.""" minimal_time(350) async with connection.cursor() as c: - await c.execute(LONG_SELECT) + await c.execute( + LONG_SELECT.format(long_value=long_test_value(LONG_SELECT_DEFAULT_V2)) + ) data = await c.fetchall() assert len(data) == 1, "Invalid data size returned by fetchall" diff --git a/tests/integration/dbapi/conftest.py b/tests/integration/dbapi/conftest.py index 9d2b53c98e..015ab0cb1d 100644 --- a/tests/integration/dbapi/conftest.py +++ b/tests/integration/dbapi/conftest.py @@ -1,3 +1,4 @@ +import os from datetime import date, datetime, timedelta, timezone from decimal import Decimal from logging import getLogger @@ -16,6 +17,19 @@ ) DROP_TEST_TABLE = 'DROP TABLE IF EXISTS "test_tbl" CASCADE' +LONG_SELECT_DEFAULT_V1 = 250000000000 +LONG_SELECT_DEFAULT_V2 = 350000000000 + + +@fixture +def long_test_value() -> int: + """Return the long test value from environment variable or 0 to use default.""" + + def long_test_value_with_default(default: int = 0) -> int: + return int(os.getenv("LONG_TEST_VALUE", default)) + + return long_test_value_with_default + @fixture def create_drop_test_table_setup_teardown(connection: Connection) -> None: diff --git a/tests/integration/dbapi/sync/V1/test_queries.py b/tests/integration/dbapi/sync/V1/test_queries.py index b331e7ac8c..2e908ff577 100644 --- a/tests/integration/dbapi/sync/V1/test_queries.py +++ b/tests/integration/dbapi/sync/V1/test_queries.py @@ -10,11 +10,12 @@ from firebolt.common._types import ColType from firebolt.common.row_set.types import Column from firebolt.db import Binary, Connection, Cursor, OperationalError, connect +from tests.integration.dbapi.conftest import LONG_SELECT_DEFAULT_V1 VALS_TO_INSERT = ",".join([f"({i},'{val}')" for (i, val) in enumerate(range(1, 360))]) LONG_INSERT = f'INSERT INTO "test_tbl" VALUES {VALS_TO_INSERT}' LONG_SELECT = ( - "SELECT checksum(*) FROM GENERATE_SERIES(1, 250000000000)" # approx 6m runtime + "SELECT checksum(*) FROM GENERATE_SERIES(1, {long_value})" # approx 6m runtime ) @@ -122,7 +123,9 @@ def test_select_nan(connection: Connection) -> None: @mark.slow @mark.timeout(timeout=1000) def test_long_query( - connection: Connection, minimal_time: Callable[[float], None] + connection: Connection, + minimal_time: Callable[[float], None], + long_test_value: Callable[[int], int], ) -> None: """AWS ALB TCP timeout set to 350, make sure we handle the keepalive correctly.""" @@ -130,7 +133,9 @@ def test_long_query( minimal_time(350) with connection.cursor() as c: - c.execute(LONG_SELECT) + c.execute( + LONG_SELECT.format(long_value=long_test_value(LONG_SELECT_DEFAULT_V1)) + ) data = c.fetchall() assert len(data) == 1, "Invalid data size returned by fetchall" diff --git a/tests/integration/dbapi/sync/V2/test_queries.py b/tests/integration/dbapi/sync/V2/test_queries.py index 869e093cc6..46e140ba8e 100644 --- a/tests/integration/dbapi/sync/V2/test_queries.py +++ b/tests/integration/dbapi/sync/V2/test_queries.py @@ -12,12 +12,13 @@ from firebolt.common.row_set.types import Column from firebolt.db import Binary, Connection, Cursor, OperationalError, connect from firebolt.utils.exception import FireboltStructuredError +from tests.integration.dbapi.conftest import LONG_SELECT_DEFAULT_V2 from tests.integration.dbapi.utils import assert_deep_eq VALS_TO_INSERT = ",".join([f"({i},'{val}')" for (i, val) in enumerate(range(1, 360))]) LONG_INSERT = f"INSERT INTO test_tbl VALUES {VALS_TO_INSERT}" LONG_SELECT = ( - "SELECT checksum(*) FROM GENERATE_SERIES(1, 350000000000)" # approx 6m runtime + "SELECT checksum(*) FROM GENERATE_SERIES(1, {long_value})" # approx 6m runtime ) @@ -106,13 +107,16 @@ def test_select_nan(connection: Connection) -> None: def test_long_query( connection: Connection, minimal_time: Callable[[float], None], + long_test_value: Callable[[int], int], ) -> None: """AWS ALB TCP timeout set to 350; make sure we handle the keepalive correctly.""" minimal_time(350) with connection.cursor() as c: - c.execute(LONG_SELECT) + c.execute( + LONG_SELECT.format(long_value=long_test_value(LONG_SELECT_DEFAULT_V2)) + ) data = c.fetchall() assert len(data) == 1, "Invalid data size returned by fetchall" From 62bffe310c7017ebec46e476f24ca04b059b4339 Mon Sep 17 00:00:00 2001 From: ptiurin Date: Tue, 29 Jul 2025 11:53:53 +0100 Subject: [PATCH 4/6] fix nested runs --- .../dbapi/async/V2/test_queries_async.py | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/integration/dbapi/async/V2/test_queries_async.py b/tests/integration/dbapi/async/V2/test_queries_async.py index fa8dc0ab12..683b2d54c3 100644 --- a/tests/integration/dbapi/async/V2/test_queries_async.py +++ b/tests/integration/dbapi/async/V2/test_queries_async.py @@ -268,18 +268,18 @@ async def test_empty_query(c: Cursor, query: str, params: tuple) -> None: async def test_parameterized_query_with_special_chars(connection: Connection) -> None: """Query parameters are handled properly.""" - async with connection.cursor() as c: - parameters = ["text with 'quote'", "text with \\slashes"] + c = connection.cursor() + parameters = ["text with 'quote'", "text with \\slashes"] - await c.execute( - "SELECT ? as one, ? as two", - parameters, - ) + await c.execute( + "SELECT ? as one, ? as two", + parameters, + ) - result = await c.fetchall() - assert result == [ - [parameters[0], parameters[1]] - ], "Invalid data in table after parameterized insert" + result = await c.fetchall() + assert result == [ + [parameters[0], parameters[1]] + ], "Invalid data in table after parameterized insert" async def test_multi_statement_query(connection: Connection) -> None: From 0cd87d5048832c65e4a76a2508c2566b2e99efd7 Mon Sep 17 00:00:00 2001 From: ptiurin Date: Tue, 29 Jul 2025 11:57:36 +0100 Subject: [PATCH 5/6] fix test timeout --- tests/integration/dbapi/async/V2/test_timeout.py | 12 ++++++++++-- tests/integration/dbapi/sync/V2/test_timeout.py | 12 ++++++++++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/tests/integration/dbapi/async/V2/test_timeout.py b/tests/integration/dbapi/async/V2/test_timeout.py index 0aff66e3d6..9827807ab5 100644 --- a/tests/integration/dbapi/async/V2/test_timeout.py +++ b/tests/integration/dbapi/async/V2/test_timeout.py @@ -1,13 +1,21 @@ +from typing import Callable + from pytest import raises from firebolt.async_db import Connection from firebolt.utils.exception import QueryTimeoutError +from tests.integration.dbapi.conftest import LONG_SELECT_DEFAULT_V2 # Cannot have absolute path here since interpreter treats word async as keyword and not as a package name from .test_queries_async import LONG_SELECT -async def test_query_timeout(connection: Connection): +async def test_query_timeout( + connection: Connection, long_test_value: Callable[[int], int] +) -> None: async with connection.cursor() as cursor: with raises(QueryTimeoutError): - await cursor.execute(LONG_SELECT, timeout_seconds=1) + await cursor.execute( + LONG_SELECT.format(long_value=long_test_value(LONG_SELECT_DEFAULT_V2)), + timeout_seconds=1, + ) diff --git a/tests/integration/dbapi/sync/V2/test_timeout.py b/tests/integration/dbapi/sync/V2/test_timeout.py index 1da0dec9a5..a883aadeb9 100644 --- a/tests/integration/dbapi/sync/V2/test_timeout.py +++ b/tests/integration/dbapi/sync/V2/test_timeout.py @@ -1,12 +1,20 @@ +from typing import Callable + from pytest import raises from firebolt.db import Connection from firebolt.utils.exception import QueryTimeoutError +from tests.integration.dbapi.conftest import LONG_SELECT_DEFAULT_V2 from .test_queries import LONG_SELECT -def test_query_timeout(connection: Connection): +def test_query_timeout( + connection: Connection, long_test_value: Callable[[int], int] +) -> None: with connection.cursor() as cursor: with raises(QueryTimeoutError): - cursor.execute(LONG_SELECT, timeout_seconds=1) + cursor.execute( + LONG_SELECT.format(long_value=long_test_value(LONG_SELECT_DEFAULT_V2)), + timeout_seconds=1, + ) From 6b953e0944c6a201b13b0fe00c0dcc8920e5a3e9 Mon Sep 17 00:00:00 2001 From: ptiurin Date: Tue, 29 Jul 2025 12:49:47 +0100 Subject: [PATCH 6/6] revert test_parameterized_query_with_special_chars --- .../dbapi/async/V2/test_queries_async.py | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/integration/dbapi/async/V2/test_queries_async.py b/tests/integration/dbapi/async/V2/test_queries_async.py index 683b2d54c3..fa8dc0ab12 100644 --- a/tests/integration/dbapi/async/V2/test_queries_async.py +++ b/tests/integration/dbapi/async/V2/test_queries_async.py @@ -268,18 +268,18 @@ async def test_empty_query(c: Cursor, query: str, params: tuple) -> None: async def test_parameterized_query_with_special_chars(connection: Connection) -> None: """Query parameters are handled properly.""" - c = connection.cursor() - parameters = ["text with 'quote'", "text with \\slashes"] + async with connection.cursor() as c: + parameters = ["text with 'quote'", "text with \\slashes"] - await c.execute( - "SELECT ? as one, ? as two", - parameters, - ) + await c.execute( + "SELECT ? as one, ? as two", + parameters, + ) - result = await c.fetchall() - assert result == [ - [parameters[0], parameters[1]] - ], "Invalid data in table after parameterized insert" + result = await c.fetchall() + assert result == [ + [parameters[0], parameters[1]] + ], "Invalid data in table after parameterized insert" async def test_multi_statement_query(connection: Connection) -> None: