From 0d2ceb63128625f5f552d5ac8e2f7b0ab0370ac3 Mon Sep 17 00:00:00 2001 From: Tzu-ping Chung Date: Sat, 14 Jul 2018 18:43:07 +0800 Subject: [PATCH] Pull in PythonFinder updates --- pipenv/vendor/pythonfinder/models/path.py | 18 +++++++++++---- pipenv/vendor/pythonfinder/pythonfinder.py | 27 ++++++++++++++++++++-- 2 files changed, 39 insertions(+), 6 deletions(-) diff --git a/pipenv/vendor/pythonfinder/models/path.py b/pipenv/vendor/pythonfinder/models/path.py index 2c6ea95098..63c8abdce2 100644 --- a/pipenv/vendor/pythonfinder/models/path.py +++ b/pipenv/vendor/pythonfinder/models/path.py @@ -26,6 +26,7 @@ @attr.s class SystemPath(object): + global_search = attr.ib(default=True) paths = attr.ib(default=attr.Factory(defaultdict)) _executables = attr.ib(default=attr.Factory(list)) _python_executables = attr.ib(default=attr.Factory(list)) @@ -94,7 +95,10 @@ def _setup_pyenv(self): (p for p in reversed(self.path_order) if PYENV_ROOT.lower() in p.lower()), None, ) - pyenv_index = self.path_order.index(last_pyenv) + try: + pyenv_index = self.path_order.index(last_pyenv) + except ValueError: + return self.pyenv_finder = PyenvFinder.create(root=PYENV_ROOT) # paths = (v.paths.values() for v in self.pyenv_finder.versions.values()) root_paths = ( @@ -200,7 +204,7 @@ def find_python_version(self, major, minor=None, patch=None, pre=None, dev=None) ) @classmethod - def create(cls, path=None, system=False, only_python=False): + def create(cls, path=None, system=False, only_python=False, global_search=True): """Create a new :class:`pythonfinder.models.SystemPath` instance. :param path: Search path to prepend when searching, defaults to None @@ -214,7 +218,9 @@ def create(cls, path=None, system=False, only_python=False): """ path_entries = defaultdict(PathEntry) - paths = os.environ.get("PATH").split(os.pathsep) + paths = [] + if global_search: + paths = os.environ.get("PATH").split(os.pathsep) if path: paths = [path] + paths _path_objects = [ensure_path(p.strip('"')) for p in paths] @@ -227,7 +233,11 @@ def create(cls, path=None, system=False, only_python=False): for p in _path_objects } ) - return cls(paths=path_entries, path_order=paths, only_python=only_python, system=system) + return cls( + paths=path_entries, path_order=paths, + only_python=only_python, + system=system, global_search=global_search, + ) @attr.s diff --git a/pipenv/vendor/pythonfinder/pythonfinder.py b/pipenv/vendor/pythonfinder/pythonfinder.py index 50e1b8d89d..7e5813bb9b 100644 --- a/pipenv/vendor/pythonfinder/pythonfinder.py +++ b/pipenv/vendor/pythonfinder/pythonfinder.py @@ -6,8 +6,30 @@ class Finder(object): - def __init__(self, path=None, system=False): + def __init__(self, path=None, system=False, global_search=True): + """Cross-platform Finder for locating python and other executables. + + Searches for python and other specified binaries starting in `path`, + if supplied, but searching the bin path of `sys.executable` if + `system=True`, and then searching in the `os.environ['PATH']` if + `global_search=True`. + + When `global_search` is `False`, this search operation is restricted to + the allowed locations of `path` and `system`. + + :param path: A bin-directory search location, or None to ignore. + :type path: str or None + :param system: Whether to include the bin-dir of `sys.executable`, + defaults to False + :type system: bool + :param global_search: Whether to search the global path from + os.environ, defaults to True. + :type global_search: bool + :returns: a :class:`~pythonfinder.pythonfinder.Finder` object. + """ + self.path_prepend = path + self.global_search = global_search self.system = system self._system_path = None self._windows_finder = None @@ -16,7 +38,8 @@ def __init__(self, path=None, system=False): def system_path(self): if not self._system_path: self._system_path = SystemPath.create( - path=self.path_prepend, system=self.system + path=self.path_prepend, system=self.system, + global_search=self.global_search, ) return self._system_path