-
Notifications
You must be signed in to change notification settings - Fork 769
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
Expected class type but received "TokenMeta" #1562
Comments
Mind you, i have no idea if what I'm doing is the correct way to annotate metaclass methods that return instances of the metaclass. I don't know of any other way, and can't find documentation anywhere on how to achieve this. If you know of a better way for me to annotate this, I'd love to hear it! Thanks |
By default, type checking is disabled in pylance. It appears that you have enabled it — probably by setting "python.analysis.typeCheckingMode" to "basic". You are dynamically generating a new class here. A static type checker like pyright (upon which pylance is built) must understand the class hierarchy. I recommend against using this form of dynamic class creation if you are interested in static type checking. If you have no way to avoid dynamic class creation, you can use a I'll also note that the code in your sample claims to be generating a class using a "metaclass", but that's not what it's actually doing. Instead, it's creating a new class with TokenMeta as a base class. That's very different from a metaclass. In this example, |
Hmmm... that's a very comprehensive answer, thank you. I'm not sure i understand what you're saying regarding class instantiation. In my example, if i write what I'm trying to do with the signature What I'd really like to do is tell the type checker " |
Ah, I misinterpreted the code. Forget what I said above in the last paragraph about the metaclass. Here's how I would annotate this: def __getattr__(cls, name: str) -> "Type[Token]":
if name[0].isupper():
parent_class_name = cls.__name__
new_subclass_name = f"{parent_class_name}.{name}"
new_subclass = cast(Type[Token], type(new_subclass_name, (cls,), {})) # type: ignore I think I now understand what this code is trying to do. It falls into the category of "someone was trying to be too clever". I recommend looking for better ways to implement this functionality if that's an option. This approach is difficult to understand and not conducive to static type checking. |
Actually, it's probably not wise for the metaclass to reference a def __getattr__(cls, name: str) -> type:
if name[0].isupper():
parent_class_name = cls.__name__
new_subclass_name = f"{parent_class_name}.{name}"
new_subclass = type(new_subclass_name, (cls,), {}) # type: ignore |
yeah, my initial implementation specifically referenced I think you're right, that this whole endeavour of trying to tell the type checker what I'm doing is a wash. All i really want to do is to tell the type checker that I also tried things like |
Hi, sorry, i just realized this issue maybe shouldn't be closed. I have a workaround for my specific problem, but the root issue remains: I believe the error "Expected class type but received "TokenMeta"" is a bug, since Thoughts? |
A type analyzer doesn't know that a particular class is going to be used as a metaclass when it is analyzing it. Furthermore, the analyzer has no way of knowing the specific type of |
ok, fair enough. Thank you |
Hello all,
I'm trying to annotate a metaclass method which returns a new subclass of a "metaclass instance" (base class? would that be the right word for a class which uses this metaclass?)
And I'm running into the above error. Please see the code snippet for details
Environment data
Code Snippet / Additional information
Expected behaviour
I expect pylance to recognize
Token.Category
as a subclass ofToken
Actual behaviour
Pylance reports the listed error, and sees Token.Category as a
TokenMeta
instance, does not provide type completion for Token.CategoryOn the surface, this issue seems identical to #360, but that issue was reportedly fixed in 2020.9.5
Logs
Click to expand
The text was updated successfully, but these errors were encountered: