Skip to content

Commit

Permalink
Support whl2conda convert --python (#109)
Browse files Browse the repository at this point in the history
  • Loading branch information
analog-cbarber committed Jan 28, 2024
1 parent 01e1d11 commit 91f3eb9
Show file tree
Hide file tree
Showing 9 changed files with 59 additions and 4 deletions.
3 changes: 3 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# whl2conda changes

## [24.1.2] - 2024-1-28

### Features
* Support `whl2conda convert --python` override.

## [24.1.1] - 2024-1-15

### Features
Expand Down
2 changes: 1 addition & 1 deletion src/whl2conda/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
24.1.1
24.1.2
18 changes: 17 additions & 1 deletion src/whl2conda/api/converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
from dataclasses import dataclass
from hashlib import sha256
from pathlib import Path
from typing import Any, Optional, Sequence, NamedTuple
from typing import Any, NamedTuple, Optional, Sequence

# third party
from wheel.wheelfile import WheelFile
Expand Down Expand Up @@ -302,6 +302,7 @@ class Wheel2CondaConverter:
keep_pip_dependencies: bool = False
dependency_rename: list[DependencyRename]
extra_dependencies: list[str]
python_version: str = ""
interactive: bool = False
build_number: Optional[int] = None

Expand Down Expand Up @@ -618,6 +619,8 @@ def _compute_conda_dependencies(
) -> list[str]:
conda_dependencies: list[str] = []

saw_python = False

for entry in dependencies:
if entry.extra_marker_name:
self._debug("Skipping extra dependency: %s", entry)
Expand All @@ -629,6 +632,14 @@ def _compute_conda_dependencies(

conda_name = pip_name = entry.name
version = self.translate_version_spec(entry.version)
if saw_python := conda_name == "python":
if self.python_version and version != self.python_version:
self._info(
"Overriding python version '%s' with '%s'",
version,
self.python_version,
)
version = self.python_version

# TODO - do something with extras (#36)
# download target pip package and its extra dependencies
Expand All @@ -650,6 +661,11 @@ def _compute_conda_dependencies(
conda_dependencies.append(conda_dep)
else:
self._debug("Dependency dropped: %s", entry)

if not saw_python and self.python_version:
self._info("Added 'python %s' dependency", self.python_version)
conda_dependencies.append(f"python {self.python_version}")

for dep in self.extra_dependencies:
self._debug("Dependency added: '%s'", dep)
conda_dependencies.append(dep)
Expand Down
2 changes: 2 additions & 0 deletions src/whl2conda/cli/convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ def _create_argparser(prog: Optional[str] = None) -> argparse.ArgumentParser:
override_opts.add_argument(
"--python",
metavar="<version-spec>",
default="",
help="Set/override python dependency.",
)

Expand Down Expand Up @@ -499,6 +500,7 @@ def convert_main(args: Optional[Sequence[str]] = None, prog: Optional[str] = Non
converter.keep_pip_dependencies = parsed.keep_pip_deps
converter.extra_dependencies.extend(pyproj_info.extra_dependencies)
converter.extra_dependencies.extend(parsed.extra_deps)
converter.python_version = parsed.python
converter.interactive = interactive
converter.build_number = parsed.build_number

Expand Down
3 changes: 2 additions & 1 deletion test/api/converter.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2023 Christopher Barber
# Copyright 2023-2024 Christopher Barber
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -175,6 +175,7 @@ def _validate(self, wheel_path: Path, package_path: Path) -> None:
r.pattern.pattern: r.replacement for r in self.dependency_rename
},
extra=converter.extra_dependencies,
expected_python_version=converter.python_version,
keep_pip_dependencies=converter.keep_pip_dependencies,
build_number=converter.build_number,
)
Expand Down
7 changes: 7 additions & 0 deletions test/api/test_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,13 @@ def test_simple_wheel(
overwrite=True,
).build()

case = test_case(
simple_wheel,
overwrite=True,
)
case.converter.python_version = ">=3.9"
case.build()


def test_debug_log(
test_case: ConverterTestCaseFactory,
Expand Down
7 changes: 6 additions & 1 deletion test/api/validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ class PackageValidator:
_extra_dependencies: Sequence[str]
_keep_pip_dependencies: bool = False
_build_number: int | None = None
_expected_python_version: str = ""

def __init__(self, tmp_dir: Path) -> None:
self.tmp_dir = tmp_dir
Expand All @@ -69,6 +70,7 @@ def validate(
renamed: Optional[dict[str, str]] = None,
std_renames: Optional[dict[str, str]] = None,
extra: Sequence[str] = (),
expected_python_version: str = "",
keep_pip_dependencies: bool = False,
build_number: int | None = None,
) -> None:
Expand All @@ -77,6 +79,7 @@ def validate(
self._renamed_dependencies = renamed or {}
self._std_renames = std_renames or {}
self._extra_dependencies = extra
self._expected_python_version = expected_python_version
self._keep_pip_dependencies = keep_pip_dependencies
self._build_number = build_number

Expand Down Expand Up @@ -314,7 +317,9 @@ def _validate_dependencies(self, dependencies: Sequence[str]) -> None:
expected_depends: set[str] = set()

wheel_md = self._wheel_md
if python_ver := wheel_md.get("requires-python"):
if self._expected_python_version:
expected_depends.add(f"python {self._expected_python_version}")
elif python_ver := wheel_md.get("requires-python"):
expected_depends.add(f"python {python_ver}")
for dep in wheel_md.get("requires-dist", []):
try:
Expand Down
16 changes: 16 additions & 0 deletions test/cli/test_convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ class CliTestCase:
expected_parser_error: str = ""
"""Relative path from projects dir"""
expected_project_root: str = ""
expected_python_version: str = ""
expected_wheel_path: str = ""

expected_prompts: list[str]
Expand Down Expand Up @@ -130,6 +131,7 @@ def __init__(
expected_package_name: str = "",
expected_parser_error: str = "",
expected_project_root: str = "",
expected_python_version: str = "",
expected_wheel_path: str = "",
from_dir: str = "",
):
Expand All @@ -155,6 +157,7 @@ def __init__(
self.expected_parser_error = expected_parser_error
self.expected_project_root = expected_project_root
self.expected_prompts = []
self.expected_python_version = expected_python_version
self.expected_wheel_path = expected_wheel_path
self.responses = []

Expand Down Expand Up @@ -297,6 +300,7 @@ def validate_converter(self, converter: Wheel2CondaConverter) -> None:
assert converter.keep_pip_dependencies is self.expected_keep_pip
assert converter.extra_dependencies == list(self.expected_extra_dependencies)
assert converter.dependency_rename == list(self.expected_dependency_renames)
assert converter.python_version == self.expected_python_version


class CliTestCaseFactory:
Expand Down Expand Up @@ -355,6 +359,7 @@ def __call__(
expected_extra_dependencies: Sequence[str] = (),
expected_interactive: bool = True,
expected_project_root: str = "",
expected_python_version: str = "",
expected_wheel_path: str = "",
from_dir: str = "",
) -> CliTestCase:
Expand All @@ -379,6 +384,7 @@ def __call__(
expected_extra_dependencies=expected_extra_dependencies,
expected_interactive=expected_interactive,
expected_project_root=expected_project_root,
expected_python_version=expected_python_version,
expected_wheel_path=expected_wheel_path,
from_dir=from_dir,
)
Expand Down Expand Up @@ -876,3 +882,13 @@ def test_build_number(
[str(simple_wheel), "--build-number", "42"],
expected_build_number=42,
).run()


def test_python_override(
test_case: CliTestCaseFactory,
simple_wheel: Path,
) -> None:
"""Test --python option"""
test_case(
[str(simple_wheel), "--python", ">=3.10"], expected_python_version=">=3.10"
).run()

0 comments on commit 91f3eb9

Please sign in to comment.