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

Fix missing dependency #195

Merged
merged 1 commit into from
May 11, 2024
Merged
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
4 changes: 2 additions & 2 deletions src/pyproject_fmt/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ def _handle_one(config: Config) -> bool:
column_width=config.column_width,
indent=config.indent,
keep_full_version=config.keep_full_version,
max_supported_python=(config.max_supported_python.major, config.max_supported_python.minor),
min_supported_python=(config.min_supported_python.major, config.min_supported_python.minor),
max_supported_python=config.max_supported_python,
min_supported_python=config.min_supported_python,
)
before = config.toml
changed = before != formatted
Expand Down
47 changes: 28 additions & 19 deletions src/pyproject_fmt/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,23 @@

from __future__ import annotations

import sys
from dataclasses import dataclass

if sys.version_info >= (3, 11): # pragma: >=3.11 cover
import tomllib
else: # pragma: <3.11 cover
import tomli as tomllib

import os
import sys
from argparse import (
ArgumentDefaultsHelpFormatter,
ArgumentParser,
ArgumentTypeError,
Namespace,
)
from dataclasses import dataclass
from importlib.metadata import version
from pathlib import Path
from typing import Sequence

from packaging.version import Version
if sys.version_info >= (3, 11): # pragma: >=3.11 cover
import tomllib
else: # pragma: <3.11 cover
import tomli as tomllib


class PyProjectFmtNamespace(Namespace):
Expand All @@ -34,8 +31,8 @@ class PyProjectFmtNamespace(Namespace):
column_width: int
indent: int
keep_full_version: bool
max_supported_python: Version
min_supported_python: Version
max_supported_python: tuple[int, int]
min_supported_python: tuple[int, int]


@dataclass(frozen=True)
Expand All @@ -49,8 +46,8 @@ class Config:
column_width: int #: maximum column width
indent: int #: indentation to apply
keep_full_version: bool #: whether to keep full dependency versions
max_supported_python: Version #: the maximum supported Python version
min_supported_python: Version #: the minimum supported Python version
max_supported_python: tuple[int, int] #: the maximum supported Python version
min_supported_python: tuple[int, int] #: the minimum supported Python version

@property
def toml(self) -> str:
Expand Down Expand Up @@ -83,6 +80,18 @@ def pyproject_toml_path_creator(argument: str) -> Path:
return path


def _version_argument(got: str) -> tuple[int, int]:
parts = got.split(".")
if len(parts) != 2: # noqa: PLR2004
msg = f"invalid version: {got}, must be e.g. 3.12"
raise ArgumentTypeError(msg)
try:
return int(parts[0]), int(parts[1])
except ValueError as exc:
msg = f"invalid version: {got} due {exc!r}, must be e.g. 3.12"
raise ArgumentTypeError(msg) from exc


def _build_cli() -> ArgumentParser:
parser = ArgumentParser(
formatter_class=ArgumentDefaultsHelpFormatter,
Expand Down Expand Up @@ -116,14 +125,14 @@ def _build_cli() -> ArgumentParser:
)
parser.add_argument(
"--min-supported-python",
type=Version,
default="3.8",
type=_version_argument,
default=(3, 8),
help="latest Python version the project supports (e.g. 3.8)",
)
parser.add_argument(
"--max-supported-python",
type=Version,
default="3.12",
type=_version_argument,
default=(3, 12),
help="latest Python version the project supports (e.g. 3.13)",
)
msg = "pyproject.toml file(s) to format"
Expand Down Expand Up @@ -159,9 +168,9 @@ def cli_args(args: Sequence[str]) -> list[Config]:
elif key == "keep_full_version":
keep_full_version = bool(entry)
elif key == "max_supported_python":
max_supported_python = Version(entry)
max_supported_python = _version_argument(entry)
elif key == "min_supported_python": # pragma: no branch
min_supported_python = Version(entry)
min_supported_python = _version_argument(entry)
res.append(
Config(
pyproject_toml=pyproject_toml,
Expand Down
25 changes: 25 additions & 0 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,31 @@ def test_cli_version(capsys: pytest.CaptureFixture[str]) -> None:
assert out == f"pyproject-fmt ({version('pyproject-fmt')})\n"


def test_cli_invalid_version(capsys: pytest.CaptureFixture[str], tmp_path: Path) -> None:
path = tmp_path / "pyproject.toml"
path.write_text("")
with pytest.raises(SystemExit) as context:
cli_args([str(path), "--max-supported-python", "3"])
assert context.value.code == 2
out, err = capsys.readouterr()
assert not out
assert "error: argument --max-supported-python: invalid version: 3, must be e.g. 3.12\n" in err


def test_cli_invalid_version_value(capsys: pytest.CaptureFixture[str], tmp_path: Path) -> None:
path = tmp_path / "pyproject.toml"
path.write_text("")
with pytest.raises(SystemExit) as context:
cli_args([str(path), "--max-supported-python", "a.1"])
assert context.value.code == 2
out, err = capsys.readouterr()
assert not out
assert (
"error: argument --max-supported-python: invalid version: a.1 due "
'ValueError("invalid literal for int() with base 10:'
) in err


def test_cli_pyproject_toml_ok(tmp_path: Path) -> None:
path = tmp_path / "tox.ini"
path.write_text("")
Expand Down