Tombi, pre-commit, prek and uv.lock¶
In almost all my Python projects, I’m using pre-commit to handle/check formatting and linting. The advantage: pre-commit is the only tool you need to install. Pre-commit itself reads its config file and installs the formatters and linters you defined in there.
Here’s a typical .pre-commit-config.yaml:
default_language_version:
python: python3
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v6.0.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
args: [--allow-multiple-documents]
- id: check-toml
- id: check-added-large-files
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.15.6
hooks:
# Run the linter.
- id: ruff
args: ["--fix"]
# Run the formatter.
- id: ruff-format
- repo: https://github.com/tombi-toml/tombi-pre-commit
rev: v0.9.6
hooks:
- id: tombi-format
args: ["--offline"]
- id: tombi-lint
args: ["--offline"]
The “tombi” at the end might be a bit curious. There’s already the build-in “check-toml” toml syntax checker, right? Well, tombi also does formatting and schema validation. And in a recent project, I handled configuration through toml files.
It was for a Django website where several geographical maps were shown, each with its own title, description, legend yes/no, etcetera. I made up a .toml configuration format so that a colleague could configure all those maps without needing to deal with the python code. I created a json schema as format specification (yes, json is funnily used for that purpose). With tombi, I could make sure the config files were valid.
Oh, and tombi has an LSP plugin, so my colleague got autocomplete and syntax help out of the box. nice.
I’m also using uv a lot. That generates an uv.lock
file, in .toml format, with all the version pins. It is a toml file, but without the
.toml extension. So pre-commit ignored it. Until suddenly it started complaining
about the indentation. But only in a github action, not locally.
Note: the complaint about the indentation is probably correct, as there’s an issue in the uv bugtracker about changing the indentation from 4 to 2 in the lockfile.
The weird thing for me was that I pin the the versions of the plugins. So the behaviour locally and on github should be the same. Some observations:
Running
tombifrom the commandline onuv.lockresulted in re-formatting to two spaces, whatever the tombi version.Pre-commit locally did not re-format the file, but pre-commit on the server did.
I tried it with the new rust-based alternative for pre-commit, prek (see https://github.com/j178/prek), which did re-format uv.lock.
Some further debugging showed that pre-commit was actually skipping the uv.lock
file. But apparently not on github. I did some searching in pre-commit’s source code and
tombi’s pre-commit hook definition. The
only relevant part there was types: [toml]. So somehow pre-commit has a definition
of what a toml file is. But I couldn’t find anything.
Until I spotted that pre-commit uses identify as
the means to detect file types. (Looks like a handy library, btw!). And that project had
a change a couple of weeks ago
that identifies uv.lock as a toml file!
My colleague updated his pre-commit installation and yes:
uv.lockwas getting re-formatted.So: github actions had a newer version than we had.
Weird, as I just updated my python tool install this morning. Ah: I installed it with homebrew instead of
uv tool, that’s why it is still older.
Anyway: small mystery solved.