Skip to content

Commit

Permalink
Requirementslib==2.3.0 (#5672)
Browse files Browse the repository at this point in the history
* Bump requirementslib that drops vistir.

* Add news fragment

* Add missing file

* Remove vistir entirely

* fix circular import

* revert issue that may be causing circular import issue

* Hackaround current pythonfinder version importlib usage.

* PR Feedback

* fix lint
  • Loading branch information
matteius authored Apr 29, 2023
1 parent 44f4250 commit 99800ec
Show file tree
Hide file tree
Showing 42 changed files with 872 additions and 3,166 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ jobs:
with:
python-version: "3.11"
- run: |
python -m pip install --upgrade wheel invoke parver beautifulsoup4 vistir towncrier requests parse hatch-fancy-pypi-readme
python -m pip install --upgrade wheel invoke parver beautifulsoup4 towncrier requests parse hatch-fancy-pypi-readme
python -m invoke vendoring.update
tests:
name: ${{matrix.os}} / ${{ matrix.python-version }}
Expand Down
1 change: 1 addition & 0 deletions news/5672.vendor.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Vendor in ``requirementslib==2.3.0`` which drops usage of ``vistir``.
35 changes: 0 additions & 35 deletions pipenv/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
# |

import os
import sys
import warnings

from pipenv.__version__ import __version__ # noqa
Expand All @@ -13,50 +12,16 @@
warnings.filterwarnings("ignore", category=DependencyWarning)
warnings.filterwarnings("ignore", category=ResourceWarning)
warnings.filterwarnings("ignore", category=UserWarning)
PIPENV_ROOT = os.path.abspath(os.path.dirname(os.path.realpath(__file__)))

PIPENV_VENDOR = os.sep.join([PIPENV_ROOT, "vendor"])
PIPENV_PATCHED = os.sep.join([PIPENV_ROOT, "patched"])
# PIP_VENDOR = os.sep.join([PIPENV_ROOT, "patched", "pip", "_vendor"])

# sys.path.insert(0, PIP_VENDOR)
# Inject vendored directory into system path.
sys.path.insert(0, PIPENV_VENDOR)
# Inject patched directory into system path.
sys.path.insert(0, PIPENV_PATCHED)


# Load patched pip instead of system pip
os.environ["PIP_DISABLE_PIP_VERSION_CHECK"] = "1"

# Hack to make things work better.
try:
if "concurrency" in sys.modules:
del sys.modules["concurrency"]
except Exception:
pass
if "urllib3" in sys.modules:
del sys.modules["urllib3"]


if os.name == "nt":
from pipenv.vendor import colorama

# Backward compatability with vistir
# These variables will be removed in vistir 0.8.0
no_color = False
for item in ("ANSI_COLORS_DISABLED", "VISTIR_DISABLE_COLORS"):
if os.getenv(item):
warnings.warn(
(
f"Please do not use {item}, as it will be removed in future versions."
"\nUse NO_COLOR instead."
),
DeprecationWarning,
stacklevel=2,
)
no_color = True

if not os.getenv("NO_COLOR") or no_color:
colorama.just_fix_windows_console()

Expand Down
166 changes: 9 additions & 157 deletions pipenv/environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import importlib.util
import itertools
import json
import operator
import os
import site
import sys
Expand All @@ -14,17 +13,18 @@
from sysconfig import get_paths, get_python_version, get_scheme_names

import pipenv
from pipenv import cmdparse
from pipenv.patched.pip._internal.commands.install import InstallCommand
from pipenv.patched.pip._internal.index.package_finder import PackageFinder
from pipenv.patched.pip._internal.req.req_uninstall import UninstallPathSet
from pipenv.patched.pip._vendor import pkg_resources
from pipenv.patched.pip._vendor.packaging.utils import canonicalize_name
from pipenv.utils.funktools import chunked, unnest
from pipenv.utils.indexes import prepare_pip_source_args
from pipenv.utils.processes import subprocess_run
from pipenv.utils.shell import make_posix, normalize_path
from pipenv.vendor import click, vistir
from pipenv.utils.shell import make_posix
from pipenv.vendor import click
from pipenv.vendor.pythonfinder.utils import is_in_path
from pipenv.vendor.requirementslib.fileutils import normalize_path, temp_path
from pipenv.vendor.requirementslib.utils import temp_environ

try:
# this is only in Python3.8 and later
Expand Down Expand Up @@ -490,7 +490,7 @@ def sys_prefix(self) -> str:
@cached_property
def paths(self) -> Dict[str, str]:
paths = {}
with vistir.contextmanagers.temp_environ(), vistir.contextmanagers.temp_path():
with temp_environ(), temp_path():
os.environ["PYTHONIOENCODING"] = "utf-8"
os.environ["PYTHONDONTWRITEBYTECODE"] = "1"
paths = self.base_paths
Expand Down Expand Up @@ -519,7 +519,7 @@ def expand_egg_links(self) -> None:
prefixes = [
Path(prefix)
for prefix in self.base_paths["libdirs"].split(os.pathsep)
if vistir.path.is_in_path(prefix, self.prefix.as_posix())
if is_in_path(prefix, self.prefix.as_posix())
]
for loc in prefixes:
if not loc.exists():
Expand All @@ -528,8 +528,7 @@ def expand_egg_links(self) -> None:
if not pth.suffix == ".egg-link":
continue
contents = [
vistir.path.normalize_path(line.strip())
for line in pth.read_text().splitlines()
normalize_path(line.strip()) for line in pth.read_text().splitlines()
]
pth.write_text("\n".join(contents))

Expand Down Expand Up @@ -796,53 +795,6 @@ def is_satisfied(self, req):
return True
return False

def run(self, cmd, cwd=os.curdir):
"""Run a command with :class:`~subprocess.Popen` in the context of the environment
:param cmd: A command to run in the environment
:type cmd: str or list
:param str cwd: The working directory in which to execute the command, defaults to :data:`os.curdir`
:return: A finished command object
:rtype: :class:`~subprocess.Popen`
"""

c = None
with self.activated():
script = cmdparse.Script.parse(cmd)
c = vistir.misc.run(
script._parts,
return_object=True,
nospin=True,
cwd=cwd,
write_to_stdout=False,
)
return c

def run_py(self, cmd, cwd=os.curdir):
"""Run a python command in the environment context.
:param cmd: A command to run in the environment - runs with `python -c`
:type cmd: str or list
:param str cwd: The working directory in which to execute the command, defaults to :data:`os.curdir`
:return: A finished command object
:rtype: :class:`~subprocess.Popen`
"""

c = None
if isinstance(cmd, str):
script = cmdparse.Script.parse(f"{self.python} -c {cmd}")
else:
script = cmdparse.Script.parse([self.python, "-c"] + list(cmd))
with self.activated():
c = vistir.misc.run(
script._parts,
return_object=True,
nospin=True,
cwd=cwd,
write_to_stdout=False,
)
return c

def run_activate_this(self):
"""Runs the environment's inline activation script"""
if self.is_venv:
Expand Down Expand Up @@ -876,7 +828,7 @@ def activated(self):
original_path = sys.path
original_prefix = sys.prefix
prefix = self.prefix.as_posix()
with vistir.contextmanagers.temp_environ(), vistir.contextmanagers.temp_path():
with temp_environ(), temp_path():
os.environ["PATH"] = os.pathsep.join(
[
self.script_basedir,
Expand All @@ -902,103 +854,3 @@ def activated(self):
finally:
sys.path = original_path
sys.prefix = original_prefix

@cached_property
def finders(self):
from pipenv.vendor.pythonfinder import Finder

finders = [
Finder(path=self.base_paths["scripts"], global_search=gs, system=False)
for gs in (False, True)
]
return finders

@property
def finder(self):
return next(iter(self.finders), None)

def which(self, search, as_path=True):
find = operator.methodcaller("which", search)
result = next(iter(filter(None, (find(finder) for finder in self.finders))), None)
if not result:
result = self._which(search)
else:
if as_path:
result = str(result.path)
return result

def install(self, requirements):
if not isinstance(requirements, (tuple, list)):
requirements = [requirements]
with self.get_finder() as finder:
args = []
for format_control in ("no_binary", "only_binary"):
formats = getattr(finder.format_control, format_control)
args.extend(
(
"--" + format_control.replace("_", "-"),
",".join(sorted(formats or {":none:"})),
)
)
if finder.index_urls:
args.extend(["-i", finder.index_urls[0]])
for extra_index in finder.index_urls[1:]:
args.extend(["--extra-index-url", extra_index])
else:
args.append("--no-index")
for link in finder.find_links:
args.extend(["--find-links", link])
for _, host, _ in finder.secure_origins:
args.extend(["--trusted-host", host])
if finder.allow_all_prereleases:
args.append("--pre")
if finder.process_dependency_links:
args.append("--process-dependency-links")
args.append("--")
args.extend(requirements)
out, _ = vistir.misc.run(
args, return_object=False, nospin=True, block=True, combine_stderr=False
)

@contextlib.contextmanager
def uninstall(self, pkgname, *args, **kwargs):
"""A context manager which allows uninstallation of packages from the environment
:param str pkgname: The name of a package to uninstall
>>> env = Environment("/path/to/env/root")
>>> with env.uninstall("pytz", auto_confirm=True, verbose=False) as uninstaller:
cleaned = uninstaller.paths
>>> if cleaned:
print("uninstalled packages: %s" % cleaned)
"""

auto_confirm = kwargs.pop("auto_confirm", True)
verbose = kwargs.pop("verbose", False)
with self.activated():
monkey_patch = next(
iter(
dist
for dist in self.base_working_set
if dist.project_name == "recursive-monkey-patch"
),
None,
)
if monkey_patch:
monkey_patch.activate()
dist = next(
iter(d for d in self.get_working_set() if d.project_name == pkgname), None
)
path_set = UninstallPathSet.from_dist(dist)
if path_set is not None:
path_set.remove(auto_confirm=auto_confirm, verbose=verbose)
try:
yield path_set
except Exception:
if path_set is not None:
path_set.rollback()
else:
if path_set is not None:
path_set.commit()
if path_set is None:
return
8 changes: 3 additions & 5 deletions pipenv/environments.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,9 @@
import re
import sys

from vistir.path import normalize_drive

from pipenv.patched.pip._vendor.platformdirs import user_cache_dir
from pipenv.utils.shell import env_to_bool, is_env_truthy
from pipenv.vendor.vistir.misc import _isatty
from pipenv.utils.shell import env_to_bool, is_env_truthy, isatty
from pipenv.vendor.requirementslib.fileutils import normalize_drive

# HACK: avoid resolver.py uses the wrong byte code files.
# I hope I can remove this one day.
Expand Down Expand Up @@ -73,7 +71,7 @@ def normalize_pipfile_path(p):
# https://bugs.python.org/issue22490
os.environ.pop("__PYVENV_LAUNCHER__", None)
# Internal, to tell whether the command line session is interactive.
SESSION_IS_INTERACTIVE = _isatty(sys.stdout)
SESSION_IS_INTERACTIVE = isatty(sys.stdout)

# TF_BUILD indicates to Azure pipelines it is a build step
PIPENV_IS_CI = get_from_env("CI", prefix="", check_for_negation=False) or is_env_truthy(
Expand Down
3 changes: 2 additions & 1 deletion pipenv/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from collections import namedtuple
from traceback import format_tb

from pipenv import environments
from pipenv.vendor import click
from pipenv.vendor.click.exceptions import ClickException, FileError, UsageError

Expand Down Expand Up @@ -31,6 +30,8 @@


def handle_exception(exc_type, exception, traceback, hook=sys.excepthook):
from pipenv import environments

if environments.Setting().is_verbose() or not issubclass(exc_type, ClickException):
hook(exc_type, exception, traceback)
else:
Expand Down
9 changes: 3 additions & 6 deletions pipenv/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@
from json.decoder import JSONDecodeError
from pathlib import Path

import click

from pipenv.cmdparse import Script
from pipenv.environment import Environment
from pipenv.environments import Setting, is_in_virtualenv, normalize_pipfile_path
Expand All @@ -30,6 +28,7 @@
python_version,
)
from pipenv.utils.internet import get_url_name, is_pypi_url, is_valid_url, proper_case
from pipenv.utils.locking import atomic_open_for_write
from pipenv.utils.shell import (
find_requirements,
find_windows_executable,
Expand All @@ -41,7 +40,7 @@
system_which,
)
from pipenv.utils.toml import cleanup_toml, convert_toml_outline_tables
from pipenv.vendor import plette, toml, tomlkit, vistir
from pipenv.vendor import click, plette, toml, tomlkit
from pipenv.vendor.requirementslib.models.utils import get_default_pyproject_backend

try:
Expand Down Expand Up @@ -842,9 +841,7 @@ def write_lockfile(self, content):
"""Write out the lockfile."""
s = self._lockfile_encoder.encode(content)
open_kwargs = {"newline": self._lockfile_newlines, "encoding": "utf-8"}
with vistir.contextmanagers.atomic_open_for_write(
self.lockfile_location, **open_kwargs
) as f:
with atomic_open_for_write(self.lockfile_location, **open_kwargs) as f:
f.write(s)
# Write newline at end of document. GH-319.
# Only need '\n' here; the file object handles the rest.
Expand Down
2 changes: 1 addition & 1 deletion pipenv/resolver.py
Original file line number Diff line number Diff line change
Expand Up @@ -691,8 +691,8 @@ def clean_outdated(results, resolver, project, category):

def parse_packages(packages, pre, clear, system, requirements_dir=None):
from pipenv.utils.indexes import parse_indexes
from pipenv.vendor.requirementslib.fileutils import cd, temp_path
from pipenv.vendor.requirementslib.models.requirements import Requirement
from pipenv.vendor.vistir.contextmanagers import cd, temp_path

parsed_packages = []
for package in packages:
Expand Down
Loading

0 comments on commit 99800ec

Please sign in to comment.