Skip to content

Commit

Permalink
Fix issues from prior refactoring and specify --no-build-isolation by…
Browse files Browse the repository at this point in the history
… default.
  • Loading branch information
matteius committed Sep 20, 2022
1 parent 7497f0c commit 9e064bc
Show file tree
Hide file tree
Showing 3 changed files with 164 additions and 88 deletions.
177 changes: 92 additions & 85 deletions pipenv/core.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import json as simplejson
import logging
import os
import queue
import re
import shutil
import subprocess
Expand Down Expand Up @@ -766,100 +767,105 @@ def do_install_dependencies(
Executes the installation functionality.
"""
procs = queue.Queue(maxsize=1)
if not categories:
if dev and dev_only:
categories = ["dev-packages"]
elif dev:
categories = ["packages", "dev-packages"]
else:
categories = ["packages"]

import queue

# Load the lockfile if it exists, or if dev_only is being used.
if skip_lock or not project.lockfile_exists:
if not bare:
click.echo(
click.style(
fix_utf8("Installing dependencies from Pipfile..."), bold=True
for category in categories:
# Load the lockfile if it exists, or if dev_only is being used.
if skip_lock or not project.lockfile_exists:
if not bare:
click.echo(
click.style(
fix_utf8("Installing dependencies from Pipfile..."), bold=True
)
)
)
# skip_lock should completely bypass the lockfile (broken in 4dac1676)
lockfile = project.get_or_create_lockfile(from_pipfile=True)
else:
lockfile = project.get_or_create_lockfile()
if not bare:
click.echo(
click.style(
fix_utf8(
"Installing dependencies from Pipfile.lock ({})...".format(
lockfile["_meta"].get("hash", {}).get("sha256")[-6:]
)
),
bold=True,
# skip_lock should completely bypass the lockfile (broken in 4dac1676)
lockfile = project.get_or_create_lockfile(from_pipfile=True)
else:
lockfile = project.get_or_create_lockfile()
if not bare:
click.echo(
click.style(
fix_utf8(
"Installing dependencies from Pipfile.lock ({})...".format(
lockfile["_meta"].get("hash", {}).get("sha256")[-6:]
)
),
bold=True,
)
)
)
dev = dev or dev_only
deps_list = list(
lockfile.get_requirements(dev=dev, only=dev_only, categories=categories)
)
nprocs = 2
procs = queue.Queue(maxsize=nprocs)
failed_deps_queue = queue.Queue()
if skip_lock:
ignore_hashes = True
editable_or_vcs_deps = [dep for dep in deps_list if (dep.editable or dep.vcs)]
normal_deps = [dep for dep in deps_list if not (dep.editable or dep.vcs)]
install_kwargs = {
"no_deps": not skip_lock,
"ignore_hashes": ignore_hashes,
"allow_global": allow_global,
"pypi_mirror": pypi_mirror,
"sequential_deps": editable_or_vcs_deps,
"extra_pip_args": extra_pip_args,
}

batch_install(
project,
normal_deps,
procs,
failed_deps_queue,
requirements_dir,
**install_kwargs,
)

if not procs.empty():
_cleanup_procs(project, procs, failed_deps_queue)

# Iterate over the hopefully-poorly-packaged dependencies...
if not failed_deps_queue.empty():
click.echo(
click.style(
fix_utf8("Installing initially failed dependencies..."), bold=True
)
dev = dev or dev_only
deps_list = list(
lockfile.get_requirements(dev=dev, only=dev_only, categories=[category])
)
retry_list = []
while not failed_deps_queue.empty():
failed_dep = failed_deps_queue.get()
retry_list.append(failed_dep)
install_kwargs.update({"retry": False})
failed_deps_queue = queue.Queue()
if skip_lock:
ignore_hashes = True
editable_or_vcs_deps = [dep for dep in deps_list if (dep.editable or dep.vcs)]
normal_deps = [dep for dep in deps_list if not (dep.editable or dep.vcs)]
install_kwargs = {
"no_deps": not skip_lock,
"ignore_hashes": ignore_hashes,
"allow_global": allow_global,
"pypi_mirror": pypi_mirror,
"sequential_deps": editable_or_vcs_deps,
"extra_pip_args": extra_pip_args,
}

batch_install(
project,
retry_list,
normal_deps,
procs,
failed_deps_queue,
requirements_dir,
**install_kwargs,
)
if not procs.empty():
_cleanup_procs(project, procs, failed_deps_queue, retry=False)
if not failed_deps_queue.empty():
failed_list = []
while not failed_deps_queue.empty():
failed_dep = failed_deps_queue.get()
failed_list.append(failed_dep)
click.echo(
click.style(
f"Failed to install some dependency or packages. "
f"The following have failed installation and attempted retry: {failed_list}",
fg="red",
),
err=True,
)
sys.exit(1)

if not procs.empty():
_cleanup_procs(project, procs, failed_deps_queue)

# Iterate over the hopefully-poorly-packaged dependencies...
if not failed_deps_queue.empty():
click.echo(
click.style(
fix_utf8("Installing initially failed dependencies..."), bold=True
)
)
retry_list = []
while not failed_deps_queue.empty():
failed_dep = failed_deps_queue.get()
retry_list.append(failed_dep)
install_kwargs.update({"retry": False})
batch_install(
project,
retry_list,
procs,
failed_deps_queue,
requirements_dir,
**install_kwargs,
)
if not procs.empty():
_cleanup_procs(project, procs, failed_deps_queue, retry=False)
if not failed_deps_queue.empty():
failed_list = []
while not failed_deps_queue.empty():
failed_dep = failed_deps_queue.get()
failed_list.append(failed_dep)
click.echo(
click.style(
f"Failed to install some dependency or packages. "
f"The following have failed installation and attempted retry: {failed_list}",
fg="red",
),
err=True,
)
sys.exit(1)


def convert_three_to_python(three, python):
Expand Down Expand Up @@ -1211,12 +1217,13 @@ def do_init(
categories=None,
):
"""Executes the init functionality."""

python = None
if project.s.PIPENV_PYTHON is not None:
python = project.s.PIPENV_PYTHON
elif project.s.PIPENV_DEFAULT_PYTHON_VERSION is not None:
python = project.s.PIPENV_DEFAULT_PYTHON_VERSION
if categories is None:
categories = []

if not system and not project.s.PIPENV_USE_SYSTEM:
if not project.virtualenv_exists:
Expand Down Expand Up @@ -1331,7 +1338,7 @@ def get_pip_args(
verbose: bool = False,
upgrade: bool = False,
require_hashes: bool = False,
no_build_isolation: bool = False,
no_build_isolation: bool = True,
no_use_pep517: bool = False,
no_deps: bool = False,
selective_upgrade: bool = False,
Expand Down
50 changes: 48 additions & 2 deletions tests/integration/test_install_categories.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import os
import tempfile

import pytest


@pytest.mark.basic
@pytest.mark.categories
@pytest.mark.install
def test_basic_category_install(pipenv_instance_private_pypi):
with pipenv_instance_private_pypi() as p:
Expand All @@ -13,7 +16,7 @@ def test_basic_category_install(pipenv_instance_private_pypi):
assert "six" in p.lockfile["prereq"]


@pytest.mark.basic
@pytest.mark.categories
@pytest.mark.install
def test_multiple_category_install(pipenv_instance_private_pypi):
with pipenv_instance_private_pypi() as p:
Expand All @@ -25,3 +28,46 @@ def test_multiple_category_install(pipenv_instance_private_pypi):
assert "six" in p.lockfile["prereq"]
assert "six" in p.lockfile["other"]
assert "six" in p.lockfile["other"]


@pytest.mark.extras
@pytest.mark.install
@pytest.mark.local
def test_multiple_category_install_proceeds_in_order_specified(pipenv_instance_private_pypi):
"""Ensure -e .[extras] installs.
"""
with pipenv_instance_private_pypi(chdir=True) as p:
#os.mkdir(os.path.join(p.path, "testpipenv"))
setup_py = os.path.join(p.path, "setup.py")
with open(setup_py, "w") as fh:
contents = """
import six
from setuptools import setup
setup(
name='testpipenv',
version='0.1',
description='Pipenv Test Package',
author='Pipenv Test',
author_email='[email protected]',
license='MIT',
packages=[],
install_requires=['six'],
zip_safe=False
)
""".strip()
fh.write(contents)
with open(os.path.join(p.path, 'Pipfile'), 'w') as fh:
fh.write("""
[packages]
testpipenv = {path = ".", editable = true}
[prereq]
six = "*"
""".strip())
c = p.pipenv("lock")
assert c.returncode == 0
assert "testpipenv" in p.lockfile["default"]
assert "testpipenv" not in p.lockfile["prereq"]
assert "six" in p.lockfile["prereq"]
c = p.pipenv('sync --categories="prereq packages" -v')
assert c.returncode == 0
25 changes: 24 additions & 1 deletion tests/integration/test_uninstall.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ def test_uninstall_missing_parameters(pipenv_instance_private_pypi):
assert "No package provided!" in c.stderr


@pytest.mark.install
@pytest.mark.categories
@pytest.mark.uninstall
def test_uninstall_category_with_shared_requirement(pipenv_instance_pypi):
with pipenv_instance_pypi() as p:
Expand All @@ -231,3 +231,26 @@ def test_uninstall_category_with_shared_requirement(pipenv_instance_pypi):

assert "six" in p.lockfile["prereq"]
assert "six" not in p.lockfile["default"]


@pytest.mark.categories
@pytest.mark.uninstall
def test_uninstall_multiple_categories(pipenv_instance_private_pypi):
with pipenv_instance_private_pypi() as p:
with open(p.pipfile_path, "w") as f:
contents = """
[after]
six = "*"
[prereq]
six = "*"
"""
f.write(contents)
c = p.pipenv("install")
assert c.returncode == 0

c = p.pipenv('uninstall six --categories="prereq after"')
assert c.returncode == 0

assert "six" not in p.lockfile["prereq"]
assert "six" not in p.lockfile["default"]

0 comments on commit 9e064bc

Please sign in to comment.