I will be a happy clam when it can check `Protocol`s.
> What is the difference from Ruff?
Ruff, like pylyzer, is a static code analysis tool for Python written in Rust, but Ruff is a linter and pylyzer is a type checker & language server. pylyzer does not perform linting, and Ruff does not perform type checking.
This unfortunately has `docstring-to-markdown` as one of its dependencies, which is a pain to install behind corporate pip proxies because it's under GPL.
In the interim, check out basedpyright [1]. It's an up-to-date fork of pyright with some improvements, less arbitrary limitations, and does not require npm to install.
I was thrilled to learn about basedpyright recently. It does a great job of filling in some of the missing parts of pyright that MS deemed a better fit for pylance – which is a vs code exclusive.
Easy to install with pipx.
As with pyright, I’ve noticed `--createstubs` helps against slowness when working in modules that import large untyped packages.
Which is a very sensible decision given that VSCode is Typescript, and also it means it can run on the web. Also Typescript is a much nicer and faster language than Python.
Looking through the code, Pylyzer seems to be a thin wrapper around Erg [1]. To typecheck, it converts your Python AST to an Erg AST, then runs its through the Erg typechecker and returns the errors.
Faster typechecking for Python is very much needed. But this project seems like it was built in a hackathon -- it is not a true standalone typechecker.
I dug into Pylyzer a few weeks back when scoping out alternatives for faster type checkers, as we have a lot of brittle Python code that we are gradually migrating in at $DAYJOB. I got the idea in my head to basically build mypy but in Rust, similar to what Ruff has done.
My research agrees with your assessment. While I'm sure it's a lot faster (I think the README implies it's one or two magnitudes faster) it just doesn't sit right to me that it's essentially just transpiles to Erg and delegates the actual hard work to the Erg typechecker. This works, but I feel like it fundamentally limits what Pylyzer is capable of, and how much control it really has over the underlying type checking process, as to it, the Erg type checker is essentially a black box.
It's a wrapper (a non-trivial one, to its credit -- especially considering everything is a wrapper if you look at it the right way -- but still a wrapper) rather than an actual full solution.
There's also really only one maintainer (who seems to do a decent job, but I don't seem to recall much more than just bug fixes). Makes me hesitant to really depend on it sticking around long-term or having features that meaningfully progress in the future.
Hopefully it can be used easily as a library. I have multiple use cases for programmatically operating on typed ASTs. MyPy plugins are very limited and most other analyzers have no such extensibility.
> Limitations [...] pylyzer (= Erg's type system) has its own type declarations for the Python standard APIs
I wonder if a better use of time would be to just focus on making mypy faster. We already have too many tools, and it's often better to just focus on making the existing stuff better rather than developing a new tool (relevant XKCD [1]). There's gotta be ways to make mypy faster, even if it takes some breaking changes.
One consideration there would probably be how many committal decisions mypy has made. One of the main reasons a new tool might be better than an old one is that it can be built fresh, with all the lessons learned but (essentially) none of the baggage of bad design decisions.
Another thing I've also weighed is that developing any kind of static analysis tool whose source code is not in the language it analyzes (such as Ruff) immediately blocks you off from a large portion of maintainers. Your maintainers cannot be your end users unless they work with both Python and Rust. While Python is definitely one or more magnitudes slower than Rust, I can't imagine that mypy is at the point where the language choice itself is the only bottleneck.
I haven't actually tried it out, but have done a bit of research in the name of scoping a competing product, and my verdict is that it's probably too immature to be worth production usage. It also makes the design decision to delegate most of the actual hard work (the type checking) to the type checker of Erg, a strongly typed superset of Python, which leaves a lot of decisions and agency out of the purview of Pylyzer itself. There will always be limitations that can only be resolved upstream.
Granted, maybe there's value in this just being a wrapper, and it's best to just deduplicate the work. However, it just sits a little wrong to me that it's not type checking Python, it's doing a transpilation step of sorts and type checking that.
"Ruff, like pylyzer, is a static code analysis tool for Python written in Rust, but Ruff is a linter and pylyzer is a type checker & language server. pylyzer does not perform linting, and Ruff does not perform type checking."
> What is the difference from Ruff? Ruff, like pylyzer, is a static code analysis tool for Python written in Rust, but Ruff is a linter and pylyzer is a type checker & language server. pylyzer does not perform linting, and Ruff does not perform type checking.