1,052 karma · joined January 28, 2022
https://crmarsh.com/ https://twitter.com/charliermarsh https://github.com/charliermarsh
I've tried to be honest about ruff's limitations: it supports only a small set of rules, it's not extensible in any way, it's missing edge-case handling, it's significantly under-tested compared to existing tools, etc. I don't consider it production-ready -- it's a proof-of-concept.
(I _did_ try to build conviction that there weren't inherent reasons for ruff to slow down significantly as the set of checks extended, but I could definitely be proven wrong as the project grows...)
My goal with ruff was partly to build a fast linter, but that was really in service of testing a broader hypothesis I have about Python developer tools could evolve. If that's interesting to you, I wrote about it a bit more here: https://notes.crmarsh.com/python-tooling-could-be-much-much-.... I'm certainly not here to say that the existing tools are bad or you shouldn't use them or that you should use ruff instead. I use those tools myself -- a lot!
With regards to code organization: oh well, this doesn't bother me given the state of the project. The code will evolve as the project grows in scope, I didn't see a need to over-abstract. I'd written a small amount of Rust prior to ruff, but much of it was a learning experience for me. (Funnily enough: not that I want ruff to be organized as such, but pyflakes, pycodestyle, and autoflake are also effectively single-file projects :))
> The main thing that eventually forced decision was a flaky (depends on cache) mypy crash using paramspecs half a year ago. At time paramspec support was still in progress and there’s a good chance that specific issue is fixed.
I actually think I ran into this exact issue (ParamSpec-related, only fails when reading from cache, etc.), which led me to pin a Mypy development version for a while and was fixed recently.
The runtime validation stuff has been interesting to watch. Do you use Pydantic? It's very popular but I have a hard time getting over its willingness to cast / coerce implicitly (if I mark a field as an int, and pass in a str, I want an error -- is that weird of me?).
I tried to acknowledge the deficiencies in LOC in the second paragraph... but it felt like a useful shorthand for conveying a sense of scale and complexity (at least to an order-of-magnitude) in a domain-agnostic way.
Outside of Mypy, we use: black, isort, flake8, docformatter, and autoflake (to remove unused imports) -- all on pre-commit + enforced on CI. I'd like to see Black cannibalize more of that toolchain :)