diff --git a/CHANGES.rst b/CHANGES.rst index e4bcaa3..3ca9544 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,6 +1,14 @@ Changelog ========= +3.0.0 +----- + +Breaking Changes +~~~~~~~~~~~~~~~~ + +- Removed support for Python 3.8 + 2.8.0 ----- diff --git a/README.rst b/README.rst index f831161..0e9af48 100644 --- a/README.rst +++ b/README.rst @@ -13,7 +13,7 @@ Please notice that sqlalchemy-hana isn't an official SAP product and isn't cover Prerequisites ------------- -* Python 3.8+ +* Python 3.9+ * SQLAlchemy 1.4 or 2.x * `hdbcli `_ diff --git a/pyproject.toml b/pyproject.toml index d6bb7cc..a5a190e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,10 +4,10 @@ build-backend = "setuptools.build_meta" [project] name = "sqlalchemy-hana" -version = "2.8.0" +version = "3.0.0" description = "SQLAlchemy dialect for SAP HANA" keywords = ["sqlalchemy", "sap", "hana"] -requires-python = "~=3.8" +requires-python = "~=3.9" readme = "README.rst" authors = [{ name = "Christoph Heer", email = "christoph.heer@sap.com" }] maintainers = [ @@ -20,7 +20,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Operating System :: OS Independent", "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", diff --git a/test/ci_setup.py b/test/ci_setup.py index 5148729..89a52dc 100644 --- a/test/ci_setup.py +++ b/test/ci_setup.py @@ -26,9 +26,12 @@ def setup(dburi: str) -> str: # always fulfill the password policy password = random_string(15) + "A1a" - with closing( - dbapi.connect(url.hostname, url.port, url.username, url.password) - ) as connection, closing(connection.cursor()) as cursor: + with ( + closing( + dbapi.connect(url.hostname, url.port, url.username, url.password) + ) as connection, + closing(connection.cursor()) as cursor, + ): cursor.execute( f'CREATE USER {user} PASSWORD "{password}" NO FORCE_FIRST_PASSWORD_CHANGE' ) @@ -41,9 +44,12 @@ def teardown(dburi: str, test_dburi: str) -> None: url = urlsplit(dburi) test_user = urlsplit(test_dburi).username - with closing( - dbapi.connect(url.hostname, url.port, url.username, url.password) - ) as connection, closing(connection.cursor()) as cursor: + with ( + closing( + dbapi.connect(url.hostname, url.port, url.username, url.password) + ) as connection, + closing(connection.cursor()) as cursor, + ): cursor.execute(f"DROP USER {test_user} CASCADE") diff --git a/test/test_dialect.py b/test/test_dialect.py index 357e21c..e88eeb9 100644 --- a/test/test_dialect.py +++ b/test/test_dialect.py @@ -194,11 +194,14 @@ def test_do_rollback_to_savepoint_unrelated_error(self) -> None: dialect = config.db.dialect connection = Mock() - with mock.patch.object( - sys, "exc_info", return_value=(ValueError, ValueError(), Mock()) - ), mock.patch.object( - DefaultDialect, "do_rollback_to_savepoint" - ) as super_rollback: + with ( + mock.patch.object( + sys, "exc_info", return_value=(ValueError, ValueError(), Mock()) + ), + mock.patch.object( + DefaultDialect, "do_rollback_to_savepoint" + ) as super_rollback, + ): dialect.do_rollback_to_savepoint(connection, "savepoint") super_rollback.assert_called_once_with(connection, "savepoint") @@ -209,11 +212,14 @@ def test_do_rollback_to_savepoint_ignores_error(self) -> None: error = Error(133, "transaction rolled back: deadlock") dbapi_error = DBAPIError(None, None, error) - with mock.patch.object( - sys, "exc_info", return_value=(DBAPIError, dbapi_error, Mock()) - ), mock.patch.object( - DefaultDialect, "do_rollback_to_savepoint" - ) as super_rollback: + with ( + mock.patch.object( + sys, "exc_info", return_value=(DBAPIError, dbapi_error, Mock()) + ), + mock.patch.object( + DefaultDialect, "do_rollback_to_savepoint" + ) as super_rollback, + ): dialect.do_rollback_to_savepoint(connection, "savepoint") super_rollback.assert_not_called() diff --git a/test/test_types.py b/test/test_types.py index 2a066f1..9cfa079 100644 --- a/test/test_types.py +++ b/test/test_types.py @@ -141,11 +141,15 @@ class BooleanTest(_TypeBaseTest): [(True, hana_types.BOOLEAN), (False, hana_types.TINYINT)], ) def test_native_boolean(self, supports_native_boolean, type_): - with mock.patch.object( - testing.db.engine.dialect, - "supports_native_boolean", - supports_native_boolean, - ), testing.db.connect() as connection, connection.begin(): + with ( + mock.patch.object( + testing.db.engine.dialect, + "supports_native_boolean", + supports_native_boolean, + ), + testing.db.connect() as connection, + connection.begin(), + ): table = Table("t", self.metadata, Column("x", types.Boolean)) table.create(bind=connection)