Skip to content

Commit

Permalink
Pip 23.0 (#5586)
Browse files Browse the repository at this point in the history
* update pip to 23.0 in patched.txt

* Vendor in pip517 since pip dropped it from its _vendor.

* adjust vendoring script.

* vendor in pip==23.0

* correct vendoring script.

* fix import with vendoring script.
  • Loading branch information
matteius committed Feb 4, 2023
1 parent 6d420e4 commit b7ed022
Show file tree
Hide file tree
Showing 143 changed files with 3,228 additions and 847 deletions.
2 changes: 1 addition & 1 deletion pipenv/patched/patched.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
pip==22.3.1
pip==23.0
safety==2.3.2
2 changes: 1 addition & 1 deletion pipenv/patched/pip/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from typing import List, Optional

__version__ = "22.3.1"
__version__ = "23.0"


def main(args: Optional[List[str]] = None) -> int:
Expand Down
15 changes: 8 additions & 7 deletions pipenv/patched/pip/_internal/build_env.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import sys
import textwrap
from collections import OrderedDict
from sysconfig import get_paths
from types import TracebackType
from typing import TYPE_CHECKING, Iterable, List, Optional, Set, Tuple, Type

Expand All @@ -18,7 +17,12 @@

from pipenv.patched.pip import __file__ as pip_location
from pipenv.patched.pip._internal.cli.spinners import open_spinner
from pipenv.patched.pip._internal.locations import get_platlib, get_prefixed_libs, get_purelib
from pipenv.patched.pip._internal.locations import (
get_isolated_environment_bin_path,
get_isolated_environment_lib_paths,
get_platlib,
get_purelib,
)
from pipenv.patched.pip._internal.metadata import get_default_environment, get_environment
from pipenv.patched.pip._internal.utils.subprocess import call_subprocess
from pipenv.patched.pip._internal.utils.temp_dir import TempDirectory, tempdir_kinds
Expand All @@ -33,11 +37,8 @@ class _Prefix:
def __init__(self, path: str) -> None:
self.path = path
self.setup = False
self.bin_dir = get_paths(
"nt" if os.name == "nt" else "posix_prefix",
vars={"base": path, "platbase": path},
)["scripts"]
self.lib_dirs = get_prefixed_libs(path)
self.bin_dir = get_isolated_environment_bin_path(path)
self.lib_dirs = get_isolated_environment_lib_paths(path)


def get_runnable_pip() -> str:
Expand Down
8 changes: 3 additions & 5 deletions pipenv/patched/pip/_internal/cli/cmdoptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -825,11 +825,9 @@ def _handle_config_settings(
dest="install_options",
action="append",
metavar="options",
help="Extra arguments to be supplied to the setup.py install "
'command (use like --install-option="--install-scripts=/usr/local/'
'bin"). Use multiple --install-option options to pass multiple '
"options to setup.py install. If you are using an option with a "
"directory path, be sure to use absolute path.",
help="This option is deprecated. Using this option with location-changing "
"options may cause unexpected behavior. "
"Use pip-level options like --user, --prefix, --root, and --target.",
)

build_options: Callable[..., Option] = partial(
Expand Down
2 changes: 1 addition & 1 deletion pipenv/patched/pip/_internal/commands/debug.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def create_vendor_txt_map() -> Dict[str, str]:

def get_module_from_module_name(module_name: str) -> ModuleType:
# Module name can be uppercase in vendor.txt for some reason...
module_name = module_name.lower()
module_name = module_name.lower().replace("-", "_")
# PATCH: setuptools is actually only pkg_resources.
if module_name == "setuptools":
module_name = "pkg_resources"
Expand Down
7 changes: 1 addition & 6 deletions pipenv/patched/pip/_internal/commands/inspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,19 +46,14 @@ def add_options(self) -> None:
self.parser.insert_option_group(0, self.cmd_opts)

def run(self, options: Values, args: List[str]) -> int:
logger.warning(
"pip inspect is currently an experimental command. "
"The output format may change in a future release without prior warning."
)

cmdoptions.check_list_path_option(options)
dists = get_environment(options.path).iter_installed_distributions(
local_only=options.local,
user_only=options.user,
skip=set(stdlib_pkgs),
)
output = {
"version": "0",
"version": "1",
"pip_version": __version__,
"installed": [self._dist_to_dict(dist) for dist in dists],
"environment": default_environment(),
Expand Down
21 changes: 15 additions & 6 deletions pipenv/patched/pip/_internal/commands/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
from pipenv.patched.pip._internal.utils.filesystem import test_writable_dir
from pipenv.patched.pip._internal.utils.logging import getLogger
from pipenv.patched.pip._internal.utils.misc import (
check_externally_managed,
ensure_dir,
get_pip_version,
protect_pip_from_modification_on_windows,
Expand Down Expand Up @@ -284,6 +285,20 @@ def run(self, options: Values, args: List[str]) -> int:
if options.use_user_site and options.target_dir is not None:
raise CommandError("Can not combine '--user' and '--target'")

# Check whether the environment we're installing into is externally
# managed, as specified in PEP 668. Specifying --root, --target, or
# --prefix disables the check, since there's no reliable way to locate
# the EXTERNALLY-MANAGED file for those cases. An exception is also
# made specifically for "--dry-run --report" for convenience.
installing_into_current_environment = (
not (options.dry_run and options.json_report_file)
and options.root_path is None
and options.target_dir is None
and options.prefix_path is None
)
if installing_into_current_environment:
check_externally_managed()

upgrade_strategy = "to-satisfy-only"
if options.upgrade:
upgrade_strategy = options.upgrade_strategy
Expand Down Expand Up @@ -402,12 +417,6 @@ def run(self, options: Values, args: List[str]) -> int:
)

if options.json_report_file:
logger.warning(
"--report is currently an experimental option. "
"The output format may change in a future release "
"without prior warning."
)

report = InstallationReport(requirement_set.requirements_to_install)
if options.json_report_file == "-":
print_json(data=report.to_dict())
Expand Down
6 changes: 6 additions & 0 deletions pipenv/patched/pip/_internal/commands/show.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ class _PackageInfo(NamedTuple):
name: str
version: str
location: str
editable_project_location: Optional[str]
requires: List[str]
required_by: List[str]
installer: str
Expand Down Expand Up @@ -120,6 +121,7 @@ def _get_requiring_packages(current_dist: BaseDistribution) -> Iterator[str]:
name=dist.raw_name,
version=str(dist.version),
location=dist.location or "",
editable_project_location=dist.editable_project_location,
requires=requires,
required_by=required_by,
installer=dist.installer,
Expand Down Expand Up @@ -158,6 +160,10 @@ def print_results(
write_output("Author-email: %s", dist.author_email)
write_output("License: %s", dist.license)
write_output("Location: %s", dist.location)
if dist.editable_project_location is not None:
write_output(
"Editable project location: %s", dist.editable_project_location
)
write_output("Requires: %s", ", ".join(dist.requires))
write_output("Required-by: %s", ", ".join(dist.required_by))

Expand Down
7 changes: 6 additions & 1 deletion pipenv/patched/pip/_internal/commands/uninstall.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@
install_req_from_line,
install_req_from_parsed_requirement,
)
from pipenv.patched.pip._internal.utils.misc import protect_pip_from_modification_on_windows
from pipenv.patched.pip._internal.utils.misc import (
check_externally_managed,
protect_pip_from_modification_on_windows,
)

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -90,6 +93,8 @@ def run(self, options: Values, args: List[str]) -> int:
f'"pip help {self.name}")'
)

check_externally_managed()

protect_pip_from_modification_on_windows(
modifying_pip="pip" in reqs_to_uninstall
)
Expand Down
87 changes: 86 additions & 1 deletion pipenv/patched/pip/_internal/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,14 @@
"""

import configparser
import contextlib
import locale
import logging
import pathlib
import re
import sys
from itertools import chain, groupby, repeat
from typing import TYPE_CHECKING, Dict, List, Optional, Union
from typing import TYPE_CHECKING, Dict, Iterator, List, Optional, Union

from pipenv.patched.pip._vendor.requests.models import Request, Response
from pipenv.patched.pip._vendor.rich.console import Console, ConsoleOptions, RenderResult
Expand All @@ -22,6 +27,8 @@
from pipenv.patched.pip._internal.metadata import BaseDistribution
from pipenv.patched.pip._internal.req.req_install import InstallRequirement

logger = logging.getLogger(__name__)


#
# Scaffolding
Expand Down Expand Up @@ -658,3 +665,81 @@ def __str__(self) -> str:
assert self.error is not None
message_part = f".\n{self.error}\n"
return f"Configuration file {self.reason}{message_part}"


_DEFAULT_EXTERNALLY_MANAGED_ERROR = f"""\
The Python environment under {sys.prefix} is managed externally, and may not be
manipulated by the user. Please use specific tooling from the distributor of
the Python installation to interact with this environment instead.
"""


class ExternallyManagedEnvironment(DiagnosticPipError):
"""The current environment is externally managed.
This is raised when the current environment is externally managed, as
defined by `PEP 668`_. The ``EXTERNALLY-MANAGED`` configuration is checked
and displayed when the error is bubbled up to the user.
:param error: The error message read from ``EXTERNALLY-MANAGED``.
"""

reference = "externally-managed-environment"

def __init__(self, error: Optional[str]) -> None:
if error is None:
context = Text(_DEFAULT_EXTERNALLY_MANAGED_ERROR)
else:
context = Text(error)
super().__init__(
message="This environment is externally managed",
context=context,
note_stmt=(
"If you believe this is a mistake, please contact your "
"Python installation or OS distribution provider."
),
hint_stmt=Text("See PEP 668 for the detailed specification."),
)

@staticmethod
def _iter_externally_managed_error_keys() -> Iterator[str]:
# LC_MESSAGES is in POSIX, but not the C standard. The most common
# platform that does not implement this category is Windows, where
# using other categories for console message localization is equally
# unreliable, so we fall back to the locale-less vendor message. This
# can always be re-evaluated when a vendor proposes a new alternative.
try:
category = locale.LC_MESSAGES
except AttributeError:
lang: Optional[str] = None
else:
lang, _ = locale.getlocale(category)
if lang is not None:
yield f"Error-{lang}"
for sep in ("-", "_"):
before, found, _ = lang.partition(sep)
if not found:
continue
yield f"Error-{before}"
yield "Error"

@classmethod
def from_config(
cls,
config: Union[pathlib.Path, str],
) -> "ExternallyManagedEnvironment":
parser = configparser.ConfigParser(interpolation=None)
try:
parser.read(config, encoding="utf-8")
section = parser["externally-managed"]
for key in cls._iter_externally_managed_error_keys():
with contextlib.suppress(KeyError):
return cls(section[key])
except KeyError:
pass
except (OSError, UnicodeDecodeError, configparser.ParsingError):
from pipenv.patched.pip._internal.utils._log import VERBOSE

exc_info = logger.isEnabledFor(VERBOSE)
logger.warning("Failed to read %s", config, exc_info=exc_info)
return cls(None)
2 changes: 1 addition & 1 deletion pipenv/patched/pip/_internal/index/collector.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
Loading

0 comments on commit b7ed022

Please sign in to comment.