Include the package name in the information to the resolver (#5930)

* Include the package name in the information to the resolver

* Fix unit tests

* fix unit tests
This commit is contained in:
Matt Davis
2023-09-11 05:13:27 -04:00
committed by GitHub
parent 539f96dc47
commit 10be5b9c16
4 changed files with 34 additions and 39 deletions
+6 -6
View File
@@ -83,7 +83,11 @@ def handle_parsed_args(parsed):
with open(parsed.constraints_file) as constraints:
file_constraints = constraints.read().strip().split("\n")
os.unlink(parsed.constraints_file)
parsed.packages += sorted(file_constraints)
packages = {}
for line in file_constraints:
dep_name, pip_line = line.split(",", 1)
packages[dep_name] = pip_line
parsed.packages = packages
return parsed
@@ -579,12 +583,8 @@ def resolve_packages(
else None
)
if not isinstance(packages, set):
packages = set(packages)
if not isinstance(constraints, set):
constraints = set(constraints) if constraints else set()
if constraints:
packages |= constraints
packages.update(constraints)
def resolve(
packages, pre, project, sources, clear, system, category, requirements_dir=None
+3 -3
View File
@@ -467,14 +467,14 @@ def convert_deps_to_pip(
include_index=False,
):
""" "Converts a Pipfile-formatted dependency to a pip-formatted one."""
dependencies = []
dependencies = {}
if indexes is None:
indexes = []
for dep_name, dep in deps.items():
req = dependency_as_pip_install_line(
dep_name, dep, include_hashes, include_markers, include_index, indexes
)
dependencies.append(req)
dependencies[dep_name] = req
return dependencies
@@ -942,7 +942,7 @@ def expansive_install_req_from_line(
:return: A tuple of the InstallRequirement and the name of the package (if determined).
"""
name = None
pip_line = pip_line.strip("'")
pip_line = pip_line.strip("'").lstrip(" ")
for new_req_symbol in ("@ ", " @ "): # Check for new style pip lines
if new_req_symbol in pip_line:
pip_line_parts = pip_line.split(new_req_symbol, 1)
+7 -12
View File
@@ -7,7 +7,7 @@ import tempfile
import warnings
from functools import lru_cache
from pathlib import Path
from typing import Dict, List, Optional, Set
from typing import Dict, List, Optional
from pipenv import environments, resolver
from pipenv.exceptions import ResolutionFailure
@@ -40,7 +40,6 @@ except ImportError:
from .dependencies import (
HackedPythonVersion,
convert_deps_to_pip,
determine_package_name,
expansive_install_req_from_line,
get_constraints_from_deps,
get_lockfile_section_using_pipfile_category,
@@ -174,7 +173,7 @@ class Resolver:
@classmethod
def create(
cls,
deps: Set[str],
deps: Dict[str, str],
project: Project,
index_lookup: Dict[str, str] = None,
markers_lookup: Dict[str, str] = None,
@@ -198,15 +197,11 @@ class Resolver:
sources = project.sources
packages = project.get_pipfile_section(category)
constraints = set()
for dep in deps: # Build up the index and markers lookups
for package_name, dep in deps.items(): # Build up the index and markers lookups
if not dep:
continue
is_constraint = True
install_req, package_name = expansive_install_req_from_line(
dep, expand_env=True
)
if package_name is None:
package_name = determine_package_name(install_req)
install_req, _ = expansive_install_req_from_line(dep, expand_env=True)
original_deps[package_name] = dep
install_reqs[package_name] = install_req
index, extra_index, trust_host, remainder = parse_indexes(dep)
@@ -782,7 +777,6 @@ def venv_resolve_deps(
deps = convert_deps_to_pip(
deps, project.pipfile_sources(), include_index=True
)
constraints = set(deps)
# Useful for debugging and hitting breakpoints in the resolver
if project.s.PIPENV_RESOLVER_PARENT_PYTHON:
try:
@@ -795,7 +789,7 @@ def venv_resolve_deps(
requirements_dir=req_dir,
packages=deps,
category=category,
constraints=constraints,
constraints=deps,
)
if results:
st.console.print(
@@ -831,7 +825,8 @@ def venv_resolve_deps(
with tempfile.NamedTemporaryFile(
mode="w+", prefix="pipenv", suffix="constraints.txt", delete=False
) as constraints_file:
constraints_file.write(str("\n".join(constraints)))
for dep_name, pip_line in deps.items():
constraints_file.write(f"{dep_name}, {pip_line}\n")
cmd.append("--constraints-file")
cmd.append(constraints_file.name)
st.console.print("Resolving dependencies...")
+18 -18
View File
@@ -13,10 +13,10 @@ from pipenv.exceptions import PipenvUsageError
# Pipfile format <-> requirements.txt format.
DEP_PIP_PAIRS = [
({"django": ">1.10"}, "django>1.10"),
({"Django": ">1.10"}, "Django>1.10"),
({"requests": {"extras": ["socks"], "version": ">1.10"}}, "requests[socks]>1.10"),
({"requests": {"extras": ["socks"], "version": "==1.10"}}, "requests[socks]==1.10"),
({"django": ">1.10"}, {"django": "django>1.10"}),
({"Django": ">1.10"}, {"Django": "Django>1.10"}),
({"requests": {"extras": ["socks"], "version": ">1.10"}}, {"requests": "requests[socks]>1.10"}),
({"requests": {"extras": ["socks"], "version": "==1.10"}}, {"requests": "requests[socks]==1.10"}),
(
{
"dataclasses-json": {
@@ -25,11 +25,11 @@ DEP_PIP_PAIRS = [
"editable": True,
}
},
"dataclasses-json@ git+https://github.com/lidatong/dataclasses-json.git@v0.5.7",
{"dataclasses-json": "dataclasses-json@ git+https://github.com/lidatong/dataclasses-json.git@v0.5.7"},
),
(
{"dataclasses-json": {"git": "https://github.com/lidatong/dataclasses-json.git", "ref": "v0.5.7"}},
"dataclasses-json@ git+https://github.com/lidatong/dataclasses-json.git@v0.5.7",
{"dataclasses-json": "dataclasses-json@ git+https://github.com/lidatong/dataclasses-json.git@v0.5.7"},
),
(
# Extras in url
@@ -39,7 +39,7 @@ DEP_PIP_PAIRS = [
"extras": ["pipenv"],
}
},
"dparse[pipenv] @ https://github.com/oz123/dparse/archive/refs/heads/master.zip",
{"dparse": "dparse[pipenv] @ https://github.com/oz123/dparse/archive/refs/heads/master.zip"},
),
(
{
@@ -50,7 +50,7 @@ DEP_PIP_PAIRS = [
"editable": False,
}
},
"requests[security]@ git+https://github.com/requests/requests.git@main",
{"requests": "requests[security]@ git+https://github.com/requests/requests.git@main"},
),
]
@@ -64,23 +64,23 @@ def mock_unpack(link, source_dir, download_dir, only_download=False, session=Non
@pytest.mark.parametrize("deps, expected", DEP_PIP_PAIRS)
@pytest.mark.needs_internet
def test_convert_deps_to_pip(deps, expected):
assert dependencies.convert_deps_to_pip(deps) == [expected]
assert dependencies.convert_deps_to_pip(deps) == expected
@pytest.mark.utils
@pytest.mark.needs_internet
def test_convert_deps_to_pip_star_specifier():
deps = {"uvicorn": "*"}
expected = "uvicorn"
assert dependencies.convert_deps_to_pip(deps) == [expected]
expected = {"uvicorn": "uvicorn"}
assert dependencies.convert_deps_to_pip(deps) == expected
@pytest.mark.utils
@pytest.mark.needs_internet
def test_convert_deps_to_pip_extras_no_version():
deps = {"uvicorn": {"extras": ["standard"], "version": "*"}}
expected = "uvicorn[standard]"
assert dependencies.convert_deps_to_pip(deps) == [expected]
expected = {"uvicorn": "uvicorn[standard]"}
assert dependencies.convert_deps_to_pip(deps) == expected
@pytest.mark.utils
@@ -95,7 +95,7 @@ def test_convert_deps_to_pip_extras_no_version():
"hash": "sha256:2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824",
}
},
"FooProject==1.2 --hash=sha256:2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824",
{"FooProject": "FooProject==1.2 --hash=sha256:2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824"},
),
(
{
@@ -105,7 +105,7 @@ def test_convert_deps_to_pip_extras_no_version():
"hash": "sha256:2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824",
}
},
"FooProject[stuff]==1.2 --hash=sha256:2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824",
{"FooProject": "FooProject[stuff]==1.2 --hash=sha256:2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824"},
),
(
{
@@ -115,7 +115,7 @@ def test_convert_deps_to_pip_extras_no_version():
"extras": ["standard"],
}
},
"git+https://github.com/encode/uvicorn.git@master#egg=uvicorn[standard]",
{"uvicorn": "git+https://github.com/encode/uvicorn.git@master#egg=uvicorn[standard]"},
),
],
)
@@ -126,8 +126,8 @@ def test_convert_deps_to_pip_one_way(deps, expected):
@pytest.mark.utils
def test_convert_deps_to_pip_one_way():
deps = {"uvicorn": {}}
expected = "uvicorn"
assert dependencies.convert_deps_to_pip(deps) == [expected.lower()]
expected = {"uvicorn": "uvicorn"}
assert dependencies.convert_deps_to_pip(deps) == expected
@pytest.mark.utils