support for abitrary pep 508 markers

Signed-off-by: Kenneth Reitz <me@kennethreitz.org>
This commit is contained in:
2017-09-22 17:31:53 -04:00
parent d69d116ca0
commit 26da1a2a74
2 changed files with 58 additions and 40 deletions
+10 -9
View File
@@ -387,6 +387,9 @@ def ensure_python(three=None, python=None):
if not python:
python = project.required_python_version
if not python:
python = PIPENV_DEFAULT_PYTHON_VERSION
if python:
path_to_python = find_a_system_python(python)
@@ -729,6 +732,7 @@ def do_install_dependencies(
block=blocking,
index=index
)
c.dep = dep
procs.append(c)
else:
@@ -825,9 +829,6 @@ def convert_three_to_python(three, python):
)
return 'python3'
# Default to PIPENV_DEFAULT_PYTHON_VERSION, if provided.
return PIPENV_DEFAULT_PYTHON_VERSION
else:
return python
@@ -988,9 +989,9 @@ def do_lock(verbose=False, system=False, clear=False):
if 'index' in dep:
lockfile['develop'][dep['name']]['index'] = dep['index']
# Add Python Version metadata to lockfile.
if 'python_version' in dep:
lockfile['develop'][dep['name']]['python_version'] = dep['python_version']
# Add PEP 508 specifier metadata to lockfile.
if 'markers' in dep:
lockfile['develop'][dep['name']]['markers'] = dep['markers']
# Add refs for VCS installs.
# TODO: be smarter about this.
@@ -1043,9 +1044,9 @@ def do_lock(verbose=False, system=False, clear=False):
if 'index' in dep:
lockfile['default'][dep['name']]['index'] = dep['index']
# Add Python Version metadata to lockfile.
if 'python_version' in dep:
lockfile['default'][dep['name']]['python_version'] = dep['python_version']
# Add PEP 508 specifier metadata to lockfile.
if 'markers' in dep:
lockfile['default'][dep['name']]['markers'] = dep['markers']
# Add refs for VCS installs.
# TODO: be smarter about this.
+48 -31
View File
@@ -27,6 +27,9 @@ from piptools.exceptions import NoCandidateFound
from pip.exceptions import DistributionNotFound
from .environments import PIPENV_DONT_EAT_EDITABLES
from .pep508checker import lookup
specifiers = [k for k in lookup.keys()]
# List of version control systems we support.
VCS_LIST = ('git', 'svn', 'hg', 'bzr')
@@ -277,7 +280,6 @@ def suggest_package(package):
return package
result = fuzzywuzzy.process.extractOne(package, packages)
print(result)
if result[1] > THRESHOLD:
return result[0]
@@ -401,7 +403,7 @@ def resolve_deps(deps, which, which_pip, project, sources=None, verbose=False, p
"""
index_lookup = {}
python_version_lookup = {}
markers_lookup = {}
with HackedPythonVersion(python):
@@ -412,31 +414,36 @@ def resolve_deps(deps, which, which_pip, project, sources=None, verbose=False, p
constraints = []
pinned_constraints = []
extra_constraints = []
for dep in deps:
t = tempfile.mkstemp(prefix='pipenv-', suffix='-requirement.txt')[1]
with open(t, 'w') as f:
f.write(dep)
t = tempfile.mkstemp(prefix='pipenv-', suffix='-requirement.txt')[1]
with open(t, 'w') as f:
f.write(dep)
if dep.startswith('-e '):
constraint = pip.req.InstallRequirement.from_editable(dep[len('-e '):])
# Resolve extra constraints from -e packages (that rely on setuptools.)
extra_constraints = best_matches_from(dep[len('-e '):], which=which, which_pip=which_pip, project=project)
extra_constraints = [pip.req.InstallRequirement.from_line(c) for c in extra_constraints]
else:
constraint = [c for c in pip.req.parse_requirements(t, session=pip._vendor.requests)][0]
extra_constraints = []
if dep.startswith('-e '):
constraint = pip.req.InstallRequirement.from_editable(dep[len('-e '):])
# Resolve extra constraints from -e packages (that rely on setuptools.)
extra_constraints = best_matches_from(dep[len('-e '):], which=which, which_pip=which_pip, project=project)
extra_constraints = [pip.req.InstallRequirement.from_line(c) for c in extra_constraints]
else:
constraint = [c for c in pip.req.parse_requirements(t, session=pip._vendor.requests)][0]
extra_constraints = []
if ' -i ' in dep:
index_lookup[constraint.name] = project.get_source(url=dep.split(' -i ')[1]).get('name')
if 'python_version' in dep:
python_version_lookup[constraint.name] = dep.split(';')[1].strip().split('python_version ')[1]
if '==' not in dep:
constraints.append(constraint)
constraints.extend(extra_constraints)
else:
pinned_constraints.append(constraint)
pinned_constraints.extend(extra_constraints)
if ' -i ' in dep:
index_lookup[constraint.name] = project.get_source(url=dep.split(' -i ')[1]).get('name')
if constraint.markers:
markers_lookup[constraint.name] = str(constraint.markers).replace('"', "'")
# if 'python_version' in dep:
# python_version_lookup[constraint.name] = dep.split(';')[1].strip().split('python_version ')[1]
if '==' not in dep:
constraints.append(constraint)
constraints.extend(extra_constraints)
else:
pinned_constraints.append(constraint)
pinned_constraints.extend(extra_constraints)
pip_command = get_pip_command()
@@ -480,7 +487,7 @@ def resolve_deps(deps, which, which_pip, project, sources=None, verbose=False, p
name = pep423_name(result.name)
version = clean_pkg_version(result.specifier)
index = index_lookup.get(result.name)
python_version = python_version_lookup.get(result.name)
markers = markers_lookup.get(result.name)
collected_hashes = []
if 'python.org' in '|'.join([source['url'] for source in sources]):
@@ -510,8 +517,8 @@ def resolve_deps(deps, which, which_pip, project, sources=None, verbose=False, p
if index:
d.update({'index': index})
if python_version:
d.update({'python_version': python_version})
if markers:
d.update({'markers': markers})
results.append(d)
@@ -621,7 +628,6 @@ def convert_deps_to_pip(deps, project=None, r=True, include_index=False):
extra = deps[dep] if isinstance(deps[dep], six.string_types) else ''
version = ''
index = ''
requires_python = ''
# Get rid of '*'.
if deps[dep] == '*' or str(extra) == '{}':
@@ -644,9 +650,20 @@ def convert_deps_to_pip(deps, project=None, r=True, include_index=False):
if not deps[dep]['version'] == '*':
version = deps[dep]['version']
if 'python_version' in deps[dep]:
if not deps[dep]['python_version'] == '*':
requires_python = '; python_version {0}'.format(deps[dep]['python_version'])
# For lockfile format.
if 'markers' in deps[dep]:
specs = '; {0}'.format(deps[dep]['markers'])
else:
# For pipfile format.
specs = []
for specifier in specifiers:
if specifier in deps[dep]:
if not deps[dep][specifier] == '*':
specs.append('{0} {1}'.format(specifier, deps[dep][specifier]))
if specs:
specs = '; {0}'.format(' and '.join(specs))
else:
specs = ''
if include_index:
if 'index' in deps[dep]:
@@ -697,7 +714,7 @@ def convert_deps_to_pip(deps, project=None, r=True, include_index=False):
else:
dep = ''
dependencies.append('{0}{1}{2}{3}{4} {5}'.format(dep, extra, version, hash, requires_python, index).strip())
dependencies.append('{0}{1}{2}{3}{4} {5}'.format(dep, extra, version, hash, specs, index).strip())
if not r:
return dependencies