diff --git a/NEWS.rst b/NEWS.rst index ff89e5cdf..1473db712 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -55,7 +55,7 @@ Bug Fixes - Ensure that the candidate ``pip`` executable exists, when checking for a new version of pip. (`#11309 `_) - Ignore distributions with invalid ``Name`` in metadata instead of crashing, when using the ``importlib.metadata`` backend. (`#11352 `_) -- Raise RequirementsFileParseError when parsing malformed requirements options that can't be sucessfully parsed by shlex. (`#11491 `_) +- Raise RequirementsFileParseError when parsing malformed requirements options that can't be successfully parsed by shlex. (`#11491 `_) - Fix build environment isolation on some system Pythons. (`#6264 `_) Vendored Libraries diff --git a/docs/html/cli/pip_download.rst b/docs/html/cli/pip_download.rst index f1fe1769e..d247c51cc 100644 --- a/docs/html/cli/pip_download.rst +++ b/docs/html/cli/pip_download.rst @@ -81,7 +81,7 @@ Examples #. Download a package and all of its dependencies with OSX specific interpreter constraints. This forces OSX 10.10 or lower compatibility. Since OSX deps are forward compatible, - this will also match ``macosx-10_9_x86_64``, ``macosx-10_8_x86_64``, ``macosx-10_8_intel``, + this will also match ``macosx_10_9_x86_64``, ``macosx_10_8_x86_64``, ``macosx_10_8_intel``, etc. It will also match deps with platform ``any``. Also force the interpreter version to ``27`` (or more generic, i.e. ``2``) and implementation to ``cp`` (or more generic, i.e. ``py``). @@ -92,7 +92,7 @@ Examples python -m pip download \ --only-binary=:all: \ - --platform macosx-10_10_x86_64 \ + --platform macosx_10_10_x86_64 \ --python-version 27 \ --implementation cp \ SomePackage @@ -103,7 +103,7 @@ Examples py -m pip download ^ --only-binary=:all: ^ - --platform macosx-10_10_x86_64 ^ + --platform macosx_10_10_x86_64 ^ --python-version 27 ^ --implementation cp ^ SomePackage diff --git a/docs/html/development/release-process.rst b/docs/html/development/release-process.rst index a9ae8465e..b71e2820b 100644 --- a/docs/html/development/release-process.rst +++ b/docs/html/development/release-process.rst @@ -31,7 +31,7 @@ to need extra work before being released, the release manager always has the option to back out the partial change prior to a release. The PR can then be reworked and resubmitted for the next release. -Vendoring updates will be picked up fron the ``main`` branch, as for any other +Vendoring updates will be picked up from the ``main`` branch, as for any other update. Ideally, vendoring updates should be merged between releases, just like any other change. If there are outstanding updates to vendored packages, the release manager *may* at their discretion choose to do a vendoring update diff --git a/docs/html/reference/installation-report.md b/docs/html/reference/installation-report.md index fff37242d..de67528cf 100644 --- a/docs/html/reference/installation-report.md +++ b/docs/html/reference/installation-report.md @@ -71,7 +71,7 @@ package with the following properties: ``` - `requested`: `true` if the requirement was explicitly provided by the user, either - directely via a command line argument or indirectly via a requirements file. `false` + directly via a command line argument or indirectly via a requirements file. `false` if the requirement was installed as a dependency of another requirement. - `requested_extras`: extras requested by the user. This field is only present when the diff --git a/news/11598.bugfix.rst b/news/11598.bugfix.rst new file mode 100644 index 000000000..031ff9ddc --- /dev/null +++ b/news/11598.bugfix.rst @@ -0,0 +1 @@ +Use the "venv" scheme if available to obtain prefixed lib paths. diff --git a/news/c1da841b-9024-4448-9ae1-6e4a5a5952f0.trivial.rst b/news/c1da841b-9024-4448-9ae1-6e4a5a5952f0.trivial.rst new file mode 100644 index 000000000..e69de29bb diff --git a/news/d4da20f5-0ed2-480c-baa9-2490e4abdff6.trivial.rst b/news/d4da20f5-0ed2-480c-baa9-2490e4abdff6.trivial.rst new file mode 100644 index 000000000..e69de29bb diff --git a/src/pip/_internal/build_env.py b/src/pip/_internal/build_env.py index cc2b38bab..e67b868e8 100644 --- a/src/pip/_internal/build_env.py +++ b/src/pip/_internal/build_env.py @@ -18,7 +18,11 @@ from pip._vendor.packaging.version import Version from pip import __file__ as pip_location from pip._internal.cli.spinners import open_spinner -from pip._internal.locations import get_platlib, get_prefixed_libs, get_purelib +from pip._internal.locations import ( + get_isolated_environment_lib_paths, + get_platlib, + get_purelib, +) from pip._internal.metadata import get_default_environment, get_environment from pip._internal.utils.subprocess import call_subprocess from pip._internal.utils.temp_dir import TempDirectory, tempdir_kinds @@ -37,7 +41,7 @@ class _Prefix: "nt" if os.name == "nt" else "posix_prefix", vars={"base": path, "platbase": path}, )["scripts"] - self.lib_dirs = get_prefixed_libs(path) + self.lib_dirs = get_isolated_environment_lib_paths(path) def get_runnable_pip() -> str: diff --git a/src/pip/_internal/index/collector.py b/src/pip/_internal/index/collector.py index 0120610c7..b3e293ea3 100644 --- a/src/pip/_internal/index/collector.py +++ b/src/pip/_internal/index/collector.py @@ -354,7 +354,7 @@ def _get_index_content(link: Link, *, session: PipSession) -> Optional["IndexCon if not url.endswith("/"): url += "/" # TODO: In the future, it would be nice if pip supported PEP 691 - # style respones in the file:// URLs, however there's no + # style responses in the file:// URLs, however there's no # standard file extension for application/vnd.pypi.simple.v1+json # so we'll need to come up with something on our own. url = urllib.parse.urljoin(url, "index.html") diff --git a/src/pip/_internal/locations/__init__.py b/src/pip/_internal/locations/__init__.py index 60afe0a73..516bd6078 100644 --- a/src/pip/_internal/locations/__init__.py +++ b/src/pip/_internal/locations/__init__.py @@ -27,7 +27,7 @@ __all__ = [ "get_bin_user", "get_major_minor_version", "get_platlib", - "get_prefixed_libs", + "get_isolated_environment_lib_paths", "get_purelib", "get_scheme", "get_src_prefix", @@ -482,13 +482,13 @@ def _looks_like_apple_library(path: str) -> bool: return path == f"/Library/Python/{get_major_minor_version()}/site-packages" -def get_prefixed_libs(prefix: str) -> List[str]: +def get_isolated_environment_lib_paths(prefix: str) -> List[str]: """Return the lib locations under ``prefix``.""" - new_pure, new_plat = _sysconfig.get_prefixed_libs(prefix) + new_pure, new_plat = _sysconfig.get_isolated_environment_lib_paths(prefix) if _USE_SYSCONFIG: return _deduplicated(new_pure, new_plat) - old_pure, old_plat = _distutils.get_prefixed_libs(prefix) + old_pure, old_plat = _distutils.get_isolated_environment_lib_paths(prefix) old_lib_paths = _deduplicated(old_pure, old_plat) # Apple's Python (shipped with Xcode and Command Line Tools) hard-code diff --git a/src/pip/_internal/locations/_distutils.py b/src/pip/_internal/locations/_distutils.py index c7712f016..a6fbcd2f0 100644 --- a/src/pip/_internal/locations/_distutils.py +++ b/src/pip/_internal/locations/_distutils.py @@ -173,7 +173,7 @@ def get_platlib() -> str: return get_python_lib(plat_specific=True) -def get_prefixed_libs(prefix: str) -> Tuple[str, str]: +def get_isolated_environment_lib_paths(prefix: str) -> Tuple[str, str]: return ( get_python_lib(plat_specific=False, prefix=prefix), get_python_lib(plat_specific=True, prefix=prefix), diff --git a/src/pip/_internal/locations/_sysconfig.py b/src/pip/_internal/locations/_sysconfig.py index 0bbc9283d..698215720 100644 --- a/src/pip/_internal/locations/_sysconfig.py +++ b/src/pip/_internal/locations/_sysconfig.py @@ -213,6 +213,10 @@ def get_platlib() -> str: return sysconfig.get_paths()["platlib"] -def get_prefixed_libs(prefix: str) -> typing.Tuple[str, str]: - paths = sysconfig.get_paths(vars={"base": prefix, "platbase": prefix}) +def get_isolated_environment_lib_paths(prefix: str) -> typing.Tuple[str, str]: + vars = {"base": prefix, "platbase": prefix} + if "venv" in sysconfig.get_scheme_names(): + paths = sysconfig.get_paths(vars=vars, scheme="venv") + else: + paths = sysconfig.get_paths(vars=vars) return (paths["purelib"], paths["platlib"]) diff --git a/src/pip/_internal/network/auth.py b/src/pip/_internal/network/auth.py index 241ddc53a..68b5a5f45 100644 --- a/src/pip/_internal/network/auth.py +++ b/src/pip/_internal/network/auth.py @@ -113,7 +113,7 @@ class KeyRingCliProvider(KeyRingBaseProvider): return self._set_password(url, username, password) def _get_password(self, service_name: str, username: str) -> Optional[str]: - """Mirror the implemenation of keyring.get_password using cli""" + """Mirror the implementation of keyring.get_password using cli""" if self.keyring is None: return None @@ -131,7 +131,7 @@ class KeyRingCliProvider(KeyRingBaseProvider): return res.stdout.decode("utf-8").strip("\n") def _set_password(self, service_name: str, username: str, password: str) -> None: - """Mirror the implemenation of keyring.set_password using cli""" + """Mirror the implementation of keyring.set_password using cli""" if self.keyring is None: return None diff --git a/src/pip/_internal/vcs/bazaar.py b/src/pip/_internal/vcs/bazaar.py index 06c80e48a..20a17ed09 100644 --- a/src/pip/_internal/vcs/bazaar.py +++ b/src/pip/_internal/vcs/bazaar.py @@ -72,7 +72,7 @@ class Bazaar(VersionControl): @classmethod def get_url_rev_and_auth(cls, url: str) -> Tuple[str, Optional[str], AuthInfo]: - # hotfix the URL scheme after removing bzr+ from bzr+ssh:// readd it + # hotfix the URL scheme after removing bzr+ from bzr+ssh:// re-add it url, rev, user_pass = super().get_url_rev_and_auth(url) if url.startswith("ssh://"): url = "bzr+" + url diff --git a/src/pip/_internal/vcs/subversion.py b/src/pip/_internal/vcs/subversion.py index 2cd6f0ae9..16d93a67b 100644 --- a/src/pip/_internal/vcs/subversion.py +++ b/src/pip/_internal/vcs/subversion.py @@ -87,7 +87,7 @@ class Subversion(VersionControl): @classmethod def get_url_rev_and_auth(cls, url: str) -> Tuple[str, Optional[str], AuthInfo]: - # hotfix the URL scheme after removing svn+ from svn+ssh:// readd it + # hotfix the URL scheme after removing svn+ from svn+ssh:// re-add it url, rev, user_pass = super().get_url_rev_and_auth(url) if url.startswith("ssh://"): url = "svn+" + url diff --git a/tests/functional/test_install.py b/tests/functional/test_install.py index f61137268..6131a4054 100644 --- a/tests/functional/test_install.py +++ b/tests/functional/test_install.py @@ -1145,39 +1145,6 @@ def test_install_with_target_or_prefix_and_scripts_no_warning( assert "--no-warn-script-location" not in result.stderr, str(result) -def _change_root(new_root: str, pathname: str) -> str: - """ - Adapted from distutils. - - Return 'pathname' with 'new_root' prepended. If 'pathname' is - relative, this is equivalent to "os.path.join(new_root,pathname)". - Otherwise, it requires making 'pathname' relative and then joining the - two, which is tricky on DOS/Windows and Mac OS. - """ - try: - from distutils.util import change_root - except ImportError: - pass - else: - return change_root(new_root, pathname) - - if os.name == "posix": - if not os.path.isabs(pathname): - return os.path.join(new_root, pathname) - else: - return os.path.join(new_root, pathname[1:]) - - elif os.name == "nt": - drive, path = os.path.splitdrive(pathname) - if path[0] == "\\": - path = path[1:] - return os.path.join(new_root, path) - - else: - # distutils raise DistutilsPlatformError here - raise RuntimeError(f"nothing known about platform '{os.name}'") - - @pytest.mark.usefixtures("with_wheel") def test_install_package_with_root(script: PipTestEnvironment, data: TestData) -> None: """ @@ -1196,8 +1163,11 @@ def test_install_package_with_root(script: PipTestEnvironment, data: TestData) - normal_install_path = os.fspath( script.base_path / script.site_packages / "simple-1.0.dist-info" ) + # use a function borrowed from distutils + # to change the root exactly how the --root option does it + from pip._internal.locations.base import change_root - root_path = _change_root(os.path.join(script.scratch, "root"), normal_install_path) + root_path = change_root(os.path.join(script.scratch, "root"), normal_install_path) result.did_create(root_path) # Should show find-links location in output diff --git a/tests/functional/test_install_vcs_git.py b/tests/functional/test_install_vcs_git.py index cb72ec0b2..60b7715a9 100644 --- a/tests/functional/test_install_vcs_git.py +++ b/tests/functional/test_install_vcs_git.py @@ -79,7 +79,7 @@ def _make_version_pkg_url( Return a "git+file://" URL to the version_pkg test package. Args: - path: a tests.lib.path.Path object pointing to a Git repository + path: a pathlib.Path object pointing to a Git repository containing the version_pkg package. rev: an optional revision to install like a branch name, tag, or SHA. """ @@ -101,7 +101,7 @@ def _install_version_pkg_only( the version). Args: - path: a tests.lib.path.Path object pointing to a Git repository + path: a pathlib.Path object pointing to a Git repository containing the package. rev: an optional revision to install like a branch name or tag. """ @@ -122,7 +122,7 @@ def _install_version_pkg( installed. Args: - path: a tests.lib.path.Path object pointing to a Git repository + path: a pathlib.Path object pointing to a Git repository containing the package. rev: an optional revision to install like a branch name or tag. """