Repository navigation
Build with uv_build instead of hatchling - #581
Merged
Merged
Conversation
The project already uses uv for package management, so use its build
backend as well.
- uv_build requires a static version, so the version now lives only in
pyproject.toml. wfdb.__version__ is read from the installed package
metadata ("unknown" if the package is imported from a source tree that
has not been installed), and the documentation reads it from
pyproject.toml. Update the release instructions accordingly.
- Use an SPDX license expression and list the license file explicitly,
since uv_build does not pick it up automatically.
- Drop the hatchling sdist excludes: uv_build only packages the wfdb
module, the license, the readme and pyproject.toml.
- Add a changelog entry.
The wheel contents are unchanged.
tompollard
approved these changes
Oct 27, 2026
tompollard
left a comment
Member
There was a problem hiding this comment.
Thanks @cbrnr, this looks good to me. I'm fine with the slimmer sdist (package, LICENSE, README.md, pyproject.toml). I don't think anyone needs docs/ or .github/ in it.
tompollard
added a commit
that referenced
this pull request
Oct 27, 2026
Fourth PR of the tooling series (after #578, #580 and #581). It replaces `black` (formatting) and `pylint` (which was not run anywhere, and had a 560 line config) with [Ruff](https://docs.astral.sh/ruff/), which does both. The PR consists of four commits, and I suggest reviewing them one by one: 1. **Replace black and pylint with Ruff:** the actual configuration. The `dev` extra now contains `ruff >= 0.13.0` (the first version that agrees with the rules below) instead of `black` and `pylint`, the style workflow runs `ruff format --check` and `ruff check`, `pylintrc` is removed, and the developer docs and the changelog are updated. 2. **Fix a test that was never run:** `tests/test_multi_record.py` defines `test_contained_combined_ranges_variable_layout` twice, so the first definition was shadowed and never ran (Ruff reports this as F811). I renamed the second test. Both pass. 3. **Apply ruff formatting and safe lint fixes:** purely mechanical (34 files). You can reproduce it with `ruff check --fix . && ruff format .` on the first two commits. It contains the formatting, plus the safe autofixes of the enabled rules: sorted imports, f-strings instead of `str.format()`, `list[...]`/`X | None` instead of `typing` aliases, `class X:` instead of `class X(object):`, and unused imports. 4. **Ignore the reformatting commit in git blame:** adds `.git-blame-ignore-revs` with commit 3 (GitHub uses this file automatically; locally, run `git config blame.ignoreRevsFile .git-blame-ignore-revs`, which is documented in `DEVELOPING.md`). Note that the hash only stays valid if the commits of this PR are preserved, i.e. with a merge commit (as for the previous PRs), not when squashing or rebasing. ## Configuration - **Line length:** Ruff's default of 88 instead of black's 80 (as configured so far). - **Rules:** `E`, `F`, `W` (pycodestyle/pyflakes), `I` (isort), `UP` (pyupgrade) and `B` (bugbear). `E501` is ignored because the formatter takes care of line lengths, and `F401` is ignored in `__init__.py` files (re-exports). - **Existing violations:** I did not want to change code behavior in this PR, so the rules whose fixes are not safe are ignored for now (about 90 occurrences in total): `E711`, `E721`, `E722`, `E741`, `F841`, `UP031`, `B006`, `B007`, `B020`, `B904`, `B905`. They can be enabled one by one in follow-up PRs. - Jupyter notebooks are not checked (black did not check them either). ## Testing - `ruff check .` and `ruff format --check .` pass (also with the oldest allowed Ruff, 0.13.0), and all modules still import. - The test suite behaves as before on Python 3.11 with the lowest allowed dependency versions and on 3.15 with the latest (65 passed, and only the 17 tests that need PhysioNet fail when offline; the test that was shadowed before is now among the passing ones). - With the ignore file, `git blame` attributes lines changed by commit 3 to their original commits.
tompollard
added a commit
that referenced
this pull request
Oct 28, 2026
#589) This is the last part of the cleanup that started with #578, #580, #581, #582 and #588. It builds the documentation without warnings, applies one docstring style everywhere, and moves the package to a `src` layout. Each commit can be reviewed on its own. 1. **Fix all Sphinx documentation warnings.** The docs build reported 94 warnings. They are fixed, and the docs workflow now builds with `-W --keep-going` so they stay fixed. - Duplicate object descriptions: repeated `automodule` directives and the classes documented on both the `wfdb` and `io` pages are marked `:no-index:`, so each object is indexed once. - `numpydoc_class_members_toctree = False`, because the autosummary stubs it links to do not exist. - Too short title underlines, and reStructuredText errors in docstrings (lists, literal blocks for the EDF/MATLAB/WAV format descriptions and tables, doctest continuation lines). - The `:no-index:` option needs Sphinx 7.2, so the pinned Sphinx version of the `docs` group goes from 7.0.0 to 7.2.6. 2. **Wrap docstrings and comments at 88 columns**, the same width as the code, and enable W505 in Ruff so it stays that way. This is a mechanical change, and the commit is listed in `.git-blame-ignore-revs`. 3. **Start docstrings on the opening quote line with a one-line summary.** Summaries that were wrapped over several lines or too long for one line are shortened, and the rest of the text moves into the description below. No code changes: comparing the ASTs with docstrings removed shows no difference. A few docstrings were reworded to fit, and the descriptions of `csv_to_wfdb` and `csv2ann` (which described reading a WFDB header) now match what the functions do. Also listed in `.git-blame-ignore-revs`. 4. **Move the package to `src/wfdb`.** This is the default module root of `uv_build`, so the `module-root` setting is removed. The tests now always run against the installed package, and `docs/conf.py` adds `src` to `sys.path`. Files are moved without changes, so `git blame` and `git log --follow` keep working. The wheel and the sdist build as expected. 5. **Ignore the two reformatting commits in git blame**, and add a note about the docstring style to `DEVELOPING.md`. The hashes stay valid with a merge commit, as in #582. 6. **Add `AGENTS.md` and `CLAUDE.md`** with short guidance for coding agents (commands and conventions). `CLAUDE.md` only points to `AGENTS.md`. Checked locally: Ruff lint and format, the docs build with `-W --keep-going`, and the tests that work offline on Python 3.11 with the lowest dependencies and on 3.15. @tompollard this concludes the tooling and infrastructure refresh. Any remaining changes are minor, such as fixing the ignored Ruff rules, which can be done later in follow-up PRs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Third PR of the tooling series (after #578 and #580). The project already uses uv for package management, so this switches the build backend to
uv_buildas well.Changes
uv_build >= 0.13.0, < 0.14replaceshatchling. The package lives in the project root (not insrc/), somodule-root = ""is set.uv_builddoes not support dynamic versions, so the version is now only specified inpyproject.toml(the release instructions inDEVELOPING.mdare updated).wfdb.__version__is read from the installed package metadata, and it is"unknown"ifwfdbis imported from a source tree that has not been installed. The documentation reads the version frompyproject.toml.uv_builddoes not include the license file automatically, solicense-files = ["LICENSE"]is set. I also switched to the SPDX expressionlicense = "MIT"(the old table form is deprecated).What changes in the distributions
License-Expression: MITinstead ofLicense: MIT License).wfdbpackage,LICENSE,README.mdandpyproject.toml(plusPKG-INFO). The hatchling sdist also containeddocs/,.github/,DEVELOPING.md,pylintrcand some dotfiles (tests, sample data and the demo files were already excluded). I think that is fine, but let me know if you would like to keep some of these in the sdist.Testing
uv_build(0.13.6) and with the lowest allowed version (0.13.0), and compared the result with the hatchling build (see above).wfdb.__version__is4.3.1. In an editable install it is4.3.1, and importing from an uninstalled source tree givesunknown.black --checkpasses.