-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Inferred type for type.__subclasses__() could be more specific #2236
Comments
You're right, though I have yet to think of a use case where this matters. (Did you discover this just by playing around, or do you have an actual application that needs this?) In any case, we may be able to fix this in typeshed once "self-type" is implemented - see PR #2193 implementing the design of issue #1212. |
I encountered this while writing a script that parses human-readable log messages from another application. There is a
And the subclasses provide their own implementation of
A little niche I know, and there are ways to solve it (e.g. by maintaining a list of "record parsers") but it seems like a "self-type" would solve this problem:
|
Yeah, this is hardly what But once we have the self-type we'll revisit this. |
Yes, it only requires self-type and a very small tweak to builtins.pyi. |
It works now by moving @classmethod
def __subclasses__(cls: Type[_T]) -> List[Type[_T]]: ... Is it reasonable? |
Sounds like a good PR to send!
|
But it won't work with |
Can you please slow down and explain more clearly what you're referring to
in the existing issue (I thought there was one already)? And without using
words like "annoying".
|
Sorry. I am not sure I understand your second sentence. But:
Adding generic self to
|
(Sorry, I missed the fact that this is the issue about I would say it should definitely not become a classmethod on object. I hope that the output you are seeing can be improved and that the actual inferred type is actually still a class. (Sometimes classes are represented internally as callables with a certain fallback type, but IIRC the string conversion doesn't honor that. And other times classes are represented differently internally, so it's not universally broken, only in some cases -- like this one, apparently.) Can you try to construct an example to prove/disprove that? Maybe try to see if an item of the resulting list still has a method characteristic of the original class. |
Seems like you are right - the result is treated as the type itself. So mypy treats |
We should make the string conversion of such callables smarter. Maybe rendering as Type[C] is good enough? |
There are two main formats for stringifying types, the "user" format and the "internal" format (names I just made up). The internal format is mostly used for debugging mypy, so it's better if it shows the real type, which is a Callable (with a special fallback type and with
|
As for the issue itself, can it not be fixed using self types with |
@rwbarton I think I've made much ado about nothing: it simply works, and the internal format confused me. But given my confusion, I would like it to be verified by someone else :) class type:
...
def __subclasses__(self: Type[_T]) -> List[Type[_T]]: ... |
I will fix this, after verifying. |
Well, I can't even repro this problem any more:
When I try that I get:
|
(That is, with my change to typeshed from c3ddd3c.) |
Example:
Expected behavior
The inferred types for
subs_1
andsubs_2
are as annotatedActual behavior
The inferred type is
List[type]
for bothsubs_1
andsubs_2
.The text was updated successfully, but these errors were encountered: