From 6153a72d529c8fa0ce2ce5ea328c37169988e814 Mon Sep 17 00:00:00 2001 From: Jacob Walls Date: Mon, 28 Jul 2025 07:38:33 -0400 Subject: [PATCH 1/6] Support Python 3.14 --- .github/workflows/primer-test.yaml | 4 ++-- .github/workflows/tests.yaml | 4 ++-- doc/whatsnew/fragments/10467.other | 3 +++ 3 files changed, 7 insertions(+), 4 deletions(-) create mode 100644 doc/whatsnew/fragments/10467.other diff --git a/.github/workflows/primer-test.yaml b/.github/workflows/primer-test.yaml index 8f7de5a0cf..de053ead41 100644 --- a/.github/workflows/primer-test.yaml +++ b/.github/workflows/primer-test.yaml @@ -30,7 +30,7 @@ jobs: timeout-minutes: 5 strategy: matrix: - python-version: ["3.10", "3.11", "3.12", "3.13"] + python-version: ["3.10", "3.11", "3.12", "3.13", "3.14-dev"] outputs: python-key: ${{ steps.generate-python-key.outputs.key }} steps: @@ -72,7 +72,7 @@ jobs: needs: prepare-tests-linux strategy: matrix: - python-version: ["3.10", "3.11", "3.12", "3.13"] + python-version: ["3.10", "3.11", "3.12", "3.13", "3.14-dev"] steps: - name: Check out code from GitHub uses: actions/checkout@v4.2.2 diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index c99707fa26..d16bec2804 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -31,7 +31,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - python-version: ["3.10", "3.11", "3.12", "3.13"] + python-version: ["3.10", "3.11", "3.12", "3.13", "3.14-dev"] include: - os: macos-latest python-version: "3.10" @@ -188,7 +188,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.10", "3.11", "3.12", "3.13"] + python-version: ["3.10", "3.11", "3.12", "3.13", "3.14-dev"] steps: - name: Set temp directory run: echo "TEMP=$env:USERPROFILE\AppData\Local\Temp" >> $env:GITHUB_ENV diff --git a/doc/whatsnew/fragments/10467.other b/doc/whatsnew/fragments/10467.other new file mode 100644 index 0000000000..b452fd4dea --- /dev/null +++ b/doc/whatsnew/fragments/10467.other @@ -0,0 +1,3 @@ +Add support for Python 3.14. + +Refs #10467 From c7ece62cd2c34398d32b2e661d34dd3253a13f23 Mon Sep 17 00:00:00 2001 From: Pierre Sassoulas Date: Wed, 6 Aug 2025 18:29:51 +0200 Subject: [PATCH 2/6] Upgrade astroid --- pyproject.toml | 2 +- requirements_test_min.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 1c7cec4511..d16b274573 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,7 +38,7 @@ dependencies = [ # Also upgrade requirements_test_min.txt. # Pinned to dev of second minor update to allow editable installs and fix primer issues, # see https://github.com/pylint-dev/astroid/issues/1341 - "astroid>=4.0.0b0,<=4.1.0.dev0", + "astroid>=4.0.0b2,<=4.1.0.dev0", "colorama>=0.4.5; sys_platform=='win32'", "dill>=0.2; python_version<'3.11'", "dill>=0.3.6; python_version>='3.11'", diff --git a/requirements_test_min.txt b/requirements_test_min.txt index 6971fdedee..46e271adcd 100644 --- a/requirements_test_min.txt +++ b/requirements_test_min.txt @@ -1,6 +1,6 @@ .[testutils,spelling] # astroid dependency is also defined in pyproject.toml -astroid==4.0.0b0 # Pinned to a specific version for tests +astroid==4.0.0b2 # Pinned to a specific version for tests typing-extensions~=4.14 py~=1.11.0 pytest~=8.4 From 8c4750ab7623d9eccbf8a7ec3a1e9082407f99c8 Mon Sep 17 00:00:00 2001 From: Marc Mueller <30130371+cdce8p@users.noreply.github.com> Date: Thu, 7 Aug 2025 00:09:17 +0200 Subject: [PATCH 3/6] Fix ForwardRef for Python 3.14 --- pylint/checkers/base/basic_error_checker.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pylint/checkers/base/basic_error_checker.py b/pylint/checkers/base/basic_error_checker.py index 2ca185212f..88af9b183f 100644 --- a/pylint/checkers/base/basic_error_checker.py +++ b/pylint/checkers/base/basic_error_checker.py @@ -20,7 +20,7 @@ ABC_METACLASSES = {"_py_abc.ABCMeta", "abc.ABCMeta"} # Python 3.7+, # List of methods which can be redefined REDEFINABLE_METHODS = frozenset(("__module__",)) -TYPING_FORWARD_REF_QNAME = "typing.ForwardRef" +FORWARD_REF_QNAME = {"typing.ForwardRef", "annotationlib.ForwardRef"} def _get_break_loop_node(break_node: nodes.Break) -> nodes.For | nodes.While | None: @@ -575,7 +575,7 @@ def _check_redefinition( if ( inferred and isinstance(inferred, astroid.Instance) - and inferred.qname() == TYPING_FORWARD_REF_QNAME + and inferred.qname() in FORWARD_REF_QNAME ): return From ab5b6b7c6b31366434bbfd6eb089b20f2eb20acb Mon Sep 17 00:00:00 2001 From: Marc Mueller <30130371+cdce8p@users.noreply.github.com> Date: Wed, 6 Aug 2025 02:40:14 +0200 Subject: [PATCH 4/6] Fix ThreadPoolExecutor, ProcessPoolExecutor imports for Python 3.14 --- .../c/consider/consider_using_with.py | 8 ++- .../c/consider/consider_using_with.txt | 52 +++++++++---------- 2 files changed, 33 insertions(+), 27 deletions(-) diff --git a/tests/functional/c/consider/consider_using_with.py b/tests/functional/c/consider/consider_using_with.py index 9ff70e08b2..4037a612f2 100644 --- a/tests/functional/c/consider/consider_using_with.py +++ b/tests/functional/c/consider/consider_using_with.py @@ -4,14 +4,20 @@ import multiprocessing import pathlib import subprocess +import sys import tarfile import tempfile import threading import urllib import zipfile -from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor from pathlib import Path +if sys.version_info >= (3, 14): + from concurrent.futures.process import ProcessPoolExecutor + from concurrent.futures.thread import ThreadPoolExecutor +else: + from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor + def test_pathlib_open(): _ = pathlib.Path("foo").open(encoding="utf8") # [consider-using-with] diff --git a/tests/functional/c/consider/consider_using_with.txt b/tests/functional/c/consider/consider_using_with.txt index 864a0784c1..5846565961 100644 --- a/tests/functional/c/consider/consider_using_with.txt +++ b/tests/functional/c/consider/consider_using_with.txt @@ -1,28 +1,28 @@ -consider-using-with:17:8:17:49:test_pathlib_open:Consider using 'with' for resource-allocating operations:UNDEFINED -consider-using-with:18:8:18:41:test_pathlib_open:Consider using 'with' for resource-allocating operations:UNDEFINED -consider-using-with:20:8:20:34:test_pathlib_open:Consider using 'with' for resource-allocating operations:UNDEFINED -consider-using-with:26:9:26:40:test_codecs_open:Consider using 'with' for resource-allocating operations:UNDEFINED -consider-using-with:31:8:31:55:test_urlopen:Consider using 'with' for resource-allocating operations:UNDEFINED -consider-using-with:39:8:39:40:test_named_temporary_file:Consider using 'with' for resource-allocating operations:UNDEFINED -consider-using-with:43:8:43:42:test_spooled_temporary_file:Consider using 'with' for resource-allocating operations:UNDEFINED -consider-using-with:47:8:47:37:test_temporary_directory:Consider using 'with' for resource-allocating operations:UNDEFINED -consider-using-with:51:12:51:44:test_zipfile:Consider using 'with' for resource-allocating operations:UNDEFINED -consider-using-with:52:8:52:30:test_zipfile:Consider using 'with' for resource-allocating operations:UNDEFINED -consider-using-with:56:12:56:46:test_pyzipfile:Consider using 'with' for resource-allocating operations:UNDEFINED -consider-using-with:61:8:61:30:test_pyzipfile:Consider using 'with' for resource-allocating operations:UNDEFINED -consider-using-with:68:9:68:43:test_tarfile:Consider using 'with' for resource-allocating operations:UNDEFINED -consider-using-with:74:9:74:47:test_tarfile:Consider using 'with' for resource-allocating operations:UNDEFINED -consider-using-with:83:4:83:18:test_lock_acquisition:Consider using 'with' for resource-allocating operations:UNDEFINED -consider-using-with:90:4:90:19:test_lock_acquisition:Consider using 'with' for resource-allocating operations:UNDEFINED -consider-using-with:97:4:97:18:test_lock_acquisition:Consider using 'with' for resource-allocating operations:UNDEFINED -consider-using-with:104:4:104:26:test_lock_acquisition:Consider using 'with' for resource-allocating operations:UNDEFINED -consider-using-with:140:8:140:30:test_multiprocessing:Consider using 'with' for resource-allocating operations:UNDEFINED -consider-using-with:145:4:145:19:test_multiprocessing:Consider using 'with' for resource-allocating operations:UNDEFINED -consider-using-with:150:4:150:19:test_multiprocessing:Consider using 'with' for resource-allocating operations:UNDEFINED -consider-using-with:156:8:156:30:test_popen:Consider using 'with' for resource-allocating operations:UNDEFINED -consider-using-with:210:4:210:26::Consider using 'with' for resource-allocating operations:UNDEFINED -consider-using-with:211:4:211:26::Consider using 'with' for resource-allocating operations:UNDEFINED +consider-using-with:23:8:23:49:test_pathlib_open:Consider using 'with' for resource-allocating operations:UNDEFINED +consider-using-with:24:8:24:41:test_pathlib_open:Consider using 'with' for resource-allocating operations:UNDEFINED +consider-using-with:26:8:26:34:test_pathlib_open:Consider using 'with' for resource-allocating operations:UNDEFINED +consider-using-with:32:9:32:40:test_codecs_open:Consider using 'with' for resource-allocating operations:UNDEFINED +consider-using-with:37:8:37:55:test_urlopen:Consider using 'with' for resource-allocating operations:UNDEFINED +consider-using-with:45:8:45:40:test_named_temporary_file:Consider using 'with' for resource-allocating operations:UNDEFINED +consider-using-with:49:8:49:42:test_spooled_temporary_file:Consider using 'with' for resource-allocating operations:UNDEFINED +consider-using-with:53:8:53:37:test_temporary_directory:Consider using 'with' for resource-allocating operations:UNDEFINED +consider-using-with:57:12:57:44:test_zipfile:Consider using 'with' for resource-allocating operations:UNDEFINED +consider-using-with:58:8:58:30:test_zipfile:Consider using 'with' for resource-allocating operations:UNDEFINED +consider-using-with:62:12:62:46:test_pyzipfile:Consider using 'with' for resource-allocating operations:UNDEFINED +consider-using-with:67:8:67:30:test_pyzipfile:Consider using 'with' for resource-allocating operations:UNDEFINED +consider-using-with:74:9:74:43:test_tarfile:Consider using 'with' for resource-allocating operations:UNDEFINED +consider-using-with:80:9:80:47:test_tarfile:Consider using 'with' for resource-allocating operations:UNDEFINED +consider-using-with:89:4:89:18:test_lock_acquisition:Consider using 'with' for resource-allocating operations:UNDEFINED +consider-using-with:96:4:96:19:test_lock_acquisition:Consider using 'with' for resource-allocating operations:UNDEFINED +consider-using-with:103:4:103:18:test_lock_acquisition:Consider using 'with' for resource-allocating operations:UNDEFINED +consider-using-with:110:4:110:26:test_lock_acquisition:Consider using 'with' for resource-allocating operations:UNDEFINED +consider-using-with:146:8:146:30:test_multiprocessing:Consider using 'with' for resource-allocating operations:UNDEFINED +consider-using-with:151:4:151:19:test_multiprocessing:Consider using 'with' for resource-allocating operations:UNDEFINED +consider-using-with:156:4:156:19:test_multiprocessing:Consider using 'with' for resource-allocating operations:UNDEFINED +consider-using-with:162:8:162:30:test_popen:Consider using 'with' for resource-allocating operations:UNDEFINED consider-using-with:216:4:216:26::Consider using 'with' for resource-allocating operations:UNDEFINED +consider-using-with:217:4:217:26::Consider using 'with' for resource-allocating operations:UNDEFINED consider-using-with:222:4:222:26::Consider using 'with' for resource-allocating operations:UNDEFINED -consider-using-with:238:18:238:40:test_subscript_assignment:Consider using 'with' for resource-allocating operations:UNDEFINED -consider-using-with:240:24:240:46:test_subscript_assignment:Consider using 'with' for resource-allocating operations:UNDEFINED +consider-using-with:228:4:228:26::Consider using 'with' for resource-allocating operations:UNDEFINED +consider-using-with:244:18:244:40:test_subscript_assignment:Consider using 'with' for resource-allocating operations:UNDEFINED +consider-using-with:246:24:246:46:test_subscript_assignment:Consider using 'with' for resource-allocating operations:UNDEFINED From 1ec86e13a31d4a1249e10ab6d0b3d36095f8c426 Mon Sep 17 00:00:00 2001 From: Marc Mueller <30130371+cdce8p@users.noreply.github.com> Date: Thu, 7 Aug 2025 13:00:35 +0200 Subject: [PATCH 5/6] Remove ByteString from tests (it was removed in Python 3.14) --- .../g/generic_alias/generic_alias_mixed_py39.py | 1 - .../g/generic_alias/generic_alias_mixed_py39.txt | 10 +++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/tests/functional/g/generic_alias/generic_alias_mixed_py39.py b/tests/functional/g/generic_alias/generic_alias_mixed_py39.py index dcfed966b8..6bf89c1bce 100644 --- a/tests/functional/g/generic_alias/generic_alias_mixed_py39.py +++ b/tests/functional/g/generic_alias/generic_alias_mixed_py39.py @@ -15,7 +15,6 @@ var_iterable: collections.abc.Iterable[int] var_awaitable: collections.abc.Awaitable[int] var_pattern: re.Pattern[int] -var_bytestring: collections.abc.ByteString var_hashable: collections.abc.Hashable var_context_manager: contextlib.AbstractContextManager[int] diff --git a/tests/functional/g/generic_alias/generic_alias_mixed_py39.txt b/tests/functional/g/generic_alias/generic_alias_mixed_py39.txt index 58b7e9860e..329b4519cb 100644 --- a/tests/functional/g/generic_alias/generic_alias_mixed_py39.txt +++ b/tests/functional/g/generic_alias/generic_alias_mixed_py39.txt @@ -1,5 +1,5 @@ -abstract-method:29:0:29:21:DerivedHashable:Method '__hash__' is abstract in class 'Hashable' but is not overridden in child class 'DerivedHashable':INFERENCE -abstract-method:32:0:32:21:DerivedIterable:Method '__iter__' is abstract in class 'Iterable' but is not overridden in child class 'DerivedIterable':INFERENCE -abstract-method:35:0:35:23:DerivedCollection:Method '__contains__' is abstract in class 'Container' but is not overridden in child class 'DerivedCollection':INFERENCE -abstract-method:35:0:35:23:DerivedCollection:Method '__iter__' is abstract in class 'Iterable' but is not overridden in child class 'DerivedCollection':INFERENCE -abstract-method:35:0:35:23:DerivedCollection:Method '__len__' is abstract in class 'Sized' but is not overridden in child class 'DerivedCollection':INFERENCE +abstract-method:28:0:28:21:DerivedHashable:Method '__hash__' is abstract in class 'Hashable' but is not overridden in child class 'DerivedHashable':INFERENCE +abstract-method:31:0:31:21:DerivedIterable:Method '__iter__' is abstract in class 'Iterable' but is not overridden in child class 'DerivedIterable':INFERENCE +abstract-method:34:0:34:23:DerivedCollection:Method '__contains__' is abstract in class 'Container' but is not overridden in child class 'DerivedCollection':INFERENCE +abstract-method:34:0:34:23:DerivedCollection:Method '__iter__' is abstract in class 'Iterable' but is not overridden in child class 'DerivedCollection':INFERENCE +abstract-method:34:0:34:23:DerivedCollection:Method '__len__' is abstract in class 'Sized' but is not overridden in child class 'DerivedCollection':INFERENCE From 8853532776a281dd321e419b771d0ea4dacc1bc9 Mon Sep 17 00:00:00 2001 From: Marc Mueller <30130371+cdce8p@users.noreply.github.com> Date: Thu, 7 Aug 2025 13:23:31 +0200 Subject: [PATCH 6/6] Update news entry --- doc/whatsnew/fragments/{10467.other => 10467.feature} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename doc/whatsnew/fragments/{10467.other => 10467.feature} (100%) diff --git a/doc/whatsnew/fragments/10467.other b/doc/whatsnew/fragments/10467.feature similarity index 100% rename from doc/whatsnew/fragments/10467.other rename to doc/whatsnew/fragments/10467.feature