Skip to content
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
1 change: 1 addition & 0 deletions src/compwa_policy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class Arguments:
allow_labels: bool
allow_vscode_coverage_gutters: bool
allowed_cell_metadata: str
branch_coverage: bool
ci_skipped_tests: str
dev_python_version: PythonVersion
doc_apt_packages: str
Expand Down
7 changes: 6 additions & 1 deletion src/compwa_policy/cli/_checks.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,12 @@ def run_checks( # noqa: C901, PLR0912, PLR0915
do(mypy.main, "mypy" in args.type_checker, precommit_config)
do(pyright.main, "pyright" in args.type_checker, precommit_config)
do(ty.main, args.type_checker, args.keep_local_precommit, precommit_config)
do(pytest.main, args.allow_vscode_coverage_gutters, args.pytest_single_threaded)
do(
pytest.main,
args.allow_vscode_coverage_gutters,
args.pytest_single_threaded,
args.branch_coverage,
)
do(pyupgrade.main, precommit_config, args.no_ruff)
if not args.no_ruff:
do(ruff.main, precommit_config, ctx.has_notebooks, args.imports_on_top)
Expand Down
7 changes: 7 additions & 0 deletions src/compwa_policy/cli/_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,13 @@ class TypeChecker(str, Enum):
bool | None,
typer.Option("--imports-on-top", help="Sort notebook imports on the top."),
]
BranchCoverage = Annotated[
bool | None,
typer.Option(
"--branch-coverage/--no-branch-coverage",
help="Enable branch coverage in the Coverage.py pytest configuration.",
),
]
TypeCheckerOption = Annotated[
list[TypeChecker] | None,
typer.Option(
Expand Down
2 changes: 2 additions & 0 deletions src/compwa_policy/cli/_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
_SCOPED_OPTIONS: dict[str, frozenset[str]] = {
"python": frozenset({
"allow_vscode_coverage_gutters",
"branch_coverage",
"excluded_python_versions",
"imports_on_top",
"keep_local_precommit",
Expand Down Expand Up @@ -185,6 +186,7 @@ class Settings(BaseSettings):
excluded_python_versions: str = ""
no_ruff: bool = False
imports_on_top: bool = False
branch_coverage: bool = True
type_checker: list[str] = []
keep_local_precommit: bool = False
pytest_single_threaded: bool = False
Expand Down
7 changes: 7 additions & 0 deletions src/compwa_policy/cli/migrate.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,11 @@
GROUP_FLAGS: dict[str, tuple[str, ...]] = {
"python": (
"--allow-vscode-coverage-gutters",
"--branch-coverage",
"--excluded-python-versions",
"--imports-on-top",
"--keep-local-precommit",
"--no-branch-coverage",
"--no-ruff",
"--pytest-single-threaded",
"--type-checker",
Expand Down Expand Up @@ -213,6 +215,11 @@ def _build_policy(args: list[str]) -> dict[str, Any]:
if flag in {"--python", "--no-python"}:
policy["python"] = flag == "--python"
continue
if flag in {"--branch-coverage", "--no-branch-coverage"}:
sub_table = policy_sub_table("branch_coverage")
target = policy if sub_table is None else policy.setdefault(sub_table, {})
target["branch-coverage"] = flag == "--branch-coverage"
continue
field = _flag_to_field(flag)
if field == "environment_variables":
environment_variables.update(_get_environment_variables(raw_value))
Expand Down
3 changes: 3 additions & 0 deletions src/compwa_policy/cli/python.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from compwa_policy.cli import _checks
from compwa_policy.cli._options import (
AllowVscodeCoverageGutters,
BranchCoverage,
DevPythonVersion,
ExcludedPythonVersions,
ImportsOnTop,
Expand All @@ -24,6 +25,7 @@ def python( # noqa: PLR0917
type_checker: TypeCheckerOption = None,
no_ruff: NoRuff = None,
imports_on_top: ImportsOnTop = None,
branch_coverage: BranchCoverage = None,
keep_local_precommit: KeepLocalPrecommit = None,
pytest_single_threaded: PytestSingleThreaded = None,
allow_vscode_coverage_gutters: AllowVscodeCoverageGutters = None,
Expand All @@ -36,6 +38,7 @@ def python( # noqa: PLR0917
type_checker=type_checker,
no_ruff=no_ruff,
imports_on_top=imports_on_top,
branch_coverage=branch_coverage,
keep_local_precommit=keep_local_precommit,
pytest_single_threaded=pytest_single_threaded,
allow_vscode_coverage_gutters=allow_vscode_coverage_gutters,
Expand Down
12 changes: 8 additions & 4 deletions src/compwa_policy/python/pytest.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,16 @@
from tomlkit.items import Array


def main(coverage_gutters: bool, single_threaded: bool) -> None:
def main(
coverage_gutters: bool, single_threaded: bool, branch_coverage: bool = True
) -> None:
with Executor() as do, ModifiablePyproject.load() as pyproject:
if not has_dependency(pyproject, "pytest"):
return
do(_merge_coverage_into_pyproject, pyproject)
do(_merge_pytest_into_pyproject, pyproject)
do(_deny_ini_options, pyproject)
do(_update_codecov_settings, pyproject)
do(_update_codecov_settings, pyproject, branch_coverage)
do(_update_settings, pyproject)
do(_update_vscode_settings, pyproject, coverage_gutters, single_threaded)
if single_threaded:
Expand Down Expand Up @@ -131,12 +133,14 @@ def __split_options(arg: str) -> list[str]:
return options


def _update_codecov_settings(pyproject: ModifiablePyproject) -> None:
def _update_codecov_settings(
pyproject: ModifiablePyproject, branch_coverage: bool = True
) -> None:
if not has_dependency(pyproject, ("coverage", "pytest-cov")):
return
updated = __update_settings(
config=pyproject.get_table("tool.coverage.run", create=True),
branch=True,
branch=branch_coverage,
omit=[
# https://github.com/microsoft/vscode-python/issues/24973#issuecomment-2886889888
"benchmarks/**/*.py",
Expand Down
21 changes: 20 additions & 1 deletion tests/python/test_pytest.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
from compwa_policy.python.pytest import _deny_ini_options
import pytest

from compwa_policy.errors import PrecommitError
from compwa_policy.python.pytest import _deny_ini_options, _update_codecov_settings
from compwa_policy.utilities.pyproject import ModifiablePyproject


Expand All @@ -9,3 +12,19 @@ def test_deny_ini_options_ignores_missing_pytest_table():
""") as pyproject:
_deny_ini_options(pyproject)
assert pyproject.changelog == []


def test_update_codecov_settings_can_disable_branch_coverage():
with (
pytest.raises(PrecommitError, match=r"Updated pytest coverage settings"),
ModifiablePyproject.load("""
[project]
name = "x"

[dependency-groups]
test = ["pytest-cov"]
""") as pyproject,
):
_update_codecov_settings(pyproject, branch_coverage=False)
coverage = pyproject.get_table("tool.coverage.run")
assert coverage["branch"] is False
25 changes: 24 additions & 1 deletion tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ def test_build_arguments_defaults() -> None:
assert args.type_checker == set()
assert args.excluded_python_versions == set()
assert args.keep_workflow == set()
assert args.branch_coverage is True
assert args.python is None


Expand Down Expand Up @@ -73,6 +74,7 @@ def test_flatten_nested_tables(
package-manager = "pixi"

[tool.compwa.policy.python]
branch-coverage = false
imports-on-top = true
type-checker = ["mypy", "pyright"]

Expand All @@ -90,6 +92,7 @@ def test_flatten_nested_tables(
assert _read_policy_config() == {
"dev_python_version": "3.12",
"package_manager": "pixi",
"branch_coverage": False,
"imports_on_top": True,
"type_checker": ["mypy", "pyright"],
"no_binder": True,
Expand All @@ -111,6 +114,7 @@ def test_pyproject_overrides_defaults(
dev-python-version = "3.12"

[tool.compwa.policy.python]
branch-coverage = false
type-checker = ["mypy", "pyright"]

[tool.compwa.policy.setup.env]
Expand All @@ -119,6 +123,7 @@ def test_pyproject_overrides_defaults(
)
args = build_arguments()
assert args.dev_python_version == "3.12"
assert args.branch_coverage is False
assert args.type_checker == {"mypy", "pyright"}
assert args.environment_variables == "PYTHONHASHSEED=0"

Expand All @@ -136,6 +141,19 @@ def test_cli_overrides_pyproject(
assert load_settings(dev_python_version="3.11").dev_python_version == "3.11"
assert load_settings(dev_python_version=None).dev_python_version == "3.12"

def test_branch_coverage_cli_overrides_pyproject(
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
_write_policy(
tmp_path,
monkeypatch,
"""
[tool.compwa.policy.python]
branch-coverage = false
""",
)
assert load_settings(branch_coverage=True).branch_coverage is True

def test_unknown_option_is_rejected(
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
Expand Down Expand Up @@ -165,6 +183,7 @@ class TestBuildPolicy:
def test_groups_into_sub_tables(self) -> None:
policy = _build_policy([
"--allow-labels",
"--no-branch-coverage",
"--keep-local-precommit",
"--no-pypi",
"--pytest-single-threaded",
Expand All @@ -174,7 +193,11 @@ def test_groups_into_sub_tables(self) -> None:
])
assert policy == {
"github": {"allow-labels": True, "no-pypi": True},
"python": {"keep-local-precommit": True, "type-checker": ["ty"]},
"python": {
"branch-coverage": False,
"keep-local-precommit": True,
"type-checker": ["ty"],
},
"pytest-single-threaded": True,
"repo-name": "policy",
"repo-title": "ComPWA repository policy",
Expand Down
Loading