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

feat: Experimental uv integration #3144

Merged
merged 16 commits into from
Sep 23, 2024
Prev Previous commit
fix tests
Signed-off-by: Frost Ming <[email protected]>
frostming committed Sep 23, 2024
commit b4cbed83ce5341aa0e56f75e2719e4cb94a05569
6 changes: 5 additions & 1 deletion src/pdm/formats/uv.py
Original file line number Diff line number Diff line change
@@ -65,7 +65,11 @@
def _enter_path(self, path: Path) -> Path:
if path.exists():
backup = path.rename(path.with_name(f"{path.name}.bak"))
self.stack.callback(backup.rename, path)

@self.stack.callback
def restore() -> None:
path.unlink(True)
backup.rename(path)
else:
self.stack.callback(path.unlink, True)
return path
@@ -75,7 +79,7 @@
packages: list[dict[str, Any]] = []
for key in locked_repo.packages:
if "[" in key[0]: # skip entries with extras
continue

Check warning on line 82 in src/pdm/formats/uv.py

Codecov / codecov/patch

src/pdm/formats/uv.py#L82

Added line #L82 was not covered by tests
# Merge related entries with the same name and version
related_packages = [
p for k, p in locked_repo.packages.items() if strip_extras(k[0])[0] == key[0] and k[1:] == key[1:]
@@ -94,11 +98,11 @@
if group == "default":
dependencies.append(dep)
else:
optional_dependencies.setdefault(group, []).append(dep)

Check warning on line 101 in src/pdm/formats/uv.py

Codecov / codecov/patch

src/pdm/formats/uv.py#L101

Added line #L101 was not covered by tests
if dependencies:
this_package["dependencies"] = dependencies # type: ignore[assignment]
if optional_dependencies:
this_package["optional-dependencies"] = optional_dependencies

Check warning on line 105 in src/pdm/formats/uv.py

Codecov / codecov/patch

src/pdm/formats/uv.py#L105

Added line #L105 was not covered by tests
packages.append(this_package)

data = {"version": 1, "requires-python": self.requires_python}
@@ -111,7 +115,7 @@

def _get_name(self, req: FileRequirement) -> str:
if req.key:
return req.key

Check warning on line 118 in src/pdm/formats/uv.py

Codecov / codecov/patch

src/pdm/formats/uv.py#L118

Added line #L118 was not covered by tests
can = Candidate(req).prepare(self.project.environment)
return normalize_name(can.metadata.name)

@@ -122,21 +126,21 @@
if req.ref:
result["rev"] = req.ref
elif req.path:
result = {"path": req.str_path}

Check warning on line 129 in src/pdm/formats/uv.py

Codecov / codecov/patch

src/pdm/formats/uv.py#L129

Added line #L129 was not covered by tests
else:
result = {"url": req.url}

Check warning on line 131 in src/pdm/formats/uv.py

Codecov / codecov/patch

src/pdm/formats/uv.py#L131

Added line #L131 was not covered by tests
if req.editable:
result["editable"] = True

Check warning on line 133 in src/pdm/formats/uv.py

Codecov / codecov/patch

src/pdm/formats/uv.py#L133

Added line #L133 was not covered by tests
return result

def _build_lock_source(self, req: Requirement) -> dict[str, Any]:
if isinstance(req, VcsRequirement):
return {req.vcs: f"{req.repo}?rev={req.ref}#{req.revision}"}

Check warning on line 138 in src/pdm/formats/uv.py

Codecov / codecov/patch

src/pdm/formats/uv.py#L138

Added line #L138 was not covered by tests
elif isinstance(req, FileRequirement):
if req.editable:
return {"editable": req.str_path}

Check warning on line 141 in src/pdm/formats/uv.py

Codecov / codecov/patch

src/pdm/formats/uv.py#L141

Added line #L141 was not covered by tests
else:
return {"url": req.url}

Check warning on line 143 in src/pdm/formats/uv.py

Codecov / codecov/patch

src/pdm/formats/uv.py#L143

Added line #L143 was not covered by tests
else:
return {"registry": self.default_source}

@@ -177,10 +181,10 @@
# the same dependencies get duplicated in those groups, but it's okay if each single extra is
# never requested alone.
if extra not in optional_dependencies:
optional_dependencies[extra] = deps # type: ignore[assignment]

Check warning on line 184 in src/pdm/formats/uv.py

Codecov / codecov/patch

src/pdm/formats/uv.py#L184

Added line #L184 was not covered by tests

if optional_dependencies:
result["optional-dependencies"] = optional_dependencies

Check warning on line 187 in src/pdm/formats/uv.py

Codecov / codecov/patch

src/pdm/formats/uv.py#L187

Added line #L187 was not covered by tests
return result

def _make_dependency(self, candidate: Candidate, req: Requirement) -> dict[str, Any] | None:
@@ -189,7 +193,7 @@
matching_entries = [e for k, e in locked_repo.packages.items() if k[0] == req.key]

def marker_match(marker: Marker | None) -> bool:
return not (parent_marker & (marker or get_marker("")).is_empty())

Check warning on line 196 in src/pdm/formats/uv.py

Codecov / codecov/patch

src/pdm/formats/uv.py#L196

Added line #L196 was not covered by tests

if not matching_entries:
return None
@@ -199,14 +203,14 @@
multiple = False
else:
candidate = next(e.candidate for e in matching_entries if marker_match(e.candidate.req.marker))
multiple = True

Check warning on line 206 in src/pdm/formats/uv.py

Codecov / codecov/patch

src/pdm/formats/uv.py#L206

Added line #L206 was not covered by tests
result.update({"name": candidate.name})
if multiple:
result.update(version=candidate.version, source=self._build_lock_source(candidate.req))

Check warning on line 209 in src/pdm/formats/uv.py

Codecov / codecov/patch

src/pdm/formats/uv.py#L209

Added line #L209 was not covered by tests
if req.extras:
result["extra"] = list(req.extras)

Check warning on line 211 in src/pdm/formats/uv.py

Codecov / codecov/patch

src/pdm/formats/uv.py#L211

Added line #L211 was not covered by tests
if req.marker is not None:
result["marker"] = str(req.marker)

Check warning on line 213 in src/pdm/formats/uv.py

Codecov / codecov/patch

src/pdm/formats/uv.py#L213

Added line #L213 was not covered by tests
return result


10 changes: 5 additions & 5 deletions tests/resolver/test_uv_resolver.py
Original file line number Diff line number Diff line change
@@ -44,11 +44,11 @@ def test_resolve_vcs_requirement(project):

def test_resolve_with_python_requires(project):
requirements = ["urllib3<2; python_version<'3.10'", "urllib3>=2; python_version>='3.10'"]

resolution = resolve(project.environment, requirements, EnvSpec.from_spec(">=3.10"))
packages = list(resolution.packages)
assert len(packages) == 1
assert packages[0].candidate.version.startswith("2.")
if project.python.version_tuple >= (3, 10):
resolution = resolve(project.environment, requirements, EnvSpec.from_spec(">=3.10"))
packages = list(resolution.packages)
assert len(packages) == 1
assert packages[0].candidate.version.startswith("2.")

resolution = resolve(project.environment, requirements, EnvSpec.from_spec(">=3.8"))
packages = list(resolution.packages)
Loading