Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pip 23.2 #5808

Merged
merged 7 commits into from
Jul 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions news/5808.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Upgrades ``pip==23.2`` which includes everything from the pip changelog. Drops the "install_compatatability_finder" pip internals patch.
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==23.1.2
pip==23.2
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__ = "23.1.2"
__version__ = "23.2"


def main(args: Optional[List[str]] = None) -> int:
Expand Down
7 changes: 0 additions & 7 deletions pipenv/patched/pip/__main__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import os
import sys
import warnings

# Remove '' and current working directory from the first entry
# of sys.path, if present to avoid using current directory
Expand All @@ -20,12 +19,6 @@
sys.path.insert(0, path)

if __name__ == "__main__":
# Work around the error reported in #9540, pending a proper fix.
# Note: It is essential the warning filter is set *before* importing
# pip, as the deprecation happens at import time, not runtime.
warnings.filterwarnings(
"ignore", category=DeprecationWarning, module=".*packaging\\.version"
)
import importlib.util
import sys
spec = importlib.util.spec_from_file_location(
Expand Down
42 changes: 31 additions & 11 deletions pipenv/patched/pip/_internal/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,17 @@ def __init__(
self.origin: Optional[DirectUrl] = None
origin_direct_url_path = Path(self.link.file_path).parent / ORIGIN_JSON_NAME
if origin_direct_url_path.exists():
self.origin = DirectUrl.from_json(origin_direct_url_path.read_text())
try:
self.origin = DirectUrl.from_json(
origin_direct_url_path.read_text(encoding="utf-8")
)
except Exception as e:
logger.warning(
"Ignoring invalid cache entry origin file %s for %s (%s)",
origin_direct_url_path,
link.filename,
e,
)


class WheelCache(Cache):
Expand Down Expand Up @@ -257,16 +267,26 @@ def get_cache_entry(
@staticmethod
def record_download_origin(cache_dir: str, download_info: DirectUrl) -> None:
origin_path = Path(cache_dir) / ORIGIN_JSON_NAME
if origin_path.is_file():
origin = DirectUrl.from_json(origin_path.read_text())
# TODO: use DirectUrl.equivalent when https://github.com/pypa/pip/pull/10564
# is merged.
if origin.url != download_info.url:
if origin_path.exists():
try:
origin = DirectUrl.from_json(origin_path.read_text(encoding="utf-8"))
except Exception as e:
logger.warning(
"Origin URL %s in cache entry %s does not match download URL %s. "
"This is likely a pip bug or a cache corruption issue.",
origin.url,
cache_dir,
download_info.url,
"Could not read origin file %s in cache entry (%s). "
"Will attempt to overwrite it.",
origin_path,
e,
)
else:
# TODO: use DirectUrl.equivalent when
# https://github.com/pypa/pip/pull/10564 is merged.
if origin.url != download_info.url:
logger.warning(
"Origin URL %s in cache entry %s does not match download URL "
"%s. This is likely a pip bug or a cache corruption issue. "
"Will overwrite it with the new value.",
origin.url,
cache_dir,
download_info.url,
)
origin_path.write_text(download_info.to_json(), encoding="utf-8")
11 changes: 11 additions & 0 deletions pipenv/patched/pip/_internal/cli/base_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,17 @@ def _main(self, args: List[str]) -> int:
", ".join(sorted(always_enabled_features)),
)

# Make sure that the --python argument isn't specified after the
# subcommand. We can tell, because if --python was specified,
# we should only reach this point if we're running in the created
# subprocess, which has the _PIP_RUNNING_IN_SUBPROCESS environment
# variable set.
if options.python and "_PIP_RUNNING_IN_SUBPROCESS" not in os.environ:
logger.critical(
"The --python option must be placed before the pip subcommand name"
)
sys.exit(ERROR)

# TODO: Try to get these passing down from the command?
# without resorting to os.environ to hold these.
# This also affects isolated builds and it should.
Expand Down
2 changes: 2 additions & 0 deletions pipenv/patched/pip/_internal/commands/check.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from pipenv.patched.pip._internal.operations.check import (
check_package_set,
create_package_set_from_installed,
warn_legacy_versions_and_specifiers,
)
from pipenv.patched.pip._internal.utils.misc import write_output

Expand All @@ -21,6 +22,7 @@ class CheckCommand(Command):

def run(self, options: Values, args: List[str]) -> int:
package_set, parsing_probs = create_package_set_from_installed()
warn_legacy_versions_and_specifiers(package_set)
missing, conflicting = check_package_set(package_set)

for project_name in missing:
Expand Down
13 changes: 4 additions & 9 deletions pipenv/patched/pip/_internal/commands/completion.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,10 @@
complete -o default -F _pip_completion {prog}
""",
"zsh": """
function _pip_completion {{
local words cword
read -Ac words
read -cn cword
reply=( $( COMP_WORDS="$words[*]" \\
COMP_CWORD=$(( cword-1 )) \\
PIP_AUTO_COMPLETE=1 $words[1] 2>/dev/null ))
}}
compctl -K _pip_completion {prog}
#compdef -P pip[0-9.]#
compadd $( COMP_WORDS="$words[*]" \\
COMP_CWORD=$((CURRENT-1)) \\
PIP_AUTO_COMPLETE=1 $words[1] 2>/dev/null )
""",
"fish": """
function __fish_complete_pip
Expand Down
4 changes: 4 additions & 0 deletions pipenv/patched/pip/_internal/commands/download.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,10 @@ def run(self, options: Values, args: List[str]) -> int:
assert req.name is not None
preparer.save_linked_requirement(req)
downloaded.append(req.name)

preparer.prepare_linked_requirements_more(requirement_set.requirements.values())
requirement_set.warn_legacy_versions_and_specifiers()

if downloaded:
write_output("Successfully downloaded %s", " ".join(downloaded))

Expand Down
19 changes: 15 additions & 4 deletions pipenv/patched/pip/_internal/commands/freeze.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,25 @@
import sys
from optparse import Values
from typing import List
from typing import AbstractSet, List

from pipenv.patched.pip._internal.cli import cmdoptions
from pipenv.patched.pip._internal.cli.base_command import Command
from pipenv.patched.pip._internal.cli.status_codes import SUCCESS
from pipenv.patched.pip._internal.operations.freeze import freeze
from pipenv.patched.pip._internal.utils.compat import stdlib_pkgs

DEV_PKGS = {"pip", "setuptools", "distribute", "wheel"}

def _should_suppress_build_backends() -> bool:
return sys.version_info < (3, 12)


def _dev_pkgs() -> AbstractSet[str]:
pkgs = {"pip"}

if _should_suppress_build_backends():
pkgs |= {"setuptools", "distribute", "wheel"}

return pkgs


class FreezeCommand(Command):
Expand Down Expand Up @@ -61,7 +72,7 @@ def add_options(self) -> None:
action="store_true",
help=(
"Do not skip these packages in the output:"
" {}".format(", ".join(DEV_PKGS))
" {}".format(", ".join(_dev_pkgs()))
),
)
self.cmd_opts.add_option(
Expand All @@ -77,7 +88,7 @@ def add_options(self) -> None:
def run(self, options: Values, args: List[str]) -> int:
skip = set(stdlib_pkgs)
if not options.freeze_all:
skip.update(DEV_PKGS)
skip.update(_dev_pkgs())

if options.excludes:
skip.update(options.excludes)
Expand Down
3 changes: 3 additions & 0 deletions pipenv/patched/pip/_internal/commands/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,9 @@ def run(self, options: Values, args: List[str]) -> int:
json.dump(report.to_dict(), f, indent=2, ensure_ascii=False)

if options.dry_run:
# In non dry-run mode, the legacy versions and specifiers check
# will be done as part of conflict detection.
requirement_set.warn_legacy_versions_and_specifiers()
would_install_items = sorted(
(r.metadata["name"], r.metadata["version"])
for r in requirement_set.requirements_to_install
Expand Down
7 changes: 5 additions & 2 deletions pipenv/patched/pip/_internal/commands/list.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,10 @@ def add_options(self) -> None:
dest="list_format",
default="columns",
choices=("columns", "freeze", "json"),
help="Select the output format among: columns (default), freeze, or json",
help=(
"Select the output format among: columns (default), freeze, or json. "
"The 'freeze' format cannot be used with the --outdated option."
),
)

self.cmd_opts.add_option(
Expand Down Expand Up @@ -157,7 +160,7 @@ def run(self, options: Values, args: List[str]) -> int:

if options.outdated and options.list_format == "freeze":
raise CommandError(
"List format 'freeze' can not be used with the --outdated option."
"List format 'freeze' cannot be used with the --outdated option."
)

cmdoptions.check_list_path_option(options)
Expand Down
3 changes: 3 additions & 0 deletions pipenv/patched/pip/_internal/commands/wheel.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,9 @@ def run(self, options: Values, args: List[str]) -> int:
elif should_build_for_wheel_command(req):
reqs_to_build.append(req)

preparer.prepare_linked_requirements_more(requirement_set.requirements.values())
requirement_set.warn_legacy_versions_and_specifiers()

# build wheels
build_successes, build_failures = build(
reqs_to_build,
Expand Down
11 changes: 9 additions & 2 deletions pipenv/patched/pip/_internal/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,8 +210,15 @@ def save(self) -> None:
# Ensure directory exists.
ensure_dir(os.path.dirname(fname))

with open(fname, "w") as f:
parser.write(f)
# Ensure directory's permission(need to be writeable)
try:
with open(fname, "w") as f:
parser.write(f)
except OSError as error:
raise ConfigurationError(
f"An error occurred while writing to the configuration file "
f"{fname}: {error}"
)

#
# Private routines
Expand Down
2 changes: 1 addition & 1 deletion pipenv/patched/pip/_internal/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -544,7 +544,7 @@ def body(self) -> str:
# so the output can be directly copied into the requirements file.
package = (
self.req.original_link
if self.req.original_link
if self.req.is_direct
# In case someone feeds something downright stupid
# to InstallRequirement's constructor.
else getattr(self.req, "req", None)
Expand Down
30 changes: 9 additions & 21 deletions pipenv/patched/pip/_internal/index/package_finder.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,6 @@ def __init__(
target_python: TargetPython,
allow_yanked: bool,
ignore_requires_python: Optional[bool] = None,
ignore_compatibility: Optional[bool] = None,
) -> None:
"""
:param project_name: The user supplied package name.
Expand All @@ -143,8 +142,6 @@ def __init__(
:param ignore_requires_python: Whether to ignore incompatible
PEP 503 "data-requires-python" values in HTML links. Defaults
to False.
:param ignore_compatibility: Whether to ignore
compatibility of python versions and allow all versions of packages.
"""
if ignore_requires_python is None:
ignore_requires_python = False
Expand All @@ -154,7 +151,6 @@ def __init__(
self._ignore_requires_python = ignore_requires_python
self._formats = formats
self._target_python = target_python
self._ignore_compatibility = ignore_compatibility

self.project_name = project_name

Expand Down Expand Up @@ -185,10 +181,10 @@ def evaluate_link(self, link: Link) -> Tuple[LinkType, str]:
LinkType.format_unsupported,
f"unsupported archive format: {ext}",
)
if "binary" not in self._formats and ext == WHEEL_EXTENSION and not self._ignore_compatibility:
if "binary" not in self._formats and ext == WHEEL_EXTENSION:
reason = f"No binaries permitted for {self.project_name}"
return (LinkType.format_unsupported, reason)
if "macosx10" in link.path and ext == ".zip" and not self._ignore_compatibility:
if "macosx10" in link.path and ext == ".zip":
return (LinkType.format_unsupported, "macosx10 one")
if ext == WHEEL_EXTENSION:
try:
Expand All @@ -203,7 +199,7 @@ def evaluate_link(self, link: Link) -> Tuple[LinkType, str]:
return (LinkType.different_project, reason)

supported_tags = self._target_python.get_tags()
if not wheel.supported(supported_tags) and not self._ignore_compatibility:
if not wheel.supported(supported_tags):
# Include the wheel's tags in the reason string to
# simplify troubleshooting compatibility issues.
file_tags = ", ".join(wheel.get_formatted_file_tags())
Expand Down Expand Up @@ -244,7 +240,7 @@ def evaluate_link(self, link: Link) -> Tuple[LinkType, str]:
version_info=self._target_python.py_version_info,
ignore_requires_python=self._ignore_requires_python,
)
if not supports_python and not self._ignore_compatibility:
if not supports_python:
reason = f"{version} Requires-Python {link.requires_python}"
return (LinkType.requires_python_mismatch, reason)

Expand Down Expand Up @@ -491,10 +487,7 @@ def get_applicable_candidates(

return sorted(filtered_applicable_candidates, key=self._sort_key)

def _sort_key(
self, candidate: InstallationCandidate,
ignore_compatibility: bool = True
) -> CandidateSortingKey:
def _sort_key(self, candidate: InstallationCandidate) -> CandidateSortingKey:
"""
Function to pass as the `key` argument to a call to sorted() to sort
InstallationCandidates by preference.
Expand Down Expand Up @@ -539,12 +532,10 @@ def _sort_key(
)
)
except ValueError:
if not ignore_compatibility:
raise UnsupportedWheel(
"{} is not a supported wheel for this platform. It "
"can't be sorted.".format(wheel.filename)
)
pri = -(support_num)
raise UnsupportedWheel(
"{} is not a supported wheel for this platform. It "
"can't be sorted.".format(wheel.filename)
)
if self._prefer_binary:
binary_preference = 1
if wheel.build_tag is not None:
Expand Down Expand Up @@ -611,7 +602,6 @@ def __init__(
format_control: Optional[FormatControl] = None,
candidate_prefs: Optional[CandidatePreferences] = None,
ignore_requires_python: Optional[bool] = None,
ignore_compatibility: Optional[bool] = False
) -> None:
"""
This constructor is primarily meant to be used by the create() class
Expand All @@ -633,7 +623,6 @@ def __init__(
self._ignore_requires_python = ignore_requires_python
self._link_collector = link_collector
self._target_python = target_python
self._ignore_compatibility = ignore_compatibility

self.format_control = format_control

Expand Down Expand Up @@ -734,7 +723,6 @@ def make_link_evaluator(self, project_name: str) -> LinkEvaluator:
target_python=self._target_python,
allow_yanked=self._allow_yanked,
ignore_requires_python=self._ignore_requires_python,
ignore_compatibility=self._ignore_compatibility
)

def _sort_links(self, links: Iterable[Link]) -> List[Link]:
Expand Down
4 changes: 2 additions & 2 deletions pipenv/patched/pip/_internal/metadata/importlib/_envs.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ def _emit_egg_deprecation(location: Optional[str]) -> None:
deprecated(
reason=f"Loading egg at {location} is deprecated.",
replacement="to use pip for package installation.",
gone_in=None,
gone_in="23.3",
)


Expand All @@ -174,7 +174,7 @@ def _iter_distributions(self) -> Iterator[BaseDistribution]:
for location in self._paths:
yield from finder.find(location)
for dist in finder.find_eggs(location):
# _emit_egg_deprecation(dist.location) # TODO: Enable this.
_emit_egg_deprecation(dist.location)
yield dist
# This must go last because that's how pkg_resources tie-breaks.
yield from finder.find_linked(location)
Expand Down
Loading