mirror of
https://github.com/kennethreitz/pipenv.git
synced 2026-06-05 22:50:18 +00:00
95f0df79e8
Signed-off-by: Dan Ryan <dan@danryan.co>
104 lines
4.2 KiB
Python
104 lines
4.2 KiB
Python
# -*- coding=utf-8 -*-
|
|
from __future__ import print_function, absolute_import
|
|
import abc
|
|
import operator
|
|
import six
|
|
from itertools import chain
|
|
from ..utils import KNOWN_EXTS, unnest
|
|
|
|
|
|
@six.add_metaclass(abc.ABCMeta)
|
|
class BaseFinder(object):
|
|
def get_versions(self):
|
|
"""Return the available versions from the finder"""
|
|
raise NotImplementedError
|
|
|
|
@classmethod
|
|
def create(cls):
|
|
raise NotImplementedError
|
|
|
|
@property
|
|
def version_paths(self):
|
|
return self.versions.values()
|
|
|
|
@property
|
|
def expanded_paths(self):
|
|
return (p.paths.values() for p in self.version_paths)
|
|
|
|
|
|
class BasePath(object):
|
|
def which(self, name):
|
|
"""Search in this path for an executable.
|
|
|
|
:param executable: The name of an executable to search for.
|
|
:type executable: str
|
|
:returns: :class:`~pythonfinder.models.PathEntry` instance.
|
|
"""
|
|
|
|
valid_names = [name] + [
|
|
"{0}.{1}".format(name, ext).lower() if ext else "{0}".format(name).lower()
|
|
for ext in KNOWN_EXTS
|
|
]
|
|
children = self.children
|
|
found = next((children[(self.path / child).as_posix()] for child in valid_names if (self.path / child).as_posix() in children), None)
|
|
return found
|
|
|
|
def find_all_python_versions(self, major=None, minor=None, patch=None, pre=None, dev=None, arch=None):
|
|
"""Search for a specific python version on the path. Return all copies
|
|
|
|
:param major: Major python version to search for.
|
|
:type major: int
|
|
:param int minor: Minor python version to search for, defaults to None
|
|
:param int patch: Patch python version to search for, defaults to None
|
|
:param bool pre: Search for prereleases (default None) - prioritize releases if None
|
|
:param bool dev: Search for devreleases (default None) - prioritize releases if None
|
|
:param str arch: Architecture to include, e.g. '64bit', defaults to None
|
|
:return: A list of :class:`~pythonfinder.models.PathEntry` instances matching the version requested.
|
|
:rtype: List[:class:`~pythonfinder.models.PathEntry`]
|
|
"""
|
|
|
|
sub_finder = operator.methodcaller(
|
|
"find_python_version", major, minor=minor, patch=patch, pre=pre, dev=dev, arch=arch
|
|
)
|
|
if not self.is_dir:
|
|
return sub_finder(self)
|
|
path_filter = filter(None, (sub_finder(p) for p in self.children.values()))
|
|
version_sort = operator.attrgetter("as_python.version_sort")
|
|
return [c for c in sorted(path_filter, key=version_sort, reverse=True)]
|
|
|
|
def find_python_version(self, major=None, minor=None, patch=None, pre=None, dev=None, arch=None):
|
|
"""Search or self for the specified Python version and return the first match.
|
|
|
|
:param major: Major version number.
|
|
:type major: int
|
|
:param int minor: Minor python version to search for, defaults to None
|
|
:param int patch: Patch python version to search for, defaults to None
|
|
:param bool pre: Search for prereleases (default None) - prioritize releases if None
|
|
:param bool dev: Search for devreleases (default None) - prioritize releases if None
|
|
:param str arch: Architecture to include, e.g. '64bit', defaults to None
|
|
:returns: A :class:`~pythonfinder.models.PathEntry` instance matching the version requested.
|
|
"""
|
|
|
|
version_matcher = operator.methodcaller(
|
|
"matches", major=major, minor=minor, patch=patch, pre=pre, dev=dev, arch=arch
|
|
)
|
|
is_py = operator.attrgetter("is_python")
|
|
py_version = operator.attrgetter("as_python")
|
|
if not self.is_dir:
|
|
if self.is_python and version_matcher(self.as_python):
|
|
return self
|
|
return
|
|
finder = ((child, child.as_python) for child in unnest(self.pythons.values()) if child.as_python)
|
|
py_filter = filter(
|
|
None, filter(lambda child: version_matcher(child[1]), finder)
|
|
)
|
|
version_sort = operator.attrgetter("version_sort")
|
|
return next(
|
|
(c[0] for c in sorted(py_filter, key=lambda child: child[1].version_sort, reverse=True)), None
|
|
)
|
|
|
|
|
|
from .path import SystemPath
|
|
from .windows import WindowsFinder
|
|
from .python import PythonVersion
|