Skip to content

Commit

Permalink
Fix parsing of markers in VCS requirements
Browse files Browse the repository at this point in the history
- Parsing of markers in non-editable vcs requirements was broken
- This PR adds some VCS repos, some utility pipfile generation functions
  and some fixture helpers
- Fixes #3249

Signed-off-by: Dan Ryan <dan@danryan.co>
  • Loading branch information
techalchemy committed Nov 19, 2018
1 parent 17c93eb commit 45e9f6e
Show file tree
Hide file tree
Showing 13 changed files with 83 additions and 5 deletions.
15 changes: 15 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[submodule "tests/test_artifacts/git/six-1.9.0"]
path = tests/test_artifacts/git/six-1.9.0
url = https://github.com/benjaminp/six.git
[submodule "tests/test_artifacts/git/pinax"]
path = tests/test_artifacts/git/pinax
url = https://github.com/pinax/pinax.git
[submodule "tests/test_artifacts/git/requests"]
path = tests/test_artifacts/git/requests
url = https://github.com/requests/requests.git
[submodule "tests/test_artifacts/git/six"]
path = tests/test_artifacts/git/six
url = https://github.com/benjaminp/six.git
[submodule "tests/test_artifacts/git/dateutil"]
path = tests/test_artifacts/git/dateutil
url = https://github.com/dateutil/dateutil
1 change: 1 addition & 0 deletions news/3249.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Adding normal pep 508 compatible markers is now fully functional when using VCS dependencies.
1 change: 0 additions & 1 deletion pipenv/cli/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,6 @@ def uninstall(
if retcode:
sys.exit(retcode)


@cli.command(short_help="Generates Pipfile.lock.")
@lock_options
@pass_state
Expand Down
6 changes: 5 additions & 1 deletion pipenv/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -1361,7 +1361,11 @@ def pip_install(
ignore_hashes = True
else:
ignore_hashes = True if not requirement.hashes else False
install_reqs = [escape_cmd(r) for r in requirement.as_line(as_list=True)]
install_reqs = requirement.as_line(as_list=True)
if not requirement.markers:
install_reqs = [escape_cmd(r) for r in install_reqs]
elif len(install_reqs) > 1:
install_reqs = install_reqs[0] + [escape_cmd(r) for r in install_reqs[1:]]
pip_command = [which_pip(allow_global=allow_global), "install"]
if pre:
pip_command.append("--pre")
Expand Down
2 changes: 1 addition & 1 deletion pytest.ini
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
addopts = -ra -n auto
testpaths = tests
; Add vendor and patched in addition to the default list of ignored dirs
norecursedirs = .* build dist CVS _darcs {arch} *.egg vendor patched news tasks docs
norecursedirs = .* build dist CVS _darcs {arch} *.egg vendor patched news tasks docs tests/test_artifacts
filterwarnings =
ignore::DeprecationWarning
ignore::PendingDeprecationWarning
Empty file added tests/conftest.py
Empty file.
44 changes: 42 additions & 2 deletions tests/integration/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from pipenv.vendor import delegator
from pipenv.vendor import requests
from pipenv.vendor import toml
from pipenv.vendor import tomlkit
from pytest_pypi.app import prepare_packages as prepare_pypi_packages
from vistir.compat import ResourceWarning, fs_str
from vistir.path import mkdir_p
Expand Down Expand Up @@ -119,6 +120,44 @@ def isolate(pathlib_tmpdir):
WE_HAVE_GITHUB_SSH_KEYS = check_github_ssh()


class _Pipfile(object):
def __init__(self, path):
self.path = path
self.document = tomlkit.document()
self.document["sources"] = tomlkit.aot()
self.document["requires"] = tomlkit.table()
self.document["packages"] = tomlkit.table()
self.document["dev_packages"] = tomlkit.table()

def install(self, package, value, dev=False):
section = "packages" if not dev else "dev_packages"
if isinstance(value, dict):
table = tomlkit.inline_table()
table.update(value)
self.document[section][package] = table
else:
self.document[section][package] = value
self.write()

def loads(self):
self.document = tomlkit.loads(self.path.read_text())

def dumps(self):
source_table = tomlkit.table()
source_table["url"] = os.environ.get("PIPENV_TEST_INDEX")
source_table["verify_ssl"] = False
source_table["name"] = "pipenv_test_index"
self.document["sources"].append(source_table)
return tomlkit.dumps(self.document)

def write(self):
self.path.write_text(self.dumps())

@classmethod
def get_fixture_path(cls, path):
return Path(__file__).absolute().parent.parent / "test_artifacts" / path


class _PipenvInstance(object):
"""An instance of a Pipenv Project..."""
def __init__(self, pypi=None, pipfile=True, chdir=False, path=None, home_dir=None):
Expand All @@ -129,7 +168,7 @@ def __init__(self, pypi=None, pipfile=True, chdir=False, path=None, home_dir=Non
os.environ["CI"] = fs_str("1")
warnings.simplefilter("ignore", category=ResourceWarning)
warnings.filterwarnings("ignore", category=ResourceWarning, message="unclosed.*<ssl.SSLSocket.*>")
path = os.environ.get("PIPENV_PROJECT_DIR", None)
path = path if path else os.environ.get("PIPENV_PROJECT_DIR", None)
if not path:
self._path = TemporaryDirectory(suffix='-project', prefix='pipenv-')
path = Path(self._path.name)
Expand All @@ -138,7 +177,7 @@ def __init__(self, pypi=None, pipfile=True, chdir=False, path=None, home_dir=Non
except OSError:
self.path = str(path.absolute())
else:
self._path = None
self._path = path
self.path = path
# set file creation perms
self.pipfile_path = None
Expand All @@ -154,6 +193,7 @@ def __init__(self, pypi=None, pipfile=True, chdir=False, path=None, home_dir=Non

self.chdir = False or chdir
self.pipfile_path = p_path
self._pipfile = _Pipfile(Path(p_path))

def __enter__(self):
os.environ['PIPENV_DONT_USE_PYENV'] = fs_str('1')
Expand Down
14 changes: 14 additions & 0 deletions tests/integration/test_install_uri.py
Original file line number Diff line number Diff line change
Expand Up @@ -270,3 +270,17 @@ def test_vcs_entry_supersedes_non_vcs(PipenvInstance, pip_src_dir):
p.lockfile["default"]["pyinstaller"]["git"]
== "https://github.com/pyinstaller/pyinstaller.git"
)


@pytest.mark.vcs
@pytest.mark.install
@pytest.mark.needs_internet
def test_vcs_can_use_markers(PipenvInstance, pip_src_dir, pypi):
with PipenvInstance(chdir=True, pypi=pypi) as p:
path = p._pipfile.get_fixture_path("git/six/.git")
p._pipfile.install("six", {"git": "{0}".format(path.as_uri()), "markers": "sys_platform == 'linux'"})
assert "six" in p.pipfile["packages"]
c = p.pipenv("install")
assert c.return_code == 0
assert "six" in p.lockfile["default"]
assert "git" in p.lockfile["default"]["six"]
1 change: 1 addition & 0 deletions tests/test_artifacts/git/dateutil
Submodule dateutil added at 6618de
1 change: 1 addition & 0 deletions tests/test_artifacts/git/pinax
Submodule pinax added at 147d85
1 change: 1 addition & 0 deletions tests/test_artifacts/git/requests
Submodule requests added at 57d728
1 change: 1 addition & 0 deletions tests/test_artifacts/git/six
Submodule six added at e114ef
1 change: 1 addition & 0 deletions tests/test_artifacts/git/six-1.9.0
Submodule six-1.9.0 added at 5efb52

0 comments on commit 45e9f6e

Please sign in to comment.