Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle editable paths more correctly #5861

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 16 additions & 32 deletions pipenv/utils/dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import configparser
import os
import re
import sys
import tarfile
import tempfile
import zipfile
Expand Down Expand Up @@ -395,12 +394,17 @@ def dependency_as_pip_install_line(
if not vcs:
for k in ["file", "path"]:
if k in dep:
if is_editable_path(dep[k]):
if dep.get("editable") and is_editable_path(dep[k]):
line.append("-e")
extras = ""
if "extras" in dep:
extras = f"[{','.join(dep['extras'])}]"
location = dep["file"] if "file" in dep else dep["path"]

# Handle Windows paths by replacing single backslashes with double backslashes
if "\\" in location and not location.startswith(("http:", "https:")):
location = location.replace("\\", "\\\\")

if location.startswith(("http:", "https:")):
line.append(f"{dep_name}{extras} @ {location}")
else:
Expand Down Expand Up @@ -522,39 +526,20 @@ def parse_setup_file(content):
try:
tree = ast.parse(content)
for node in ast.walk(tree):
if isinstance(node, ast.Call) and getattr(node.func, "id", "") == "setup":
for keyword in node.keywords:
if keyword.arg == "name":
if isinstance(keyword.value, ast.Str):
return keyword.value.s
elif sys.version_info < (3, 9) and isinstance(
keyword.value, ast.Subscript
):
if (
isinstance(keyword.value.value, ast.Name)
and keyword.value.value.id == "about"
):
if isinstance(
keyword.value.slice, ast.Index
) and isinstance(keyword.value.slice.value, ast.Str):
return keyword.value.slice.value.s
return keyword.value.s
elif sys.version_info >= (3, 9) and isinstance(
keyword.value, ast.Subscript
):
# If the name is a lookup in a dictionary, only handle the case where it's a static lookup
if (
isinstance(keyword.value.value, ast.Name)
and isinstance(keyword.value.slice, ast.Str)
and keyword.value.value.id == "about"
):
return keyword.value.slice.s
if isinstance(node, ast.Call) and isinstance(node.func, ast.Attribute):
if (
node.func.attr == "setup"
and isinstance(node.func.value, ast.Name)
and node.func.value.id == "setuptools"
):
for keyword in node.keywords:
if keyword.arg == "name":
if isinstance(keyword.value, ast.Str):
return keyword.value.s

except ValueError:
pass # We will not exec unsafe code to determine the name pre-resolver

return None


def parse_cfg_file(content):
config = configparser.ConfigParser()
Expand Down Expand Up @@ -1077,7 +1062,6 @@ def prepare_constraint_file(
):
if not directory:
directory = create_tracked_tempdir(suffix="-requirements", prefix="pipenv-")

constraints = set(constraints)
constraints_file = NamedTemporaryFile(
mode="w",
Expand Down
8 changes: 6 additions & 2 deletions pipenv/utils/requirements.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,9 +184,13 @@ def requirement_from_lockfile(
line = []
if k in package_info:
path = package_info[k]
if is_editable_path(path):
if package_info.get("editable") and is_editable_path(path):
line.append("-e")
line.append(f"{package_info[k]}")

# Handle Windows paths by replacing single backslashes with double backslashes
# if "\\" in path and not path.startswith(("http:", "https:")):
# path = path.replace("\\", "\\\\")
line.append(path)
pip_line = " ".join(line)
return pip_line

Expand Down
3 changes: 1 addition & 2 deletions pipenv/utils/resolver.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ def create(
if is_constraint:
constraints.add(dep)
resolver = Resolver(
set(),
constraints,
req_dir,
project,
sources,
Expand All @@ -243,7 +243,6 @@ def create(
install_req = install_reqs[package_name]
if resolver.check_if_package_req_skipped(install_req):
resolver.skipped[package_name] = dep
resolver.initial_constraints = constraints
resolver.index_lookup = index_lookup
resolver.finder.index_lookup = index_lookup
resolver.markers_lookup = markers_lookup
Expand Down
Loading