mirror of
https://github.com/kennethreitz/pipenv.git
synced 2026-06-05 22:50:18 +00:00
+1
-1
@@ -10,7 +10,7 @@ from .exceptions import InvalidPythonVersion
|
||||
from .models import SystemPath, WindowsFinder
|
||||
from .pythonfinder import Finder
|
||||
|
||||
__version__ = "1.2.1"
|
||||
__version__ = "1.2.2.dev0"
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -15,7 +15,8 @@ import sys
|
||||
# These tags are treated specially when the Company is 'PythonCore'
|
||||
_PYTHONCORE_COMPATIBILITY_TAGS = {
|
||||
'2.0', '2.1', '2.2', '2.3', '2.4', '2.5', '2.6', '2.7',
|
||||
'3.0', '3.1', '3.2', '3.3', '3.4'
|
||||
'3.0', '3.1', '3.2', '3.3', '3.4', '3.5', '3.6', '3.7',
|
||||
'3.8'
|
||||
}
|
||||
|
||||
_IS_64BIT_OS = None
|
||||
|
||||
+2
-2
@@ -14,8 +14,6 @@ from cached_property import cached_property
|
||||
from vistir.compat import Path, fs_str
|
||||
from vistir.misc import dedup
|
||||
|
||||
from .mixins import BaseFinder, BasePath
|
||||
from .python import PythonVersion
|
||||
from ..environment import (
|
||||
ASDF_DATA_DIR,
|
||||
ASDF_INSTALLED,
|
||||
@@ -42,6 +40,8 @@ from ..utils import (
|
||||
split_version_and_name,
|
||||
unnest,
|
||||
)
|
||||
from .mixins import BaseFinder, BasePath
|
||||
from .python import PythonVersion
|
||||
|
||||
if MYPY_RUNNING:
|
||||
from typing import (
|
||||
|
||||
+28
-9
@@ -13,7 +13,6 @@ import six
|
||||
from packaging.version import Version
|
||||
from vistir.compat import Path, lru_cache
|
||||
|
||||
from .mixins import BaseFinder, BasePath
|
||||
from ..environment import ASDF_DATA_DIR, MYPY_RUNNING, PYENV_ROOT, SYSTEM_ARCH
|
||||
from ..exceptions import InvalidPythonVersion
|
||||
from ..utils import (
|
||||
@@ -21,14 +20,17 @@ from ..utils import (
|
||||
_filter_none,
|
||||
ensure_path,
|
||||
get_python_version,
|
||||
guess_company,
|
||||
is_in_path,
|
||||
looks_like_python,
|
||||
optional_instance_of,
|
||||
parse_asdf_version_order,
|
||||
parse_pyenv_version_order,
|
||||
parse_python_version,
|
||||
path_is_pythoncore,
|
||||
unnest,
|
||||
)
|
||||
from .mixins import BaseFinder, BasePath
|
||||
|
||||
if MYPY_RUNNING:
|
||||
from typing import (
|
||||
@@ -114,7 +116,8 @@ class PythonFinder(BaseFinder, BasePath):
|
||||
versions[v] for v in parse_asdf_version_order() if v in versions
|
||||
]
|
||||
for version in version_order:
|
||||
version_paths.remove(version)
|
||||
if version in version_paths:
|
||||
version_paths.remove(version)
|
||||
if version_order:
|
||||
version_order += version_paths
|
||||
else:
|
||||
@@ -351,6 +354,7 @@ class PythonVersion(object):
|
||||
architecture = attr.ib(default=None) # type: Optional[str]
|
||||
comes_from = attr.ib(default=None) # type: Optional[PathEntry]
|
||||
executable = attr.ib(default=None) # type: Optional[str]
|
||||
company = attr.ib(default="PythonCore") # type: Optional[str]
|
||||
name = attr.ib(default=None, type=str)
|
||||
|
||||
def __getattribute__(self, key):
|
||||
@@ -381,11 +385,14 @@ class PythonVersion(object):
|
||||
"""
|
||||
A tuple for sorting against other instances of the same class.
|
||||
|
||||
Returns a tuple of the python version but includes a point for non-dev,
|
||||
and a point for non-prerelease versions. So released versions will have 2 points
|
||||
for this value. E.g. `(3, 6, 6, 2)` is a release, `(3, 6, 6, 1)` is a prerelease,
|
||||
`(3, 6, 6, 0)` is a dev release, and `(3, 6, 6, 3)` is a postrelease.
|
||||
Returns a tuple of the python version but includes points for core python,
|
||||
non-dev, and non-prerelease versions. So released versions will have 2 points
|
||||
for this value. E.g. ``(1, 3, 6, 6, 2)`` is a release, ``(1, 3, 6, 6, 1)`` is a
|
||||
prerelease, ``(1, 3, 6, 6, 0)`` is a dev release, and ``(1, 3, 6, 6, 3)`` is a
|
||||
postrelease. ``(0, 3, 7, 3, 2)`` represents a non-core python release, e.g. by
|
||||
a repackager of python like Continuum.
|
||||
"""
|
||||
company_sort = 1 if self.company == "PythonCore" else 0
|
||||
release_sort = 2
|
||||
if self.is_postrelease:
|
||||
release_sort = 3
|
||||
@@ -395,7 +402,13 @@ class PythonVersion(object):
|
||||
release_sort = 0
|
||||
elif self.is_debug:
|
||||
release_sort = 1
|
||||
return (self.major, self.minor, self.patch if self.patch else 0, release_sort)
|
||||
return (
|
||||
company_sort,
|
||||
self.major,
|
||||
self.minor,
|
||||
self.patch if self.patch else 0,
|
||||
release_sort,
|
||||
)
|
||||
|
||||
@property
|
||||
def version_tuple(self):
|
||||
@@ -473,6 +486,7 @@ class PythonVersion(object):
|
||||
"is_devrelease": self.is_devrelease,
|
||||
"is_debug": self.is_debug,
|
||||
"version": self.version,
|
||||
"company": self.company,
|
||||
}
|
||||
|
||||
def update_metadata(self, metadata):
|
||||
@@ -532,8 +546,8 @@ class PythonVersion(object):
|
||||
return self.architecture
|
||||
|
||||
@classmethod
|
||||
def from_path(cls, path, name=None, ignore_unsupported=True):
|
||||
# type: (Union[str, PathEntry], Optional[str], bool) -> PythonVersion
|
||||
def from_path(cls, path, name=None, ignore_unsupported=True, company=None):
|
||||
# type: (Union[str, PathEntry], Optional[str], bool, Optional[str]) -> PythonVersion
|
||||
"""
|
||||
Parses a python version from a system path.
|
||||
|
||||
@@ -544,6 +558,7 @@ class PythonVersion(object):
|
||||
:type path: str or :class:`~pythonfinder.models.path.PathEntry` instance
|
||||
:param str name: Name of the python distribution in question
|
||||
:param bool ignore_unsupported: Whether to ignore or error on unsupported paths.
|
||||
:param Optional[str] company: The company or vendor packaging the distribution.
|
||||
:return: An instance of a PythonVersion.
|
||||
:rtype: :class:`~pythonfinder.models.python.PythonVersion`
|
||||
"""
|
||||
@@ -576,6 +591,8 @@ class PythonVersion(object):
|
||||
instance_dict = cls.parse_executable(path.path.absolute().as_posix())
|
||||
if name is None:
|
||||
name = path_name
|
||||
if company is None:
|
||||
company = guess_company(path.path.as_posix())
|
||||
instance_dict.update(
|
||||
{"comes_from": path, "name": name, "executable": path.path.as_posix()}
|
||||
)
|
||||
@@ -622,6 +639,7 @@ class PythonVersion(object):
|
||||
exe_path = ensure_path(
|
||||
getattr(launcher_entry.info.install_path, "executable_path", default_path)
|
||||
)
|
||||
company = getattr(launcher_entry, "company", "PythonCore")
|
||||
creation_dict.update(
|
||||
{
|
||||
"architecture": getattr(
|
||||
@@ -629,6 +647,7 @@ class PythonVersion(object):
|
||||
),
|
||||
"executable": exe_path,
|
||||
"name": name,
|
||||
"company": company,
|
||||
}
|
||||
)
|
||||
py_version = cls.create(**creation_dict)
|
||||
|
||||
+7
-4
@@ -6,12 +6,12 @@ from collections import defaultdict
|
||||
|
||||
import attr
|
||||
|
||||
from .mixins import BaseFinder
|
||||
from .path import PathEntry
|
||||
from .python import PythonVersion, VersionMap
|
||||
from ..environment import MYPY_RUNNING
|
||||
from ..exceptions import InvalidPythonVersion
|
||||
from ..utils import ensure_path
|
||||
from .mixins import BaseFinder
|
||||
from .path import PathEntry
|
||||
from .python import PythonVersion, VersionMap
|
||||
|
||||
if MYPY_RUNNING:
|
||||
from typing import DefaultDict, Tuple, List, Optional, Union, TypeVar, Type, Any
|
||||
@@ -81,6 +81,7 @@ class WindowsFinder(BaseFinder):
|
||||
path = None
|
||||
for version_object in env_versions:
|
||||
install_path = getattr(version_object.info, "install_path", None)
|
||||
name = getattr(version_object, "tag", None)
|
||||
if install_path is None:
|
||||
continue
|
||||
try:
|
||||
@@ -88,7 +89,9 @@ class WindowsFinder(BaseFinder):
|
||||
except AttributeError:
|
||||
continue
|
||||
try:
|
||||
py_version = PythonVersion.from_windows_launcher(version_object)
|
||||
py_version = PythonVersion.from_windows_launcher(
|
||||
version_object, name=name
|
||||
)
|
||||
except InvalidPythonVersion:
|
||||
continue
|
||||
if py_version is None:
|
||||
|
||||
Vendored
+34
@@ -239,6 +239,40 @@ def path_is_python(path):
|
||||
return path_is_executable(path) and looks_like_python(path.name)
|
||||
|
||||
|
||||
@lru_cache(maxsize=1024)
|
||||
def guess_company(path):
|
||||
# type: (str) -> Optional[str]
|
||||
"""Given a path to python, guess the company who created it
|
||||
|
||||
:param str path: The path to guess about
|
||||
:return: The guessed company
|
||||
:rtype: Optional[str]
|
||||
"""
|
||||
non_core_pythons = [impl for impl in PYTHON_IMPLEMENTATIONS if impl != "python"]
|
||||
return next(
|
||||
iter(impl for impl in non_core_pythons if impl in path.lower()), "PythonCore"
|
||||
)
|
||||
|
||||
|
||||
@lru_cache(maxsize=1024)
|
||||
def path_is_pythoncore(path):
|
||||
# type: (str) -> bool
|
||||
"""Given a path, determine whether it appears to be pythoncore.
|
||||
|
||||
Does not verify whether the path is in fact a path to python, but simply
|
||||
does an exclusionary check on the possible known python implementations
|
||||
to see if their names are present in the path (fairly dumb check).
|
||||
|
||||
:param str path: The path to check
|
||||
:return: Whether that path is a PythonCore path or not
|
||||
:rtype: bool
|
||||
"""
|
||||
company = guess_company(path)
|
||||
if company:
|
||||
return company == "PythonCore"
|
||||
return False
|
||||
|
||||
|
||||
@lru_cache(maxsize=1024)
|
||||
def ensure_path(path):
|
||||
# type: (Union[vistir.compat.Path, str]) -> vistir.compat.Path
|
||||
|
||||
Reference in New Issue
Block a user