Skip to content

Commit

Permalink
Attempt to fix the local/editable file installs (#5870)
Browse files Browse the repository at this point in the history
* 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.
  • Loading branch information
matteius committed Aug 26, 2023
1 parent 60c8c97 commit a3b197e
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 32 deletions.
5 changes: 3 additions & 2 deletions pipenv/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,8 @@ def get_hashes_from_remote_index_urls(self, ireq, source):
)
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:
Expand Down Expand Up @@ -1126,7 +1127,7 @@ def generate_package_pipfile_entry(self, package, pip_line, category=None):
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:
Expand Down
27 changes: 8 additions & 19 deletions pipenv/utils/dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
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
Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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)
Expand Down
15 changes: 5 additions & 10 deletions pipenv/utils/funktools.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
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
Expand Down Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion tests/integration/test_install_uri.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
Expand Down

0 comments on commit a3b197e

Please sign in to comment.