mirror of
https://github.com/kennethreitz/pipenv.git
synced 2026-06-05 22:50:18 +00:00
+1
-1
@@ -1,5 +1,5 @@
|
||||
# -*- coding=utf-8 -*-
|
||||
__version__ = "1.0.1"
|
||||
__version__ = "1.0.5.dev0"
|
||||
|
||||
|
||||
from .exceptions import RequirementError
|
||||
|
||||
+4
-3
@@ -9,8 +9,8 @@ from .._compat import Path, FileNotFoundError
|
||||
|
||||
@attr.s
|
||||
class Lockfile(object):
|
||||
dev_requirements = attr.ib(default=list)
|
||||
requirements = attr.ib(default=list)
|
||||
dev_requirements = attr.ib(default=attr.Factory(list))
|
||||
requirements = attr.ib(default=attr.Factory(list))
|
||||
path = attr.ib(default=None, validator=optional_instance_of(Path))
|
||||
pipfile_hash = attr.ib(default=None)
|
||||
|
||||
@@ -31,7 +31,8 @@ class Lockfile(object):
|
||||
if not lockfile_path.exists():
|
||||
raise FileNotFoundError("No such lockfile: %s" % lockfile_path)
|
||||
|
||||
lockfile = json.loads(lockfile_path.read_text(encoding="utf-8"))
|
||||
with lockfile_path.open(encoding="utf-8") as f:
|
||||
lockfile = json.loads(f.read())
|
||||
for k in lockfile["develop"].keys():
|
||||
dev_requirements.append(Requirement.from_pipfile(k, lockfile["develop"][k]))
|
||||
for k in lockfile["default"].keys():
|
||||
|
||||
+8
-5
@@ -324,7 +324,7 @@ class FileRequirement(BaseRequirement):
|
||||
vcs_type, prefer, relpath, path, uri, link = cls.get_link_from_line(line)
|
||||
setup_path = Path(path) / "setup.py" if path else None
|
||||
arg_dict = {
|
||||
"path": relpath or path,
|
||||
"path": relpath if relpath else path,
|
||||
"uri": unquote(link.url_without_fragment),
|
||||
"link": link,
|
||||
"editable": editable,
|
||||
@@ -347,6 +347,11 @@ class FileRequirement(BaseRequirement):
|
||||
uri = pipfile.get("uri")
|
||||
fil = pipfile.get("file")
|
||||
path = pipfile.get("path")
|
||||
if path:
|
||||
if isinstance(path, Path) and not path.is_absolute():
|
||||
path = get_converted_relative_path(path.as_posix())
|
||||
elif not os.path.isabs(path):
|
||||
path = get_converted_relative_path(path)
|
||||
if path and uri:
|
||||
raise ValueError("do not specify both 'path' and 'uri'")
|
||||
if path and fil:
|
||||
@@ -387,7 +392,7 @@ class FileRequirement(BaseRequirement):
|
||||
):
|
||||
seed = unquote(self.link.url_without_fragment) or self.uri
|
||||
else:
|
||||
seed = self.formatted_path or self.link.url or self.uri
|
||||
seed = self.formatted_path or unquote(self.link.url_without_fragment) or self.uri
|
||||
# add egg fragments to remote artifacts (valid urls only)
|
||||
if not self._has_hashed_name and self.is_remote_artifact:
|
||||
seed += "#egg={0}".format(self.name)
|
||||
@@ -789,9 +794,7 @@ class Requirement(object):
|
||||
|
||||
@property
|
||||
def constraint_line(self):
|
||||
if self.is_named or self.is_vcs:
|
||||
return self.as_line()
|
||||
return self.req.req.line
|
||||
return self.as_line()
|
||||
|
||||
def as_pipfile(self):
|
||||
good_keys = (
|
||||
|
||||
+1
-1
@@ -84,7 +84,7 @@ def strip_ssh_from_git_uri(uri):
|
||||
|
||||
|
||||
def add_ssh_scheme_to_git_uri(uri):
|
||||
"""Cleans VCS uris from pipenv.patched.notpip format"""
|
||||
"""Cleans VCS uris from pip format"""
|
||||
if isinstance(uri, six.string_types):
|
||||
# Add scheme for parsing purposes, this is also what pip does
|
||||
if uri.startswith("git+") and "://" not in uri:
|
||||
|
||||
+5
-2
@@ -69,8 +69,11 @@ def get_converted_relative_path(path, relative_to=os.curdir):
|
||||
path = start.joinpath(".", path).relative_to(start)
|
||||
# Normalize these to use forward slashes even on windows
|
||||
if os.name == "nt":
|
||||
return os.altsep.join([".", path.as_posix()])
|
||||
return os.sep.join([".", path.as_posix()])
|
||||
relpath = os.altsep.join([".", path.as_posix()])
|
||||
relpath = os.sep.join([".", path.as_posix()])
|
||||
if relpath in ['./.', '.\\.']:
|
||||
relpath = '.'
|
||||
return relpath
|
||||
|
||||
|
||||
def multi_split(s, split):
|
||||
|
||||
Vendored
+1
-1
@@ -27,7 +27,7 @@ requests==2.19.1
|
||||
idna==2.7
|
||||
urllib3==1.23
|
||||
certifi==2018.4.16
|
||||
requirementslib==1.0.1
|
||||
requirementslib==1.0.4
|
||||
attrs==18.1.0
|
||||
distlib==0.2.7
|
||||
packaging==17.1
|
||||
|
||||
@@ -2,7 +2,13 @@ import contextlib
|
||||
import os
|
||||
|
||||
from pipenv.utils import temp_environ
|
||||
from pipenv._compat import TemporaryDirectory
|
||||
from pipenv.vendor import delegator
|
||||
from pipenv.project import Project
|
||||
try:
|
||||
from pathlib import Path
|
||||
except ImportError:
|
||||
from pipenv.vendor.pathlib2 import Path
|
||||
|
||||
import pytest
|
||||
|
||||
@@ -267,6 +273,31 @@ def test_requirements_to_pipfile(PipenvInstance, pypi):
|
||||
assert 'pysocks' in p.lockfile['default']
|
||||
|
||||
|
||||
@pytest.mark.install
|
||||
@pytest.mark.requirements
|
||||
def test_skip_requirements_when_pipfile(PipenvInstance, pypi):
|
||||
|
||||
with PipenvInstance(chdir=True, pypi=pypi) as p:
|
||||
with open('requirements.txt', 'w') as f:
|
||||
f.write('requests==2.18.1\n')
|
||||
c = p.pipenv('install six')
|
||||
assert c.return_code == 0
|
||||
with open(p.pipfile_path, 'w') as f:
|
||||
contents = """
|
||||
[packages]
|
||||
six = "*"
|
||||
tablib = "<0.12"
|
||||
""".strip()
|
||||
f.write(contents)
|
||||
c = p.pipenv('install')
|
||||
assert 'tablib' in p.pipfile['packages']
|
||||
assert 'tablib' in p.lockfile['default']
|
||||
assert 'six' in p.pipfile['packages']
|
||||
assert 'six' in p.lockfile['default']
|
||||
assert 'requests' not in p.pipfile['packages']
|
||||
assert 'requests' not in p.lockfile['default']
|
||||
|
||||
|
||||
@pytest.mark.cli
|
||||
@pytest.mark.clean
|
||||
def test_clean_on_empty_venv(PipenvInstance, pypi):
|
||||
@@ -277,6 +308,9 @@ def test_clean_on_empty_venv(PipenvInstance, pypi):
|
||||
|
||||
@pytest.mark.install
|
||||
def test_install_does_not_extrapolate_environ(PipenvInstance, pypi):
|
||||
"""This test is deisgned to make sure that pipenv ignores requirements.txt files
|
||||
for projects that already exist (already have a Pipfile) as well as for times when a
|
||||
package name is passed in to the install command."""
|
||||
with temp_environ(), PipenvInstance(pypi=pypi, chdir=True) as p:
|
||||
os.environ['PYPI_URL'] = pypi.url
|
||||
|
||||
@@ -309,3 +343,42 @@ def test_editable_no_args(PipenvInstance):
|
||||
c = p.pipenv('install -e')
|
||||
assert c.return_code != 0
|
||||
assert 'Please provide path to editable package' in c.err
|
||||
|
||||
|
||||
@pytest.mark.install
|
||||
@pytest.mark.virtualenv
|
||||
def test_install_venv_project_directory(PipenvInstance, pypi):
|
||||
"""Test pew's project functionality during virtualenv creation. Since .venv
|
||||
virtualenvs are not created with pew, we need to swap to a workon_home based
|
||||
virtualenv for this test"""
|
||||
with PipenvInstance(pypi=pypi, chdir=True) as p:
|
||||
with temp_environ(), TemporaryDirectory(prefix='pipenv-', suffix='temp_workon_home') as workon_home:
|
||||
os.environ['WORKON_HOME'] = workon_home.name
|
||||
if 'PIPENV_VENV_IN_PROJECT' in os.environ:
|
||||
del os.environ['PIPENV_VENV_IN_PROJECT']
|
||||
c = p.pipenv('install six')
|
||||
assert c.return_code == 0
|
||||
project = Project()
|
||||
assert Path(project.virtualenv_location).joinpath('.project').exists()
|
||||
|
||||
|
||||
@pytest.mark.deploy
|
||||
@pytest.mark.system
|
||||
def test_system_and_deploy_work(PipenvInstance, pypi):
|
||||
with PipenvInstance(chdir=True, pypi=pypi) as p:
|
||||
c = p.pipenv('install six requests')
|
||||
assert c.return_code == 0
|
||||
c = p.pipenv('--rm')
|
||||
assert c.return_code == 0
|
||||
c = delegator.run('virtualenv .venv')
|
||||
assert c.return_code == 0
|
||||
c = p.pipenv('install --system --deploy')
|
||||
assert c.return_code == 0
|
||||
c = p.pipenv('--rm')
|
||||
assert c.return_code == 0
|
||||
Path(p.pipfile_path).write_text(u"""
|
||||
[packages]
|
||||
requests
|
||||
""".strip())
|
||||
c = p.pipenv('install --system')
|
||||
assert c.return_code == 0
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import os
|
||||
import shutil
|
||||
|
||||
from pipenv.project import Project
|
||||
try:
|
||||
import pathlib
|
||||
except ImportError:
|
||||
@@ -16,36 +16,48 @@ from flaky import flaky
|
||||
@pytest.mark.extras
|
||||
@pytest.mark.install
|
||||
@pytest.mark.local
|
||||
@pytest.mark.skip(reason="I'm not mocking this.")
|
||||
def test_local_extras_install(PipenvInstance, pypi):
|
||||
with PipenvInstance(pypi=pypi) as p:
|
||||
@pytest.mark.parametrize('line, pipfile', [
|
||||
['-e .[dev]', {'testpipenv': {'path': '.', 'editable': True, 'extras': ['dev']}}]
|
||||
])
|
||||
def test_local_extras_install(PipenvInstance, pypi, line, pipfile):
|
||||
"""Test -e .[extras] installs... note that the extras themselves
|
||||
are currently not landing in the lockfile for reasons that are unclear.
|
||||
"""
|
||||
with PipenvInstance(pypi=pypi, chdir=True) as p:
|
||||
project = Project()
|
||||
setup_py = os.path.join(p.path, 'setup.py')
|
||||
with open(setup_py, 'w') as fh:
|
||||
contents = """
|
||||
from setuptools import setup, find_packages
|
||||
|
||||
setup(
|
||||
name='test_pipenv',
|
||||
name='testpipenv',
|
||||
version='0.1',
|
||||
description='Pipenv Test Package',
|
||||
author='Pipenv Test',
|
||||
author_email='test@pipenv.package',
|
||||
license='PIPENV',
|
||||
license='MIT',
|
||||
packages=find_packages(),
|
||||
install_requires=['tablib'],
|
||||
extras_require={'dev': ['flake8', 'pylint']},
|
||||
install_requires=[],
|
||||
extras_require={'dev': ['six']},
|
||||
zip_safe=False
|
||||
)
|
||||
""".strip()
|
||||
fh.write(contents)
|
||||
c = p.pipenv('install .[dev]')
|
||||
project.write_toml({'packages': pipfile, 'dev-packages': {}})
|
||||
c = p.pipenv('install')
|
||||
assert c.return_code == 0
|
||||
key = [k for k in p.pipfile['packages'].keys()][0]
|
||||
dep = p.pipfile['packages'][key]
|
||||
assert dep['path'] == '.'
|
||||
assert dep['extras'] == ['dev']
|
||||
assert key in p.lockfile['default']
|
||||
assert 'dev' in p.lockfile['default'][key]['extras']
|
||||
assert 'testpipenv' in p.lockfile['default']
|
||||
assert p.lockfile['default']['testpipenv']['extras'] == ['dev']
|
||||
assert 'six' in p.lockfile['default']
|
||||
c = p.pipenv('--rm')
|
||||
assert c.return_code == 0
|
||||
project.write_toml({'packages': {}, 'dev-packages': {}})
|
||||
c = p.pipenv('install {0}'.format(line))
|
||||
assert c.return_code == 0
|
||||
assert 'testpipenv' in p.pipfile['packages']
|
||||
assert p.pipfile['packages']['testpipenv']['path'] == '.'
|
||||
assert p.pipfile['packages']['testpipenv']['extras'] == ['dev']
|
||||
assert 'six' in p.lockfile['default']
|
||||
|
||||
|
||||
@pytest.mark.e
|
||||
@@ -230,3 +242,25 @@ def test_install_local_file_collision(PipenvInstance, pypi):
|
||||
assert target_package in p.pipfile['packages']
|
||||
assert p.pipfile['packages'][target_package] == '*'
|
||||
assert target_package in p.lockfile['default']
|
||||
|
||||
|
||||
@pytest.mark.url
|
||||
@pytest.mark.install
|
||||
def test_install_local_uri_special_character(PipenvInstance, testsroot):
|
||||
file_name = 'six-1.11.0+mkl-py2.py3-none-any.whl'
|
||||
source_path = os.path.abspath(os.path.join(testsroot, 'test_artifacts', file_name))
|
||||
with PipenvInstance() as p:
|
||||
artifact_dir = 'artifacts'
|
||||
artifact_path = os.path.join(p.path, artifact_dir)
|
||||
mkdir_p(artifact_path)
|
||||
shutil.copy(source_path, os.path.join(artifact_path, file_name))
|
||||
with open(p.pipfile_path, 'w') as f:
|
||||
contents = """
|
||||
# Pre comment
|
||||
[packages]
|
||||
six = {{path = "./artifacts/{}"}}
|
||||
""".format(file_name)
|
||||
f.write(contents.strip())
|
||||
c = p.pipenv('install')
|
||||
assert c.return_code == 0
|
||||
assert 'six' in p.lockfile['default']
|
||||
|
||||
@@ -307,12 +307,11 @@ requests = "==2.14.0"
|
||||
""".strip().format(url=pypi.url)
|
||||
f.write(contents)
|
||||
|
||||
os.environ['MY_ENV_VAR'] = 'simple'
|
||||
c = p.pipenv('lock')
|
||||
assert c.return_code == 0
|
||||
assert 'requests' in p.lockfile['default']
|
||||
|
||||
del os.environ['MY_ENV_VAR']
|
||||
with temp_environ():
|
||||
os.environ['MY_ENV_VAR'] = 'simple'
|
||||
c = p.pipenv('lock')
|
||||
assert c.return_code == 0
|
||||
assert 'requests' in p.lockfile['default']
|
||||
|
||||
with open(p.pipfile_path, 'w') as f:
|
||||
contents = """
|
||||
@@ -328,3 +327,21 @@ requests = "==2.14.0"
|
||||
assert c.return_code == 0
|
||||
assert 'requests' in p.lockfile['default']
|
||||
|
||||
|
||||
@pytest.mark.lock
|
||||
@pytest.mark.vcs
|
||||
@pytest.mark.needs_internet
|
||||
def lock_editable_vcs_without_install(PipenvInstance, pypi):
|
||||
with PipenvInstance(pypi=pypi, chdir=True) as p:
|
||||
with open(p.pipfile_path, 'w') as f:
|
||||
f.write("""
|
||||
[packages]
|
||||
requests = {git = "https://github.com/requests/requests.git", ref = "master", editable = true}
|
||||
""".strip())
|
||||
c = p.pipenv('lock')
|
||||
assert c.return_code == 0
|
||||
assert 'requests' in p.lockfile['default']
|
||||
assert 'idna' in p.lockfile['default']
|
||||
assert 'chardet' in p.lockfile['default']
|
||||
c = p.pipenv('install')
|
||||
assert c.return_code == 0
|
||||
|
||||
@@ -5,8 +5,7 @@ XXX: Try our best to reduce tests in this file.
|
||||
|
||||
from pipenv.core import activate_virtualenv
|
||||
from pipenv.project import Project
|
||||
|
||||
|
||||
from pipenv.vendor import delegator
|
||||
import pytest
|
||||
|
||||
|
||||
@@ -83,3 +82,13 @@ def test_update_locks(PipenvInstance, pypi):
|
||||
assert c.return_code == 0
|
||||
lines = c.out.splitlines()
|
||||
assert 'requests==2.19.1' in [l.strip() for l in lines]
|
||||
|
||||
|
||||
@pytest.mark.project
|
||||
@pytest.mark.proper_names
|
||||
def test_proper_names_unamanged_virtualenv(PipenvInstance, pypi):
|
||||
with PipenvInstance(chdir=True, pypi=pypi) as p:
|
||||
c = delegator.run('python -m virtualenv .venv')
|
||||
assert c.return_code == 0
|
||||
project = Project()
|
||||
assert project.proper_names == []
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user