diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 70a09b6a88f..43229f9f64e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -104,7 +104,6 @@ jobs: matrix: os: [Ubuntu, MacOS] python: - - "3.7" - "3.8" - "3.9" - "3.10" @@ -155,9 +154,8 @@ jobs: matrix: os: [Windows] python: - - "3.7" + - "3.8" # Commented out, since Windows tests are expensively slow. - # - "3.8" # - "3.9" # - "3.10" - "3.11" diff --git a/docs/html/development/ci.rst b/docs/html/development/ci.rst index 01bec42472e..2e950232fca 100644 --- a/docs/html/development/ci.rst +++ b/docs/html/development/ci.rst @@ -18,7 +18,6 @@ Supported interpreters pip support a variety of Python interpreters: -- CPython 3.7 - CPython 3.8 - CPython 3.9 - CPython 3.10 @@ -90,9 +89,7 @@ Actual testing +------------------------------+---------------+-----------------+ | **interpreter** | **unit** | **integration** | +-----------+----------+-------+---------------+-----------------+ -| | x86 | CP3.7 | | | -| | +-------+---------------+-----------------+ -| | | CP3.8 | | | +| | x86 | CP3.8 | | | | | +-------+---------------+-----------------+ | | | CP3.9 | | | | | +-------+---------------+-----------------+ @@ -104,9 +101,7 @@ Actual testing | | +-------+---------------+-----------------+ | | | PyPy3 | | | | Windows +----------+-------+---------------+-----------------+ -| | x64 | CP3.7 | GitHub | GitHub | -| | +-------+---------------+-----------------+ -| | | CP3.8 | | | +| | x64 | CP3.8 | GitHub | GitHub | | | +-------+---------------+-----------------+ | | | CP3.9 | | | | | +-------+---------------+-----------------+ @@ -118,9 +113,7 @@ Actual testing | | +-------+---------------+-----------------+ | | | PyPy3 | | | +-----------+----------+-------+---------------+-----------------+ -| | x86 | CP3.7 | | | -| | +-------+---------------+-----------------+ -| | | CP3.8 | | | +| | x86 | CP3.8 | | | | | +-------+---------------+-----------------+ | | | CP3.9 | | | | | +-------+---------------+-----------------+ @@ -132,9 +125,7 @@ Actual testing | | +-------+---------------+-----------------+ | | | PyPy3 | | | | Linux +----------+-------+---------------+-----------------+ -| | x64 | CP3.7 | GitHub | GitHub | -| | +-------+---------------+-----------------+ -| | | CP3.8 | GitHub | GitHub | +| | x64 | CP3.8 | GitHub | GitHub | | | +-------+---------------+-----------------+ | | | CP3.9 | GitHub | GitHub | | | +-------+---------------+-----------------+ @@ -146,9 +137,7 @@ Actual testing | | +-------+---------------+-----------------+ | | | PyPy3 | | | +-----------+----------+-------+---------------+-----------------+ -| | arm64 | CP3.7 | | | -| | +-------+---------------+-----------------+ -| | | CP3.8 | | | +| | arm64 | CP3.8 | | | | | +-------+---------------+-----------------+ | | | CP3.9 | | | | | +-------+---------------+-----------------+ @@ -160,9 +149,7 @@ Actual testing | | +-------+---------------+-----------------+ | | | PyPy3 | | | | macOS +----------+-------+---------------+-----------------+ -| | x64 | CP3.7 | GitHub | GitHub | -| | +-------+---------------+-----------------+ -| | | CP3.8 | GitHub | GitHub | +| | x64 | CP3.8 | GitHub | GitHub | | | +-------+---------------+-----------------+ | | | CP3.9 | GitHub | GitHub | | | +-------+---------------+-----------------+ diff --git a/docs/html/installation.md b/docs/html/installation.md index c61fceaed2b..4b3d4e8888c 100644 --- a/docs/html/installation.md +++ b/docs/html/installation.md @@ -102,8 +102,8 @@ $ pip install --upgrade pip The current version of pip works on: -- Windows, Linux and MacOS. -- CPython 3.7, 3.8, 3.9, 3.10, 3.11, 3.12, and latest PyPy3. +- Windows, Linux and macOS. +- CPython 3.8, 3.9, 3.10, 3.11, 3.12, and latest PyPy3. pip is tested to work on the latest patch version of the Python interpreter, for each of the minor versions listed above. Previous patch versions are diff --git a/news/11934.removal.rst b/news/11934.removal.rst new file mode 100644 index 00000000000..bf146d23baa --- /dev/null +++ b/news/11934.removal.rst @@ -0,0 +1 @@ +Drop support for EOL Python 3.7. diff --git a/noxfile.py b/noxfile.py index 34430e30077..0a838ea3e05 100644 --- a/noxfile.py +++ b/noxfile.py @@ -67,7 +67,7 @@ def should_update_common_wheels() -> bool: # ----------------------------------------------------------------------------- # Development Commands # ----------------------------------------------------------------------------- -@nox.session(python=["3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "pypy3"]) +@nox.session(python=["3.8", "3.9", "3.10", "3.11", "3.12", "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 2da7793a026..9be6a6da1cb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,7 +13,6 @@ classifiers = [ "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", @@ -28,7 +27,7 @@ authors = [ # NOTE: requires-python is duplicated in __pip-runner__.py. # When changing this value, please change the other copy as well. -requires-python = ">=3.7" +requires-python = ">=3.8" [project.urls] Homepage = "https://pip.pypa.io/" @@ -139,7 +138,7 @@ webencodings = "https://github.com/SimonSapin/python-webencodings/raw/master/LIC [tool.ruff] src = ["src"] -target-version = "py37" +target-version = "py38" line-length = 88 extend-exclude = [ "_vendor", diff --git a/src/pip/__pip-runner__.py b/src/pip/__pip-runner__.py index 49a148a097e..c633787fced 100644 --- a/src/pip/__pip-runner__.py +++ b/src/pip/__pip-runner__.py @@ -8,8 +8,8 @@ import sys -# Copied from setup.py -PYTHON_REQUIRES = (3, 7) +# Copied from pyproject.toml +PYTHON_REQUIRES = (3, 8) def version_str(version): # type: ignore diff --git a/src/pip/_internal/commands/search.py b/src/pip/_internal/commands/search.py index 03ed925b246..55880a155e5 100644 --- a/src/pip/_internal/commands/search.py +++ b/src/pip/_internal/commands/search.py @@ -5,7 +5,7 @@ import xmlrpc.client from collections import OrderedDict from optparse import Values -from typing import TYPE_CHECKING, Dict, List, Optional +from typing import TYPE_CHECKING, Dict, List, Optional, TypedDict from pip._vendor.packaging.version import parse as parse_version @@ -20,7 +20,6 @@ from pip._internal.utils.misc import write_output if TYPE_CHECKING: - from typing import TypedDict class TransformedHit(TypedDict): name: str diff --git a/src/pip/_internal/distributions/sdist.py b/src/pip/_internal/distributions/sdist.py index 15ff42b7b15..4cb0e453969 100644 --- a/src/pip/_internal/distributions/sdist.py +++ b/src/pip/_internal/distributions/sdist.py @@ -117,7 +117,7 @@ def _install_build_reqs(self, finder: PackageFinder) -> None: if ( self.req.editable and self.req.permit_editable_wheels - and self.req.supports_pyproject_editable() + and self.req.supports_pyproject_editable ): build_reqs = self._get_build_requires_editable() else: diff --git a/src/pip/_internal/exceptions.py b/src/pip/_internal/exceptions.py index 5007a622d82..29acd9babc6 100644 --- a/src/pip/_internal/exceptions.py +++ b/src/pip/_internal/exceptions.py @@ -13,7 +13,7 @@ import re import sys from itertools import chain, groupby, repeat -from typing import TYPE_CHECKING, Dict, Iterator, List, Optional, Union +from typing import TYPE_CHECKING, Dict, Iterator, List, Literal, Optional, Union from pip._vendor.requests.models import Request, Response from pip._vendor.rich.console import Console, ConsoleOptions, RenderResult @@ -22,7 +22,6 @@ if TYPE_CHECKING: from hashlib import _Hash - from typing import Literal from pip._internal.metadata import BaseDistribution from pip._internal.req.req_install import InstallRequirement diff --git a/src/pip/_internal/index/collector.py b/src/pip/_internal/index/collector.py index 08c8bddcb69..f4d476abacd 100644 --- a/src/pip/_internal/index/collector.py +++ b/src/pip/_internal/index/collector.py @@ -14,7 +14,6 @@ from html.parser import HTMLParser from optparse import Values from typing import ( - TYPE_CHECKING, Callable, Dict, Iterable, @@ -22,6 +21,7 @@ MutableMapping, NamedTuple, Optional, + Protocol, Sequence, Tuple, Union, @@ -42,11 +42,6 @@ from .sources import CandidatesFromPage, LinkSource, build_source -if TYPE_CHECKING: - from typing import Protocol -else: - Protocol = object - logger = logging.getLogger(__name__) ResponseHeaders = MutableMapping[str, str] diff --git a/src/pip/_internal/locations/__init__.py b/src/pip/_internal/locations/__init__.py index d54bc63eba3..32382be7fe5 100644 --- a/src/pip/_internal/locations/__init__.py +++ b/src/pip/_internal/locations/__init__.py @@ -336,17 +336,6 @@ def get_scheme( if skip_linux_system_special_case: continue - # On Python 3.7 and earlier, sysconfig does not include sys.abiflags in - # the "pythonX.Y" part of the path, but distutils does. - skip_sysconfig_abiflag_bug = ( - sys.version_info < (3, 8) - and not WINDOWS - and k in ("headers", "platlib", "purelib") - and tuple(_fix_abiflags(old_v.parts)) == new_v.parts - ) - if skip_sysconfig_abiflag_bug: - continue - # MSYS2 MINGW's sysconfig patch does not include the "site-packages" # part of the path. This is incorrect and will be fixed in MSYS. skip_msys2_mingw_bug = ( diff --git a/src/pip/_internal/metadata/base.py b/src/pip/_internal/metadata/base.py index 92491244108..af0412c819c 100644 --- a/src/pip/_internal/metadata/base.py +++ b/src/pip/_internal/metadata/base.py @@ -8,7 +8,6 @@ import zipfile from typing import ( IO, - TYPE_CHECKING, Any, Collection, Container, @@ -18,6 +17,7 @@ List, NamedTuple, Optional, + Protocol, Tuple, Union, ) @@ -41,11 +41,6 @@ from ._json import msg_to_json -if TYPE_CHECKING: - from typing import Protocol -else: - Protocol = object - DistributionVersion = Union[LegacyVersion, Version] InfoPath = Union[str, pathlib.PurePath] @@ -385,15 +380,7 @@ def iter_entry_points(self) -> Iterable[BaseEntryPoint]: def _metadata_impl(self) -> email.message.Message: raise NotImplementedError() - @functools.lru_cache(maxsize=1) - def _metadata_cached(self) -> email.message.Message: - # When we drop python 3.7 support, move this to the metadata property and use - # functools.cached_property instead of lru_cache. - metadata = self._metadata_impl() - self._add_egg_info_requires(metadata) - return metadata - - @property + @functools.cached_property def metadata(self) -> email.message.Message: """Metadata of distribution parsed from e.g. METADATA or PKG-INFO. @@ -402,7 +389,9 @@ def metadata(self) -> email.message.Message: :raises NoneMetadataError: If the metadata file is available, but does not contain valid metadata. """ - return self._metadata_cached() + metadata = self._metadata_impl() + self._add_egg_info_requires(metadata) + return metadata @property def metadata_dict(self) -> Dict[str, Any]: diff --git a/src/pip/_internal/network/auth.py b/src/pip/_internal/network/auth.py index 94a82fa6618..e23444ebefa 100644 --- a/src/pip/_internal/network/auth.py +++ b/src/pip/_internal/network/auth.py @@ -151,7 +151,7 @@ def _set_password(self, service_name: str, username: str, password: str) -> None env["PYTHONIOENCODING"] = "utf-8" subprocess.run( [self.keyring, "set", service_name, username], - input=f"{password}{os.linesep}".encode("utf-8"), + input=f"{password}{os.linesep}".encode(), env=env, check=True, ) diff --git a/src/pip/_internal/network/session.py b/src/pip/_internal/network/session.py index f17efc52992..e07b795b461 100644 --- a/src/pip/_internal/network/session.py +++ b/src/pip/_internal/network/session.py @@ -230,7 +230,7 @@ def send( # to return a better error message: resp.status_code = 404 resp.reason = type(exc).__name__ - resp.raw = io.BytesIO(f"{resp.reason}: {exc}".encode("utf8")) + resp.raw = io.BytesIO(f"{resp.reason}: {exc}".encode()) else: modified = email.utils.formatdate(stats.st_mtime, usegmt=True) content_type = mimetypes.guess_type(pathname)[0] or "text/plain" diff --git a/src/pip/_internal/operations/build/build_tracker.py b/src/pip/_internal/operations/build/build_tracker.py index 37919322b00..85adc1d711a 100644 --- a/src/pip/_internal/operations/build/build_tracker.py +++ b/src/pip/_internal/operations/build/build_tracker.py @@ -99,7 +99,7 @@ def add(self, req: InstallRequirement, key: TrackerId) -> None: except FileNotFoundError: pass else: - message = "{} is already being built: {}".format(req.link, contents) + message = f"{req.link} is already being built: {contents}" raise LookupError(message) # If we're here, req should really not be building already. diff --git a/src/pip/_internal/operations/build/metadata_legacy.py b/src/pip/_internal/operations/build/metadata_legacy.py index e60988d643e..c01dd1c678a 100644 --- a/src/pip/_internal/operations/build/metadata_legacy.py +++ b/src/pip/_internal/operations/build/metadata_legacy.py @@ -27,7 +27,7 @@ def _find_egg_info(directory: str) -> str: if len(filenames) > 1: raise InstallationError( - "More than one .egg-info directory found in {}".format(directory) + f"More than one .egg-info directory found in {directory}" ) return os.path.join(directory, filenames[0]) diff --git a/src/pip/_internal/operations/install/wheel.py b/src/pip/_internal/operations/install/wheel.py index f67180c9e65..6b9d083eb27 100644 --- a/src/pip/_internal/operations/install/wheel.py +++ b/src/pip/_internal/operations/install/wheel.py @@ -28,6 +28,7 @@ List, NewType, Optional, + Protocol, Sequence, Set, Tuple, @@ -60,7 +61,6 @@ from pip._internal.utils.wheel import parse_wheel if TYPE_CHECKING: - from typing import Protocol class File(Protocol): src_record_path: "RecordPath" diff --git a/src/pip/_internal/req/req_file.py b/src/pip/_internal/req/req_file.py index 1ef3d5ef6e7..58cf94cd25f 100644 --- a/src/pip/_internal/req/req_file.py +++ b/src/pip/_internal/req/req_file.py @@ -17,6 +17,7 @@ Generator, Iterable, List, + NoReturn, Optional, Tuple, ) @@ -30,10 +31,6 @@ from pip._internal.utils.urls import get_url_scheme if TYPE_CHECKING: - # NoReturn introduced in 3.6.2; imported only for type checking to maintain - # pip compatibility with older patch versions of Python 3.6 - from typing import NoReturn - from pip._internal.index.package_finder import PackageFinder __all__ = ["parse_requirements"] diff --git a/src/pip/_internal/req/req_install.py b/src/pip/_internal/req/req_install.py index a65611c320b..49c88fca187 100644 --- a/src/pip/_internal/req/req_install.py +++ b/src/pip/_internal/req/req_install.py @@ -244,7 +244,7 @@ def name(self) -> Optional[str]: return None return self.req.name - @functools.lru_cache() # use cached_property in python 3.8+ + @functools.cached_property def supports_pyproject_editable(self) -> bool: if not self.use_pep517: return False @@ -542,7 +542,7 @@ def isolated_editable_sanity_check(self) -> None: if ( self.editable and self.use_pep517 - and not self.supports_pyproject_editable() + and not self.supports_pyproject_editable and not os.path.isfile(self.setup_py_path) and not os.path.isfile(self.setup_cfg_path) ): @@ -568,7 +568,7 @@ def prepare_metadata(self) -> None: if ( self.editable and self.permit_editable_wheels - and self.supports_pyproject_editable() + and self.supports_pyproject_editable ): self.metadata_directory = generate_editable_metadata( build_env=self.build_env, diff --git a/src/pip/_internal/req/req_uninstall.py b/src/pip/_internal/req/req_uninstall.py index 707fde1b2b9..eec9bd8edcd 100644 --- a/src/pip/_internal/req/req_uninstall.py +++ b/src/pip/_internal/req/req_uninstall.py @@ -315,7 +315,7 @@ def __init__(self, dist: BaseDistribution) -> None: # Create local cache of normalize_path results. Creating an UninstallPathSet # can result in hundreds/thousands of redundant calls to normalize_path with # the same args, which hurts performance. - self._normalize_path_cached = functools.lru_cache()(normalize_path) + self._normalize_path_cached = functools.lru_cache(normalize_path) def _permitted(self, path: str) -> bool: """ diff --git a/src/pip/_internal/resolution/resolvelib/factory.py b/src/pip/_internal/resolution/resolvelib/factory.py index 4adeb4309ce..14e29472473 100644 --- a/src/pip/_internal/resolution/resolvelib/factory.py +++ b/src/pip/_internal/resolution/resolvelib/factory.py @@ -11,6 +11,7 @@ Mapping, NamedTuple, Optional, + Protocol, Sequence, Set, Tuple, @@ -70,7 +71,6 @@ ) if TYPE_CHECKING: - from typing import Protocol class ConflictCause(Protocol): requirement: RequiresPythonRequirement diff --git a/src/pip/_internal/utils/hashes.py b/src/pip/_internal/utils/hashes.py index 843cffc6b3d..c073b09dd98 100644 --- a/src/pip/_internal/utils/hashes.py +++ b/src/pip/_internal/utils/hashes.py @@ -1,5 +1,5 @@ import hashlib -from typing import TYPE_CHECKING, BinaryIO, Dict, Iterable, List, Optional +from typing import TYPE_CHECKING, BinaryIO, Dict, Iterable, List, NoReturn, Optional from pip._internal.exceptions import HashMismatch, HashMissing, InstallationError from pip._internal.utils.misc import read_chunks @@ -7,10 +7,6 @@ if TYPE_CHECKING: from hashlib import _Hash - # NoReturn introduced in 3.6.2; imported only for type checking to maintain - # pip compatibility with older patch versions of Python 3.6 - from typing import NoReturn - # The recommended hash algo of the moment. Change this whenever the state of # the art changes; it won't hurt backward compatibility. diff --git a/src/pip/_internal/utils/subprocess.py b/src/pip/_internal/utils/subprocess.py index 79580b05320..cb2e23f007a 100644 --- a/src/pip/_internal/utils/subprocess.py +++ b/src/pip/_internal/utils/subprocess.py @@ -2,16 +2,7 @@ import os import shlex import subprocess -from typing import ( - TYPE_CHECKING, - Any, - Callable, - Iterable, - List, - Mapping, - Optional, - Union, -) +from typing import Any, Callable, Iterable, List, Literal, Mapping, Optional, Union from pip._vendor.rich.markup import escape @@ -20,12 +11,6 @@ from pip._internal.utils.logging import VERBOSE, subprocess_logger from pip._internal.utils.misc import HiddenText -if TYPE_CHECKING: - # Literal was introduced in Python 3.8. - # - # TODO: Remove `if TYPE_CHECKING` when dropping support for Python 3.7. - from typing import Literal - CommandArgs = List[Union[str, HiddenText]] diff --git a/src/pip/_internal/vcs/versioncontrol.py b/src/pip/_internal/vcs/versioncontrol.py index 46ca2799b76..1e2be8d1acd 100644 --- a/src/pip/_internal/vcs/versioncontrol.py +++ b/src/pip/_internal/vcs/versioncontrol.py @@ -6,12 +6,12 @@ import sys import urllib.parse from typing import ( - TYPE_CHECKING, Any, Dict, Iterable, Iterator, List, + Literal, Mapping, Optional, Tuple, @@ -39,13 +39,6 @@ ) from pip._internal.utils.urls import get_url_scheme -if TYPE_CHECKING: - # Literal was introduced in Python 3.8. - # - # TODO: Remove `if TYPE_CHECKING` when dropping support for Python 3.7. - from typing import Literal - - __all__ = ["vcs"] diff --git a/src/pip/_internal/wheel_builder.py b/src/pip/_internal/wheel_builder.py index b1debe3496c..93f8e1f5b2f 100644 --- a/src/pip/_internal/wheel_builder.py +++ b/src/pip/_internal/wheel_builder.py @@ -70,7 +70,7 @@ def _should_build( if req.editable: # we only build PEP 660 editable requirements - return req.supports_pyproject_editable() + return req.supports_pyproject_editable return True diff --git a/tests/data/packages/BrokenEmitsUTF8/setup.py b/tests/data/packages/BrokenEmitsUTF8/setup.py index eb4ebf2d380..21266b3fcf6 100644 --- a/tests/data/packages/BrokenEmitsUTF8/setup.py +++ b/tests/data/packages/BrokenEmitsUTF8/setup.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - import sys from distutils.core import setup @@ -11,13 +9,11 @@ class FakeError(Exception): if sys.argv[1] in ("install", "bdist_wheel"): if hasattr(sys.stdout, "buffer"): sys.stdout.buffer.write( - "\nThis package prints out UTF-8 stuff like:\n".encode("utf-8") - ) - sys.stdout.buffer.write( - "* return type of ‘main’ is not ‘int’\n".encode("utf-8") + "\nThis package prints out UTF-8 stuff like:\n".encode() ) + sys.stdout.buffer.write("* return type of ‘main’ is not ‘int’\n".encode()) sys.stdout.buffer.write( - "* Björk Guðmundsdóttir [ˈpjœr̥k ˈkvʏðmʏntsˌtoʊhtɪr]".encode("utf-8") + "* Björk Guðmundsdóttir [ˈpjœr̥k ˈkvʏðmʏntsˌtoʊhtɪr]".encode() ) else: pass diff --git a/tests/functional/test_cache.py b/tests/functional/test_cache.py index a744dbbb9bc..5b7e585260d 100644 --- a/tests/functional/test_cache.py +++ b/tests/functional/test_cache.py @@ -114,10 +114,8 @@ def list_matches_wheel_abspath(wheel_name: str, result: TestPipResult) -> bool: lines = result.stdout.splitlines() expected = f"{wheel_name}-py3-none-any.whl" return any( - ( - (os.path.basename(line).startswith(expected) and os.path.exists(line)) - for line in lines - ) + (os.path.basename(line).startswith(expected) and os.path.exists(line)) + for line in lines ) diff --git a/tests/functional/test_completion.py b/tests/functional/test_completion.py index 4be033583ca..cc8583b1a38 100644 --- a/tests/functional/test_completion.py +++ b/tests/functional/test_completion.py @@ -1,20 +1,12 @@ import os import sys from pathlib import Path -from typing import TYPE_CHECKING, Tuple, Union +from typing import Protocol, Tuple, Union import pytest from tests.lib import PipTestEnvironment, ScriptFactory, TestData, TestPipResult -if TYPE_CHECKING: - from typing import Protocol -else: - # TODO: Protocol was introduced in Python 3.8. Remove this branch when - # dropping support for Python 3.7. - Protocol = object - - COMPLETION_FOR_SUPPORTED_SHELLS_TESTS = ( ( "bash", diff --git a/tests/functional/test_install.py b/tests/functional/test_install.py index 3411f66d801..c013f2eaf72 100644 --- a/tests/functional/test_install.py +++ b/tests/functional/test_install.py @@ -2289,10 +2289,6 @@ def test_error_all_yanked_files_and_no_pin( ), str(result) -@pytest.mark.skipif( - sys.platform == "linux" and sys.version_info < (3, 8), - reason="Custom SSL certification not running well in CI", -) @pytest.mark.parametrize( "install_args", [ diff --git a/tests/functional/test_install_config.py b/tests/functional/test_install_config.py index 96151ce2811..9374fade121 100644 --- a/tests/functional/test_install_config.py +++ b/tests/functional/test_install_config.py @@ -1,6 +1,5 @@ import os import ssl -import sys import tempfile import textwrap from pathlib import Path @@ -260,10 +259,6 @@ def test_install_no_binary_via_config_disables_cached_wheels( assert "Building wheel for upper" in str(res), str(res) -@pytest.mark.skipif( - sys.platform == "linux" and sys.version_info < (3, 8), - reason="Custom SSL certification not running well in CI", -) def test_prompt_for_authentication( script: PipTestEnvironment, data: TestData, cert_factory: CertFactory ) -> None: @@ -304,10 +299,6 @@ def test_prompt_for_authentication( assert f"User for {server.host}:{server.port}" in result.stdout, str(result) -@pytest.mark.skipif( - sys.platform == "linux" and sys.version_info < (3, 8), - reason="Custom SSL certification not running well in CI", -) def test_do_not_prompt_for_authentication( script: PipTestEnvironment, data: TestData, cert_factory: CertFactory ) -> None: @@ -398,10 +389,6 @@ def flags( return flags -@pytest.mark.skipif( - sys.platform == "linux" and sys.version_info < (3, 8), - reason="Custom SSL certification not running well in CI", -) def test_prompt_for_keyring_if_needed( data: TestData, cert_factory: CertFactory, diff --git a/tests/functional/test_install_reqs.py b/tests/functional/test_install_reqs.py index 993f25a2abf..3cdc9fec147 100644 --- a/tests/functional/test_install_reqs.py +++ b/tests/functional/test_install_reqs.py @@ -2,7 +2,7 @@ import os import textwrap from pathlib import Path -from typing import TYPE_CHECKING, Any +from typing import Any, Protocol import pytest @@ -18,11 +18,6 @@ ) from tests.lib.local_repos import local_checkout -if TYPE_CHECKING: - from typing import Protocol -else: - Protocol = object - class ArgRecordingSdist: def __init__(self, sdist_path: Path, args_path: Path) -> None: diff --git a/tests/functional/test_new_resolver.py b/tests/functional/test_new_resolver.py index afe07cbf3ec..0207d61aac6 100644 --- a/tests/functional/test_new_resolver.py +++ b/tests/functional/test_new_resolver.py @@ -2,7 +2,7 @@ import pathlib import sys import textwrap -from typing import TYPE_CHECKING, Callable, Dict, List, Tuple +from typing import TYPE_CHECKING, Callable, Dict, List, Protocol, Tuple import pytest from packaging.utils import canonicalize_name @@ -18,9 +18,6 @@ from tests.lib.venv import VirtualEnvironment from tests.lib.wheel import make_wheel -if TYPE_CHECKING: - from typing import Protocol - MakeFakeWheel = Callable[[str, str, str], pathlib.Path] diff --git a/tests/lib/__init__.py b/tests/lib/__init__.py index ea755c83812..5488bea4b37 100644 --- a/tests/lib/__init__.py +++ b/tests/lib/__init__.py @@ -13,7 +13,6 @@ from io import BytesIO, StringIO from textwrap import dedent from typing import ( - TYPE_CHECKING, Any, AnyStr, Callable, @@ -21,8 +20,10 @@ Iterable, Iterator, List, + Literal, Mapping, Optional, + Protocol, Tuple, Union, cast, @@ -45,13 +46,7 @@ from tests.lib.venv import VirtualEnvironment from tests.lib.wheel import make_wheel -if TYPE_CHECKING: - from typing import Literal, Protocol - - ResolverVariant = Literal["resolvelib", "legacy"] -else: # TODO: Remove this branch when dropping support for Python 3.7. - Protocol = object # Protocol was introduced in Python 3.8. - ResolverVariant = str # Literal was introduced in Python 3.8. +ResolverVariant = Literal["resolvelib", "legacy"] DATA_DIR = pathlib.Path(__file__).parent.parent.joinpath("data").resolve() SRC_DIR = pathlib.Path(__file__).resolve().parent.parent.parent diff --git a/tests/lib/venv.py b/tests/lib/venv.py index 12aa739db23..fac54d3bd2c 100644 --- a/tests/lib/venv.py +++ b/tests/lib/venv.py @@ -7,17 +7,11 @@ import textwrap import venv as _venv from pathlib import Path -from typing import TYPE_CHECKING, Dict, Optional, Union +from typing import Dict, Literal, Optional, Union import virtualenv as _virtualenv -if TYPE_CHECKING: - # Literal was introduced in Python 3.8. - from typing import Literal - - VirtualEnvironmentType = Literal["virtualenv", "venv"] -else: - VirtualEnvironmentType = str +VirtualEnvironmentType = Literal["virtualenv", "venv"] class VirtualEnvironment: diff --git a/tests/unit/test_req_file.py b/tests/unit/test_req_file.py index 94ccfb98d86..19ade8a7fa4 100644 --- a/tests/unit/test_req_file.py +++ b/tests/unit/test_req_file.py @@ -4,7 +4,7 @@ import textwrap from optparse import Values from pathlib import Path -from typing import TYPE_CHECKING, Any, Iterator, List, Optional, Tuple, Union +from typing import Any, Iterator, List, Optional, Protocol, Tuple, Union from unittest import mock import pytest @@ -29,12 +29,6 @@ from pip._internal.req.req_install import InstallRequirement from tests.lib import TestData, make_test_finder, requirements_file -if TYPE_CHECKING: - from typing import Protocol -else: - # Protocol was introduced in Python 3.8. - Protocol = object - @pytest.fixture def session() -> PipSession: diff --git a/tests/unit/test_wheel_builder.py b/tests/unit/test_wheel_builder.py index 9044f945307..d5f372dd5cd 100644 --- a/tests/unit/test_wheel_builder.py +++ b/tests/unit/test_wheel_builder.py @@ -1,5 +1,6 @@ import logging import os +from dataclasses import dataclass from pathlib import Path from typing import Optional, cast @@ -31,29 +32,16 @@ def test_contains_egg_info(s: str, expected: bool) -> None: assert result == expected +@dataclass class ReqMock: - def __init__( - self, - name: str = "pendulum", - is_wheel: bool = False, - editable: bool = False, - link: Optional[Link] = None, - constraint: bool = False, - source_dir: Optional[str] = "/tmp/pip-install-123/pendulum", - use_pep517: bool = True, - supports_pyproject_editable: bool = False, - ) -> None: - self.name = name - self.is_wheel = is_wheel - self.editable = editable - self.link = link - self.constraint = constraint - self.source_dir = source_dir - self.use_pep517 = use_pep517 - self._supports_pyproject_editable = supports_pyproject_editable - - def supports_pyproject_editable(self) -> bool: - return self._supports_pyproject_editable + name: str = "pendulum" + is_wheel: bool = False + editable: bool = False + link: Optional[Link] = None + constraint: bool = False + source_dir: Optional[str] = "/tmp/pip-install-123/pendulum" + use_pep517: bool = True + supports_pyproject_editable: bool = False @pytest.mark.parametrize(