From: Federico Caselli Date: Tue, 7 Nov 2023 18:21:06 +0000 (+0100) Subject: More python 3.7 removal cleanups X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4da59c6f534371d8c76cd728e8a459018e9112b6;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git More python 3.7 removal cleanups Change-Id: I6de7754361c649af323fa1a90fe29371c98b1541 --- diff --git a/.github/workflows/create-wheels.yaml b/.github/workflows/create-wheels.yaml index b5c0126be6..8d81486c67 100644 --- a/.github/workflows/create-wheels.yaml +++ b/.github/workflows/create-wheels.yaml @@ -20,7 +20,7 @@ jobs: matrix: # emulated wheels on linux take too much time, split wheels into multiple runs python: - - "cp37-* cp38-*" + - "cp38-*" - "cp39-* cp310-*" - "cp311-* cp312-*" wheel_mode: diff --git a/.github/workflows/run-test.yaml b/.github/workflows/run-test.yaml index fa2fa54f2e..a273a76a9a 100644 --- a/.github/workflows/run-test.yaml +++ b/.github/workflows/run-test.yaml @@ -30,13 +30,12 @@ jobs: - "windows-latest" - "macos-latest" python-version: - - "3.7" - "3.8" - "3.9" - "3.10" - "3.11" - "3.12" - - "pypy-3.9" + - "pypy-3.10" build-type: - "cext" - "nocext" @@ -46,7 +45,7 @@ jobs: include: # autocommit tests fail on the ci for some reason - - python-version: "pypy-3.9" + - python-version: "pypy-3.10" pytest-args: "-k 'not test_autocommit_on and not test_turn_autocommit_off_via_default_iso_level and not test_autocommit_isolation_level'" - os: "ubuntu-latest" pytest-args: "--dbdriver pysqlite --dbdriver aiosqlite" @@ -58,10 +57,10 @@ jobs: - os: "macos-latest" architecture: x86 # pypy does not have cext or x86 - - python-version: "pypy-3.9" + - python-version: "pypy-3.10" build-type: "cext" - os: "windows-latest" - python-version: "pypy-3.9" + python-version: "pypy-3.10" architecture: x86 fail-fast: false @@ -91,7 +90,7 @@ jobs: - name: Run tests run: tox -e github-${{ matrix.build-type }} -- -q --nomemory --notimingintensive ${{ matrix.pytest-args }} - continue-on-error: ${{ matrix.python-version == 'pypy-3.9' }} + continue-on-error: ${{ matrix.python-version == 'pypy-3.10' }} run-test-arm64: name: test-arm64-${{ matrix.python-version }}-${{ matrix.build-type }}-${{ matrix.os }} @@ -99,11 +98,11 @@ jobs: strategy: matrix: python-version: - - cp37-cp37m - cp38-cp38 - cp39-cp39 - cp310-cp310 - cp311-cp311 + - cp312-cp312 build-type: - "cext" - "nocext" diff --git a/README.unittests.rst b/README.unittests.rst index 9cf309d2d7..f3cd4d6363 100644 --- a/README.unittests.rst +++ b/README.unittests.rst @@ -15,20 +15,20 @@ Advanced Tox Options For more elaborate CI-style test running, the tox script provided will run against various Python / database targets. For a basic run against -Python 3.8 using an in-memory SQLite database:: +Python 3.11 using an in-memory SQLite database:: - tox -e py38-sqlite + tox -e py311-sqlite The tox runner contains a series of target combinations that can run against various combinations of databases. The test suite can be run against SQLite with "backend" tests also running against a PostgreSQL database:: - tox -e py38-sqlite-postgresql + tox -e py311-sqlite-postgresql Or to run just "backend" tests against a MySQL database:: - tox -e py38-mysql-backendonly + tox -e py311-mysql-backendonly Running against backends other than SQLite requires that a database of that vendor be available at a specific URL. See "Setting Up Databases" below @@ -137,7 +137,7 @@ with the tox runner also:: [db] postgresql=postgresql+psycopg2://username:pass@hostname/dbname -Now when we run ``tox -e py38-postgresql``, it will use our custom URL instead +Now when we run ``tox -e py311-postgresql``, it will use our custom URL instead of the fixed one in setup.cfg. Database Configuration diff --git a/doc/build/orm/collection_api.rst b/doc/build/orm/collection_api.rst index 2d56bb9b2b..eff6d87cb4 100644 --- a/doc/build/orm/collection_api.rst +++ b/doc/build/orm/collection_api.rst @@ -87,7 +87,7 @@ Or for a ``set``, illustrated in the same child_id: Mapped[int] = mapped_column(primary_key=True) parent_id: Mapped[int] = mapped_column(ForeignKey("parent.id")) -.. note:: If using Python 3.7 or 3.8, annotations for collections need +.. note:: If using Python 3.8, annotations for collections need to use ``typing.List`` or ``typing.Set``, e.g. ``Mapped[List["Child"]]`` or ``Mapped[Set["Child"]]``; the ``list`` and ``set`` Python built-ins don't yet support generic annotation in these Python versions, such as:: diff --git a/lib/sqlalchemy/dialects/sqlite/pysqlite.py b/lib/sqlalchemy/dialects/sqlite/pysqlite.py index 3cd6e5f231..5925b405cf 100644 --- a/lib/sqlalchemy/dialects/sqlite/pysqlite.py +++ b/lib/sqlalchemy/dialects/sqlite/pysqlite.py @@ -544,7 +544,7 @@ class SQLiteDialect_pysqlite(SQLiteDialect): return None return re.search(a, b) is not None - if util.py38 and self._get_server_version_info(None) >= (3, 9): + if self._get_server_version_info(None) >= (3, 9): # sqlite must be greater than 3.8.3 for deterministic=True # https://docs.python.org/3/library/sqlite3.html#sqlite3.Connection.create_function # the check is more conservative since there were still issues diff --git a/lib/sqlalchemy/log.py b/lib/sqlalchemy/log.py index 8de6d188ce..39af45714d 100644 --- a/lib/sqlalchemy/log.py +++ b/lib/sqlalchemy/log.py @@ -30,18 +30,13 @@ from typing import TypeVar from typing import Union from .util import py311 -from .util import py38 from .util.typing import Literal -if py38: - STACKLEVEL = True - # needed as of py3.11.0b1 - # #8019 - STACKLEVEL_OFFSET = 2 if py311 else 1 -else: - STACKLEVEL = False - STACKLEVEL_OFFSET = 0 +STACKLEVEL = True +# needed as of py3.11.0b1 +# #8019 +STACKLEVEL_OFFSET = 2 if py311 else 1 _IT = TypeVar("_IT", bound="Identified") diff --git a/lib/sqlalchemy/orm/mapper.py b/lib/sqlalchemy/orm/mapper.py index c66d876e08..b686996370 100644 --- a/lib/sqlalchemy/orm/mapper.py +++ b/lib/sqlalchemy/orm/mapper.py @@ -3058,7 +3058,7 @@ class Mapper( 2. For each class, yield the attributes in the order in which they appear in ``__dict__``, with the exception of those in step - 3 below. In Python 3.6 and above this ordering will be the + 3 below. The order will be the same as that of the class' construction, with the exception of attributes that were added after the fact by the application or the mapper. diff --git a/lib/sqlalchemy/testing/requirements.py b/lib/sqlalchemy/testing/requirements.py index 5d1f3fb166..f06ccd58bd 100644 --- a/lib/sqlalchemy/testing/requirements.py +++ b/lib/sqlalchemy/testing/requirements.py @@ -1506,12 +1506,6 @@ class SuiteRequirements(Requirements): return exclusions.skip_if(check) - @property - def python38(self): - return exclusions.only_if( - lambda: util.py38, "Python 3.8 or above required" - ) - @property def python39(self): return exclusions.only_if( diff --git a/lib/sqlalchemy/util/__init__.py b/lib/sqlalchemy/util/__init__.py index c804f96887..caaa657f93 100644 --- a/lib/sqlalchemy/util/__init__.py +++ b/lib/sqlalchemy/util/__init__.py @@ -66,7 +66,6 @@ from .compat import osx as osx from .compat import py310 as py310 from .compat import py311 as py311 from .compat import py312 as py312 -from .compat import py38 as py38 from .compat import py39 as py39 from .compat import pypy as pypy from .compat import win32 as win32 diff --git a/lib/sqlalchemy/util/compat.py b/lib/sqlalchemy/util/compat.py index 98a0b65ec9..a0dbc9104a 100644 --- a/lib/sqlalchemy/util/compat.py +++ b/lib/sqlalchemy/util/compat.py @@ -13,6 +13,7 @@ from __future__ import annotations import base64 import dataclasses import hashlib +from importlib import metadata as importlib_metadata import inspect import operator import platform @@ -33,12 +34,10 @@ from typing import Tuple from typing import Type from typing import TypeVar - py312 = sys.version_info >= (3, 12) py311 = sys.version_info >= (3, 11) py310 = sys.version_info >= (3, 10) py39 = sys.version_info >= (3, 9) -py38 = sys.version_info >= (3, 8) pypy = platform.python_implementation() == "PyPy" cpython = platform.python_implementation() == "CPython" @@ -132,12 +131,6 @@ else: return hashlib.md5() -if typing.TYPE_CHECKING or py38: - from importlib import metadata as importlib_metadata -else: - import importlib_metadata # noqa - - if typing.TYPE_CHECKING or py39: # pep 584 dict union dict_union = operator.or_ # noqa diff --git a/lib/sqlalchemy/util/langhelpers.py b/lib/sqlalchemy/util/langhelpers.py index 9c56487c40..8cf26955b4 100644 --- a/lib/sqlalchemy/util/langhelpers.py +++ b/lib/sqlalchemy/util/langhelpers.py @@ -69,7 +69,7 @@ else: def get_annotations(obj: Any) -> Mapping[str, Any]: # it's been observed that cls.__annotations__ can be non present. - # it's not clear what causes this, running under tox py37/38 it + # it's not clear what causes this, running under tox py38 it # happens, running straight pytest it doesnt # https://docs.python.org/3/howto/annotations.html#annotations-howto diff --git a/pyproject.toml b/pyproject.toml index 3cdf49301f..4f6d48eec9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ [tool.black] line-length = 79 -target-version = ['py37'] +target-version = ['py38'] [tool.zimports] black-line-length = 79 @@ -83,9 +83,9 @@ test-requires = "pytest pytest-xdist" test-command = "python -s -m pytest -c {project}/pyproject.toml -n2 -q --nomemory --notimingintensive --nomypy {project}/test" build = "*" -# python 3.6 is no longer supported by sqlalchemy +# python 3.6, 3.7 are no longer supported by sqlalchemy # pypy uses the universal wheel fallback, since it does not use any compiled extension -skip = "cp36-* pp*" +skip = "cp36-* cp37-* pp*" # TODO: remove this skip once action support arm macs test-skip = "*-macosx_arm64" diff --git a/test/dialect/postgresql/test_async_pg_py3k.py b/test/dialect/postgresql/test_async_pg_py3k.py index ed3d63d833..c09acf5b47 100644 --- a/test/dialect/postgresql/test_async_pg_py3k.py +++ b/test/dialect/postgresql/test_async_pg_py3k.py @@ -253,7 +253,6 @@ class AsyncPgTest(fixtures.TestBase): "setup_asyncpg_jsonb_codec", argnames="methname", ) - @testing.requires.python38 @async_test async def test_codec_registration( self, metadata, async_testing_engine, methname diff --git a/test/dialect/test_sqlite.py b/test/dialect/test_sqlite.py index d6e444bb30..701635d90d 100644 --- a/test/dialect/test_sqlite.py +++ b/test/dialect/test_sqlite.py @@ -2739,19 +2739,7 @@ class RegexpTest(fixtures.TestBase, testing.AssertsCompiledSQL): "mytable", column("myid", Integer), column("name", String) ) - def _only_on_py38_w_sqlite_39(): - """in python 3.9 and above you can actually do:: - - @(testing.requires.python38 + testing.only_on("sqlite > 3.9")) - def test_determinsitic_parameter(self): - ... - - that'll be cool. until then... - - """ - return testing.requires.python38 + testing.only_on("sqlite >= 3.9") - - @_only_on_py38_w_sqlite_39() + @testing.only_on("sqlite >= 3.9") def test_determinsitic_parameter(self): """for #9379, make sure that "deterministic=True" is used when we are on python 3.8 with modern SQLite version. diff --git a/test/engine/test_logging.py b/test/engine/test_logging.py index a498ec85c8..de6386ccc7 100644 --- a/test/engine/test_logging.py +++ b/test/engine/test_logging.py @@ -893,14 +893,12 @@ class TransactionContextLoggingTest(fixtures.TestBase): ] ) - @testing.requires.python38 def test_log_messages_have_correct_metadata_plain( self, plain_logging_engine ): """test #7612""" self._test_log_messages_have_correct_metadata(plain_logging_engine) - @testing.requires.python38 def test_log_messages_have_correct_metadata_echo(self, logging_engine): """test #7612""" self._test_log_messages_have_correct_metadata(logging_engine) diff --git a/test/ext/mypy/plugin_files/dataclasses_workaround.py b/test/ext/mypy/plugin_files/dataclasses_workaround.py index 8ad69dbd0f..a4d1389993 100644 --- a/test/ext/mypy/plugin_files/dataclasses_workaround.py +++ b/test/ext/mypy/plugin_files/dataclasses_workaround.py @@ -1,5 +1,3 @@ -# PYTHON_VERSION>=3.7 - from __future__ import annotations from dataclasses import dataclass diff --git a/test/sql/test_resultset.py b/test/sql/test_resultset.py index a5d1befa20..2caef7f8e5 100644 --- a/test/sql/test_resultset.py +++ b/test/sql/test_resultset.py @@ -1,4 +1,3 @@ -import collections import collections.abc as collections_abc from contextlib import contextmanager import csv @@ -1474,10 +1473,7 @@ class CursorResultTest(fixtures.TablesTest): row = result.first() dict_row = row._asdict() - # dictionaries aren't ordered in Python 3 until 3.7 - odict_row = collections.OrderedDict( - [("user_id", 1), ("user_name", "foo")] - ) + odict_row = dict([("user_id", 1), ("user_name", "foo")]) eq_(dict_row, odict_row) mapping_row = row._mapping diff --git a/tox.ini b/tox.ini index 6e2a6d732b..bc95175597 100644 --- a/tox.ini +++ b/tox.ini @@ -137,7 +137,7 @@ setenv= mysql: EXTRA_MYSQL_DRIVERS={env:EXTRA_MYSQL_DRIVERS:--dbdriver mysqldb --dbdriver pymysql --dbdriver asyncmy --dbdriver aiomysql --dbdriver mariadbconnector} mssql: MSSQL={env:TOX_MSSQL:--db mssql} - py{3,37,38,39,310,311}-mssql: EXTRA_MSSQL_DRIVERS={env:EXTRA_MSSQL_DRIVERS:--dbdriver pyodbc --dbdriver aioodbc --dbdriver pymssql} + py{3,38,39,310,311}-mssql: EXTRA_MSSQL_DRIVERS={env:EXTRA_MSSQL_DRIVERS:--dbdriver pyodbc --dbdriver aioodbc --dbdriver pymssql} py312-mssql: EXTRA_MSSQL_DRIVERS={env:EXTRA_MSSQL_DRIVERS:--dbdriver pyodbc --dbdriver aioodbc} oracle,mssql,sqlite_file: IDENTS=--write-idents db_idents.txt @@ -175,7 +175,6 @@ commands= [testenv:pep484] deps= greenlet != 0.4.17 - importlib_metadata; python_version < '3.8' mypy >= 1.6.0 commands = mypy {env:MYPY_COLOR} ./lib/sqlalchemy @@ -188,7 +187,6 @@ deps= pytest>=7.0.0rc1,<8 pytest-xdist greenlet != 0.4.17 - importlib_metadata; python_version < '3.8' mypy >= 1.2.0 patch==1.*