DetachHead / basedpyright

pyright fork with various type checking improvements, improved vscode support and pylance features built into the language server
https://docs.basedpyright.com
Other
723 stars 14 forks source link

infer types of dunders #288

Open KotlinIsland opened 3 months ago

KotlinIsland commented 3 months ago
class A:
    def __getattr__(self, attr):
         reveal_type(attr)  # str
DetachHead commented 3 months ago

are there ABCs for these dunders? if so, this would be covered by #289

KotlinIsland commented 3 months ago

Some don't have ABCs, such as __format__. Additionally, I think it would be convenient if these were inferred without the base classes, as it's not very common to explicitly extend some of these such as ContextManager.

DetachHead commented 3 months ago

Some don't have ABCs, such as __format__.

@jorenham made optype which i think could cover this use case (eg. the CanFormat type), but it looks like it's more aimed towards .pyi files and they aren't intended to be used as base classes. but perhaps we could make something similar in basedtyping?

it's not very common to explicitly extend some of these such as ContextManager.

i think if you're using types in your code there's no reason not to explicitly extend the ABCs. that's what they're there for right?

some other concerns:

jorenham commented 3 months ago

In practice, it's no problem whatsover to inherit from optype protocols, e.g.

class A[V](optype.CanGetattr[str, V]): ...

I believe that most "things" in collections.abc are (somehow) both an ABC and a protocol, and they work fine a subtype (unless we're talking about .pyi stubs, then they're pretty much useless).

But from a theoretical perspective protocol inheritance can be considered haram, in which case you could do something like:

class A[V]:
    def __getattr__(self: optype.CanGetattr[str, V], name: str) -> V:
        reveal_type(attr)

warning: arbitrary typeshed rant incoming

Stub files could perhaps also be used to figure out the operator types. But unfortunately, the typeshed builtin stubs are in many cases unnecessarily broad, restrictive, or just plain wrong. Additionally, there are way too many Any's; it's uncanny (awkwardly drops mic on toe).

To illustrate, I recently made an attempt to fix the reversed builtin in https://github.com/python/typeshed/pull/11646. But it has been deferred due to a long-standing mypy bug in __new__, which for some totally ~un~related reason, having a correctly typed reversed would lead to mypy errors in a bunch of popular libraries 🤷🏻 .

So I'm starting to thing that perhaps an "optypeshed" (i.e. a builtin stubs package with optypean type signatures) might be worth building. At least with optype, this should be an easy task. Although I'm not sure on whether annotating each self is the way to go about it, or if inheritance (without ABC's) is the way to go 🤔.


tldr; Would it be possible to recycle the annotations of (builtin) typing stubs for this? With optype, I imagine it'd be a piece of cake to create such a stub package (although I can't comment on the size of said cake).

KotlinIsland commented 3 months ago

Erm, you sound like you know a lot about typing things correctly, I can't stand typeshed/mypy being absurdly wrong 99% of the time and not fixing bugs because it would cause a library to have to fix their types, I'm happy to see work to make things correct in basedmypy/basedpyright