diff --git a/pipenv/utils/shell.py b/pipenv/utils/shell.py index 27c6fcc8..ffb6f579 100644 --- a/pipenv/utils/shell.py +++ b/pipenv/utils/shell.py @@ -246,6 +246,7 @@ def find_python(finder, line=None): if os.name == "nt": line = make_posix(line) return line + if not finder: from pipenv.vendor.pythonfinder import Finder diff --git a/pipenv/utils/virtualenv.py b/pipenv/utils/virtualenv.py index cac6b581..30533dfd 100644 --- a/pipenv/utils/virtualenv.py +++ b/pipenv/utils/virtualenv.py @@ -317,12 +317,6 @@ def ensure_python(project, python=None): ) # Print the results, in a beautiful blue... click.secho(c.stdout, fg="cyan", err=True) - # Clear the pythonfinder caches - from pipenv.vendor.pythonfinder import Finder - - finder = Finder(system=False, global_search=True) - finder.find_python_version.cache_clear() - finder.find_all_python_versions.cache_clear() # Find the newly installed Python, hopefully. version = str(version) path_to_python = find_a_system_python(version) diff --git a/pipenv/vendor/click/core.py b/pipenv/vendor/click/core.py index d96e51b7..66bd1d98 100644 --- a/pipenv/vendor/click/core.py +++ b/pipenv/vendor/click/core.py @@ -38,7 +38,7 @@ from .utils import make_str from .utils import PacifyFlushWrapper if t.TYPE_CHECKING: - from pipenv.patched.pip._vendor import typing_extensions as te + import typing_extensions as te from .shell_completion import CompletionItem F = t.TypeVar("F", bound=t.Callable[..., t.Any]) diff --git a/pipenv/vendor/click/globals.py b/pipenv/vendor/click/globals.py index 0af2392e..480058f1 100644 --- a/pipenv/vendor/click/globals.py +++ b/pipenv/vendor/click/globals.py @@ -2,7 +2,7 @@ import typing as t from threading import local if t.TYPE_CHECKING: - from pipenv.patched.pip._vendor import typing_extensions as te + import typing_extensions as te from .core import Context _local = local() diff --git a/pipenv/vendor/click/parser.py b/pipenv/vendor/click/parser.py index b005ba0d..2d5a2ed7 100644 --- a/pipenv/vendor/click/parser.py +++ b/pipenv/vendor/click/parser.py @@ -32,7 +32,7 @@ from .exceptions import NoSuchOption from .exceptions import UsageError if t.TYPE_CHECKING: - from pipenv.patched.pip._vendor import typing_extensions as te + import typing_extensions as te from .core import Argument as CoreArgument from .core import Context from .core import Option as CoreOption diff --git a/pipenv/vendor/click/types.py b/pipenv/vendor/click/types.py index fcb5e732..92e16036 100644 --- a/pipenv/vendor/click/types.py +++ b/pipenv/vendor/click/types.py @@ -13,7 +13,7 @@ from .utils import LazyFile from .utils import safecall if t.TYPE_CHECKING: - from pipenv.patched.pip._vendor import typing_extensions as te + import typing_extensions as te from .core import Context from .core import Parameter from .shell_completion import CompletionItem diff --git a/pipenv/vendor/click/utils.py b/pipenv/vendor/click/utils.py index 5867362f..8283788a 100644 --- a/pipenv/vendor/click/utils.py +++ b/pipenv/vendor/click/utils.py @@ -19,7 +19,7 @@ from ._compat import WIN from .globals import resolve_color_default if t.TYPE_CHECKING: - from pipenv.patched.pip._vendor import typing_extensions as te + import typing_extensions as te F = t.TypeVar("F", bound=t.Callable[..., t.Any]) diff --git a/pipenv/vendor/markupsafe/__init__.py b/pipenv/vendor/markupsafe/__init__.py index ad025038..7166b192 100644 --- a/pipenv/vendor/markupsafe/__init__.py +++ b/pipenv/vendor/markupsafe/__init__.py @@ -4,7 +4,7 @@ import string import typing as t if t.TYPE_CHECKING: - from pipenv.patched.pip._vendor import typing_extensions as te + import typing_extensions as te class HasHTML(te.Protocol): def __html__(self) -> str: diff --git a/pipenv/vendor/pythonfinder/__init__.py b/pipenv/vendor/pythonfinder/__init__.py index 8a5aedcd..116f95ca 100644 --- a/pipenv/vendor/pythonfinder/__init__.py +++ b/pipenv/vendor/pythonfinder/__init__.py @@ -4,7 +4,7 @@ from .exceptions import InvalidPythonVersion from .models import SystemPath from .pythonfinder import Finder -__version__ = "2.0.0" +__version__ = "2.0.1" __all__ = ["Finder", "SystemPath", "InvalidPythonVersion"] diff --git a/pipenv/vendor/pythonfinder/environment.py b/pipenv/vendor/pythonfinder/environment.py index 1eb93129..d168faf2 100644 --- a/pipenv/vendor/pythonfinder/environment.py +++ b/pipenv/vendor/pythonfinder/environment.py @@ -3,6 +3,10 @@ from __future__ import annotations import os import platform import sys +import posixpath +import ntpath +import re +import shutil def is_type_checking(): @@ -13,16 +17,19 @@ def is_type_checking(): return TYPE_CHECKING -PYENV_INSTALLED = bool(os.environ.get("PYENV_SHELL")) or bool( - os.environ.get("PYENV_ROOT") -) -ASDF_INSTALLED = bool(os.environ.get("ASDF_DIR")) PYENV_ROOT = os.path.expanduser( os.path.expandvars(os.environ.get("PYENV_ROOT", "~/.pyenv")) ) +# Check if the path is in Unix-style (Git Bash) +if PYENV_ROOT.startswith('/') and os.name == 'nt': + # Convert to Windows-style path + drive, tail = re.match(r"^/([a-zA-Z])/(.*)", PYENV_ROOT).groups() + PYENV_ROOT = drive.upper() + ":\\" + tail.replace('/', '\\') +PYENV_INSTALLED = shutil.which("pyenv") != None ASDF_DATA_DIR = os.path.expanduser( os.path.expandvars(os.environ.get("ASDF_DATA_DIR", "~/.asdf")) ) +ASDF_INSTALLED = shutil.which("asdf") != None IS_64BIT_OS = None SYSTEM_ARCH = platform.architecture()[0] @@ -41,10 +48,50 @@ Set to **5** by default. """ -def get_shim_paths(): - shim_paths = [] +def join_path_for_platform(path, path_parts): + # If we're on Unix or Unix-like system + if os.name == 'posix' or sys.platform == 'linux': + return posixpath.join(path, *path_parts) + # If we're on Windows + elif os.name == 'nt' or sys.platform == 'win32': + return ntpath.join(path, *path_parts) + else: + raise Exception("Unknown environment") + + +def set_asdf_paths(): if ASDF_INSTALLED: - shim_paths.append(os.path.join(ASDF_DATA_DIR, "shims")) + python_versions = join_path_for_platform(ASDF_DATA_DIR, ["installs", "python"]) + try: + # Get a list of all files and directories in the given path + all_files_and_dirs = os.listdir(python_versions) + # Filter out files and keep only directories + for name in all_files_and_dirs: + if os.path.isdir(os.path.join(python_versions, name)): + asdf_path = os.path.join(python_versions, name) + asdf_path = os.path.join(asdf_path, "bin") + os.environ['PATH'] = asdf_path + os.pathsep + os.environ['PATH'] + except FileNotFoundError: + pass + + +def set_pyenv_paths(): if PYENV_INSTALLED: - shim_paths.append(os.path.join(PYENV_ROOT, "shims")) - return [os.path.normpath(os.path.normcase(p)) for p in shim_paths] + is_windows = False + if os.name == "nt": + python_versions = join_path_for_platform(PYENV_ROOT, ["pyenv-win", "versions"]) + is_windows = True + else: + python_versions = join_path_for_platform(PYENV_ROOT, ["versions"]) + try: + # Get a list of all files and directories in the given path + all_files_and_dirs = os.listdir(python_versions) + # Filter out files and keep only directories + for name in all_files_and_dirs: + if os.path.isdir(os.path.join(python_versions, name)): + pyenv_path = os.path.join(python_versions, name) + if not is_windows: + pyenv_path = os.path.join(pyenv_path, "bin") + os.environ['PATH'] = pyenv_path + os.pathsep + os.environ['PATH'] + except FileNotFoundError: + pass diff --git a/pipenv/vendor/pythonfinder/models/mixins.py b/pipenv/vendor/pythonfinder/models/mixins.py index e5e20d7a..a89dadef 100644 --- a/pipenv/vendor/pythonfinder/models/mixins.py +++ b/pipenv/vendor/pythonfinder/models/mixins.py @@ -14,16 +14,13 @@ from typing import ( from pipenv.vendor.pydantic import BaseModel, Field, validator -from ..environment import get_shim_paths from ..exceptions import InvalidPythonVersion from ..utils import ( KNOWN_EXTS, ensure_path, expand_paths, filter_pythons, - is_in_path, looks_like_python, - normalize_path, path_is_known_executable, ) @@ -317,7 +314,6 @@ class PathEntry(BaseModel): return children def _gen_children(self) -> Iterator: - shim_paths = get_shim_paths() pass_name = self.name != self.path.name pass_args = {"is_root": False, "only_python": self.only_python} if pass_name: @@ -330,8 +326,6 @@ class PathEntry(BaseModel): yield (self.path.as_posix(), self) elif self.is_root: for child in self._filter_children(): - if any(is_in_path(str(child), shim) for shim in shim_paths): - continue if self.only_python: try: entry = PathEntry.create(path=child, **pass_args) @@ -372,7 +366,6 @@ class PathEntry(BaseModel): :param str name: Name of the python version, e.g. ``anaconda3-5.3.0`` :return: A new instance of the class. """ - target = ensure_path(path) guessed_name = False if not name: @@ -393,8 +386,6 @@ class PathEntry(BaseModel): if not guessed_name: child_creation_args["name"] = _new.name for pth, python in pythons.items(): - if any(shim in normalize_path(str(pth)) for shim in get_shim_paths()): - continue pth = ensure_path(pth) children[pth.as_posix()] = PathEntry( py_version=python, path=pth, **child_creation_args diff --git a/pipenv/vendor/pythonfinder/models/path.py b/pipenv/vendor/pythonfinder/models/path.py index 7fda9ccc..59efdfc7 100644 --- a/pipenv/vendor/pythonfinder/models/path.py +++ b/pipenv/vendor/pythonfinder/models/path.py @@ -27,7 +27,6 @@ from ..environment import ( ASDF_INSTALLED, PYENV_INSTALLED, PYENV_ROOT, - get_shim_paths, ) from ..utils import ( dedup, @@ -180,10 +179,6 @@ class SystemPath(FinderBaseModel): path_instances = [ ensure_path(p.strip('"')) for p in path_order - if not any( - is_in_path(normalize_path(str(p)), normalize_path(shim)) - for shim in get_shim_paths() - ) ] self.paths.update( { @@ -249,6 +244,16 @@ class SystemPath(FinderBaseModel): self.path_order = path_order return self + def _remove_shims(self): + path_copy = [p for p in self.path_order[:]] + new_order = [] + for current_path in path_copy: + if not current_path.endswith("shims"): + normalized = normalize_path(current_path) + new_order.append(normalized) + new_order = [ensure_path(p).as_posix() for p in new_order] + self.path_order = new_order + def _remove_path(self, path) -> SystemPath: path_copy = [p for p in reversed(self.path_order[:])] new_order = [] @@ -306,7 +311,6 @@ class SystemPath(FinderBaseModel): version_glob_path="versions/*", ignore_unsupported=self.ignore_unsupported, ) - pyenv_index = None try: pyenv_index = self._get_last_instance(PYENV_ROOT) except ValueError: @@ -321,7 +325,7 @@ class SystemPath(FinderBaseModel): self.paths[pyenv_finder.root] = pyenv_finder self.paths.update(pyenv_finder.roots) self.pyenv_finder = pyenv_finder - self._remove_path(os.path.join(PYENV_ROOT, "shims")) + self._remove_shims() self._register_finder("pyenv", pyenv_finder) return self @@ -518,9 +522,6 @@ class SystemPath(FinderBaseModel): } ) paths = [path, *paths] - paths = [ - p for p in paths if not any(is_in_path(p, shim) for shim in get_shim_paths()) - ] _path_objects = [ensure_path(p.strip('"')) for p in paths] path_entries.update( { diff --git a/pipenv/vendor/pythonfinder/models/python.py b/pipenv/vendor/pythonfinder/models/python.py index a5ec6705..dbd43490 100644 --- a/pipenv/vendor/pythonfinder/models/python.py +++ b/pipenv/vendor/pythonfinder/models/python.py @@ -53,8 +53,6 @@ class PythonFinder(PathEntry): roots: Dict = Field(default_factory=lambda: defaultdict()) #: List of paths discovered during search paths: List = Field(default_factory=lambda: list()) - #: shim directory - shim_dir: str = "shims" #: Versions discovered in the specified paths _versions: Dict = Field(default_factory=lambda: defaultdict()) pythons_ref: Dict = Field(default_factory=lambda: defaultdict()) diff --git a/pipenv/vendor/pythonfinder/pythonfinder.py b/pipenv/vendor/pythonfinder/pythonfinder.py index 48bfd27a..ab9ea300 100644 --- a/pipenv/vendor/pythonfinder/pythonfinder.py +++ b/pipenv/vendor/pythonfinder/pythonfinder.py @@ -7,6 +7,7 @@ from .exceptions import InvalidPythonVersion from .models.common import FinderBaseModel from .models.path import PathEntry, SystemPath from .models.python import PythonVersion +from .environment import set_asdf_paths, set_pyenv_paths from .utils import Iterable, version_re @@ -32,6 +33,8 @@ class Finder(FinderBaseModel): return self.__hash__ == other.__hash__ def create_system_path(self) -> SystemPath: + set_asdf_paths() + set_pyenv_paths() return SystemPath.create( path=self.path_prepend, system=self.system, diff --git a/pipenv/vendor/vendor.txt b/pipenv/vendor/vendor.txt index 170336d6..5f88631d 100644 --- a/pipenv/vendor/vendor.txt +++ b/pipenv/vendor/vendor.txt @@ -12,7 +12,7 @@ plette[validation]==0.4.4 ptyprocess==0.7.0 pydantic==1.10.7 python-dotenv==1.0.0 -pythonfinder==2.0.0 +pythonfinder==2.0.1 requirementslib==2.3.0 ruamel.yaml==0.17.21 shellingham==1.5.0.post1