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

Fix race condition when installing 2+ editable non-VCS pkgs at once #3237

Merged
merged 7 commits into from
Nov 18, 2018
Merged
2 changes: 1 addition & 1 deletion pipenv/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -731,7 +731,7 @@ def batch_install(deps_list, procs, failed_deps_queue,
ignore_hashes=any([ignore_hashes, dep.editable, dep.is_vcs]),
allow_global=allow_global,
no_deps=False if is_artifact else no_deps,
block=any([dep.is_vcs, blocking]),
block=any([dep.editable, dep.is_vcs, blocking]),
index=index,
requirements_dir=requirements_dir,
pypi_mirror=pypi_mirror,
Expand Down
52 changes: 52 additions & 0 deletions tests/integration/test_install_twists.py
Original file line number Diff line number Diff line change
Expand Up @@ -333,3 +333,55 @@ def test_install_local_uri_special_character(PipenvInstance, testsroot):
c = p.pipenv("install")
assert c.return_code == 0
assert "six" in p.lockfile["default"]


@pytest.mark.files
@pytest.mark.install
@pytest.mark.run
def test_multiple_editable_packages_should_not_race(PipenvInstance, pypi, tmpdir, testsroot):
"""Test for a race condition that can occur when installing multiple 'editable' packages at
once, and which causes some of them to not be importable.

This issue had been fixed for VCS packages already, but not local 'editable' packages.

So this test locally installs packages from tarballs that have already been committed in
the local `pypi` dir to avoid using VCS packages.
"""
pkgs = {
"requests-2.19.1": "requests/requests-2.19.1.tar.gz",
"Flask-0.12.2": "flask/Flask-0.12.2.tar.gz",
"six-1.11.0": "six/six-1.11.0.tar.gz",
"Jinja2-2.10": "jinja2/Jinja2-2.10.tar.gz",
}

pipfile_string="""
[packages]
"""
# Unzip tarballs to known location, and update Pipfile template.
for pkg_name, file_name in pkgs.items():
source_path = str(Path(testsroot, "pypi", file_name))
unzip_path = str(Path(tmpdir.strpath, pkg_name))

import tarfile

with tarfile.open(source_path, "r:gz") as tgz:
tgz.extractall(path=tmpdir.strpath)

pipfile_string += "'{0}' = {{path = '{1}', editable = true}}\n".format(pkg_name, unzip_path)

with PipenvInstance(pypi=pypi, chdir=True) as p:
print(pipfile_string)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove the debugging prints.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 will do!

with open(p.pipfile_path, 'w') as f:
f.write(pipfile_string.strip())

c = p.pipenv('install')
assert c.return_code == 0

c = p.pipenv('run python -c "import requests"')
assert c.return_code == 0
c = p.pipenv('run python -c "import flask"')
assert c.return_code == 0
c = p.pipenv('run python -c "import six"')
assert c.return_code == 0
c = p.pipenv('run python -c "import jinja2"')
assert c.return_code == 0