Attempt to fix the local/editable file installs (#5870)

* Attempt to fix the local/editable file installs

* More refinements to handling directories vs files and when it is relative vs not

* Add back missing egg fragment (I removed it during the initial removal of requirementslib).  Also fix the latest ruff error.
This commit is contained in:
Matt Davis
2023-08-26 08:54:43 -04:00
committed by GitHub
parent 60c8c97a6c
commit a3b197e491
4 changed files with 17 additions and 32 deletions
+3 -2
View File
@@ -333,7 +333,8 @@ class Project:
)
return None
def get_file_hash(self, session, link):
@staticmethod
def get_file_hash(session, link):
h = hashlib.new(FAVORITE_HASH)
err.print(f"Downloading file {link.filename} to obtain hash...")
with open_file(link.url, session) as fp:
@@ -1126,7 +1127,7 @@ class Project:
if extras:
entry["extras"] = list(extras)
if path_specifier:
entry["file"] = unquote(path_specifier)
entry["file"] = unquote(str(path_specifier))
elif vcs_specifier:
for vcs in VCS_LIST:
if vcs in package.link.scheme:
+8 -19
View File
@@ -11,7 +11,7 @@ from functools import lru_cache
from pathlib import Path
from tempfile import NamedTemporaryFile, TemporaryDirectory
from typing import Any, AnyStr, Dict, List, Mapping, Optional, Sequence, Union
from urllib.parse import urljoin, urlparse, urlsplit, urlunsplit
from urllib.parse import urlparse, urlsplit, urlunsplit
from pipenv.patched.pip._internal.models.link import Link
from pipenv.patched.pip._internal.network.download import Downloader
@@ -639,15 +639,12 @@ def find_package_name_from_directory(directory):
def determine_path_specifier(package: InstallRequirement):
if package.link:
if package.link.scheme in ["http", "https"]:
path_specifier = package.link.url_without_fragment
return path_specifier
return package.link.url_without_fragment
if package.link.scheme == "file":
try:
path_specifier = os.path.relpath(package.link.file_path)
return Path(package.link.file_path).relative_to(Path.cwd()).as_posix()
except ValueError:
# If os.path.relpath() fails, use the absolute path instead
path_specifier = os.path.abspath(package.link.file_path)
return path_specifier
return Path(package.link.file_path).as_posix()
def determine_vcs_specifier(package: InstallRequirement):
@@ -900,13 +897,7 @@ def expansive_install_req_from_line(
if expand_env:
name = expand_env_variables(name)
if os.path.isfile(name) or os.path.isdir(name):
if not name.startswith("file:"):
# Make sure the path is absolute and properly formatted as a file: URL
absolute_path = os.path.abspath(name)
name = urljoin("file:", absolute_path)
name = "file:" + name
if editable or os.path.isdir(name):
return install_req_from_editable(name, line_source)
vcs_part = name
@@ -926,9 +917,7 @@ def expansive_install_req_from_line(
constraint=constraint,
user_supplied=user_supplied,
)
if editable:
return install_req_from_editable(name, line_source)
if urlparse(name).scheme in ("http", "https", "file"):
if urlparse(name).scheme in ("http", "https", "file") or os.path.isfile(name):
parts = parse_req_from_line(name, line_source)
else:
# It's a requirement
@@ -992,9 +981,9 @@ def install_req_from_pipfile(name, pipfile):
else:
req_str = f"{name}{extras_str}@ {req_str}"
elif "path" in _pipfile:
req_str = f"{_pipfile['path']}{extras_str}"
req_str = str(Path(_pipfile["path"]).as_posix())
elif "file" in _pipfile:
req_str = f"{_pipfile['file']}{extras_str}"
req_str = str(Path(_pipfile["file"]).as_posix())
else:
# We ensure version contains an operator. Default to equals (==)
_pipfile["version"] = version = get_version(pipfile)
+5 -10
View File
@@ -9,7 +9,7 @@ import subprocess
import time
import warnings
from functools import partial
from itertools import count, islice, tee
from itertools import count, islice
from typing import Any, Iterable
DIRECTORY_CLEANUP_TIMEOUT = 1.0
@@ -62,18 +62,13 @@ def unnest(elem: Iterable) -> Any:
"""
if isinstance(elem, Iterable) and not isinstance(elem, str):
elem, target = tee(elem, 2)
else:
target = elem
if not target or not _is_iterable(target):
yield target
else:
for el in target:
for el in elem:
if isinstance(el, Iterable) and not isinstance(el, str):
el, el_copy = tee(el, 2)
yield from unnest(el_copy)
yield from unnest(el)
else:
yield el
else:
yield elem
def dedup(iterable: Iterable) -> Iterable:
+1 -1
View File
@@ -187,7 +187,7 @@ def test_install_local_vcs_not_in_lockfile(pipenv_instance_pypi):
def test_get_vcs_refs(pipenv_instance_private_pypi):
with pipenv_instance_private_pypi() as p:
c = p.pipenv(
"install -e git+https://github.com/benjaminp/six.git@1.9.0"
"install -e git+https://github.com/benjaminp/six.git@1.9.0#egg=six"
)
assert c.returncode == 0
assert "six" in p.pipfile["packages"]