mirror of
https://github.com/kennethreitz/pipenv.git
synced 2026-06-05 22:50:18 +00:00
Don't share project objects but create own
This commit is contained in:
+69
-55
@@ -2,22 +2,22 @@ import os
|
||||
import sys
|
||||
|
||||
from click import (
|
||||
argument, echo, edit, group, option, pass_context, secho, types, version_option, Choice
|
||||
Choice, argument, echo, edit, group, option, pass_context, secho, types,
|
||||
version_option
|
||||
)
|
||||
|
||||
from pipenv.__version__ import __version__
|
||||
from pipenv._compat import fix_utf8
|
||||
from pipenv.exceptions import PipenvOptionsError
|
||||
from pipenv.patched import crayons
|
||||
from pipenv.vendor import click_completion
|
||||
from pipenv.utils import subprocess_run
|
||||
from pipenv.cli.options import (
|
||||
CONTEXT_SETTINGS, PipenvGroup, code_option, common_options, deploy_option,
|
||||
general_options, install_options, lock_options, pass_state,
|
||||
general_options, install_options, lock_options, pass_project, pass_state,
|
||||
pypi_mirror_option, python_option, site_packages_option, skip_lock_option,
|
||||
sync_options, system_option, three_option, uninstall_options,
|
||||
verbose_option
|
||||
sync_options, system_option, three_option, uninstall_options, verbose_option
|
||||
)
|
||||
from pipenv.exceptions import PipenvOptionsError
|
||||
from pipenv.patched import crayons
|
||||
from pipenv.utils import subprocess_run
|
||||
from pipenv.vendor import click_completion
|
||||
|
||||
|
||||
# Enable shell completion.
|
||||
@@ -54,9 +54,11 @@ subcommand_context_no_interspersion["allow_interspersed_args"] = False
|
||||
@general_options
|
||||
@version_option(prog_name=crayons.normal("pipenv", bold=True), version=__version__)
|
||||
@pass_state
|
||||
@pass_project
|
||||
@pass_context
|
||||
def cli(
|
||||
ctx,
|
||||
project,
|
||||
state,
|
||||
where=False,
|
||||
venv=False,
|
||||
@@ -88,15 +90,8 @@ def cli(
|
||||
return 0
|
||||
|
||||
from ..core import (
|
||||
system_which,
|
||||
do_py,
|
||||
warn_in_virtualenv,
|
||||
do_where,
|
||||
project,
|
||||
cleanup_virtualenv,
|
||||
ensure_project,
|
||||
format_help,
|
||||
do_clear,
|
||||
cleanup_virtualenv, do_clear, do_py, do_where, ensure_project,
|
||||
format_help, system_which, warn_in_virtualenv
|
||||
)
|
||||
from ..utils import create_spinner
|
||||
|
||||
@@ -126,20 +121,20 @@ def cli(
|
||||
if ctx.invoked_subcommand is None:
|
||||
# --where was passed...
|
||||
if where:
|
||||
do_where(bare=True)
|
||||
do_where(project, bare=True)
|
||||
return 0
|
||||
elif py:
|
||||
do_py()
|
||||
do_py(project)
|
||||
return 0
|
||||
# --support was passed...
|
||||
elif support:
|
||||
from ..help import get_pipenv_diagnostics
|
||||
|
||||
get_pipenv_diagnostics()
|
||||
get_pipenv_diagnostics(project)
|
||||
return 0
|
||||
# --clear was passed...
|
||||
elif state.clear:
|
||||
do_clear()
|
||||
do_clear(project)
|
||||
return 0
|
||||
# --venv was passed...
|
||||
elif venv:
|
||||
@@ -181,7 +176,7 @@ def cli(
|
||||
)
|
||||
with create_spinner(text="Running..."):
|
||||
# Remove the virtualenv.
|
||||
cleanup_virtualenv(bare=True)
|
||||
cleanup_virtualenv(project, bare=True)
|
||||
return 0
|
||||
else:
|
||||
echo(
|
||||
@@ -195,6 +190,7 @@ def cli(
|
||||
# --two / --three was passed...
|
||||
if (state.python or state.three is not None) or state.site_packages:
|
||||
ensure_project(
|
||||
project,
|
||||
three=state.three,
|
||||
python=state.python,
|
||||
warn=True,
|
||||
@@ -219,16 +215,19 @@ def cli(
|
||||
@skip_lock_option
|
||||
@install_options
|
||||
@pass_state
|
||||
@pass_project
|
||||
@pass_context
|
||||
def install(
|
||||
ctx,
|
||||
project,
|
||||
state,
|
||||
**kwargs
|
||||
):
|
||||
"""Installs provided packages and adds them to Pipfile, or (if no packages are given), installs all packages from Pipfile."""
|
||||
from ..core import do_install
|
||||
|
||||
retcode = do_install(
|
||||
do_install(
|
||||
project,
|
||||
dev=state.installstate.dev,
|
||||
three=state.three,
|
||||
python=state.python,
|
||||
@@ -250,8 +249,6 @@ def install(
|
||||
editable_packages=state.installstate.editables,
|
||||
site_packages=state.site_packages
|
||||
)
|
||||
if retcode:
|
||||
ctx.abort()
|
||||
|
||||
|
||||
@cli.command(
|
||||
@@ -271,10 +268,12 @@ def install(
|
||||
help="Purge all package(s) from virtualenv. Does not edit Pipfile.",
|
||||
)
|
||||
@uninstall_options
|
||||
@pass_project
|
||||
@pass_state
|
||||
@pass_context
|
||||
def uninstall(
|
||||
ctx,
|
||||
project,
|
||||
state,
|
||||
all_dev=False,
|
||||
all=False,
|
||||
@@ -283,6 +282,7 @@ def uninstall(
|
||||
"""Uninstalls a provided package and removes it from Pipfile."""
|
||||
from ..core import do_uninstall
|
||||
retcode = do_uninstall(
|
||||
project,
|
||||
packages=state.installstate.packages,
|
||||
editable_packages=state.installstate.editables,
|
||||
three=state.three,
|
||||
@@ -318,19 +318,22 @@ LOCK_DEV_NOTE = """\
|
||||
@cli.command(short_help="Generates Pipfile.lock.", context_settings=CONTEXT_SETTINGS)
|
||||
@lock_options
|
||||
@pass_state
|
||||
@pass_project
|
||||
@pass_context
|
||||
def lock(
|
||||
ctx,
|
||||
project,
|
||||
state,
|
||||
**kwargs
|
||||
):
|
||||
"""Generates Pipfile.lock."""
|
||||
from ..core import ensure_project, do_init, do_lock
|
||||
from ..core import do_init, do_lock, ensure_project
|
||||
|
||||
# Ensure that virtualenv is available.
|
||||
# Note that we don't pass clear on to ensure_project as it is also
|
||||
# handled in do_lock
|
||||
ensure_project(
|
||||
three=state.three, python=state.python, pypi_mirror=state.pypi_mirror,
|
||||
project, three=state.three, python=state.python, pypi_mirror=state.pypi_mirror,
|
||||
warn=(not state.quiet), site_packages=state.site_packages,
|
||||
)
|
||||
emit_requirements = state.lockoptions.emit_requirements
|
||||
@@ -352,6 +355,7 @@ def lock(
|
||||
# Setting "emit_requirements=True" means do_init() just emits the
|
||||
# install requirements file to stdout, it doesn't install anything
|
||||
do_init(
|
||||
project,
|
||||
dev=dev,
|
||||
dev_only=dev_only,
|
||||
emit_requirements=emit_requirements,
|
||||
@@ -365,6 +369,7 @@ def lock(
|
||||
"Aborting."
|
||||
)
|
||||
do_lock(
|
||||
project,
|
||||
ctx=ctx,
|
||||
clear=state.clear,
|
||||
pre=pre,
|
||||
@@ -396,14 +401,16 @@ def lock(
|
||||
@three_option
|
||||
@python_option
|
||||
@pass_state
|
||||
@pass_project
|
||||
def shell(
|
||||
project,
|
||||
state,
|
||||
fancy=False,
|
||||
shell_args=None,
|
||||
anyway=False,
|
||||
):
|
||||
"""Spawns a shell within the virtualenv."""
|
||||
from ..core import load_dot_env, do_shell
|
||||
from ..core import do_shell, load_dot_env
|
||||
|
||||
# Prevent user from activating nested environments.
|
||||
if "PIPENV_ACTIVE" in os.environ:
|
||||
@@ -420,11 +427,12 @@ def shell(
|
||||
)
|
||||
sys.exit(1)
|
||||
# Load .env file.
|
||||
load_dot_env()
|
||||
load_dot_env(project)
|
||||
# Use fancy mode for Windows.
|
||||
if os.name == "nt":
|
||||
fancy = True
|
||||
do_shell(
|
||||
project,
|
||||
three=state.three,
|
||||
python=state.python,
|
||||
fancy=fancy,
|
||||
@@ -441,11 +449,12 @@ def shell(
|
||||
@argument("command")
|
||||
@argument("args", nargs=-1)
|
||||
@pass_state
|
||||
def run(state, command, args):
|
||||
@pass_project
|
||||
def run(project, state, command, args):
|
||||
"""Spawns a command installed into the virtualenv."""
|
||||
from ..core import do_run
|
||||
do_run(
|
||||
command=command, args=args, three=state.three, python=state.python, pypi_mirror=state.pypi_mirror
|
||||
project, command=command, args=args, three=state.three, python=state.python, pypi_mirror=state.pypi_mirror
|
||||
)
|
||||
|
||||
|
||||
@@ -495,7 +504,9 @@ def run(state, command, args):
|
||||
@system_option
|
||||
@argument("args", nargs=-1)
|
||||
@pass_state
|
||||
@pass_project
|
||||
def check(
|
||||
project,
|
||||
state,
|
||||
unused=False,
|
||||
db=None,
|
||||
@@ -511,6 +522,7 @@ def check(
|
||||
from ..core import do_check
|
||||
|
||||
do_check(
|
||||
project,
|
||||
three=state.three,
|
||||
python=state.python,
|
||||
system=state.system,
|
||||
@@ -533,9 +545,11 @@ def check(
|
||||
@option("--dry-run", is_flag=True, default=None, help="List out-of-date dependencies.")
|
||||
@install_options
|
||||
@pass_state
|
||||
@pass_project
|
||||
@pass_context
|
||||
def update(
|
||||
ctx,
|
||||
project,
|
||||
state,
|
||||
bare=False,
|
||||
dry_run=None,
|
||||
@@ -543,21 +557,15 @@ def update(
|
||||
**kwargs
|
||||
):
|
||||
"""Runs lock, then sync."""
|
||||
from ..core import (
|
||||
ensure_project,
|
||||
do_outdated,
|
||||
do_lock,
|
||||
do_sync,
|
||||
project,
|
||||
)
|
||||
from ..core import do_lock, do_outdated, do_sync, ensure_project, project
|
||||
ensure_project(
|
||||
three=state.three, python=state.python, pypi_mirror=state.pypi_mirror,
|
||||
project, three=state.three, python=state.python, pypi_mirror=state.pypi_mirror,
|
||||
warn=(not state.quiet), site_packages=state.site_packages, clear=state.clear
|
||||
)
|
||||
if not outdated:
|
||||
outdated = bool(dry_run)
|
||||
if outdated:
|
||||
do_outdated(clear=state.clear, pre=state.installstate.pre, pypi_mirror=state.pypi_mirror)
|
||||
do_outdated(project, clear=state.clear, pre=state.installstate.pre, pypi_mirror=state.pypi_mirror)
|
||||
packages = [p for p in state.installstate.packages if p]
|
||||
editable = [p for p in state.installstate.editables if p]
|
||||
if not packages:
|
||||
@@ -583,6 +591,7 @@ def update(
|
||||
)
|
||||
ctx.abort()
|
||||
do_lock(
|
||||
project,
|
||||
ctx=ctx,
|
||||
clear=state.clear,
|
||||
pre=state.installstate.pre,
|
||||
@@ -591,7 +600,7 @@ def update(
|
||||
write=not state.quiet,
|
||||
)
|
||||
do_sync(
|
||||
ctx=ctx,
|
||||
project,
|
||||
dev=state.installstate.dev,
|
||||
three=state.three,
|
||||
python=state.python,
|
||||
@@ -613,11 +622,12 @@ def update(
|
||||
@option("--json", is_flag=True, default=False, help="Output JSON.")
|
||||
@option("--json-tree", is_flag=True, default=False, help="Output JSON in nested tree.")
|
||||
@option("--reverse", is_flag=True, default=False, help="Reversed dependency graph.")
|
||||
def graph(bare=False, json=False, json_tree=False, reverse=False):
|
||||
@pass_project
|
||||
def graph(project, bare=False, json=False, json_tree=False, reverse=False):
|
||||
"""Displays currently-installed dependency graph information."""
|
||||
from ..core import do_graph
|
||||
|
||||
do_graph(bare=bare, json=json, json_tree=json_tree, reverse=reverse)
|
||||
do_graph(project, bare=bare, json=json, json_tree=json_tree, reverse=reverse)
|
||||
|
||||
|
||||
@cli.command(
|
||||
@@ -627,7 +637,8 @@ def graph(bare=False, json=False, json_tree=False, reverse=False):
|
||||
@common_options
|
||||
@argument("module", nargs=1)
|
||||
@pass_state
|
||||
def run_open(state, module, *args, **kwargs):
|
||||
@pass_project
|
||||
def run_open(project, state, module, *args, **kwargs):
|
||||
"""View a given module in your editor.
|
||||
|
||||
This uses the EDITOR environment variable. You can temporarily override it,
|
||||
@@ -635,15 +646,17 @@ def run_open(state, module, *args, **kwargs):
|
||||
|
||||
EDITOR=atom pipenv open requests
|
||||
"""
|
||||
from ..core import which, ensure_project, inline_activate_virtual_environment
|
||||
from ..core import (
|
||||
ensure_project, inline_activate_virtual_environment, which
|
||||
)
|
||||
|
||||
# Ensure that virtualenv is available.
|
||||
ensure_project(
|
||||
three=state.three, python=state.python,
|
||||
project, three=state.three, python=state.python,
|
||||
validate=False, pypi_mirror=state.pypi_mirror,
|
||||
)
|
||||
c = subprocess_run(
|
||||
which("python"), "-c", "import {0}; print({0}.__file__)".format(module)
|
||||
[which("python"), "-c", "import {0}; print({0}.__file__)".format(module)]
|
||||
)
|
||||
if c.returncode:
|
||||
echo(crayons.red("Module not found!"))
|
||||
@@ -653,7 +666,7 @@ def run_open(state, module, *args, **kwargs):
|
||||
else:
|
||||
p = c.stdout.strip().rstrip("cdo")
|
||||
echo(crayons.normal(f"Opening {p!r} in your EDITOR.", bold=True))
|
||||
inline_activate_virtual_environment()
|
||||
inline_activate_virtual_environment(project)
|
||||
edit(filename=p)
|
||||
return 0
|
||||
|
||||
@@ -666,9 +679,11 @@ def run_open(state, module, *args, **kwargs):
|
||||
@option("--bare", is_flag=True, default=False, help="Minimal output.")
|
||||
@sync_options
|
||||
@pass_state
|
||||
@pass_project
|
||||
@pass_context
|
||||
def sync(
|
||||
ctx,
|
||||
project,
|
||||
state,
|
||||
bare=False,
|
||||
user=False,
|
||||
@@ -679,7 +694,7 @@ def sync(
|
||||
from ..core import do_sync
|
||||
|
||||
retcode = do_sync(
|
||||
ctx=ctx,
|
||||
project,
|
||||
dev=state.installstate.dev,
|
||||
three=state.three,
|
||||
python=state.python,
|
||||
@@ -706,11 +721,11 @@ def sync(
|
||||
@three_option
|
||||
@python_option
|
||||
@pass_state
|
||||
@pass_context
|
||||
def clean(ctx, state, dry_run=False, bare=False, user=False):
|
||||
@pass_project
|
||||
def clean(project, state, dry_run=False, bare=False, user=False):
|
||||
"""Uninstalls all packages not specified in Pipfile.lock."""
|
||||
from ..core import do_clean
|
||||
do_clean(ctx=ctx, three=state.three, python=state.python, dry_run=dry_run,
|
||||
do_clean(project, three=state.three, python=state.python, dry_run=dry_run,
|
||||
system=state.system)
|
||||
|
||||
|
||||
@@ -719,10 +734,9 @@ def clean(ctx, state, dry_run=False, bare=False, user=False):
|
||||
context_settings=subcommand_context_no_interspersion,
|
||||
)
|
||||
@common_options
|
||||
def scripts():
|
||||
@pass_project
|
||||
def scripts(project):
|
||||
"""Lists scripts in current environment config."""
|
||||
from ..core import project
|
||||
|
||||
if not project.pipfile_exists:
|
||||
echo("No Pipfile present at project home.", err=True)
|
||||
sys.exit(1)
|
||||
|
||||
@@ -3,10 +3,13 @@ import os
|
||||
import click.types
|
||||
|
||||
from click import (
|
||||
BadParameter, BadArgumentUsage, Group, Option, argument, echo, make_pass_decorator, option
|
||||
BadArgumentUsage, BadParameter, Group, Option, argument, echo,
|
||||
make_pass_decorator, option
|
||||
)
|
||||
from click_didyoumean import DYMMixin
|
||||
|
||||
from pipenv.project import Project
|
||||
|
||||
from .. import environments
|
||||
from ..utils import is_valid_url
|
||||
|
||||
@@ -89,6 +92,7 @@ class LockOptions:
|
||||
|
||||
|
||||
pass_state = make_pass_decorator(State, ensure=True)
|
||||
pass_project = make_pass_decorator(Project, ensure=True)
|
||||
|
||||
|
||||
def index_option(f):
|
||||
|
||||
+102
-116
@@ -23,10 +23,9 @@ from pipenv.environments import (
|
||||
SESSION_IS_INTERACTIVE, is_type_checking
|
||||
)
|
||||
from pipenv.patched import crayons
|
||||
from pipenv.project import Project
|
||||
from pipenv.utils import (
|
||||
convert_deps_to_pip, create_spinner, download_file, find_python,
|
||||
find_windows_executable, get_canonical_names, get_source_list, is_pinned,
|
||||
get_canonical_names, get_source_list, is_pinned,
|
||||
is_python_command, is_required_version, is_star, is_valid_url,
|
||||
parse_indexes, pep423_name, prepare_pip_source_args, proper_case,
|
||||
python_version, run_command, subprocess_run, venv_resolve_deps
|
||||
@@ -80,37 +79,7 @@ if PIPENV_COLORBLIND:
|
||||
crayons.disable()
|
||||
|
||||
|
||||
def which(command, location=None, allow_global=False):
|
||||
if not allow_global and location is None:
|
||||
if project.virtualenv_exists:
|
||||
location = project.virtualenv_location
|
||||
else:
|
||||
location = os.environ.get("VIRTUAL_ENV", None)
|
||||
if not (location and os.path.exists(location)) and not allow_global:
|
||||
raise RuntimeError("location not created nor specified")
|
||||
|
||||
version_str = "python{}".format(".".join([str(v) for v in sys.version_info[:2]]))
|
||||
is_python = command in ("python", os.path.basename(sys.executable), version_str)
|
||||
if not allow_global:
|
||||
if os.name == "nt":
|
||||
p = find_windows_executable(os.path.join(location, "Scripts"), command)
|
||||
else:
|
||||
p = os.path.join(location, "bin", command)
|
||||
else:
|
||||
if is_python:
|
||||
p = sys.executable
|
||||
if not os.path.exists(p):
|
||||
if is_python:
|
||||
p = sys.executable or system_which("python")
|
||||
else:
|
||||
p = system_which(command)
|
||||
return p
|
||||
|
||||
|
||||
project = Project(which=which)
|
||||
|
||||
|
||||
def do_clear():
|
||||
def do_clear(project):
|
||||
click.echo(crayons.normal(fix_utf8("Clearing caches..."), bold=True))
|
||||
try:
|
||||
from pip._internal import locations
|
||||
@@ -134,7 +103,7 @@ def do_clear():
|
||||
raise
|
||||
|
||||
|
||||
def load_dot_env():
|
||||
def load_dot_env(project):
|
||||
"""Loads .env file into sys.environ."""
|
||||
if not environments.PIPENV_DONT_LOAD_ENV:
|
||||
# If the project doesn't exist yet, check current directory for a .env file
|
||||
@@ -163,13 +132,7 @@ def load_dot_env():
|
||||
importlib.reload(environments)
|
||||
|
||||
|
||||
def add_to_path(p):
|
||||
"""Adds a given path to the PATH."""
|
||||
if p not in os.environ["PATH"]:
|
||||
os.environ["PATH"] = "{}{}{}".format(p, os.pathsep, os.environ["PATH"])
|
||||
|
||||
|
||||
def cleanup_virtualenv(bare=True):
|
||||
def cleanup_virtualenv(project, bare=True):
|
||||
"""Removes the virtualenv directory from the system."""
|
||||
if not bare:
|
||||
click.echo(crayons.red("Environment creation aborted."))
|
||||
@@ -187,7 +150,7 @@ def cleanup_virtualenv(bare=True):
|
||||
click.echo(crayons.cyan(e), err=True)
|
||||
|
||||
|
||||
def import_requirements(r=None, dev=False):
|
||||
def import_requirements(project, r=None, dev=False):
|
||||
from .patched.notpip._vendor import requests as pip_requests
|
||||
from .vendor.pip_shims.shims import parse_requirements
|
||||
|
||||
@@ -261,12 +224,12 @@ def import_from_code(path="."):
|
||||
return []
|
||||
|
||||
|
||||
def ensure_pipfile(validate=True, skip_requirements=False, system=False):
|
||||
def ensure_pipfile(project, validate=True, skip_requirements=False, system=False):
|
||||
"""Creates a Pipfile for the project, if it doesn't exist."""
|
||||
from .environments import PIPENV_VIRTUALENV
|
||||
|
||||
# Assert Pipfile exists.
|
||||
python = which("python") if not (USING_DEFAULT_PYTHON or system) else None
|
||||
python = project._which("python") if not (USING_DEFAULT_PYTHON or system) else None
|
||||
if project.pipfile_is_empty:
|
||||
# Show an error message and exit if system is passed and no pipfile exists
|
||||
if system and not PIPENV_VIRTUALENV:
|
||||
@@ -288,7 +251,7 @@ def ensure_pipfile(validate=True, skip_requirements=False, system=False):
|
||||
with create_spinner("Importing requirements...") as sp:
|
||||
# Import requirements.txt.
|
||||
try:
|
||||
import_requirements()
|
||||
import_requirements(project)
|
||||
except Exception:
|
||||
sp.fail(environments.PIPENV_SPINNER_FAIL_TEXT.format("Failed..."))
|
||||
else:
|
||||
@@ -348,7 +311,7 @@ def find_a_system_python(line):
|
||||
return python_entry
|
||||
|
||||
|
||||
def ensure_python(three=None, python=None):
|
||||
def ensure_python(project, three=None, python=None):
|
||||
# Runtime import is necessary due to the possibility that the environments module may have been reloaded.
|
||||
from .environments import PIPENV_PYTHON, PIPENV_YES
|
||||
|
||||
@@ -475,7 +438,7 @@ def ensure_python(three=None, python=None):
|
||||
return path_to_python
|
||||
|
||||
|
||||
def ensure_virtualenv(three=None, python=None, site_packages=None, pypi_mirror=None):
|
||||
def ensure_virtualenv(project, three=None, python=None, site_packages=None, pypi_mirror=None):
|
||||
"""Creates a virtualenv, if one doesn't exist."""
|
||||
from .environments import PIPENV_USE_SYSTEM
|
||||
|
||||
@@ -488,7 +451,7 @@ def ensure_virtualenv(three=None, python=None, site_packages=None, pypi_mirror=N
|
||||
# Ensure environment variables are set properly.
|
||||
ensure_environment()
|
||||
# Ensure Python is available.
|
||||
python = ensure_python(three=three, python=python)
|
||||
python = ensure_python(project, three=three, python=python)
|
||||
if python is not None and not isinstance(python, str):
|
||||
python = python.path.as_posix()
|
||||
# Create the virtualenv.
|
||||
@@ -506,13 +469,13 @@ def ensure_virtualenv(three=None, python=None, site_packages=None, pypi_mirror=N
|
||||
)
|
||||
except KeyboardInterrupt:
|
||||
# If interrupted, cleanup the virtualenv.
|
||||
cleanup_virtualenv(bare=False)
|
||||
cleanup_virtualenv(project, bare=False)
|
||||
sys.exit(1)
|
||||
# If --three, --two, or --python were passed...
|
||||
elif (python) or (three is not None) or (site_packages is not None):
|
||||
USING_DEFAULT_PYTHON = False
|
||||
# Ensure python is installed before deleting existing virtual env
|
||||
python = ensure_python(three=three, python=python)
|
||||
python = ensure_python(project, three=three, python=python)
|
||||
if python is not None and not isinstance(python, str):
|
||||
python = python.path.as_posix()
|
||||
|
||||
@@ -529,9 +492,10 @@ def ensure_virtualenv(three=None, python=None, site_packages=None, pypi_mirror=N
|
||||
crayons.normal(fix_utf8("Removing existing virtualenv..."), bold=True), err=True
|
||||
)
|
||||
# Remove the virtualenv.
|
||||
cleanup_virtualenv(bare=True)
|
||||
cleanup_virtualenv(project, bare=True)
|
||||
# Call this function again.
|
||||
ensure_virtualenv(
|
||||
project,
|
||||
three=three,
|
||||
python=python,
|
||||
site_packages=site_packages,
|
||||
@@ -540,6 +504,7 @@ def ensure_virtualenv(three=None, python=None, site_packages=None, pypi_mirror=N
|
||||
|
||||
|
||||
def ensure_project(
|
||||
project,
|
||||
three=None,
|
||||
python=None,
|
||||
validate=True,
|
||||
@@ -567,6 +532,7 @@ def ensure_project(
|
||||
# Skip virtualenv creation when --system was used.
|
||||
if not system:
|
||||
ensure_virtualenv(
|
||||
project,
|
||||
three=three,
|
||||
python=python,
|
||||
site_packages=site_packages,
|
||||
@@ -575,7 +541,7 @@ def ensure_project(
|
||||
if warn:
|
||||
# Warn users if they are using the wrong version of Python.
|
||||
if project.required_python_version:
|
||||
path_to_python = which("python") or which("py")
|
||||
path_to_python = project._which("python") or project._which("py")
|
||||
if path_to_python and project.required_python_version not in (
|
||||
python_version(path_to_python) or ""
|
||||
):
|
||||
@@ -605,7 +571,7 @@ def ensure_project(
|
||||
raise exceptions.DeployException
|
||||
# Ensure the Pipfile exists.
|
||||
ensure_pipfile(
|
||||
validate=validate, skip_requirements=skip_requirements, system=system
|
||||
project, validate=validate, skip_requirements=skip_requirements, system=system
|
||||
)
|
||||
|
||||
|
||||
@@ -623,7 +589,7 @@ def shorten_path(location, bold=False):
|
||||
|
||||
|
||||
# return short
|
||||
def do_where(virtualenv=False, bare=True):
|
||||
def do_where(project, virtualenv=False, bare=True):
|
||||
"""Executes the where functionality."""
|
||||
if not virtualenv:
|
||||
if not project.pipfile_exists:
|
||||
@@ -655,7 +621,7 @@ def do_where(virtualenv=False, bare=True):
|
||||
click.echo(location)
|
||||
|
||||
|
||||
def _cleanup_procs(procs, failed_deps_queue, retry=True):
|
||||
def _cleanup_procs(project, procs, failed_deps_queue, retry=True):
|
||||
while not procs.empty():
|
||||
c = procs.get()
|
||||
try:
|
||||
@@ -708,7 +674,7 @@ def _cleanup_procs(procs, failed_deps_queue, retry=True):
|
||||
failed_deps_queue.put(dep)
|
||||
|
||||
|
||||
def batch_install(deps_list, procs, failed_deps_queue,
|
||||
def batch_install(project, deps_list, procs, failed_deps_queue,
|
||||
requirements_dir, no_deps=True, ignore_hashes=False,
|
||||
allow_global=False, blocking=False, pypi_mirror=None,
|
||||
retry=True, sequential_deps=None):
|
||||
@@ -770,6 +736,7 @@ def batch_install(deps_list, procs, failed_deps_queue,
|
||||
is_sequential = sequential_deps and dep.name in sequential_dep_names
|
||||
is_blocking = any([dep.editable, dep.is_vcs, blocking, is_sequential])
|
||||
c = pip_install(
|
||||
project,
|
||||
dep,
|
||||
ignore_hashes=any([ignore_hashes, dep.editable, dep.is_vcs]),
|
||||
allow_global=allow_global,
|
||||
@@ -786,10 +753,11 @@ def batch_install(deps_list, procs, failed_deps_queue,
|
||||
|
||||
procs.put(c)
|
||||
if procs.full() or procs.qsize() == len(deps_list) or is_sequential:
|
||||
_cleanup_procs(procs, failed_deps_queue, retry=retry)
|
||||
_cleanup_procs(project, procs, failed_deps_queue, retry=retry)
|
||||
|
||||
|
||||
def do_install_dependencies(
|
||||
project,
|
||||
dev=False,
|
||||
dev_only=False,
|
||||
bare=False,
|
||||
@@ -835,7 +803,7 @@ def do_install_dependencies(
|
||||
deps_list = list(lockfile.get_requirements(dev=dev, only=dev_only))
|
||||
if emit_requirements:
|
||||
index_args = prepare_pip_source_args(
|
||||
get_source_list(pypi_mirror=pypi_mirror, project=project)
|
||||
get_source_list(project, pypi_mirror=pypi_mirror, project=project)
|
||||
)
|
||||
index_args = " ".join(index_args).replace(" -", "\n-")
|
||||
deps = [
|
||||
@@ -861,11 +829,11 @@ def do_install_dependencies(
|
||||
}
|
||||
|
||||
batch_install(
|
||||
normal_deps, procs, failed_deps_queue, requirements_dir, **install_kwargs
|
||||
project, normal_deps, procs, failed_deps_queue, requirements_dir, **install_kwargs
|
||||
)
|
||||
|
||||
if not procs.empty():
|
||||
_cleanup_procs(procs, failed_deps_queue)
|
||||
_cleanup_procs(project, procs, failed_deps_queue)
|
||||
|
||||
# click.echo(crayons.normal(
|
||||
# decode_for_output("Installing editable and vcs dependencies..."), bold=True
|
||||
@@ -890,10 +858,10 @@ def do_install_dependencies(
|
||||
retry_list.append(failed_dep)
|
||||
install_kwargs.update({"retry": False})
|
||||
batch_install(
|
||||
retry_list, procs, failed_deps_queue, requirements_dir, **install_kwargs
|
||||
project, retry_list, procs, failed_deps_queue, requirements_dir, **install_kwargs
|
||||
)
|
||||
if not procs.empty():
|
||||
_cleanup_procs(procs, failed_deps_queue, retry=False)
|
||||
_cleanup_procs(project, procs, failed_deps_queue, retry=False)
|
||||
|
||||
|
||||
def convert_three_to_python(three, python):
|
||||
@@ -911,7 +879,7 @@ def convert_three_to_python(three, python):
|
||||
return python
|
||||
|
||||
|
||||
def do_create_virtualenv(python=None, site_packages=None, pypi_mirror=None):
|
||||
def do_create_virtualenv(project, python=None, site_packages=None, pypi_mirror=None):
|
||||
"""Creates a virtualenv."""
|
||||
|
||||
click.echo(
|
||||
@@ -991,7 +959,7 @@ def do_create_virtualenv(python=None, site_packages=None, pypi_mirror=None):
|
||||
)
|
||||
project._environment.add_dist("pipenv")
|
||||
# Say where the virtualenv is.
|
||||
do_where(virtualenv=True, bare=False)
|
||||
do_where(project, virtualenv=True, bare=False)
|
||||
|
||||
|
||||
def parse_download_fname(fname, name):
|
||||
@@ -1008,7 +976,7 @@ def parse_download_fname(fname, name):
|
||||
return version
|
||||
|
||||
|
||||
def get_downloads_info(names_map, section):
|
||||
def get_downloads_info(project, names_map, section):
|
||||
from .vendor.requirementslib.models.requirements import Requirement
|
||||
|
||||
info = []
|
||||
@@ -1020,7 +988,7 @@ def get_downloads_info(names_map, section):
|
||||
version = parse_download_fname(fname, name)
|
||||
# Get the hash of each file.
|
||||
cmd = [
|
||||
which_pip(),
|
||||
which_pip(project),
|
||||
"hash",
|
||||
os.sep.join([project.download_location, fname]),
|
||||
]
|
||||
@@ -1043,6 +1011,7 @@ def overwrite_dev(prod, dev):
|
||||
|
||||
|
||||
def do_lock(
|
||||
project,
|
||||
ctx=None,
|
||||
system=False,
|
||||
clear=False,
|
||||
@@ -1095,7 +1064,7 @@ def do_lock(
|
||||
# Mutates the lockfile
|
||||
venv_resolve_deps(
|
||||
packages,
|
||||
which=which,
|
||||
which=project._which,
|
||||
project=project,
|
||||
dev=is_dev,
|
||||
clear=clear,
|
||||
@@ -1146,7 +1115,7 @@ def do_lock(
|
||||
return lockfile
|
||||
|
||||
|
||||
def do_purge(bare=False, downloads=False, allow_global=False):
|
||||
def do_purge(project, bare=False, downloads=False, allow_global=False):
|
||||
"""Executes the purge functionality."""
|
||||
|
||||
if downloads:
|
||||
@@ -1176,7 +1145,7 @@ def do_purge(bare=False, downloads=False, allow_global=False):
|
||||
)
|
||||
|
||||
command = [
|
||||
which_pip(allow_global=allow_global),
|
||||
which_pip(project, allow_global=allow_global),
|
||||
"uninstall", "-y",
|
||||
] + list(to_remove)
|
||||
if environments.is_verbose():
|
||||
@@ -1191,6 +1160,7 @@ def do_purge(bare=False, downloads=False, allow_global=False):
|
||||
|
||||
|
||||
def do_init(
|
||||
project,
|
||||
dev=False,
|
||||
dev_only=False,
|
||||
emit_requirements=False,
|
||||
@@ -1219,13 +1189,13 @@ def do_init(
|
||||
if not system and not PIPENV_USE_SYSTEM:
|
||||
if not project.virtualenv_exists:
|
||||
try:
|
||||
do_create_virtualenv(python=python, three=None, pypi_mirror=pypi_mirror)
|
||||
do_create_virtualenv(project, python=python, three=None, pypi_mirror=pypi_mirror)
|
||||
except KeyboardInterrupt:
|
||||
cleanup_virtualenv(bare=False)
|
||||
cleanup_virtualenv(project, bare=False)
|
||||
sys.exit(1)
|
||||
# Ensure the Pipfile exists.
|
||||
if not deploy:
|
||||
ensure_pipfile(system=system)
|
||||
ensure_pipfile(project, system=system)
|
||||
if not requirements_dir:
|
||||
requirements_dir = vistir.path.create_tracked_tempdir(
|
||||
suffix="-requirements", prefix="pipenv-"
|
||||
@@ -1267,6 +1237,7 @@ def do_init(
|
||||
err=True,
|
||||
)
|
||||
do_lock(
|
||||
project,
|
||||
system=system,
|
||||
pre=pre,
|
||||
keep_outdated=keep_outdated,
|
||||
@@ -1290,6 +1261,7 @@ def do_init(
|
||||
err=True,
|
||||
)
|
||||
do_lock(
|
||||
project,
|
||||
system=system,
|
||||
pre=pre,
|
||||
keep_outdated=keep_outdated,
|
||||
@@ -1297,6 +1269,7 @@ def do_init(
|
||||
pypi_mirror=pypi_mirror,
|
||||
)
|
||||
do_install_dependencies(
|
||||
project,
|
||||
dev=dev,
|
||||
dev_only=dev_only,
|
||||
emit_requirements=emit_requirements,
|
||||
@@ -1319,6 +1292,7 @@ def do_init(
|
||||
|
||||
|
||||
def get_pip_args(
|
||||
project,
|
||||
pre=False, # type: bool
|
||||
verbose=False, # type: bool
|
||||
upgrade=False, # type: bool
|
||||
@@ -1417,6 +1391,7 @@ def write_requirement_to_file(
|
||||
|
||||
|
||||
def pip_install(
|
||||
project,
|
||||
requirement=None,
|
||||
r=None,
|
||||
allow_global=False,
|
||||
@@ -1469,7 +1444,7 @@ def pip_install(
|
||||
include_hashes=not ignore_hashes
|
||||
)
|
||||
sources = get_source_list(
|
||||
index, extra_indexes=extra_indexes, trusted_hosts=trusted_hosts,
|
||||
project, index, extra_indexes=extra_indexes, trusted_hosts=trusted_hosts,
|
||||
pypi_mirror=pypi_mirror
|
||||
)
|
||||
if r:
|
||||
@@ -1484,9 +1459,9 @@ def pip_install(
|
||||
err=True,
|
||||
)
|
||||
|
||||
pip_command = [which("python", allow_global=allow_global), "-m", "pip", "install"]
|
||||
pip_command = [project._which("python", allow_global=allow_global), "-m", "pip", "install"]
|
||||
pip_args = get_pip_args(
|
||||
pre=pre, verbose=environments.is_verbose(), upgrade=True,
|
||||
project, pre=pre, verbose=environments.is_verbose(), upgrade=True,
|
||||
selective_upgrade=selective_upgrade, no_use_pep517=not use_pep517,
|
||||
no_deps=no_deps, require_hashes=not ignore_hashes,
|
||||
)
|
||||
@@ -1523,7 +1498,7 @@ def pip_install(
|
||||
return c
|
||||
|
||||
|
||||
def pip_download(package_name):
|
||||
def pip_download(project, package_name):
|
||||
cache_dir = vistir.compat.Path(PIPENV_CACHE_DIR)
|
||||
pip_config = {
|
||||
"PIP_CACHE_DIR": vistir.misc.fs_str(cache_dir.as_posix()),
|
||||
@@ -1534,7 +1509,7 @@ def pip_download(package_name):
|
||||
}
|
||||
for source in project.sources:
|
||||
cmd = [
|
||||
which_pip(),
|
||||
which_pip(project),
|
||||
"download",
|
||||
package_name,
|
||||
"-i", source["url"],
|
||||
@@ -1581,7 +1556,7 @@ def fallback_which(command, location=None, allow_global=False, system=False):
|
||||
return ""
|
||||
|
||||
|
||||
def which_pip(allow_global=False):
|
||||
def which_pip(project, allow_global=False):
|
||||
"""Returns the location of virtualenv-installed pip."""
|
||||
|
||||
location = None
|
||||
@@ -1589,7 +1564,7 @@ def which_pip(allow_global=False):
|
||||
location = os.environ["VIRTUAL_ENV"]
|
||||
if allow_global:
|
||||
if location:
|
||||
pip = which("pip", location=location)
|
||||
pip = project._which("pip", location=location)
|
||||
if pip:
|
||||
return pip
|
||||
|
||||
@@ -1598,7 +1573,7 @@ def which_pip(allow_global=False):
|
||||
if where:
|
||||
return where
|
||||
|
||||
pip = which("pip")
|
||||
pip = project._which("pip")
|
||||
if not pip:
|
||||
pip = fallback_which("pip", allow_global=allow_global, location=location)
|
||||
return pip
|
||||
@@ -1750,7 +1725,7 @@ def warn_in_virtualenv():
|
||||
)
|
||||
|
||||
|
||||
def ensure_lockfile(keep_outdated=False, pypi_mirror=None):
|
||||
def ensure_lockfile(project, keep_outdated=False, pypi_mirror=None):
|
||||
"""Ensures that the lockfile is up-to-date."""
|
||||
if not keep_outdated:
|
||||
keep_outdated = project.settings.get("keep_outdated")
|
||||
@@ -1768,12 +1743,12 @@ def ensure_lockfile(keep_outdated=False, pypi_mirror=None):
|
||||
),
|
||||
err=True,
|
||||
)
|
||||
do_lock(keep_outdated=keep_outdated, pypi_mirror=pypi_mirror)
|
||||
do_lock(project, keep_outdated=keep_outdated, pypi_mirror=pypi_mirror)
|
||||
else:
|
||||
do_lock(keep_outdated=keep_outdated, pypi_mirror=pypi_mirror)
|
||||
do_lock(project, keep_outdated=keep_outdated, pypi_mirror=pypi_mirror)
|
||||
|
||||
|
||||
def do_py(system=False):
|
||||
def do_py(project, system=False):
|
||||
if not project.virtualenv_exists:
|
||||
click.echo(
|
||||
"{}({}){}".format(
|
||||
@@ -1786,12 +1761,12 @@ def do_py(system=False):
|
||||
return
|
||||
|
||||
try:
|
||||
click.echo(which("python", allow_global=system))
|
||||
click.echo(project._which("python", allow_global=system))
|
||||
except AttributeError:
|
||||
click.echo(crayons.red("No project found!"))
|
||||
|
||||
|
||||
def do_outdated(pypi_mirror=None, pre=False, clear=False):
|
||||
def do_outdated(project, pypi_mirror=None, pre=False, clear=False):
|
||||
# TODO: Allow --skip-lock here?
|
||||
from collections import namedtuple
|
||||
|
||||
@@ -1817,7 +1792,7 @@ def do_outdated(pypi_mirror=None, pre=False, clear=False):
|
||||
dep = Requirement.from_line(str(result.as_requirement()))
|
||||
packages.update(dep.as_pipfile())
|
||||
updated_packages = {}
|
||||
lockfile = do_lock(clear=clear, pre=pre, write=False, pypi_mirror=pypi_mirror)
|
||||
lockfile = do_lock(project, clear=clear, pre=pre, write=False, pypi_mirror=pypi_mirror)
|
||||
for section in ("develop", "default"):
|
||||
for package in lockfile[section]:
|
||||
try:
|
||||
@@ -1870,6 +1845,7 @@ def do_outdated(pypi_mirror=None, pre=False, clear=False):
|
||||
|
||||
|
||||
def do_install(
|
||||
project,
|
||||
packages=False,
|
||||
editable_packages=False,
|
||||
index_url=False,
|
||||
@@ -1910,6 +1886,7 @@ def do_install(
|
||||
concurrent = not sequential
|
||||
# Ensure that virtualenv is available and pipfile are available
|
||||
ensure_project(
|
||||
project,
|
||||
three=three,
|
||||
python=python,
|
||||
system=system,
|
||||
@@ -1981,7 +1958,7 @@ def do_install(
|
||||
err=True,
|
||||
)
|
||||
try:
|
||||
import_requirements(r=project.path_to(requirementstxt), dev=dev)
|
||||
import_requirements(project, r=project.path_to(requirementstxt), dev=dev)
|
||||
except (UnicodeDecodeError, PipError) as e:
|
||||
# Don't print the temp file path if remote since it will be deleted.
|
||||
req_path = requirements_url if remote else project.path_to(requirementstxt)
|
||||
@@ -2042,6 +2019,7 @@ def do_install(
|
||||
if pre:
|
||||
project.update_settings({"allow_prereleases": pre})
|
||||
do_init(
|
||||
project,
|
||||
dev=dev,
|
||||
allow_global=system,
|
||||
ignore_pipfile=ignore_pipfile,
|
||||
@@ -2063,6 +2041,7 @@ def do_install(
|
||||
pkg_list = packages + [f'-e {pkg}' for pkg in editable_packages]
|
||||
if not system and not project.virtualenv_exists:
|
||||
do_init(
|
||||
project,
|
||||
dev=dev,
|
||||
system=system,
|
||||
allow_global=system,
|
||||
@@ -2103,6 +2082,7 @@ def do_install(
|
||||
if environments.is_verbose():
|
||||
sp.hide_and_write(f"Installing package: {pkg_requirement.as_line(include_hashes=False)}")
|
||||
c = pip_install(
|
||||
project,
|
||||
pkg_requirement,
|
||||
ignore_hashes=True,
|
||||
allow_global=system,
|
||||
@@ -2183,6 +2163,7 @@ def do_install(
|
||||
if pip_shims_module:
|
||||
os.environ["PIP_SHIMS_BASE_MODULE"] = pip_shims_module
|
||||
do_init(
|
||||
project,
|
||||
dev=dev,
|
||||
system=system,
|
||||
allow_global=system,
|
||||
@@ -2197,6 +2178,7 @@ def do_install(
|
||||
|
||||
|
||||
def do_uninstall(
|
||||
project,
|
||||
packages=False,
|
||||
editable_packages=False,
|
||||
three=None,
|
||||
@@ -2219,7 +2201,7 @@ def do_uninstall(
|
||||
# Ensure that virtualenv is available.
|
||||
# TODO: We probably shouldn't ensure a project exists if the outcome will be to just
|
||||
# install things in order to remove them... maybe tell the user to install first?
|
||||
ensure_project(three=three, python=python, pypi_mirror=pypi_mirror)
|
||||
ensure_project(project, three=three, python=python, pypi_mirror=pypi_mirror)
|
||||
# Un-install all dependencies, if --all was provided.
|
||||
if not any([packages, editable_packages, all_dev, all]):
|
||||
raise exceptions.PipenvUsageError("No package provided!", ctx=ctx)
|
||||
@@ -2275,7 +2257,7 @@ def do_uninstall(
|
||||
)), bold=True
|
||||
)
|
||||
)
|
||||
do_purge(bare=False, allow_global=system)
|
||||
do_purge(project, bare=False, allow_global=system)
|
||||
sys.exit(0)
|
||||
|
||||
selected_pkg_map = {
|
||||
@@ -2296,7 +2278,7 @@ def do_uninstall(
|
||||
if package_name in packages_to_remove:
|
||||
with project.environment.activated():
|
||||
if pip_path is None:
|
||||
pip_path = which_pip(allow_global=system)
|
||||
pip_path = which_pip(project, allow_global=system)
|
||||
cmd = [pip_path, "uninstall", package_name, "-y"]
|
||||
c = run_command(cmd)
|
||||
click.echo(crayons.cyan(c.stdout))
|
||||
@@ -2339,14 +2321,14 @@ def do_uninstall(
|
||||
if in_packages:
|
||||
project.remove_package_from_pipfile(package_name, dev=False)
|
||||
if lock:
|
||||
do_lock(system=system, keep_outdated=keep_outdated, pypi_mirror=pypi_mirror)
|
||||
do_lock(project, system=system, keep_outdated=keep_outdated, pypi_mirror=pypi_mirror)
|
||||
sys.exit(int(failure))
|
||||
|
||||
|
||||
def do_shell(three=None, python=False, fancy=False, shell_args=None, pypi_mirror=None):
|
||||
def do_shell(project, three=None, python=False, fancy=False, shell_args=None, pypi_mirror=None):
|
||||
# Ensure that virtualenv is available.
|
||||
ensure_project(
|
||||
three=three, python=python, validate=False, pypi_mirror=pypi_mirror,
|
||||
project, three=three, python=python, validate=False, pypi_mirror=pypi_mirror,
|
||||
)
|
||||
|
||||
# Support shell compatibility mode.
|
||||
@@ -2386,9 +2368,9 @@ def do_shell(three=None, python=False, fancy=False, shell_args=None, pypi_mirror
|
||||
shell.fork(*fork_args)
|
||||
|
||||
|
||||
def _inline_activate_virtualenv():
|
||||
def _inline_activate_virtualenv(project):
|
||||
try:
|
||||
activate_this = which("activate_this.py")
|
||||
activate_this = project._which("activate_this.py")
|
||||
if not activate_this or not os.path.exists(activate_this):
|
||||
raise exceptions.VirtualenvActivationException()
|
||||
with open(activate_this) as f:
|
||||
@@ -2405,7 +2387,7 @@ def _inline_activate_virtualenv():
|
||||
)
|
||||
|
||||
|
||||
def _inline_activate_venv():
|
||||
def _inline_activate_venv(project):
|
||||
"""Built-in venv doesn't have activate_this.py, but doesn't need it anyway.
|
||||
|
||||
As long as we find the correct executable, built-in venv sets up the
|
||||
@@ -2423,12 +2405,12 @@ def _inline_activate_venv():
|
||||
os.environ["PATH"] = os.pathsep.join(components)
|
||||
|
||||
|
||||
def inline_activate_virtual_environment():
|
||||
def inline_activate_virtual_environment(project):
|
||||
root = project.virtualenv_location
|
||||
if os.path.exists(os.path.join(root, "pyvenv.cfg")):
|
||||
_inline_activate_venv()
|
||||
_inline_activate_venv(project)
|
||||
else:
|
||||
_inline_activate_virtualenv()
|
||||
_inline_activate_virtualenv(project)
|
||||
if "VIRTUAL_ENV" not in os.environ:
|
||||
os.environ["VIRTUAL_ENV"] = vistir.misc.fs_str(root)
|
||||
|
||||
@@ -2456,13 +2438,13 @@ def _launch_windows_subprocess(script):
|
||||
return subprocess.Popen(script.cmdify(), shell=True, **options)
|
||||
|
||||
|
||||
def do_run_nt(script):
|
||||
def do_run_nt(project, script):
|
||||
p = _launch_windows_subprocess(script)
|
||||
p.communicate()
|
||||
sys.exit(p.returncode)
|
||||
|
||||
|
||||
def do_run_posix(script, command):
|
||||
def do_run_posix(project, script, command):
|
||||
command_path = system_which(script.command)
|
||||
if not command_path:
|
||||
if project.has_script(command):
|
||||
@@ -2493,7 +2475,7 @@ def do_run_posix(script, command):
|
||||
)
|
||||
|
||||
|
||||
def do_run(command, args, three=None, python=False, pypi_mirror=None):
|
||||
def do_run(project, command, args, three=None, python=False, pypi_mirror=None):
|
||||
"""Attempt to run command either pulling from project or interpreting as executable.
|
||||
|
||||
Args are appended to the command in [scripts] section of project if found.
|
||||
@@ -2502,15 +2484,15 @@ def do_run(command, args, three=None, python=False, pypi_mirror=None):
|
||||
|
||||
# Ensure that virtualenv is available.
|
||||
ensure_project(
|
||||
three=three, python=python, validate=False, pypi_mirror=pypi_mirror,
|
||||
project, three=three, python=python, validate=False, pypi_mirror=pypi_mirror,
|
||||
)
|
||||
|
||||
load_dot_env()
|
||||
load_dot_env(project)
|
||||
|
||||
previous_pip_shims_module = os.environ.pop("PIP_SHIMS_BASE_MODULE", None)
|
||||
|
||||
# Activate virtualenv under the current interpreter's environment
|
||||
inline_activate_virtual_environment()
|
||||
inline_activate_virtual_environment(project)
|
||||
|
||||
# Set an environment variable, so we know we're in the environment.
|
||||
# Only set PIPENV_ACTIVE after finishing reading virtualenv_location
|
||||
@@ -2528,7 +2510,7 @@ def do_run(command, args, three=None, python=False, pypi_mirror=None):
|
||||
click.echo(crayons.normal(f"$ {cmd_string}"), err=True)
|
||||
except ScriptEmptyError:
|
||||
click.echo("Can't run script {0!r}-it's empty?", err=True)
|
||||
run_args = [script]
|
||||
run_args = [project, script]
|
||||
run_kwargs = {}
|
||||
if os.name == "nt":
|
||||
run_fn = do_run_nt
|
||||
@@ -2546,6 +2528,7 @@ def do_run(command, args, three=None, python=False, pypi_mirror=None):
|
||||
|
||||
|
||||
def do_check(
|
||||
project,
|
||||
three=None,
|
||||
python=False,
|
||||
system=False,
|
||||
@@ -2564,6 +2547,7 @@ def do_check(
|
||||
if not system:
|
||||
# Ensure that virtualenv is available.
|
||||
ensure_project(
|
||||
project,
|
||||
three=three,
|
||||
python=python,
|
||||
validate=False,
|
||||
@@ -2599,7 +2583,7 @@ def do_check(
|
||||
os.path.dirname(os.path.abspath(__file__)), "patched", "safety"
|
||||
)
|
||||
if not system:
|
||||
python = which("python")
|
||||
python = project._which("python")
|
||||
else:
|
||||
python = first(system_which(p) for p in ("python", "python3", "python2"))
|
||||
if not python:
|
||||
@@ -2705,12 +2689,12 @@ def do_check(
|
||||
sys.exit(c.returncode)
|
||||
|
||||
|
||||
def do_graph(bare=False, json=False, json_tree=False, reverse=False):
|
||||
def do_graph(project, bare=False, json=False, json_tree=False, reverse=False):
|
||||
from pipenv.vendor import pipdeptree
|
||||
from pipenv.vendor.vistir.compat import JSONDecodeError
|
||||
pipdeptree_path = pipdeptree.__file__.rstrip("cdo")
|
||||
try:
|
||||
python_path = which("python")
|
||||
python_path = project._which("python")
|
||||
except AttributeError:
|
||||
click.echo(
|
||||
"{}: {}".format(
|
||||
@@ -2844,7 +2828,7 @@ def do_graph(bare=False, json=False, json_tree=False, reverse=False):
|
||||
|
||||
|
||||
def do_sync(
|
||||
ctx,
|
||||
project,
|
||||
dev=False,
|
||||
three=None,
|
||||
python=None,
|
||||
@@ -2864,6 +2848,7 @@ def do_sync(
|
||||
|
||||
# Ensure that virtualenv is available if not system.
|
||||
ensure_project(
|
||||
project,
|
||||
three=three,
|
||||
python=python,
|
||||
validate=False,
|
||||
@@ -2876,6 +2861,7 @@ def do_sync(
|
||||
suffix="-requirements", prefix="pipenv-"
|
||||
)
|
||||
do_init(
|
||||
project,
|
||||
dev=dev,
|
||||
allow_global=system,
|
||||
concurrent=(not sequential),
|
||||
@@ -2890,13 +2876,13 @@ def do_sync(
|
||||
|
||||
|
||||
def do_clean(
|
||||
ctx, three=None, python=None, dry_run=False, bare=False, pypi_mirror=None,
|
||||
project, three=None, python=None, dry_run=False, bare=False, pypi_mirror=None,
|
||||
system=False
|
||||
):
|
||||
# Ensure that virtualenv is available.
|
||||
from packaging.utils import canonicalize_name
|
||||
ensure_project(three=three, python=python, validate=False, pypi_mirror=pypi_mirror)
|
||||
ensure_lockfile(pypi_mirror=pypi_mirror)
|
||||
ensure_project(project, three=three, python=python, validate=False, pypi_mirror=pypi_mirror)
|
||||
ensure_lockfile(project, pypi_mirror=pypi_mirror)
|
||||
# Make sure that the virtualenv's site packages are configured correctly
|
||||
# otherwise we may end up removing from the global site packages directory
|
||||
installed_package_names = project.installed_package_names.copy()
|
||||
@@ -2914,7 +2900,7 @@ def do_clean(
|
||||
if used_package in installed_package_names:
|
||||
installed_package_names.remove(used_package)
|
||||
failure = False
|
||||
cmd = [which_pip(allow_global=system), "uninstall", "-y", "-qq"]
|
||||
cmd = [which_pip(project, allow_global=system), "uninstall", "-y", "-qq"]
|
||||
for apparent_bad_package in installed_package_names:
|
||||
if dry_run and not bare:
|
||||
click.echo(apparent_bad_package)
|
||||
@@ -2926,7 +2912,7 @@ def do_clean(
|
||||
)
|
||||
)
|
||||
# Uninstall the package.
|
||||
cmd = [which_pip(), "uninstall", apparent_bad_package, "-y"]
|
||||
cmd = [which_pip(project), "uninstall", apparent_bad_package, "-y"]
|
||||
c = run_command(cmd)
|
||||
if c.returncode != 0:
|
||||
failure = True
|
||||
|
||||
@@ -258,17 +258,6 @@ class SystemUsageError(PipenvOptionsError):
|
||||
super().__init__(option_name, message=message, ctx=ctx, extra=extra, **kwargs)
|
||||
|
||||
|
||||
class PipfileException(PipenvFileError):
|
||||
def __init__(self, hint=None, **kwargs):
|
||||
from .core import project
|
||||
|
||||
if not hint:
|
||||
hint = "{} {}".format(crayons.red("ERROR (PACKAGE NOT INSTALLED):"), hint)
|
||||
filename = project.pipfile_location
|
||||
extra = kwargs.pop("extra", [])
|
||||
PipenvFileError.__init__(self, filename, hint, extra=extra, **kwargs)
|
||||
|
||||
|
||||
class SetupException(PipenvException):
|
||||
def __init__(self, message=None, **kwargs):
|
||||
PipenvException.__init__(self, message, **kwargs)
|
||||
|
||||
+3
-3
@@ -4,7 +4,6 @@ import sys
|
||||
|
||||
import pipenv
|
||||
|
||||
from pipenv.core import project
|
||||
from pipenv.pep508checker import lookup
|
||||
from pipenv.vendor import pythonfinder
|
||||
|
||||
@@ -16,7 +15,7 @@ def print_utf(line):
|
||||
print(line.encode("utf-8"))
|
||||
|
||||
|
||||
def get_pipenv_diagnostics():
|
||||
def get_pipenv_diagnostics(project):
|
||||
print("<details><summary>$ pipenv --support</summary>")
|
||||
print("")
|
||||
print(f"Pipenv version: `{pipenv.__version__!r}`")
|
||||
@@ -82,4 +81,5 @@ def get_pipenv_diagnostics():
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
get_pipenv_diagnostics()
|
||||
from pipenv.project import Project
|
||||
get_pipenv_diagnostics(Project())
|
||||
|
||||
+49
-19
@@ -11,34 +11,37 @@ import re
|
||||
import sys
|
||||
import urllib.parse
|
||||
|
||||
import pipfile
|
||||
import pipfile.api
|
||||
import toml
|
||||
import tomlkit
|
||||
import vistir
|
||||
|
||||
import pipfile
|
||||
import pipfile.api
|
||||
|
||||
from pipenv.vendor.cached_property import cached_property
|
||||
|
||||
from pipenv.cmdparse import Script
|
||||
from pipenv.core import system_which
|
||||
from pipenv.environment import Environment
|
||||
from pipenv.environments import (
|
||||
PIPENV_DEFAULT_PYTHON_VERSION, PIPENV_IGNORE_VIRTUALENVS, PIPENV_MAX_DEPTH,
|
||||
PIPENV_PIPFILE, PIPENV_PYTHON, PIPENV_TEST_INDEX, PIPENV_VENV_IN_PROJECT,
|
||||
PIPENV_USE_SYSTEM, is_in_virtualenv, is_type_checking, is_using_venv
|
||||
PIPENV_PIPFILE, PIPENV_PYTHON, PIPENV_TEST_INDEX, PIPENV_USE_SYSTEM,
|
||||
PIPENV_VENV_IN_PROJECT, is_in_virtualenv, is_type_checking, is_using_venv
|
||||
)
|
||||
from pipenv.vendor.requirementslib.models.utils import get_default_pyproject_backend
|
||||
from pipenv.utils import (
|
||||
cleanup_toml, convert_toml_outline_tables, find_requirements,
|
||||
get_canonical_names, get_url_name, get_workon_home, is_editable,
|
||||
is_installable_file, is_star, is_valid_url, is_virtual_environment,
|
||||
looks_like_dir, normalize_drive, pep423_name, proper_case, python_version,
|
||||
safe_expandvars, get_pipenv_dist
|
||||
find_windows_executable, get_canonical_names, get_pipenv_dist, get_url_name,
|
||||
get_workon_home, is_editable, is_installable_file, is_star, is_valid_url,
|
||||
is_virtual_environment, looks_like_dir, normalize_drive, pep423_name,
|
||||
proper_case, python_version, safe_expandvars
|
||||
)
|
||||
from pipenv.vendor.cached_property import cached_property
|
||||
from pipenv.vendor.requirementslib.models.utils import (
|
||||
get_default_pyproject_backend
|
||||
)
|
||||
|
||||
|
||||
if is_type_checking():
|
||||
import pkg_resources
|
||||
from typing import Dict, List, Optional, Set, Text, Tuple, Union
|
||||
|
||||
import pkg_resources
|
||||
TSource = Dict[Text, Union[Text, bool]]
|
||||
TPackageEntry = Dict[str, Union[bool, str, List[str]]]
|
||||
TPackage = Dict[str, TPackageEntry]
|
||||
@@ -134,13 +137,12 @@ class SourceNotFound(KeyError):
|
||||
pass
|
||||
|
||||
|
||||
class Project(object):
|
||||
class Project:
|
||||
"""docstring for Project"""
|
||||
|
||||
_lockfile_encoder = _LockFileEncoder()
|
||||
|
||||
def __init__(self, which=None, python_version=None, chdir=True):
|
||||
super(Project, self).__init__()
|
||||
def __init__(self, python_version=None, chdir=True):
|
||||
self._name = None
|
||||
self._virtualenv_location = None
|
||||
self._download_location = None
|
||||
@@ -151,7 +153,6 @@ class Project(object):
|
||||
self._requirements_location = None
|
||||
self._original_dir = os.path.abspath(os.curdir)
|
||||
self._environment = None
|
||||
self._which = which
|
||||
self._build_system = {
|
||||
"requires": ["setuptools", "wheel"]
|
||||
}
|
||||
@@ -652,7 +653,8 @@ class Project(object):
|
||||
|
||||
@property
|
||||
def _pipfile(self):
|
||||
from .vendor.requirementslib.models.pipfile import Pipfile as ReqLibPipfile
|
||||
from .vendor.requirementslib.models.pipfile import \
|
||||
Pipfile as ReqLibPipfile
|
||||
pf = ReqLibPipfile.load(self.pipfile_location)
|
||||
return pf
|
||||
|
||||
@@ -735,6 +737,7 @@ class Project(object):
|
||||
def create_pipfile(self, python=None):
|
||||
"""Creates the Pipfile, filled with juicy defaults."""
|
||||
from .vendor.pip_shims.shims import InstallCommand
|
||||
|
||||
# Inherit the pip's index configuration of install command.
|
||||
command = InstallCommand()
|
||||
indexes = command.cmd_opts.get_option("--extra-index-url").default
|
||||
@@ -780,7 +783,8 @@ class Project(object):
|
||||
return source
|
||||
|
||||
def get_or_create_lockfile(self, from_pipfile=False):
|
||||
from pipenv.vendor.requirementslib.models.lockfile import Lockfile as Req_Lockfile
|
||||
from pipenv.vendor.requirementslib.models.lockfile import \
|
||||
Lockfile as Req_Lockfile
|
||||
lockfile = None
|
||||
if from_pipfile and self.pipfile_exists:
|
||||
lockfile_dict = {
|
||||
@@ -1141,3 +1145,29 @@ class Project(object):
|
||||
if as_path:
|
||||
result = str(result.path)
|
||||
return result
|
||||
|
||||
def _which(self, command, location=None, allow_global=False):
|
||||
if not allow_global and location is None:
|
||||
if self.virtualenv_exists:
|
||||
location = self.virtualenv_location
|
||||
else:
|
||||
location = os.environ.get("VIRTUAL_ENV", None)
|
||||
if not (location and os.path.exists(location)) and not allow_global:
|
||||
raise RuntimeError("location not created nor specified")
|
||||
|
||||
version_str = "python{}".format(".".join([str(v) for v in sys.version_info[:2]]))
|
||||
is_python = command in ("python", os.path.basename(sys.executable), version_str)
|
||||
if not allow_global:
|
||||
if os.name == "nt":
|
||||
p = find_windows_executable(os.path.join(location, "Scripts"), command)
|
||||
else:
|
||||
p = os.path.join(location, "bin", command)
|
||||
else:
|
||||
if is_python:
|
||||
p = sys.executable
|
||||
if not os.path.exists(p):
|
||||
if is_python:
|
||||
p = sys.executable or system_which("python")
|
||||
else:
|
||||
p = system_which(command)
|
||||
return p
|
||||
|
||||
+2
-1
@@ -688,7 +688,8 @@ def resolve_packages(pre, clear, verbose, system, write, requirements_dir, packa
|
||||
req_dir=requirements_dir
|
||||
)
|
||||
|
||||
from pipenv.core import project
|
||||
from pipenv.project import Project
|
||||
project = Project()
|
||||
sources = (
|
||||
replace_pypi_sources(project.pipfile_sources, pypi_mirror_source)
|
||||
if pypi_mirror_source
|
||||
|
||||
+9
-20
@@ -273,11 +273,9 @@ def prepare_pip_source_args(sources, pip_args=None):
|
||||
return pip_args
|
||||
|
||||
|
||||
def get_project_index(index=None, trusted_hosts=None, project=None):
|
||||
def get_project_index(project, index=None, trusted_hosts=None):
|
||||
# type: (Optional[Union[str, TSource]], Optional[List[str]], Optional[Project]) -> TSource
|
||||
from .project import SourceNotFound
|
||||
if not project:
|
||||
from .core import project
|
||||
if trusted_hosts is None:
|
||||
trusted_hosts = []
|
||||
if isinstance(index, Mapping):
|
||||
@@ -293,23 +291,21 @@ def get_project_index(index=None, trusted_hosts=None, project=None):
|
||||
|
||||
|
||||
def get_source_list(
|
||||
project, # type: Project
|
||||
index=None, # type: Optional[Union[str, TSource]]
|
||||
extra_indexes=None, # type: Optional[List[str]]
|
||||
trusted_hosts=None, # type: Optional[List[str]]
|
||||
pypi_mirror=None, # type: Optional[str]
|
||||
project=None, # type: Optional[Project]
|
||||
):
|
||||
# type: (...) -> List[TSource]
|
||||
sources = [] # type: List[TSource]
|
||||
if not project:
|
||||
from .core import project
|
||||
if index:
|
||||
sources.append(get_project_index(index))
|
||||
sources.append(get_project_index(project, index))
|
||||
if extra_indexes:
|
||||
if isinstance(extra_indexes, str):
|
||||
extra_indexes = [extra_indexes]
|
||||
for source in extra_indexes:
|
||||
extra_src = get_project_index(source)
|
||||
extra_src = get_project_index(project, source)
|
||||
if not sources or extra_src["url"] != sources[0]["url"]:
|
||||
sources.append(extra_src)
|
||||
else:
|
||||
@@ -326,10 +322,8 @@ def get_source_list(
|
||||
return sources
|
||||
|
||||
|
||||
def get_indexes_from_requirement(req, project=None, index=None, extra_indexes=None, trusted_hosts=None, pypi_mirror=None):
|
||||
# type: (Requirement, Optional[Project], Optional[Text], Optional[List[Text]], Optional[List[Text]], Optional[Text]) -> Tuple[TSource, List[TSource], List[Text]]
|
||||
if not project:
|
||||
from .core import project
|
||||
def get_indexes_from_requirement(req, project, ndex=None, extra_indexes=None, trusted_hosts=None, pypi_mirror=None):
|
||||
# type: (Requirement, Project, Optional[Text], Optional[List[Text]], Optional[List[Text]], Optional[Text]) -> Tuple[TSource, List[TSource], List[Text]]
|
||||
index_sources = [] # type: List[TSource]
|
||||
if not trusted_hosts:
|
||||
trusted_hosts = [] # type: List[Text]
|
||||
@@ -630,9 +624,9 @@ class Resolver:
|
||||
def create(
|
||||
cls,
|
||||
deps, # type: List[str]
|
||||
project, # type: Project
|
||||
index_lookup=None, # type: Dict[str, str]
|
||||
markers_lookup=None, # type: Dict[str, str]
|
||||
project=None, # type: Project
|
||||
sources=None, # type: List[str]
|
||||
req_dir=None, # type: str
|
||||
clear=False, # type: bool
|
||||
@@ -646,9 +640,6 @@ class Resolver:
|
||||
index_lookup = {}
|
||||
if markers_lookup is None:
|
||||
markers_lookup = {}
|
||||
if project is None:
|
||||
from pipenv.core import project
|
||||
project = project
|
||||
if sources is None:
|
||||
sources = project.sources
|
||||
constraints, skipped, index_lookup, markers_lookup = cls.get_metadata(
|
||||
@@ -661,11 +652,9 @@ class Resolver:
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def from_pipfile(cls, project=None, pipfile=None, dev=False, pre=False, clear=False):
|
||||
def from_pipfile(cls, project, pipfile=None, dev=False, pre=False, clear=False):
|
||||
# type: (Optional[Project], Optional[Pipfile], bool, bool, bool) -> "Resolver"
|
||||
from pipenv.vendor.vistir.path import create_tracked_tempdir
|
||||
if not project:
|
||||
from pipenv.core import project
|
||||
if not pipfile:
|
||||
pipfile = project._pipfile
|
||||
req_dir = create_tracked_tempdir(suffix="-requirements", prefix="pipenv-")
|
||||
@@ -1097,7 +1086,7 @@ def actually_resolve_deps(
|
||||
|
||||
with warnings.catch_warnings(record=True) as warning_list:
|
||||
resolver = Resolver.create(
|
||||
deps, index_lookup, markers_lookup, project, sources, req_dir, clear, pre
|
||||
deps, project, index_lookup, markers_lookup, sources, req_dir, clear, pre
|
||||
)
|
||||
resolver.resolve()
|
||||
hashes = resolver.resolve_hashes()
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def project():
|
||||
from pipenv.project import Project
|
||||
return Project()
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ def test_suppress_nested_venv_warning(capsys):
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def test_load_dot_env_from_environment_variable_location(monkeypatch, capsys):
|
||||
def test_load_dot_env_from_environment_variable_location(monkeypatch, capsys, project):
|
||||
with temp_environ(), monkeypatch.context() as m, TemporaryDirectory(prefix='pipenv-', suffix='') as tempdir:
|
||||
if os.name == "nt":
|
||||
import click
|
||||
@@ -33,12 +33,12 @@ def test_load_dot_env_from_environment_variable_location(monkeypatch, capsys):
|
||||
|
||||
m.setenv("PIPENV_DOTENV_LOCATION", str(dotenv_path))
|
||||
m.setattr("pipenv.environments.PIPENV_DOTENV_LOCATION", str(dotenv_path))
|
||||
load_dot_env()
|
||||
load_dot_env(project)
|
||||
assert os.environ[key] == val
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def test_doesnt_load_dot_env_if_disabled(monkeypatch, capsys):
|
||||
def test_doesnt_load_dot_env_if_disabled(monkeypatch, capsys, project):
|
||||
with temp_environ(), monkeypatch.context() as m, TemporaryDirectory(prefix='pipenv-', suffix='') as tempdir:
|
||||
if os.name == "nt":
|
||||
import click
|
||||
@@ -52,15 +52,15 @@ def test_doesnt_load_dot_env_if_disabled(monkeypatch, capsys):
|
||||
m.setenv("PIPENV_DOTENV_LOCATION", str(dotenv_path))
|
||||
m.setattr("pipenv.environments.PIPENV_DOTENV_LOCATION", str(dotenv_path))
|
||||
m.setattr("pipenv.environments.PIPENV_DONT_LOAD_ENV", True)
|
||||
load_dot_env()
|
||||
load_dot_env(project)
|
||||
assert key not in os.environ
|
||||
m.setattr("pipenv.environments.PIPENV_DONT_LOAD_ENV", False)
|
||||
load_dot_env()
|
||||
load_dot_env(project)
|
||||
assert key in os.environ
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def test_load_dot_env_warns_if_file_doesnt_exist(monkeypatch, capsys):
|
||||
def test_load_dot_env_warns_if_file_doesnt_exist(monkeypatch, capsys, project):
|
||||
with temp_environ(), monkeypatch.context() as m, TemporaryDirectory(prefix='pipenv-', suffix='') as tempdir:
|
||||
if os.name == "nt":
|
||||
import click
|
||||
@@ -69,6 +69,6 @@ def test_load_dot_env_warns_if_file_doesnt_exist(monkeypatch, capsys):
|
||||
dotenv_path = os.path.join(tempdir.name, 'does-not-exist.env')
|
||||
m.setenv("PIPENV_DOTENV_LOCATION", str(dotenv_path))
|
||||
m.setattr("pipenv.environments.PIPENV_DOTENV_LOCATION", str(dotenv_path))
|
||||
load_dot_env()
|
||||
load_dot_env(project)
|
||||
output, err = capsys.readouterr()
|
||||
assert 'Warning' in err
|
||||
|
||||
Reference in New Issue
Block a user