Skip to content

Commit 7921942

Browse files
Merge branch 'main' into consolidate-bot-prs-379-383
2 parents 32ea919 + 658306c commit 7921942

11 files changed

Lines changed: 76 additions & 58 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 =

.github/actions/setup-python/action.yml

Lines changed: 11 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,6 @@ inputs:
66
python-version:
77
description: "Python version (e.g. '3.7', '3.8.13', '3.11.0-alpha.1', '3.x')."
88
required: true
9-
install-seed-packages:
10-
description: >
11-
Set to 'true' to install and/or upgrade seed packages (pip, setuptools, and wheel)
12-
before installing other packages.
13-
required: false
14-
default: "false"
159
requirements:
1610
description: "Optional list of arguments passed to `uv pip install` (e.g. 'numpy==1.19.5', '-r requirements.txt')."
1711
required: false
@@ -23,37 +17,19 @@ runs:
2317
with:
2418
python-version: "${{ inputs.python-version }}"
2519

20+
# Install uv and enable its built-in cache. The cache key takes the
21+
# platform, the uv version, and a hash of the files below into account.
22+
# See https://docs.astral.sh/uv/guides/integration/github/ for details.
23+
# NOTE: setup-uv publishes immutable releases only (no
24+
# floating major tags), so we pin the full version
2625
- name: Install uv
27-
shell: bash
28-
run: pip install --upgrade uv
29-
30-
# >>>>>>>> Caching uv packages >>>>>>>>
31-
32-
- name: Get uv cache dir
33-
id: uv-cache
34-
shell: bash
35-
run: echo "dir=$(uv cache dir)" >> $GITHUB_OUTPUT
36-
37-
- name: Get the current date in format YYYYWW (year and week-of-year)
38-
id: get-date
39-
shell: bash
40-
run: echo "date=$(/bin/date -u "+%Y%U")" >> $GITHUB_OUTPUT
41-
42-
- name: uv cache
43-
uses: actions/cache@v4
26+
uses: astral-sh/setup-uv@v9.0.0
4427
with:
45-
path: ${{ steps.uv-cache.outputs.dir }}
46-
# The cache's TTL is 7 days (one week)
47-
key: uv-${{ runner.os }}-${{ inputs.python-version }}-${{ steps.get-date.outputs.date }}
48-
# Fall back to the previous week's cache
49-
restore-keys: uv-${{ runner.os }}-${{ inputs.python-version }}-
50-
51-
# <<<<<<<< Caching uv packages <<<<<<<<
52-
53-
- name: Install and/or upgrade seed packages
54-
if: ${{ inputs.install-seed-packages == 'true' }}
55-
shell: bash
56-
run: uv pip install --verbose --system --upgrade pip setuptools wheel
28+
enable-cache: true
29+
cache-suffix: "py${{ inputs.python-version }}"
30+
cache-dependency-glob: |
31+
pyproject.toml
32+
requirements/*.txt
5733
5834
- name: Install requirements
5935
if: ${{ inputs.requirements != '' }}

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: 4 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`)
@@ -19,6 +22,7 @@ Unreleased changes
1922
- Bump actions/checkout from 6 to 7 ({gh-pr}`383`)
2023
- pre-commit autoupdate ({gh-pr}`379`)
2124
- Fix the test suite's compatibility with the latest pytest release ({gh-pr}`384`)
25+
- Use the official `astral-sh/setup-uv` action to install and cache `uv` in CI ({gh-pr}`386`)
2226

2327
---
2428

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:

0 commit comments

Comments
 (0)