Skip to content
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

[red-knot] Support metaclasses #14096

Open
AlexWaygood opened this issue Nov 4, 2024 · 1 comment · May be fixed by #14120
Open

[red-knot] Support metaclasses #14096

AlexWaygood opened this issue Nov 4, 2024 · 1 comment · May be fixed by #14120
Assignees
Labels
red-knot Multi-file analysis & type inference

Comments

@AlexWaygood
Copy link
Member

Currently we infer that all class objects are instances of builtins.type:

// TODO not accurate if there's a custom metaclass...
Type::ClassLiteral(_) => KnownClass::Type.to_class(db),

Contrary to the TODO comment there (not sure who wrote that), this is accurate -- all classes are indeed instances of builtins.type. However, it could be a lot more precise, since some classes have a custom metaclass!

>>> class Meta(type): pass
... 
>>> class Foo(metaclass=Meta): pass
... 
>>> type(Foo)
<class '__main__.Meta'>
>>> isinstance(Foo, Meta)
True

For the Foo class here, Type::to_meta_type should return a type representing the class object Meta rather than a type representing the class object builtins.type.


Miscellaneous details on semantics

If a class is a subclass of a class with a custom metaclass, then the subclass will also have that metaclass:

>>> class Bar(Foo): pass
... 
>>> type(Bar)
<class '__main__.Meta'>

And if the metaclasses of the bases conflict, then this can happen (we'll need to detect this and emit a diagnostic):

>>> class A(type): ...
... 
>>> class B(type): ...
... 
>>> class C(metaclass=A): ...
... 
>>> class D(metaclass=B): ...
... 
>>> class E(C, D): ...
... 
Traceback (most recent call last):
  File "<python-input-4>", line 1, in <module>
    class E(C, D): ...
TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases

We'll probably need to add a method to ClassType to retrieve the type of the metaclass. It will probably be best to wait until #14087 has landed before working on this.

@AlexWaygood AlexWaygood added the red-knot Multi-file analysis & type inference label Nov 4, 2024
@AlexWaygood
Copy link
Member Author

AlexWaygood commented Nov 5, 2024

Could be a good @charliermarsh -sized task!

@charliermarsh charliermarsh self-assigned this Nov 5, 2024
@charliermarsh charliermarsh linked a pull request Nov 6, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
red-knot Multi-file analysis & type inference
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants