Posted by brianzelip 11 hours ago
I used to find this kind of tooling explosion exhausting (and back then with JS it truly was), but generally speaking it's a good sign that the community is hungry to push things forward. Choice is good, as long as we keep the Unix spirit alive: small, composable tools that play nicely together and can be interchanged.
Anything whatever the FE team feels like using, and the less I know about it, the better.
So which is it that you want, to just reach for one tool or have tools that have specific design goals and then have to reach for many tools in a full workflow?
FWIW Astral's long term goal appears to be to just reach for one tool, hence why you can now do "uv format".
There is a reason us old timers mostly wait on the sidelines until the dust settles.
We have seen this movie already too many times.
The problem with the python tooling is no one can get it right. There aren't clear winners for a lot of the tooling.
* uv: project management, formatting
* Pyright: type checking
* Pylint: linting (this is probably optional though I would strongly recommend it). Ruff is an option but I don't think it is quite as comprehensive yet.
There are alternatives for those tools but they are pretty clearly the best options at the moment. There's nothing in uv's league, and the only alternatives in Pyright's league is BasedPyright. Hopefully Ty and Pyrefly will be good options in future but I don't think they're ready for production use just yet.
> pyrefly, ty, pyright, and basedpyright
All of them will complain 2-4x more about your code than PyCharm. I had more than 300 typing errors when I first opened my 20k LOC project in pyright that I wrote in Pycharm.
PyCharm works great when your code is not annotated. It infers types very well. But it won't complain in a lot of cases when your code is annotated.
Related reddit post https://old.reddit.com/r/Python/comments/1ajnikt/to_pycharm_...
They are designed for code which are more or less fully typed, as opposed to PyCharm which cobbles together a bunch of heuristics to try to make sense out of untyped code. An admirable quest, but not one I'm personally interested in.
And their insistence on only supporting this approach drove my entire team away from using PyCharm.
(From shallowly observing notifications on the 20+ typehint related issues I'm subscribed to, they seem to have kinda turned around and working toward fully supporting the python type system finally - possibly by integrating with one of the third-party type-checkers)
Nowadays I'm finding myself using Zed a lot more, so maybe the story will be that all these nice Rust based tools become baked in giving it super powers for Python.
- zuban
- ty (from ruff team)
- pyrefly
One year ago, we had none of them, only slow options.
It is interesting that nobody was writing these tools in C or in C++. There are obvious ergonomic reasons, but perhaps also it matters that Rust cares a lot more about types than either of those languages.
This one's easier to explain. People interested in tooling for a specific language probably want to write that tooling in that language (hence pip, poetry, mypy, jedi, etc). Normally that would be the end if it, if Python wasn't 10-100x slower than a natively compiled language. And going from Python to Rust is an order of magnitude easier than going from Python to C or Python to C++, because the compiler is so good at identifying silly mistakes. Rust is just a friendlier language.
The author of Zuban started writing it back in 2020 or 2021, so it took him more than 4 years to complete it. And he is the author of Jedi, so he had prior experience already.
Zuban seems to have a bunch of scary "I'm not sure if this is correct" unsafe blocks, which to me would be a red flag. I mean, it's better that there's a comment expressing the doubt, but my experience is that if you're not sure whether it's correct, it's probably not correct.
For anyone reaching for unsafe, there are in many cases either an existing API (split_at_mut comes to mind). For others, using zero-copy or bytemuck instead of unsafe is a good idea too.
None of that is to say "never write unsafe", unsafe existing is pretty much one of the reasons for Rust to be :)
For example in crates/zuban_python/src/file/diagnostics.rs:
"TODO this unsafe feels very wrong, because a bit lower we might modify the complex/ points."
or crates/zuban_python/src/database.rs:
"Points are guarded by specific logic and if they are overwritten by something that shouldn't it should not be that tragic."
I saw nothing where I was like "ZOMG this is definitely busted" but I definitely did not get the robust "Oh, I see now why this is correct" that I like from a good unsafe rationale comment, and these aren't tiny things like the small unsafe bit twiddling transmutes which are probably either actually correct or in any case will do what you expected at compile time and so any surprises are priced in without a rationale text.
All I know is it is much more strict about stuff than pylance was.
Also a me problem!
https://github.com/microsoft/pyright/issues/1739
> I think EAFP is a very unfortunate and ill-advised practice.
They want you to not write the idiomatic Python:
try:
foo = bar["baz"]["qux"]
...
except KeyError:
...
…and instead write the non-idiomatic version: if "baz" in bar and "qux" in bar["baz"]:
foo = bar["baz"]["qux"]
...
else:
...
If this were a linter then I would accept that it is going to be opinionated. But this is not a linter, it’s a type checker. Their opinions about EAFP are irrelevant. That’s idiomatic Python.All of them had some big issue that prevented it from getting mainstream. Either it was slow, or didn’t work with existing workflow, or had complex configuration, or something that prevented gradual adoption.
uv is universally praised as the second coming Christ in Python world (and for a good reason). So no, I doubt there will be something else. Not only you need to be better than uv, you also need to have community momentum.
Pydantic is probably the problem here, but it is what it is.
foo = eval(result)
It can’t know what you’re going to load until it actually does it.Things which lean heavily into metaprogramming, typically ORMs or things like Pydantic, fall into that category. I can’t hold that against the type system.
I think we should. Dataclasses have existed in Python for an extremely long time, and yet the type system doesn't support defining your own similar classes. Kwargs have also existed forever, but they forgot to support that and had to add TypedDict's much later. And it still doesn't properly support optional fields. There's a lot of stuff like this in the language which are unbelievably frustrating, because for some reason they implemented the syntax before implementing a typechecker. Everything has been hacked in ever since. I consider python's type system to be a lost cause, just hoping for someone to make the Typescript equivalent for Python.
I don't think you understand what Pydantic brings to the table or why people use it. It has lots more to do with serialization, complex validation and data mapping.
Already there is some support in Pydantic for native dataclasses: https://docs.pydantic.dev/latest/concepts/dataclasses/
[1]: https://docs.python.org/3/library/dataclasses.html#dataclass...
[2]: https://docs.python.org/3/library/dataclasses.html#dataclass...
Aside from basic inheritance and complex nested types, the pydantic ‘TypeAdapter’ is awesome for simply validating native dataclasses. It’s a little slow, but everything pydantic is =)