Skip to content

Commit

Permalink
feat: default python read from .python-version-default or .python-ver…
Browse files Browse the repository at this point in the history
…sion file
  • Loading branch information
wpk committed Dec 31, 2024
1 parent 11fd847 commit 185ac3d
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 14 deletions.
45 changes: 45 additions & 0 deletions changelog.d/20241231_083257_william.krekelberg.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<!-- markdownlint-disable MD041 -->
<!--
A new scriv changelog fragment.
Uncomment the section that is right (remove the HTML comment wrapper).
-->

<!--
### Removed
- A bullet item for the Removed category.
-->
<!--
### Added
- A bullet item for the Added category.
-->

### Changed

- Read default version from first found file, in order,
`.python-version-default` and `.python-version`. This allows for "default"
version being different from pinned version specifier, as the latter can be a
range of python values.

<!--
### Deprecated
- A bullet item for the Deprecated category.
-->
<!--
### Fixed
- A bullet item for the Fixed category.
-->
<!--
### Security
- A bullet item for the Security category.
-->
15 changes: 8 additions & 7 deletions src/pyproject2conda/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -267,13 +267,14 @@ class Overwrite(str, Enum):
`--python-version={version} --python-include=python{version}`. if
passed, this overrides values of passed via `--python-version` and
`--python-include`. pass `--python="default"` to include the python
version (major.minor only) from `.python-version` file in the current
directory. pass `"lowest"` or `"highest"` to include the lowest or
highest python version, respectively, from
`pyproject.toml:project.classifiers` table. in project mode, you can
pass multiple python version in `pyproject.toml` with, e.g., `python =
["3.8", "3.9", ....]`, or using `python = "all"`, to include all python
versions extracted from `pyproject.toml:project.classifiers` table.
version (major.minor only) from, in order, `.python-version-default` or
`.python-version`file in the current directory. pass `"lowest"` or
`"highest"` to include the lowest or highest python version,
respectively, from `pyproject.toml:project.classifiers` table. in
project mode, you can pass multiple python version in `pyproject.toml`
with, e.g., `python = ["3.8", "3.9", ....]`, or using `python = "all"`,
to include all python versions extracted from
`pyproject.toml:project.classifiers` table.
""",
),
]
Expand Down
4 changes: 2 additions & 2 deletions src/pyproject2conda/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from pyproject2conda.utils import (
filename_from_template,
get_all_pythons,
get_default_pythons,
get_default_pythons_with_fallback,
get_in,
select_pythons,
)
Expand Down Expand Up @@ -459,7 +459,7 @@ def from_toml_dict(

c = cls(
data,
default_pythons=get_default_pythons(),
default_pythons=get_default_pythons_with_fallback(),
all_pythons=get_all_pythons(data_toml),
)

Expand Down
14 changes: 13 additions & 1 deletion src/pyproject2conda/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,18 @@ def get_default_pythons(path: str | Path = ".python-version") -> list[str]:
return []


def get_default_pythons_with_fallback(
paths: Iterable[str | Path] = (".python-version-default", ".python-version"),
) -> list[str]:
"""Get default pythons from possibly multiple sources"""
for path in paths:
out = get_default_pythons(path)
if len(out) > 0:
return out

return []


def get_all_pythons(
data: dict[str, Any] | None, path: str | Path | None = None
) -> list[str]:
Expand Down Expand Up @@ -120,7 +132,7 @@ def select_pythons(

if python == "default":
if not default_pythons:
msg = "Must include `.python-version` to use `python = 'default'`."
msg = "Must include `.python-version-default` or `.python-version` to use `python = 'default'`."
raise ValueError(msg)
return default_pythons

Expand Down
34 changes: 30 additions & 4 deletions tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -345,17 +345,43 @@ def test_option_override_base3_default_python_error(
simple_config: Config,
) -> None:
# using default python without a version
with pytest.raises(ValueError, match="Must include `.python-version` .*"):
with pytest.raises(
ValueError,
match="Must include `.python-version-default` or `.python-version`.*",
):
list(simple_config.iter_envs(envs=["base3"]))


@pytest.mark.parametrize(
("python_version_default", "python_version", "expected"),
[
(None, None, []),
(None, "3.10", ["3.10"]),
("3.12", "3.11", ["3.12"]),
("3.11", None, ["3.11"]),
],
)
def test_default_pythons(
example_path, python_version_default, python_version, expected
) -> None:
for name, version in zip(
[".python-version-default", ".python-version"],
[python_version_default, python_version],
):
if version is not None:
with (example_path / name).open("w") as f:
f.write(f"{version}\n")

assert utils.get_default_pythons_with_fallback() == expected


def test_option_override_base3_default_python(example_path, simple_toml: str) -> None:
with (example_path / ".python-version").open("w") as f:
with (example_path / ".python-version-default").open("w") as f:
f.write("3.10\n")

from pyproject2conda.utils import get_default_pythons
from pyproject2conda.utils import get_default_pythons_with_fallback

assert get_default_pythons() == ["3.10"]
assert get_default_pythons_with_fallback() == ["3.10"]

config = Config.from_string(dedent(simple_toml))
output = list(config.iter_envs(envs=["base3"]))
Expand Down

0 comments on commit 185ac3d

Please sign in to comment.