Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update requirementslib and pythonfinder #3254

Merged
merged 8 commits into from
Nov 19, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions news/3254.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Updated ``requirementslib`` and ``pythonfinder`` for multiple bugfixes.
2 changes: 1 addition & 1 deletion pipenv/vendor/pythonfinder/environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
PYENV_INSTALLED = bool(os.environ.get("PYENV_SHELL")) or bool(
os.environ.get("PYENV_ROOT")
)
ASDF_INSTALLED = bool(os.environ.get("ASDF_DATA_DIR"))
ASDF_INSTALLED = bool(os.environ.get("ASDF_DIR"))
PYENV_ROOT = os.path.expanduser(
os.path.expandvars(os.environ.get("PYENV_ROOT", "~/.pyenv"))
)
Expand Down
11 changes: 9 additions & 2 deletions pipenv/vendor/pythonfinder/models/path.py
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,14 @@ def _gen_children(self):
for child in self._filter_children():
if any(shim in normalize_path(str(child)) for shim in SHIM_PATHS):
continue
yield (child.as_posix(), PathEntry.create(path=child, **pass_args))
if self.only_python:
try:
entry = PathEntry.create(path=child, **pass_args)
except (InvalidPythonVersion, ValueError):
continue
else:
entry = PathEntry.create(path=child, **pass_args)
yield (child.as_posix(), entry)
return

@cached_property
Expand All @@ -508,7 +515,7 @@ def get_py_version(self):
if self.is_python:
try:
py_version = PythonVersion.from_path(path=self, name=self.name)
except InvalidPythonVersion:
except (InvalidPythonVersion, ValueError):
py_version = None
except Exception:
if not IGNORE_UNSUPPORTED:
Expand Down
38 changes: 26 additions & 12 deletions pipenv/vendor/pythonfinder/models/python.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
is_in_path,
parse_pyenv_version_order,
parse_asdf_version_order,
parse_python_version,
)

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -361,19 +362,32 @@ def parse(cls, version):
try:
version = parse_version(str(version))
except TypeError:
raise ValueError("Unable to parse version: %s" % version)
if not version or not version.release:
raise ValueError("Not a valid python version: %r" % version)
return
if len(version.release) >= 3:
major, minor, patch = version.release[:3]
elif len(version.release) == 2:
major, minor = version.release
patch = None
try:
version_dict = parse_python_version(str(version))
except Exception:
raise ValueError("Unable to parse version: %s" % version)
else:
if not version_dict:
raise ValueError("Not a valid python version: %r" % version)
major = int(version_dict.get("major"))
minor = int(version_dict.get("minor"))
patch = version_dict.get("patch")
if patch:
patch = int(patch)
version = ".".join([v for v in [major, minor, patch] if v is not None])
version = parse_version(version)
else:
major = version.release[0]
minor = None
patch = None
if not version or not version.release:
raise ValueError("Not a valid python version: %r" % version)
if len(version.release) >= 3:
major, minor, patch = version.release[:3]
elif len(version.release) == 2:
major, minor = version.release
patch = None
else:
major = version.release[0]
minor = None
patch = None
return {
"major": major,
"minor": minor,
Expand Down
18 changes: 16 additions & 2 deletions pipenv/vendor/pythonfinder/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import attr
import io
import re
import six

import vistir
Expand All @@ -24,6 +25,9 @@
from backports.functools_lru_cache import lru_cache


version_re = re.compile(r"(?P<major>[0-9]+)\.(?P<minor>[0-9]+)\.?(?P<patch>(?<=\.)[0-9]+)")


PYTHON_IMPLEMENTATIONS = (
"python", "ironpython", "jython", "pypy", "anaconda", "miniconda",
"stackless", "activepython", "micropython"
Expand All @@ -46,20 +50,28 @@
)


@lru_cache(maxsize=128)
@lru_cache(maxsize=1024)
def get_python_version(path):
"""Get python version string using subprocess from a given path."""
version_cmd = [path, "-c", "import sys; print(sys.version.split()[0])"]
try:
c = vistir.misc.run(version_cmd, block=True, nospin=True, return_object=True,
combine_stderr=False)
combine_stderr=False, write_to_stdout=False)
except OSError:
raise InvalidPythonVersion("%s is not a valid python path" % path)
if not c.out:
raise InvalidPythonVersion("%s is not a valid python path" % path)
return c.out.strip()


@lru_cache(maxsize=1024)
def parse_python_version(version_str):
m = version_re.match(version_str)
if not m:
raise InvalidPythonVersion("%s is not a python version" % version_str)
return m.groupdict()


def optional_instance_of(cls):
return attr.validators.optional(attr.validators.instance_of(cls))

Expand Down Expand Up @@ -151,6 +163,7 @@ def parse_pyenv_version_order(filename="version"):
contents = fh.read()
version_order = [v for v in contents.splitlines()]
return version_order
return []


def parse_asdf_version_order(filename=".tool-versions"):
Expand All @@ -165,6 +178,7 @@ def parse_asdf_version_order(filename=".tool-versions"):
python_key, _, versions = python_section.partition(" ")
if versions:
return versions.split()
return []


# TODO: Reimplement in vistir
Expand Down
17 changes: 11 additions & 6 deletions pipenv/vendor/requirementslib/models/lockfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,15 +160,20 @@ def load_projectfile(cls, path, create=True, data=None):
path = os.curdir
path = Path(path).absolute()
project_path = path if path.is_dir() else path.parent
lockfile_path = project_path / "Pipfile.lock"
lockfile_path = path if path.is_file() else project_path / "Pipfile.lock"
if not project_path.exists():
raise OSError("Project does not exist: %s" % project_path.as_posix())
elif not lockfile_path.exists() and not create:
raise FileNotFoundError("Lockfile does not exist: %s" % lockfile_path.as_posix())
projectfile = cls.read_projectfile(lockfile_path.as_posix())
if not lockfile_path.exists():
if not data:
lf = cls.lockfile_from_pipfile(project_path.joinpath("Pipfile"))
path_str = lockfile_path.as_posix()
if path_str[-5:] == ".lock":
pipfile = Path(path_str[:-5])
else:
pipfile = project_path.joinpath("Pipfile")
lf = cls.lockfile_from_pipfile(pipfile)
else:
lf = plette.lockfiles.Lockfile(data)
projectfile.model = lf
Expand Down Expand Up @@ -212,7 +217,7 @@ def from_data(cls, path, data, meta_from_project=True):
def load(cls, path, create=True):
"""Create a new lockfile instance.

:param project_path: Path to project root
:param project_path: Path to project root or lockfile
:type project_path: str or :class:`pathlib.Path`
:param str lockfile_name: Name of the lockfile in the project root directory
:param pipfile_path: Path to the project pipfile
Expand All @@ -225,9 +230,9 @@ def load(cls, path, create=True):
projectfile = cls.load_projectfile(path, create=create)
except JSONDecodeError:
path = os.path.abspath(path)
if not os.path.isdir(path):
path = os.path.dirname(path)
path = Path(os.path.join(path, "Pipfile.lock"))
path = Path(
os.path.join(path, "Pipfile.lock") if os.path.isdir(path) else path
)
formatted_path = path.as_posix()
backup_path = "%s.bak" % formatted_path
LockfileCorruptException.show(formatted_path, backup_path=backup_path)
Expand Down
2 changes: 1 addition & 1 deletion pipenv/vendor/requirementslib/models/pipfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ def load_projectfile(cls, path, create=False):
raise RuntimeError("Must pass a path to classmethod 'Pipfile.load'")
if not isinstance(path, Path):
path = Path(path).absolute()
pipfile_path = path if path.name == "Pipfile" else path.joinpath("Pipfile")
pipfile_path = path if path.is_file() else path.joinpath("Pipfile")
project_path = pipfile_path.parent
if not project_path.exists():
raise FileNotFoundError("%s is not a valid project path!" % path)
Expand Down
11 changes: 6 additions & 5 deletions pipenv/vendor/requirementslib/models/setup_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ def iter_egginfos(path, pkg_name=None):
if not entry.name.endswith("egg-info"):
for dir_entry in iter_egginfos(entry.path, pkg_name=pkg_name):
yield dir_entry
elif pkg_name is None or entry.name.startswith(pkg_name):
elif pkg_name is None or entry.name.startswith(pkg_name.replace("-", "_")):
yield entry


Expand Down Expand Up @@ -223,16 +223,16 @@ def run_setup(self):
if self.setup_py is not None and self.setup_py.exists():
target_cwd = self.setup_py.parent.as_posix()
with cd(target_cwd), _suppress_distutils_logs():
# This is for you, Hynek
# see https://github.com/hynek/environ_config/blob/69b1c8a/setup.py
script_name = self.setup_py.as_posix()
args = ["egg_info", "--egg-base", self.base_dir]
args = ["egg_info"]
g = {"__file__": script_name, "__name__": "__main__"}
local_dict = {}
if sys.version_info < (3, 5):
save_argv = sys.argv
else:
save_argv = sys.argv.copy()
# This is for you, Hynek
# see https://github.com/hynek/environ_config/blob/69b1c8a/setup.py
try:
global _setup_distribution, _setup_stop_after
_setup_stop_after = "run"
Expand All @@ -247,7 +247,8 @@ def run_setup(self):
except NameError:
python = os.environ.get('PIP_PYTHON_PATH', sys.executable)
out, _ = run([python, "setup.py"] + args, cwd=target_cwd, block=True,
combine_stderr=False, return_object=False, nospin=True)
combine_stderr=False, return_object=False, nospin=True,
write_to_stdout=False)
finally:
_setup_stop_after = None
sys.argv = save_argv
Expand Down
3 changes: 1 addition & 2 deletions pipenv/vendor/vistir/misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,6 @@ def _spawn_subprocess(script, env=None, block=True, cwd=None, combine_stderr=Tru
return subprocess.Popen(script.cmdify(), **options)



def _create_subprocess(
cmd,
env=None,
Expand All @@ -153,7 +152,7 @@ def _create_subprocess(
write_to_stdout=True
):
if not env:
env = {}
env = os.environ.copy()
try:
c = _spawn_subprocess(cmd, env=env, block=block, cwd=cwd,
combine_stderr=combine_stderr)
Expand Down