Skip to content

Commit abb6fa8

Browse files
Merge branch 'main' into 219-setup-uv-action
2 parents 4de9e70 + 978b863 commit abb6fa8

11 files changed

Lines changed: 65 additions & 24 deletions

File tree

.coveragerc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ src =
1717
[report]
1818
precision = 1
1919
show_missing = true
20-
skip_covered = false
20+
skip_covered = true
2121
fail_under = 50
2222

2323
# Some of the patterns below were taken or adapted
@@ -36,6 +36,7 @@ exclude_lines =
3636
: \.\.\.(\s*#.*)?$
3737
^ +\.\.\.$
3838
-> ['"]?NoReturn['"]?:
39+
^\s*assert_never\b
3940
# non-runnable code
4041
if __name__ == ['"]__main__['"]:$
4142
partial_branches =

AGENTS.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,8 @@ def _coerce_to_densities(...):
209209
## CI/CD Pipeline
210210

211211
GitHub Actions runs tests on Python 3.10–3.14 across Ubuntu, macOS, and Windows.
212-
Codecov minimums are 98% overall and 100% diff coverage for new code.
212+
Codecov minimums are 100% overall and 100% diff coverage for new code.
213+
Intentionally-untested lines must carry an explicit `# pragma: no cover` comment.
213214

214215
## Notes for AI Assistants
215216

codecov.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Codecov configuration
2+
# ref: https://docs.codecov.com/docs/codecov-yaml
3+
#
4+
# Note: CI only uploads the combined coverage report
5+
# (see the coverage-combine env in tox.ini), which omits
6+
# "cicd_utils/*" and "tests/*", so these targets apply
7+
# to the src/ridgeplot package only.
8+
coverage:
9+
status:
10+
project:
11+
default:
12+
target: 100%
13+
patch:
14+
default:
15+
target: 100%

docs/reference/changelog.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ Unreleased changes
77

88
### CI/CD
99

10+
- Review the coverage configuration in light of `covdefaults`, adopting its `assert_never` exclusion and `skip_covered` report setting, and raising all package coverage gates to 100% ({gh-pr}`390`)
11+
- Adopt pytest's strict mode, following the recommendations from pytest's "Good Integration Practices" guide ({gh-pr}`387`)
12+
- Make the e2e path sanity check independent of the checkout directory's name, so tests can run from git worktrees ({gh-pr}`391`)
1013
- Bump actions/download-artifact from 7 to 8 ({gh-pr}`368`)
1114
- Bump actions/upload-artifact from 6 to 7 ({gh-pr}`369`)
1215
- Bump sigstore/gh-action-sigstore-python from 3.2.0 to 3.3.0 ({gh-pr}`370`)

pytest.ini

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,17 @@
11
[pytest]
22
addopts =
33
# Tests summary report
4-
# ref: https://docs.pytest.org/en/8.3.x/how-to/output.html#producing-a-detailed-summary-report
4+
# ref: https://docs.pytest.org/en/stable/how-to/output.html#producing-a-detailed-summary-report
55
-ra
66
# (V)Verbose
77
-vv
88
# Show local variables in tracebacks
99
--showlocals
10-
# Raise error on unknown markers
11-
--strict-markers
1210
# Import mode
13-
# ref: https://docs.pytest.org/en/8.3.x/explanation/pythonpath.html#import-modes
11+
# ref: https://docs.pytest.org/en/stable/explanation/pythonpath.html#import-modes
1412
--import-mode=importlib
1513
# Minimal duration in seconds for inclusion in slowest list
16-
# ref: https://docs.pytest.org/en/8.3.x/how-to/usage.html#profiling-test-execution-duration
14+
# ref: https://docs.pytest.org/en/stable/how-to/usage.html#profiling-test-execution-duration
1715
--durations-min=0.5
1816
# Fail if a test tries to open a network connection
1917
# ref: https://github.com/miketheman/pytest-socket
@@ -25,22 +23,25 @@ addopts =
2523
--no-cov-on-fail
2624
--cov-report=term-missing
2725

26+
# Enable all of pytest's strictness options (requires pytest>=9).
27+
# As of pytest 9.1, this enables: strict_config, strict_markers,
28+
# strict_parametrization_ids, and strict_xfail. Any new strictness
29+
# options added in future pytest releases will also be picked up here.
30+
# ref: https://docs.pytest.org/en/stable/explanation/goodpractices.html#using-pytest-s-strict-mode
31+
# ref: https://docs.pytest.org/en/stable/reference/reference.html#confval-strict
32+
strict = true
33+
2834
# Default list of directories that pytest will search for tests in.
2935
# This should be overridden in tox.ini to run specific test suites.
30-
# https://docs.pytest.org/en/8.3.x/reference/reference.html#confval-testpaths
36+
# https://docs.pytest.org/en/stable/reference/reference.html#confval-testpaths
3137
testpaths = tests
3238

3339
# List of directories that should be added to the python search path
34-
# https://docs.pytest.org/en/8.3.x/reference/reference.html#confval-pythonpath
40+
# https://docs.pytest.org/en/stable/reference/reference.html#confval-pythonpath
3541
pythonpath = cicd_utils
3642

37-
# Tests marked with @pytest.mark.xfail that actually
38-
# succeed will by default fail the test suite.
39-
# https://docs.pytest.org/en/8.3.x/reference/reference.html#confval-xfail_strict
40-
xfail_strict = true
41-
4243
# Warning filters pattern: action:message:category:module:line
43-
# ref: https://docs.pytest.org/en/8.3.x/how-to/capture-warnings.html
44+
# ref: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
4445
# ref: https://docs.python.org/3/library/warnings.html#describing-warning-filters
4546
# ref: https://docs.python.org/3/using/cmdline.html#cmdoption-W
4647
filterwarnings =

requirements/tests.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# pytest and plugins
2-
pytest
2+
# (pytest>=9 is needed for the `strict` config option set in pytest.ini)
3+
pytest>=9
34
pytest-icdiff
45
pytest-socket
56

tests/e2e/test_examples.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@
1313

1414

1515
def test_paths_exist() -> None:
16-
assert PATH_ROOT.name == "ridgeplot"
16+
# Sanity check that PATH_ROOT points at the repo root, without
17+
# depending on the name of the checkout directory (which differs
18+
# in git worktrees and renamed clones)
19+
assert (PATH_ROOT / "pyproject.toml").is_file()
1720
assert PATH_ARTIFACTS.is_dir()
1821
assert PATH_CHARTS.is_dir()
1922

tests/unit/test_hist.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,11 @@ def test_bin_trace_samples_nbins(nbins: int) -> None:
3939
assert len(density_trace) == nbins
4040

4141

42-
@pytest.mark.parametrize("non_finite_value", [np.inf, np.nan, float("inf"), float("nan")])
42+
@pytest.mark.parametrize(
43+
"non_finite_value",
44+
[np.inf, np.nan, float("inf"), float("nan")],
45+
ids=["np-inf", "np-nan", "float-inf", "float-nan"],
46+
)
4347
def test_bin_trace_samples_fails_for_non_finite_values(non_finite_value: float) -> None:
4448
err_msg = "The samples array should not contain any infs or NaNs."
4549
with pytest.raises(ValueError, match=err_msg):
@@ -64,7 +68,11 @@ def test_bin_trace_samples_weights_not_same_length() -> None:
6468
bin_trace_samples(trace_samples=SAMPLES_IN, nbins=NBINS, weights=[1, 1, 1])
6569

6670

67-
@pytest.mark.parametrize("non_finite_value", [np.inf, np.nan, float("inf"), float("nan")])
71+
@pytest.mark.parametrize(
72+
"non_finite_value",
73+
[np.inf, np.nan, float("inf"), float("nan")],
74+
ids=["np-inf", "np-nan", "float-inf", "float-nan"],
75+
)
6876
def test_bin_trace_samples_weights_fails_for_non_finite_values(
6977
non_finite_value: float,
7078
) -> None:

tests/unit/test_kde.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,11 @@ def test_estimate_density_trace_points() -> None:
4949
assert np.argmin(y) == 0
5050

5151

52-
@pytest.mark.parametrize("non_finite_value", [np.inf, np.nan, float("inf"), float("nan")])
52+
@pytest.mark.parametrize(
53+
"non_finite_value",
54+
[np.inf, np.nan, float("inf"), float("nan")],
55+
ids=["np-inf", "np-nan", "float-inf", "float-nan"],
56+
)
5357
def test_estimate_density_trace_fails_for_non_finite_values(non_finite_value: float) -> None:
5458
err_msg = "The samples array should not contain any infs or NaNs."
5559
with pytest.raises(ValueError, match=err_msg):
@@ -101,7 +105,11 @@ def test_estimate_density_trace_weights_not_same_length() -> None:
101105
)
102106

103107

104-
@pytest.mark.parametrize("non_finite_value", [np.inf, np.nan, float("inf"), float("nan")])
108+
@pytest.mark.parametrize(
109+
"non_finite_value",
110+
[np.inf, np.nan, float("inf"), float("nan")],
111+
ids=["np-inf", "np-nan", "float-inf", "float-nan"],
112+
)
105113
def test_estimate_density_trace_weights_fails_for_non_finite_values(
106114
non_finite_value: float,
107115
) -> None:

tests/unit/test_utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ def test_raise_for_non_2d_array(self) -> None:
4444

4545
@pytest.mark.parametrize(
4646
("densities_type", "rows_type"),
47-
product((id_func, tuple, list), (id_func, tuple, list, np.asarray)),
47+
list(product((id_func, tuple, list), (id_func, tuple, list, np.asarray))),
4848
)
4949
def test_expected_output(
5050
self,

0 commit comments

Comments
 (0)