diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 815617e1c19..f3d69fa5763 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -122,6 +122,7 @@ jobs: - "3.11" - "3.12" - "3.13" + - "3.14" steps: - uses: actions/checkout@v4 @@ -181,6 +182,7 @@ jobs: # - "3.11" # - "3.12" - "3.13" + - "3.14" group: - { number: 1, pytest-filter: "not test_install" } - { number: 2, pytest-filter: "test_install" } diff --git a/docs/html/development/ci.rst b/docs/html/development/ci.rst index f2db084addb..031c283d815 100644 --- a/docs/html/development/ci.rst +++ b/docs/html/development/ci.rst @@ -23,6 +23,7 @@ pip support a variety of Python interpreters: - CPython 3.11 - CPython 3.12 - CPython 3.13 +- CPython 3.14 - Latest PyPy3 on different operating systems: @@ -37,7 +38,7 @@ and on different architectures: - x86 - arm64 (macOS only) -so 49 hypothetical interpreters. +so 56 hypothetical interpreters. Checks @@ -100,6 +101,8 @@ Actual testing | | +-------+---------------+-----------------+ | | | CP3.13| | | | | +-------+---------------+-----------------+ +| | | CP3.14| | | +| | +-------+---------------+-----------------+ | | | PyPy3 | | | | Windows +----------+-------+---------------+-----------------+ | | x64 | CP3.9 | GitHub | GitHub | @@ -112,6 +115,8 @@ Actual testing | | +-------+---------------+-----------------+ | | | CP3.13| GitHub | GitHub | | | +-------+---------------+-----------------+ +| | | CP3.14| GitHub | GitHub | +| | +-------+---------------+-----------------+ | | | PyPy3 | | | +-----------+----------+-------+---------------+-----------------+ | | x86 | CP3.9 | | | @@ -124,6 +129,8 @@ Actual testing | | +-------+---------------+-----------------+ | | | CP3.13| | | | | +-------+---------------+-----------------+ +| | | CP3.14| | | +| | +-------+---------------+-----------------+ | | | PyPy3 | | | | Linux +----------+-------+---------------+-----------------+ | | x64 | CP3.9 | GitHub | GitHub | @@ -136,6 +143,8 @@ Actual testing | | +-------+---------------+-----------------+ | | | CP3.13| GitHub | GitHub | | | +-------+---------------+-----------------+ +| | | CP3.14| GitHub | GitHub | +| | +-------+---------------+-----------------+ | | | PyPy3 | | | +-----------+----------+-------+---------------+-----------------+ | | arm64 | CP3.9 | GitHub | GitHub | @@ -148,6 +157,8 @@ Actual testing | | +-------+---------------+-----------------+ | | | CP3.13| GitHub | GitHub | | | +-------+---------------+-----------------+ +| | | CP3.14| GitHub | GitHub | +| | +-------+---------------+-----------------+ | | | PyPy3 | | | | macOS +----------+-------+---------------+-----------------+ | | x64 | CP3.9 | GitHub | GitHub | @@ -160,5 +171,7 @@ Actual testing | | +-------+---------------+-----------------+ | | | CP3.13| GitHub | GitHub | | | +-------+---------------+-----------------+ +| | | CP3.14| GitHub | GitHub | +| | +-------+---------------+-----------------+ | | | PyPy3 | | | +-----------+----------+-------+---------------+-----------------+ diff --git a/news/13506.feature.rst b/news/13506.feature.rst new file mode 100644 index 00000000000..597ea4546aa --- /dev/null +++ b/news/13506.feature.rst @@ -0,0 +1 @@ +Declare support for Python 3.14 diff --git a/noxfile.py b/noxfile.py index 160e823e9f1..88e9d5dec66 100644 --- a/noxfile.py +++ b/noxfile.py @@ -67,7 +67,7 @@ def should_update_common_wheels() -> bool: # ----------------------------------------------------------------------------- # Development Commands # ----------------------------------------------------------------------------- -@nox.session(python=["3.9", "3.10", "3.11", "3.12", "3.13", "pypy3"]) +@nox.session(python=["3.9", "3.10", "3.11", "3.12", "3.13", "3.14", "pypy3"]) def test(session: nox.Session) -> None: # Get the common wheels. if should_update_common_wheels(): diff --git a/pyproject.toml b/pyproject.toml index 019cab5eb3f..2da4e4aa2b5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", ] @@ -299,7 +300,15 @@ follow_imports = "skip" # [tool.pytest.ini_options] -addopts = "--ignore src/pip/_vendor --ignore tests/tests_cache -r aR --color=yes --disable-socket --allow-hosts=localhost" +addopts = [ + "-r=aR", + "--color=yes", + "--ignore=src/pip/_vendor", + "--ignore=tests/tests_cache", + "--disable-socket", + "--allow-unix-socket", + "--allow-hosts=localhost", +] xfail_strict = true markers = [ "network: tests that need network", diff --git a/tests/functional/test_install.py b/tests/functional/test_install.py index f23b156dcf7..a1bd81d31d0 100644 --- a/tests/functional/test_install.py +++ b/tests/functional/test_install.py @@ -1880,7 +1880,7 @@ def test_install_editable_with_wrong_egg_name( result = script.pip( "install", "--editable", - f"file://{pkga_path}#egg=pkgb", + path_to_url(str(pkga_path)) + "#egg=pkgb", expect_error=(resolver_variant == "resolvelib"), ) assert ( diff --git a/tests/functional/test_proxy.py b/tests/functional/test_proxy.py index 3f9db4a958b..32eb94a1edf 100644 --- a/tests/functional/test_proxy.py +++ b/tests/functional/test_proxy.py @@ -1,4 +1,5 @@ import ssl +import sys from pathlib import Path from typing import Any @@ -92,6 +93,11 @@ def test_proxy_does_not_override_netrc( script.assert_installed(simple="3.0") +@pytest.mark.xfail( + sys.version_info >= (3, 14), + reason="Access logs are blank intermittently on 3.14", + strict=False, +) @pytest.mark.network def test_build_deps_use_proxy_from_cli( script: PipTestEnvironment, capfd: pytest.CaptureFixture[str], data: TestData diff --git a/tests/unit/test_req.py b/tests/unit/test_req.py index 0547131134e..a2c4cf243ca 100644 --- a/tests/unit/test_req.py +++ b/tests/unit/test_req.py @@ -51,6 +51,7 @@ handle_requirement_line, ) from pip._internal.resolution.legacy.resolver import Resolver +from pip._internal.utils.urls import path_to_url from tests.lib import TestData, make_test_finder, requirements_file, wheel @@ -224,16 +225,12 @@ def test_unsupported_hashes(self, data: TestData) -> None: dir_path = data.packages.joinpath("FSPkg") reqset.add_unnamed_requirement( get_processed_req_from_line( - f"file://{dir_path}", + path_to_url(str(dir_path)), lineno=2, ) ) finder = make_test_finder(find_links=[data.find_links]) - sep = os.path.sep - if sep == "\\": - sep = "\\\\" # This needs to be escaped for the regex - with self._basic_resolver(finder, require_hashes=True) as resolver: with pytest.raises( HashErrors, @@ -244,7 +241,7 @@ def test_unsupported_hashes(self, data: TestData) -> None: r"file \(line 1\)\)\n" r"Can't verify hashes for these file:// requirements because " r"they point to directories:\n" - rf" file://.*{sep}data{sep}packages{sep}FSPkg " + r" file://.*/data/packages/FSPkg " r"\(from -r file \(line 2\)\)" ), ):