

Join the discussion
Write your take first — we'll ask for email only when you're ready to publish.
- Hacker News
- TIL RustPython uses Ruff's AST which is fast.
LibCST can modify the AST/CST to do python codemod, now in Rust too;
rustpython-ruff_python_parser: https://crates.io/crates/rustpython-ruff_python_parser .. https://github.com/astral-sh/ruff
by westurner
Why. Why must my poor semver be hurt so!Ruff v0.16 has a small number of breaking changesI sorta kinda get why `ty` is pre v1.0.0 -- it's a typechecker that doesn't check a huge number of types. But what are we waiting for with `ruff`? Surely it's eaten whatever the old options were (black? maybe a few takes on py+lint?) by now many times over, and is even more dominant than `uv`.
I run this program hundreds of times a day so I'm generally excited for new features, but I guess the OAI acquisition has made me ornery when it comes to these folks. Apologies to kindly nerds who made this release happen, and congrats <3
by bbor- Zerover for lifeby Leynos
- It's conventional for semver to allow breaking changes for 0.x minor releases (but not for patch releases).by colinmarc
- Why must my poor semver be hurt so!
It is fully according to their versioning policy:
https://docs.astral.sh/ruff/versioning/
But also compliant with semver:
Major version zero (0.y.z) is for initial development. Anything MAY change at any time. The public API SHOULD NOT be considered stable.
(Maybe I misinterpreted your remark, but semver does not get hurt.)
by microtonal - If you listen closely you can hear the thousands of CI jobs that just pull latest UV failing all at once.by aomix
- Looks like it's recommended to use zero-config now, which is great! My new .ruff.toml is just:
line-length = 300 - I really wish Ruff would introduce something similar to Nix’s stateVersion, which is used to determine the set of defaults that will be applied. Updating Ruff at a scale beyond a single repo is a bit of a crapshoot currently, with every version introducing a bunch of new default rules which you then have to deal with immediately (either by turning them off or fixing them).
I’m aware we could have an allowlist in place which specifies all rules that are turned on but I’d much rather have a simpler config file, and be able to bump the state version at a good time for everyone to spend a few hours fixing new violations.
by jon-wood - If you want to be protected from changes in the default set, you can choose the ones you want with `select`.by maleldil
- > with every version introducing a bunch of new default rules which you then have to deal with immediately
According to the original post
> Ruff's default rule set was last modified in v0.1.0
Which was over 2 years ago.
by gcarvalho - > I really wish Ruff would introduce something similar to Nix’s stateVersion
Two approaches:
You can pin the version of `ruff` in `pyproject.toml`.
You, to let ruff command version advance but pin the settings to a prior version:
The `flat2toml` script is left as an exercise. Then in `ruff.toml`:uvx ruff@0.15.22 check --isolated --show-settings | flat2toml > pinned.tomlextend = "pinned.toml"by frumiousirc - I think the consensus is that this would be the wrong end to tackle the problem from. Your project should include ruff at the version it wants to use in its pyproject.toml. Bump the version when you're ready to spend the time on one project, but no need to coordinate across multiple projects. If you really want to do it, you can, but if there's one hold-out, you're not stuck behind forever because one project can't move yet.by mirashii
- This is great news! With the advent of agentic coding, strong linting is more important than ever. What I'd really like to see is forbidigo for more languages.by kstenerud
- 100% agree, I am upgrading my projects now. And yet, I have mixed feelings about this. I like to think that when I (was) writing code myself, I applied a great deal of intuition to decide when to skip or ignore some rule. On the hand, I also saw projects were developers where using pylint with most rules enabled and I have to say the code was not better - on the contrary it had plenty of hacks to make pylint happy at the cost of illegible code.
Not unlike that experience, I also saw coding agents spend lots of tokens trying to fix a benign issue, as well as doing the opposite - like disabling the tests !!! when they don't pass. :facepalm:
I grew to trust AI results in terms of overall correctness, but I still have hard time trusting their *judgement* on the *code quality*.
by alentred - Good news. enabling 413 rules by default means most projects get useful linting without touching the config at all!by hyeongjun
- Maybe it's just me, but getting overrun with "413 x potential warnings" hardly sounds useful :) Great for greenfield, less so for existing projects. Although nowadays, fire up your agent with "/goal work through and address all lint warnings by fixing the code according to XYZ" and leave it alone for a couple of hours and I guess it's no longer an issue...
Don't get me wrong, the new level of details coming from Ruff is much appreciated and a good thing :)
- I wish Go had something like Ruff! A lot of languages are getting amazing tool but Go has a very fragmented ecosystem with a lot of tools but none of them feel as high quality has the likes of Ruff, Oxc, Biome or even PHP's Magoby gempir
- What? I feel go has one of the best language tooling out there without requiring a bully ide to do stuff. golangci-lint is quite comprehensive. What do you miss otherwise?
(Honestly go's distributing itself has covered a lot of it)
by aki237 - Golang-ci exists for a while and everyone is using it.
Not sure what you're talking about.
by Thaxll - I’m not entirely sure what you mean by a fragmented ecosystem? Go has first-party formatting and linting and the language is deliberately restricted to ensure it is written in a certain way, even when written by complete novices.
Compare that to Python or TypeScript which are Wild West languages without opinionated first-party tooling, and it’s clear why Ruff/Biome feel great.
You just wouldn’t get that same high with Go.
by bargainbin - Oh wow, not so long ago the sentiment was exactly opposite. Python community was struggling with tools and everyone wished to have `gofmt` for Python.
Granted, this is a linter, not a formatter, but my larger point is I am glad that Python ecosystem evolved like it did recently.
by alentred - It does and it is even better. It is called the Go Analysis Framework (https://pkg.go.dev/golang.org/x/tools/go/analysis).
It is fairly new so not well known but it is what powers go fix and go vet under the hood. And I believe the Go team is currently working on making it possible for module authors to easily describe their own custom analysis passes that would run automatically when running go fix.
It is extremely easy to define your own analysis.Analyzer struct that describes your own static analysis pass. You get access to all sorts of useful information such as the AST, types, even SSA info and you can even compose the information between analyzers. Then you can easily compile it into a binary and run it by passing that binary to go fix with a command line flag. The go toolchain itself handles all the complex caching logic so that your analyzers run fast.
Since it is made by the go team itself and part of the toolchain it should slowly become the unified standard you are looking for. So hopefully golangci-lint and others should eventually all unify under this framework.
You can easily give it a go by telling some AI agent to write some Go Analysis analyzers and telling them to drive them with go fix. My Go projects tend to accumulate a bunch of these to enforce all sorts of rules deterministically and automatically instead of some imprecise markdown file.
by gopherino - Great to see ruff, ty and uv being actively developed, even after Astral was acquired by OpenAI.
- Tbh I was super enthusiastic about Ty but it’s just so far behind basedpyright I had to switch off it. The lack of checks wasn’t the issue, it was the false positives which were the real dealbreaker. That and it doesn’t have support for baselining, which is such an insanely awesome feature for larger codebases. uv and ruff are incredible though. Maybe someday on Ty.by appplication
- The amount of fascination that people have with these "grammar nazi" bots -- some of them implementing completely arbitrary "rules" and some of them disagreeing with others on what "good" Python code should look like -- doesn't stop to amaze me.
Here's "bad" code:
Here's what "good" code should look like:important_numbers = { 'x': 3, 'y': 42, # Answer to the Ultimate Question! 'z': 2 }
Which completely misses the writer's intent. But did you notice that there are two spaces before the pound now? Also, the quotes are now double because apparently it's somehow more kosher! So much improvement!important_numbers = {"x": 3, "y": 42, "z": 2} # Answer to the Ultimate Question!The actual problems in the code I work with are not the spaces at the end of line or imports in non-alphabetic order, it's the 10-line list comprehensions that are so long that they're impossible for me to parse. None of these tools catch that. My place used pylint, flake8, black, ruff -- with hundreds of commits on every change. All that energy could be better spent elsewhere.
by maratc - > The actual problems in the code I work with are not the spaces at the end of line or imports in non-alphabetic order, it's the 10-line list comprehensions that are so long that they're impossible for me to parse.
100%. Almost all of my time burned navigating code is not hung up on stylistic conventions but on nasty services with inconsistent abstractions and patterns.
BUT, conventions and consistency make code easier to read and write, period. If you’re debating over single or double quotes that’s almost a fireable offense IMO.
Additionally, when you have a culture that delegates to tools as much as possible, the focus sharpens in a healthy way.
by dirtbag__dad - The actual rules are less important, only the consistency of applying them is.
I find that people who argue against automatic linting and formatting tend to be the same that would argue incessantly about style. So much wasted energy, I want none of that.
Also, in your example above, if you put the comment on the line _above_ instead of inline the formatter will most likely do the right thing.
by elteto - This seems like a strange hill to die on. Linters don’t consume energy, that’s the entire point. They get everyone on the same standard so that no energy is wasted by anyone on having to discuss, debate, and implement these standards. And yes, there are instances where someone’s non-standard coding style is not a problem. But there are instances where it absolutely can be, and these tools help there.
I’m also not sure I understand the “ My place used pylint, flake8, black, ruff -- with hundreds of commits on every change”. These tools don’t add extra commits. You run them prior to your PR, get them aligned with the linting, and then commit the change you were already going to make. Thats 0 extra commits.
For someone ultimately arguing that there is too much effort spent on people’s coding styles, you are spending a lot of effort arguing about people’s coding styles. These tools are some of the most set it and forget it things around.
by NeutralCrane - It’s because you forgot a comma after the last item. If you had kept that the items wouldn’t have been compacted (at least in black, I’ve stopped linking my code because it breaks intends of formatting more often than it helps)by wodenokoto
- Those tools actually save team energy. Without them any programmer has different opinion on formating, code quality, what is readable etc. You can discuss it endlesly or you can just use ruff.by jbvlkt