mirror of
https://github.com/kennethreitz/pipenv.git
synced 2026-06-05 06:46:15 +00:00
@@ -18,7 +18,7 @@ repos:
|
||||
exclude: .patch
|
||||
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
rev: v0.0.285
|
||||
rev: v0.0.286
|
||||
hooks:
|
||||
- id: ruff
|
||||
args: [--fix, --exit-non-zero-on-fix]
|
||||
|
||||
@@ -525,7 +525,7 @@ class Environment:
|
||||
if not loc.exists():
|
||||
continue
|
||||
for pth in loc.iterdir():
|
||||
if not pth.suffix == ".egg-link":
|
||||
if pth.suffix != ".egg-link":
|
||||
continue
|
||||
contents = [
|
||||
normalize_path(line.strip()) for line in pth.read_text().splitlines()
|
||||
@@ -688,10 +688,10 @@ class Environment:
|
||||
|
||||
tree = PackageDAG.from_pkgs(packages).sort()
|
||||
branch_keys = {r.key for r in flatten(tree.values())}
|
||||
if pkg is not None:
|
||||
nodes = [p for p in tree.keys() if p.key == pkg]
|
||||
if pkg is None:
|
||||
nodes = [p for p in tree if p.key not in branch_keys]
|
||||
else:
|
||||
nodes = [p for p in tree.keys() if p.key not in branch_keys]
|
||||
nodes = [p for p in tree if p.key == pkg]
|
||||
key_tree = {k.key: v for k, v in tree.items()}
|
||||
|
||||
return [self._get_requirements_for_package(p, key_tree) for p in nodes]
|
||||
|
||||
@@ -222,7 +222,7 @@ class Setting:
|
||||
_spinners.SPINNERS[None] = {"interval": 80, "frames": " "}
|
||||
self.PIPENV_SPINNER = None
|
||||
else:
|
||||
pipenv_spinner = "dots" if not os.name == "nt" else "bouncingBar"
|
||||
pipenv_spinner = "bouncingBar" if os.name == "nt" else "dots"
|
||||
self.PIPENV_SPINNER = get_from_env(
|
||||
"SPINNER", check_for_negation=False, default=pipenv_spinner
|
||||
)
|
||||
@@ -397,10 +397,10 @@ class Setting:
|
||||
del self.PIPENV_VERBOSE
|
||||
|
||||
def is_verbose(self, threshold=1):
|
||||
return self.PIPENV_VERBOSITY >= threshold
|
||||
return threshold <= self.PIPENV_VERBOSITY
|
||||
|
||||
def is_quiet(self, threshold=-1):
|
||||
return self.PIPENV_VERBOSITY <= threshold
|
||||
return threshold >= self.PIPENV_VERBOSITY
|
||||
|
||||
|
||||
def is_using_venv() -> bool:
|
||||
|
||||
+7
-8
@@ -21,6 +21,8 @@ try:
|
||||
except ImportError:
|
||||
from pipenv.vendor import tomli as toml
|
||||
|
||||
import contextlib
|
||||
|
||||
from pipenv.cmdparse import Script
|
||||
from pipenv.environment import Environment
|
||||
from pipenv.environments import Setting, is_in_virtualenv, normalize_pipfile_path
|
||||
@@ -208,10 +210,8 @@ class Project:
|
||||
|
||||
# Hack to skip this during pipenv run, or -r.
|
||||
if ("run" not in sys.argv) and chdir:
|
||||
try:
|
||||
with contextlib.suppress(TypeError, AttributeError):
|
||||
os.chdir(self.project_directory)
|
||||
except (TypeError, AttributeError):
|
||||
pass
|
||||
|
||||
def path_to(self, p: str) -> str:
|
||||
"""Returns the absolute path to a given relative path."""
|
||||
@@ -1079,7 +1079,7 @@ class Project:
|
||||
if section is None:
|
||||
section = {}
|
||||
package_name = pep423_name(package_name)
|
||||
for name in section.keys():
|
||||
for name in section:
|
||||
if pep423_name(name) == package_name:
|
||||
return name
|
||||
return None
|
||||
@@ -1218,10 +1218,9 @@ class Project:
|
||||
try:
|
||||
source = self.get_source(url=index)
|
||||
except SourceNotFound:
|
||||
try:
|
||||
with contextlib.suppress(SourceNotFound):
|
||||
source = self.get_source(name=index)
|
||||
except SourceNotFound:
|
||||
pass
|
||||
|
||||
if source is not None:
|
||||
return source["name"]
|
||||
source = {"url": index, "verify_ssl": verify_ssl}
|
||||
@@ -1312,7 +1311,7 @@ class Project:
|
||||
"""
|
||||
# Casing for section.
|
||||
changed_values = False
|
||||
unknown_names = [k for k in section.keys() if k not in set(self.proper_names)]
|
||||
unknown_names = [k for k in section if k not in set(self.proper_names)]
|
||||
# Replace each package with proper casing.
|
||||
for dep in unknown_names:
|
||||
try:
|
||||
|
||||
+4
-6
@@ -286,7 +286,7 @@ class Entry:
|
||||
|
||||
@property
|
||||
def is_in_pipfile(self):
|
||||
return True if self.pipfile_name else False
|
||||
return bool(self.pipfile_name)
|
||||
|
||||
@property
|
||||
def pipfile_packages(self):
|
||||
@@ -315,7 +315,7 @@ class Entry:
|
||||
def clean_specifier(specifier):
|
||||
from pipenv.patched.pip._vendor.packaging.specifiers import Specifier
|
||||
|
||||
if not any(specifier.startswith(k) for k in Specifier._operators.keys()):
|
||||
if not any(specifier.startswith(k) for k in Specifier._operators):
|
||||
if specifier.strip().lower() in ["any", "<any>", "*"]:
|
||||
return "*"
|
||||
specifier = f"=={specifier}"
|
||||
@@ -327,14 +327,12 @@ class Entry:
|
||||
def strip_version(specifier):
|
||||
from pipenv.patched.pip._vendor.packaging.specifiers import Specifier
|
||||
|
||||
op = next(
|
||||
iter(k for k in Specifier._operators.keys() if specifier.startswith(k)), None
|
||||
)
|
||||
op = next(iter(k for k in Specifier._operators if specifier.startswith(k)), None)
|
||||
if op:
|
||||
specifier = specifier[len(op) :]
|
||||
while op:
|
||||
op = next(
|
||||
iter(k for k in Specifier._operators.keys() if specifier.startswith(k)),
|
||||
iter(k for k in Specifier._operators if specifier.startswith(k)),
|
||||
None,
|
||||
)
|
||||
if op:
|
||||
|
||||
@@ -30,7 +30,7 @@ def do_graph(project, bare=False, json=False, json_tree=False, reverse=False):
|
||||
except RuntimeError:
|
||||
pass
|
||||
else:
|
||||
if not os.name == "nt": # bugfix #4388
|
||||
if os.name != "nt": # bugfix #4388
|
||||
python_path = Path(python_path).as_posix()
|
||||
pipdeptree_path = Path(pipdeptree_path).as_posix()
|
||||
|
||||
|
||||
@@ -604,13 +604,12 @@ def do_init(
|
||||
if categories is None:
|
||||
categories = []
|
||||
|
||||
if not system and not project.s.PIPENV_USE_SYSTEM:
|
||||
if not project.virtualenv_exists:
|
||||
try:
|
||||
do_create_virtualenv(project, python=python, pypi_mirror=pypi_mirror)
|
||||
except KeyboardInterrupt:
|
||||
cleanup_virtualenv(project, bare=False)
|
||||
sys.exit(1)
|
||||
if not system and not project.s.PIPENV_USE_SYSTEM and not project.virtualenv_exists:
|
||||
try:
|
||||
do_create_virtualenv(project, python=python, pypi_mirror=pypi_mirror)
|
||||
except KeyboardInterrupt:
|
||||
cleanup_virtualenv(project, bare=False)
|
||||
sys.exit(1)
|
||||
# Ensure the Pipfile exists.
|
||||
if not deploy:
|
||||
ensure_pipfile(project, system=system)
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import contextlib
|
||||
|
||||
from pipenv.utils.dependencies import (
|
||||
get_pipfile_category_using_lockfile_section,
|
||||
)
|
||||
@@ -54,10 +56,8 @@ def do_lock(
|
||||
)
|
||||
|
||||
# Prune old lockfile category as new one will be created.
|
||||
try:
|
||||
with contextlib.suppress(KeyError):
|
||||
old_lock_data = lockfile.pop(category)
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
from pipenv.utils.resolver import venv_resolve_deps
|
||||
|
||||
|
||||
+11
-12
@@ -41,15 +41,14 @@ def load_dot_env(project, as_dict=False, quiet=False):
|
||||
|
||||
def ensure_environment():
|
||||
# Skip this on Windows...
|
||||
if os.name != "nt":
|
||||
if "LANG" not in os.environ:
|
||||
click.echo(
|
||||
"{}: the environment variable {} is not set!"
|
||||
"\nWe recommend setting this in {} (or equivalent) for "
|
||||
"proper expected behavior.".format(
|
||||
click.style("Warning", fg="red", bold=True),
|
||||
click.style("LANG", bold=True),
|
||||
click.style("~/.profile", fg="green"),
|
||||
),
|
||||
err=True,
|
||||
)
|
||||
if os.name != "nt" and "LANG" not in os.environ:
|
||||
click.echo(
|
||||
"{}: the environment variable {} is not set!"
|
||||
"\nWe recommend setting this in {} (or equivalent) for "
|
||||
"proper expected behavior.".format(
|
||||
click.style("Warning", fg="red", bold=True),
|
||||
click.style("LANG", bold=True),
|
||||
click.style("~/.profile", fg="green"),
|
||||
),
|
||||
err=True,
|
||||
)
|
||||
|
||||
@@ -212,12 +212,9 @@ def create_tracked_tempdir(*args: Any, **kwargs: Any) -> str:
|
||||
def check_for_unc_path(path):
|
||||
# type: (Path) -> bool
|
||||
"""Checks to see if a pathlib `Path` object is a unc path or not."""
|
||||
if (
|
||||
return bool(
|
||||
os.name == "nt"
|
||||
and len(path.drive) > 2
|
||||
and not path.drive[0].isalpha()
|
||||
and path.drive[1] != ":"
|
||||
):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
)
|
||||
|
||||
@@ -348,13 +348,12 @@ def handle_remove_readonly(func, path, exc):
|
||||
try:
|
||||
func(path)
|
||||
except (OSError, FileNotFoundError, PermissionError) as e: # noqa:B014
|
||||
if e.errno in PERM_ERRORS:
|
||||
if e.errno != errno.ENOENT: # File still exists
|
||||
warnings.warn(
|
||||
default_warning_message.format(path),
|
||||
ResourceWarning,
|
||||
stacklevel=2,
|
||||
)
|
||||
if e.errno in PERM_ERRORS and e.errno != errno.ENOENT: # File still exists
|
||||
warnings.warn(
|
||||
default_warning_message.format(path),
|
||||
ResourceWarning,
|
||||
stacklevel=2,
|
||||
)
|
||||
return
|
||||
else:
|
||||
raise exc_exception
|
||||
|
||||
+6
-11
@@ -2,7 +2,7 @@ import copy
|
||||
import itertools
|
||||
import os
|
||||
import stat
|
||||
from contextlib import contextmanager
|
||||
from contextlib import contextmanager, suppress
|
||||
from json import JSONDecodeError
|
||||
from pathlib import Path
|
||||
from tempfile import NamedTemporaryFile
|
||||
@@ -61,10 +61,7 @@ def format_requirement_for_lockfile(
|
||||
if req.link and req.link.is_vcs:
|
||||
vcs = req.link.scheme.split("+", 1)[0]
|
||||
entry["ref"] = determine_vcs_revision_hash(req, vcs, pipfile_entry.get("ref"))
|
||||
if name in original_deps:
|
||||
entry[vcs] = original_deps[name]
|
||||
else:
|
||||
entry[vcs] = req.link.url
|
||||
entry[vcs] = original_deps.get(name, req.link.url)
|
||||
if pipfile_entry.get("subdirectory"):
|
||||
entry["subdirectory"] = pipfile_entry["subdirectory"]
|
||||
if req.req:
|
||||
@@ -218,18 +215,16 @@ def atomic_open_for_write(target, binary=False, newline=None, encoding=None) ->
|
||||
delete=False,
|
||||
)
|
||||
# set permissions to 0644
|
||||
try:
|
||||
with suppress(OSError):
|
||||
os.chmod(f.name, stat.S_IWUSR | stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
try:
|
||||
yield f
|
||||
except BaseException:
|
||||
f.close()
|
||||
try:
|
||||
with suppress(OSError):
|
||||
os.remove(f.name)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
raise
|
||||
else:
|
||||
f.close()
|
||||
|
||||
@@ -48,7 +48,7 @@ class PipenvMarkers(BaseModel):
|
||||
@classmethod
|
||||
def from_pipfile(cls, name, pipfile):
|
||||
attr_fields = list(cls.__fields__)
|
||||
found_keys = [k for k in pipfile.keys() if k in attr_fields]
|
||||
found_keys = [k for k in pipfile if k in attr_fields]
|
||||
marker_strings = [f"{k} {pipfile[k]}" for k in found_keys]
|
||||
if pipfile.get("markers"):
|
||||
marker_strings.append(pipfile.get("markers"))
|
||||
@@ -399,9 +399,8 @@ def _markers_contains_key(markers, key):
|
||||
for element in reversed(markers):
|
||||
if isinstance(element, tuple) and element[0].value == key:
|
||||
return True
|
||||
elif isinstance(element, list):
|
||||
if _markers_contains_key(element, key):
|
||||
return True
|
||||
elif isinstance(element, list) and _markers_contains_key(element, key):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
@@ -628,7 +627,7 @@ def normalize_marker_str(marker) -> str:
|
||||
|
||||
|
||||
def marker_from_specifier(spec) -> Marker:
|
||||
if not any(spec.startswith(k) for k in Specifier._operators.keys()):
|
||||
if not any(spec.startswith(k) for k in Specifier._operators):
|
||||
if spec.strip().lower() in ["any", "<any>", "*"]:
|
||||
return None
|
||||
spec = f"=={spec}"
|
||||
|
||||
+1
-1
@@ -136,7 +136,7 @@ def get_pip_args(
|
||||
"src_dir": src_dir,
|
||||
}
|
||||
arg_set = ["--no-input"] if project.settings.get("disable_pip_input", True) else []
|
||||
for key in arg_map.keys():
|
||||
for key in arg_map:
|
||||
if key in locals() and locals().get(key):
|
||||
arg_set.extend(arg_map.get(key))
|
||||
arg_set += extra_pip_args or []
|
||||
|
||||
+9
-14
@@ -1,3 +1,4 @@
|
||||
import contextlib
|
||||
import io
|
||||
import itertools
|
||||
import os
|
||||
@@ -55,11 +56,10 @@ def find_pipfile(max_depth=3):
|
||||
for c, _, _ in walk_up(os.getcwd()):
|
||||
i += 1
|
||||
|
||||
if i < max_depth:
|
||||
if "Pipfile":
|
||||
p = os.path.join(c, "Pipfile")
|
||||
if os.path.isfile(p):
|
||||
return p
|
||||
if i < max_depth and "Pipfile":
|
||||
p = os.path.join(c, "Pipfile")
|
||||
if os.path.isfile(p):
|
||||
return p
|
||||
raise RuntimeError("No Pipfile found!")
|
||||
|
||||
|
||||
@@ -190,10 +190,8 @@ class PipfileLoader(pipfiles.Pipfile):
|
||||
for key, klass in pipfiles.PIPFILE_SECTIONS.items():
|
||||
if key not in data or key == "sources":
|
||||
continue
|
||||
try:
|
||||
with contextlib.suppress(Exception):
|
||||
klass.validate(data[key])
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def ensure_package_sections(cls, data):
|
||||
@@ -207,9 +205,7 @@ class PipfileLoader(pipfiles.Pipfile):
|
||||
sections are present
|
||||
:rtype: :class:`~tomlkit.toml_document.TOMLDocument`
|
||||
"""
|
||||
package_keys = (
|
||||
k for k in pipfiles.PIPFILE_SECTIONS.keys() if k.endswith("packages")
|
||||
)
|
||||
package_keys = (k for k in pipfiles.PIPFILE_SECTIONS if k.endswith("packages"))
|
||||
for key in package_keys:
|
||||
if key not in data:
|
||||
data.update({key: tomlkit.table()})
|
||||
@@ -401,9 +397,8 @@ class Pipfile(BaseModel):
|
||||
project_path = pipfile_path.parent
|
||||
if not project_path.exists():
|
||||
raise FileNotFoundError("%s is not a valid project path!" % path)
|
||||
elif not pipfile_path.exists() or not pipfile_path.is_file():
|
||||
if not create:
|
||||
raise RequirementError("%s is not a valid Pipfile" % pipfile_path)
|
||||
elif (not pipfile_path.exists() or not pipfile_path.is_file()) and not create:
|
||||
raise RequirementError("%s is not a valid Pipfile" % pipfile_path)
|
||||
return cls.read_projectfile(pipfile_path.as_posix())
|
||||
|
||||
@classmethod
|
||||
|
||||
@@ -63,15 +63,14 @@ VCS_SCHEMES = [
|
||||
def strip_ssh_from_git_uri(uri):
|
||||
# type: (S) -> S
|
||||
"""Return git+ssh:// formatted URI to git+git@ format."""
|
||||
if isinstance(uri, str):
|
||||
if "git+ssh://" in uri:
|
||||
parsed = urlparse(uri)
|
||||
# split the path on the first separating / so we can put the first segment
|
||||
# into the 'netloc' section with a : separator
|
||||
path_part, _, path = parsed.path.lstrip("/").partition("/")
|
||||
path = f"/{path}"
|
||||
parsed = parsed._replace(netloc=f"{parsed.netloc}:{path_part}", path=path)
|
||||
uri = urlunparse(parsed).replace("git+ssh://", "git+", 1)
|
||||
if isinstance(uri, str) and "git+ssh://" in uri:
|
||||
parsed = urlparse(uri)
|
||||
# split the path on the first separating / so we can put the first segment
|
||||
# into the 'netloc' section with a : separator
|
||||
path_part, _, path = parsed.path.lstrip("/").partition("/")
|
||||
path = f"/{path}"
|
||||
parsed = parsed._replace(netloc=f"{parsed.netloc}:{path_part}", path=path)
|
||||
uri = urlunparse(parsed).replace("git+ssh://", "git+", 1)
|
||||
return uri
|
||||
|
||||
|
||||
@@ -94,7 +93,7 @@ def is_vcs(pipfile_entry):
|
||||
# type: (PipfileType) -> bool
|
||||
"""Determine if dictionary entry from Pipfile is for a vcs dependency."""
|
||||
if isinstance(pipfile_entry, Mapping):
|
||||
return any(key for key in pipfile_entry.keys() if key in VCS_LIST)
|
||||
return any(key for key in pipfile_entry if key in VCS_LIST)
|
||||
|
||||
elif isinstance(pipfile_entry, str):
|
||||
if not is_valid_url(pipfile_entry) and pipfile_entry.startswith("git+"):
|
||||
@@ -136,9 +135,7 @@ def convert_entry_to_path(path):
|
||||
|
||||
elif "path" in path:
|
||||
path = path["path"]
|
||||
if not os.name == "nt":
|
||||
return os.fsdecode(path)
|
||||
return Path(os.fsdecode(path)).as_posix()
|
||||
return Path(os.fsdecode(path)).as_posix() if os.name == "nt" else os.fsdecode(path)
|
||||
|
||||
|
||||
def is_installable_file(path):
|
||||
|
||||
@@ -548,7 +548,7 @@ class Resolver:
|
||||
reqs = [(ireq,) for ireq in self.resolved_tree]
|
||||
results = {}
|
||||
for (ireq,) in reqs:
|
||||
if normalize_name(ireq.name) in self.skipped.keys():
|
||||
if normalize_name(ireq.name) in self.skipped:
|
||||
continue
|
||||
collected_hashes = self.hashes.get(ireq, set())
|
||||
if collected_hashes:
|
||||
|
||||
@@ -199,16 +199,12 @@ def get_workon_home():
|
||||
def is_file(package):
|
||||
"""Determine if a package name is for a File dependency."""
|
||||
if hasattr(package, "keys"):
|
||||
return any(key for key in package.keys() if key in ["file", "path"])
|
||||
return any(key for key in package if key in ["file", "path"])
|
||||
|
||||
if os.path.exists(str(package)):
|
||||
return True
|
||||
|
||||
for start in SCHEME_LIST:
|
||||
if str(package).startswith(start):
|
||||
return True
|
||||
|
||||
return False
|
||||
return any(str(package).startswith(start) for start in SCHEME_LIST)
|
||||
|
||||
|
||||
def is_virtual_environment(path):
|
||||
|
||||
@@ -23,10 +23,9 @@ def cleanup_toml(tml):
|
||||
# Add newlines between TOML sections.
|
||||
for i, line in enumerate(toml.split("\n")):
|
||||
# Skip the first line.
|
||||
if line.startswith("["):
|
||||
if i > 0:
|
||||
# Insert a newline before the heading.
|
||||
new_toml.append("")
|
||||
if line.startswith("[") and i > 0:
|
||||
# Insert a newline before the heading.
|
||||
new_toml.append("")
|
||||
new_toml.append(line)
|
||||
# adding new line at the end of the TOML file
|
||||
new_toml.append("")
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import contextlib
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
@@ -179,12 +180,11 @@ def ensure_virtualenv(project, python=None, site_packages=None, pypi_mirror=None
|
||||
# If VIRTUAL_ENV is set, there is a possibility that we are
|
||||
# going to remove the active virtualenv that the user cares
|
||||
# about, so confirm first.
|
||||
if "VIRTUAL_ENV" in os.environ:
|
||||
if not (
|
||||
project.s.PIPENV_YES
|
||||
or click.confirm("Use existing virtualenv?", default=True)
|
||||
):
|
||||
abort()
|
||||
if "VIRTUAL_ENV" in os.environ and not (
|
||||
project.s.PIPENV_YES
|
||||
or click.confirm("Use existing virtualenv?", default=True)
|
||||
):
|
||||
abort()
|
||||
click.echo(click.style("Using existing virtualenv...", bold=True), err=True)
|
||||
# Remove the virtualenv.
|
||||
cleanup_virtualenv(project, bare=True)
|
||||
@@ -261,15 +261,12 @@ def ensure_python(project, python=None):
|
||||
# method of the user for new python installs.
|
||||
installer = None
|
||||
if not project.s.PIPENV_DONT_USE_PYENV:
|
||||
try:
|
||||
with contextlib.suppress(InstallerNotFound):
|
||||
installer = Pyenv(project)
|
||||
except InstallerNotFound:
|
||||
pass
|
||||
|
||||
if installer is None and not project.s.PIPENV_DONT_USE_ASDF:
|
||||
try:
|
||||
with contextlib.suppress(InstallerNotFound):
|
||||
installer = Asdf(project)
|
||||
except InstallerNotFound:
|
||||
pass
|
||||
|
||||
if not installer:
|
||||
abort("Neither 'pyenv' nor 'asdf' could be found to install Python.")
|
||||
|
||||
@@ -395,9 +395,10 @@ def vendor(ctx, vendor_dir, package=None, rewrite=True):
|
||||
log("Rewriting imports for %s..." % item)
|
||||
rewrite_imports(item, vendored_libs)
|
||||
rename_if_needed(ctx, vendor_dir, item)
|
||||
elif item.name not in FILE_WHITE_LIST:
|
||||
if rewrite and not package or (package and item.stem.lower() in package):
|
||||
rewrite_file_imports(item, vendored_libs)
|
||||
elif item.name not in FILE_WHITE_LIST and (
|
||||
rewrite and not package or (package and item.stem.lower() in package)
|
||||
):
|
||||
rewrite_file_imports(item, vendored_libs)
|
||||
if not package:
|
||||
apply_patches(ctx, patched=is_patched, pre=False)
|
||||
if is_patched:
|
||||
@@ -793,9 +794,8 @@ def vendor_artifact(ctx, package, version=None):
|
||||
dest_dir.mkdir()
|
||||
_, _, dest_path = urllib3_parse(link).path.rpartition("/")
|
||||
dest_file = dest_dir / dest_path
|
||||
with open(dest_file.as_posix(), "wb") as target_handle:
|
||||
with open_file(link) as fp:
|
||||
if fp is None:
|
||||
print(f"Error downloading {link}")
|
||||
continue
|
||||
shutil.copyfileobj(fp, target_handle)
|
||||
with open(dest_file.as_posix(), "wb") as target_handle, open_file(link) as fp:
|
||||
if fp is None:
|
||||
print(f"Error downloading {link}")
|
||||
continue
|
||||
shutil.copyfileobj(fp, target_handle)
|
||||
|
||||
@@ -18,6 +18,7 @@ from pipenv.vendor import tomlkit
|
||||
from pipenv.utils.processes import subprocess_run
|
||||
from pipenv.utils.funktools import handle_remove_readonly
|
||||
from pipenv.utils.shell import temp_environ
|
||||
import contextlib
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
warnings.simplefilter("default", category=ResourceWarning)
|
||||
@@ -61,7 +62,7 @@ def check_github_ssh():
|
||||
# registered with GitHub. Otherwise, the command will fail with
|
||||
# return_code=255 and say 'Permission denied (publickey).'
|
||||
c = subprocess_run('ssh -o StrictHostKeyChecking=no -o CheckHostIP=no -T git@github.com', timeout=30, shell=True)
|
||||
res = True if c.returncode == 1 else False
|
||||
res = c.returncode == 1
|
||||
except KeyboardInterrupt:
|
||||
warnings.warn(
|
||||
"KeyboardInterrupt while checking GitHub ssh access", RuntimeWarning, stacklevel=1
|
||||
@@ -145,9 +146,8 @@ class _Pipfile:
|
||||
|
||||
def remove(self, package, dev=False):
|
||||
section = "packages" if not dev else "dev-packages"
|
||||
if not dev and package not in self.document[section]:
|
||||
if package in self.document["dev-packages"]:
|
||||
section = "dev-packages"
|
||||
if not dev and package not in self.document[section] and package in self.document["dev-packages"]:
|
||||
section = "dev-packages"
|
||||
del self.document[section][package]
|
||||
self.write()
|
||||
|
||||
@@ -164,7 +164,7 @@ class _Pipfile:
|
||||
if not self.document.get("source"):
|
||||
source_table = tomlkit.table()
|
||||
source_table["url"] = self.index
|
||||
source_table["verify_ssl"] = True if self.index.startswith("https") else False
|
||||
source_table["verify_ssl"] = bool(self.index.startswith("https"))
|
||||
source_table["name"] = "pipenv_test_index"
|
||||
self.document["source"].append(source_table)
|
||||
return tomlkit.dumps(self.document)
|
||||
@@ -204,10 +204,9 @@ class _PipenvInstance:
|
||||
self.pipfile_path = p_path
|
||||
|
||||
if pipfile:
|
||||
try:
|
||||
with contextlib.suppress(FileNotFoundError):
|
||||
os.remove(p_path)
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
|
||||
with open(p_path, 'a'):
|
||||
os.utime(p_path, None)
|
||||
|
||||
@@ -221,10 +220,9 @@ class _PipenvInstance:
|
||||
def __exit__(self, *args):
|
||||
warn_msg = 'Failed to remove resource: {!r}'
|
||||
if self.pipfile_path:
|
||||
try:
|
||||
with contextlib.suppress(OSError):
|
||||
os.remove(self.pipfile_path)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
os.chdir(self.original_dir)
|
||||
if self._path:
|
||||
try:
|
||||
|
||||
@@ -50,17 +50,16 @@ def test_venv_in_project_disabled_ignores_venv(false_value, pipenv_instance_pypi
|
||||
@pytest.mark.dotvenv
|
||||
@pytest.mark.parametrize("true_value", TRUE_VALUES)
|
||||
def test_venv_at_project_root(true_value, pipenv_instance_pypi):
|
||||
with temp_environ():
|
||||
with pipenv_instance_pypi() as p:
|
||||
os.environ['PIPENV_VENV_IN_PROJECT'] = true_value
|
||||
c = p.pipenv('install')
|
||||
assert c.returncode == 0
|
||||
assert normalize_drive(p.path) in p.pipenv('--venv').stdout
|
||||
del os.environ['PIPENV_VENV_IN_PROJECT']
|
||||
os.mkdir('subdir')
|
||||
os.chdir('subdir')
|
||||
# should still detect installed
|
||||
assert normalize_drive(p.path) in p.pipenv('--venv').stdout
|
||||
with temp_environ(), pipenv_instance_pypi() as p:
|
||||
os.environ['PIPENV_VENV_IN_PROJECT'] = true_value
|
||||
c = p.pipenv('install')
|
||||
assert c.returncode == 0
|
||||
assert normalize_drive(p.path) in p.pipenv('--venv').stdout
|
||||
del os.environ['PIPENV_VENV_IN_PROJECT']
|
||||
os.mkdir('subdir')
|
||||
os.chdir('subdir')
|
||||
# should still detect installed
|
||||
assert normalize_drive(p.path) in p.pipenv('--venv').stdout
|
||||
|
||||
|
||||
@pytest.mark.dotvenv
|
||||
@@ -136,22 +135,21 @@ def test_empty_venv_file(pipenv_instance_pypi):
|
||||
def test_venv_in_project_default_when_venv_exists(pipenv_instance_pypi):
|
||||
"""Tests virtualenv creation when a .venv file exists at the project root.
|
||||
"""
|
||||
with temp_environ(), pipenv_instance_pypi() as p:
|
||||
with TemporaryDirectory(
|
||||
prefix='pipenv-', suffix='-test_venv'
|
||||
) as venv_path:
|
||||
file_path = os.path.join(p.path, '.venv')
|
||||
with open(file_path, 'w') as f:
|
||||
f.write(venv_path)
|
||||
with temp_environ(), pipenv_instance_pypi() as p, TemporaryDirectory(
|
||||
prefix='pipenv-', suffix='-test_venv'
|
||||
) as venv_path:
|
||||
file_path = os.path.join(p.path, '.venv')
|
||||
with open(file_path, 'w') as f:
|
||||
f.write(venv_path)
|
||||
|
||||
c = p.pipenv('install')
|
||||
assert c.returncode == 0
|
||||
c = p.pipenv('--venv')
|
||||
assert c.returncode == 0
|
||||
venv_loc = Path(c.stdout.strip())
|
||||
c = p.pipenv('install')
|
||||
assert c.returncode == 0
|
||||
c = p.pipenv('--venv')
|
||||
assert c.returncode == 0
|
||||
venv_loc = Path(c.stdout.strip())
|
||||
|
||||
assert venv_loc.joinpath('.project').exists()
|
||||
assert venv_loc == Path(venv_path)
|
||||
assert venv_loc.joinpath('.project').exists()
|
||||
assert venv_loc == Path(venv_path)
|
||||
|
||||
|
||||
@pytest.mark.dotenv
|
||||
|
||||
@@ -31,8 +31,8 @@ def test_mirror_install(pipenv_instance_pypi):
|
||||
# Ensure the --pypi-mirror parameter hasn't altered the Pipfile or Pipfile.lock sources
|
||||
assert len(p.pipfile["source"]) == 1
|
||||
assert len(p.lockfile["_meta"]["sources"]) == 1
|
||||
assert "https://pypi.org/simple" == p.pipfile["source"][0]["url"]
|
||||
assert "https://pypi.org/simple" == p.lockfile["_meta"]["sources"][0]["url"]
|
||||
assert p.pipfile["source"][0]["url"] == "https://pypi.org/simple"
|
||||
assert p.lockfile["_meta"]["sources"][0]["url"] == "https://pypi.org/simple"
|
||||
|
||||
assert "dataclasses-json" in p.pipfile["packages"]
|
||||
assert "dataclasses-json" in p.lockfile["default"]
|
||||
@@ -345,21 +345,20 @@ def test_editable_no_args(pipenv_instance_pypi):
|
||||
def test_install_venv_project_directory(pipenv_instance_pypi):
|
||||
"""Test the project functionality during virtualenv creation.
|
||||
"""
|
||||
with pipenv_instance_pypi() as p:
|
||||
with temp_environ(), TemporaryDirectory(
|
||||
prefix="pipenv-", suffix="temp_workon_home"
|
||||
) as workon_home:
|
||||
os.environ["WORKON_HOME"] = workon_home
|
||||
with pipenv_instance_pypi() as p, temp_environ(), TemporaryDirectory(
|
||||
prefix="pipenv-", suffix="temp_workon_home"
|
||||
) as workon_home:
|
||||
os.environ["WORKON_HOME"] = workon_home
|
||||
|
||||
c = p.pipenv("install six")
|
||||
assert c.returncode == 0
|
||||
c = p.pipenv("install six")
|
||||
assert c.returncode == 0
|
||||
|
||||
venv_loc = None
|
||||
for line in c.stderr.splitlines():
|
||||
if line.startswith("Virtualenv location:"):
|
||||
venv_loc = Path(line.split(":", 1)[-1].strip())
|
||||
assert venv_loc is not None
|
||||
assert venv_loc.joinpath(".project").exists()
|
||||
venv_loc = None
|
||||
for line in c.stderr.splitlines():
|
||||
if line.startswith("Virtualenv location:"):
|
||||
venv_loc = Path(line.split(":", 1)[-1].strip())
|
||||
assert venv_loc is not None
|
||||
assert venv_loc.joinpath(".project").exists()
|
||||
|
||||
|
||||
@pytest.mark.cli
|
||||
|
||||
@@ -157,10 +157,9 @@ def test_resolver_unique_markers(pipenv_instance_pypi):
|
||||
@pytest.mark.project
|
||||
@pytest.mark.needs_internet
|
||||
def test_environment_variable_value_does_not_change_hash(pipenv_instance_private_pypi):
|
||||
with pipenv_instance_private_pypi() as p:
|
||||
with temp_environ():
|
||||
with open(p.pipfile_path, 'w') as f:
|
||||
f.write("""
|
||||
with pipenv_instance_private_pypi() as p, temp_environ():
|
||||
with open(p.pipfile_path, 'w') as f:
|
||||
f.write("""
|
||||
[[source]]
|
||||
url = 'https://${PYPI_USERNAME}:${PYPI_PASSWORD}@pypi.org/simple'
|
||||
verify_ssl = true
|
||||
@@ -169,24 +168,24 @@ name = 'pypi'
|
||||
[packages]
|
||||
six = "*"
|
||||
""")
|
||||
project = Project()
|
||||
project = Project()
|
||||
|
||||
os.environ['PYPI_USERNAME'] = 'whatever'
|
||||
os.environ['PYPI_PASSWORD'] = 'pass'
|
||||
assert project.get_lockfile_hash() is None
|
||||
os.environ['PYPI_USERNAME'] = 'whatever'
|
||||
os.environ['PYPI_PASSWORD'] = 'pass'
|
||||
assert project.get_lockfile_hash() is None
|
||||
|
||||
c = p.pipenv('install')
|
||||
assert c.returncode == 0
|
||||
lock_hash = project.get_lockfile_hash()
|
||||
assert lock_hash is not None
|
||||
assert lock_hash == project.calculate_pipfile_hash()
|
||||
c = p.pipenv('install')
|
||||
assert c.returncode == 0
|
||||
lock_hash = project.get_lockfile_hash()
|
||||
assert lock_hash is not None
|
||||
assert lock_hash == project.calculate_pipfile_hash()
|
||||
|
||||
assert c.returncode == 0
|
||||
assert project.get_lockfile_hash() == project.calculate_pipfile_hash()
|
||||
assert c.returncode == 0
|
||||
assert project.get_lockfile_hash() == project.calculate_pipfile_hash()
|
||||
|
||||
os.environ['PYPI_PASSWORD'] = 'pass2'
|
||||
assert project.get_lockfile_hash() == project.calculate_pipfile_hash()
|
||||
os.environ['PYPI_PASSWORD'] = 'pass2'
|
||||
assert project.get_lockfile_hash() == project.calculate_pipfile_hash()
|
||||
|
||||
with open(p.pipfile_path, 'a') as f:
|
||||
f.write('requests = "==2.14.0"\n')
|
||||
assert project.get_lockfile_hash() != project.calculate_pipfile_hash()
|
||||
with open(p.pipfile_path, 'a') as f:
|
||||
f.write('requests = "==2.14.0"\n')
|
||||
assert project.get_lockfile_hash() != project.calculate_pipfile_hash()
|
||||
|
||||
@@ -220,19 +220,18 @@ allow_prereleases = true
|
||||
@flaky
|
||||
def test_complex_deps_lock_and_install_properly(pipenv_instance_pypi):
|
||||
# This uses the real PyPI because Maya has too many dependencies...
|
||||
with pipenv_instance_pypi() as p:
|
||||
with open(p.pipfile_path, 'w') as f:
|
||||
contents = """
|
||||
with pipenv_instance_pypi() as p, open(p.pipfile_path, 'w') as f:
|
||||
contents = """
|
||||
[packages]
|
||||
maya = "*"
|
||||
""".strip()
|
||||
f.write(contents)
|
||||
f.write(contents)
|
||||
|
||||
c = p.pipenv('lock --verbose')
|
||||
assert c.returncode == 0
|
||||
c = p.pipenv('lock --verbose')
|
||||
assert c.returncode == 0
|
||||
|
||||
c = p.pipenv('install')
|
||||
assert c.returncode == 0
|
||||
c = p.pipenv('install')
|
||||
assert c.returncode == 0
|
||||
|
||||
|
||||
@pytest.mark.lock
|
||||
|
||||
@@ -74,11 +74,10 @@ def test_proper_names_unmanaged_virtualenv(pipenv_instance_pypi):
|
||||
|
||||
@pytest.mark.cli
|
||||
def test_directory_with_leading_dash(pipenv_instance_pypi):
|
||||
with temp_environ():
|
||||
with pipenv_instance_pypi() as p:
|
||||
c = p.pipenv('run pip freeze')
|
||||
assert c.returncode == 0
|
||||
c = p.pipenv('--venv')
|
||||
assert c.returncode == 0
|
||||
venv_path = c.stdout.strip()
|
||||
assert os.path.isdir(venv_path)
|
||||
with temp_environ(), pipenv_instance_pypi() as p:
|
||||
c = p.pipenv('run pip freeze')
|
||||
assert c.returncode == 0
|
||||
c = p.pipenv('--venv')
|
||||
assert c.returncode == 0
|
||||
venv_path = c.stdout.strip()
|
||||
assert os.path.isdir(venv_path)
|
||||
|
||||
@@ -13,10 +13,9 @@ from pipenv.utils.fileutils import normalize_path
|
||||
@pytest.mark.sources
|
||||
@pytest.mark.environ
|
||||
def test_pipfile_envvar_expansion(pipenv_instance_pypi):
|
||||
with pipenv_instance_pypi() as p:
|
||||
with temp_environ():
|
||||
with open(p.pipfile_path, 'w') as f:
|
||||
f.write("""
|
||||
with pipenv_instance_pypi() as p, temp_environ():
|
||||
with open(p.pipfile_path, 'w') as f:
|
||||
f.write("""
|
||||
[[source]]
|
||||
url = 'https://${TEST_HOST}/simple'
|
||||
verify_ssl = false
|
||||
@@ -25,11 +24,11 @@ name = "pypi"
|
||||
[packages]
|
||||
pytz = "*"
|
||||
""".strip())
|
||||
os.environ['TEST_HOST'] = 'localhost:5000'
|
||||
project = Project()
|
||||
assert project.sources[0]['url'] == 'https://localhost:5000/simple'
|
||||
assert 'localhost:5000' not in str(Pipfile.load(open(p.pipfile_path)))
|
||||
print(str(Pipfile.load(open(p.pipfile_path))))
|
||||
os.environ['TEST_HOST'] = 'localhost:5000'
|
||||
project = Project()
|
||||
assert project.sources[0]['url'] == 'https://localhost:5000/simple'
|
||||
assert 'localhost:5000' not in str(Pipfile.load(open(p.pipfile_path)))
|
||||
print(str(Pipfile.load(open(p.pipfile_path))))
|
||||
|
||||
|
||||
@pytest.mark.project
|
||||
|
||||
@@ -60,8 +60,8 @@ def test_mirror_uninstall(pipenv_instance_pypi):
|
||||
# Ensure the --pypi-mirror parameter hasn't altered the Pipfile or Pipfile.lock sources
|
||||
assert len(p.pipfile["source"]) == 1
|
||||
assert len(p.lockfile["_meta"]["sources"]) == 1
|
||||
assert "https://pypi.org/simple" == p.pipfile["source"][0]["url"]
|
||||
assert "https://pypi.org/simple" == p.lockfile["_meta"]["sources"][0]["url"]
|
||||
assert p.pipfile["source"][0]["url"] == "https://pypi.org/simple"
|
||||
assert p.lockfile["_meta"]["sources"][0]["url"] == "https://pypi.org/simple"
|
||||
|
||||
c = p.pipenv("run python -m django --version")
|
||||
assert c.returncode == 0
|
||||
@@ -74,8 +74,8 @@ def test_mirror_uninstall(pipenv_instance_pypi):
|
||||
# Ensure the --pypi-mirror parameter hasn't altered the Pipfile or Pipfile.lock sources
|
||||
assert len(p.pipfile["source"]) == 1
|
||||
assert len(p.lockfile["_meta"]["sources"]) == 1
|
||||
assert "https://pypi.org/simple" == p.pipfile["source"][0]["url"]
|
||||
assert "https://pypi.org/simple" == p.lockfile["_meta"]["sources"][0]["url"]
|
||||
assert p.pipfile["source"][0]["url"] == "https://pypi.org/simple"
|
||||
assert p.lockfile["_meta"]["sources"][0]["url"] == "https://pypi.org/simple"
|
||||
|
||||
c = p.pipenv("run python -m django --version")
|
||||
assert c.returncode > 0
|
||||
|
||||
Reference in New Issue
Block a user