-
-
Notifications
You must be signed in to change notification settings - Fork 3k
Closed
Description
The Python metaclass data model allows the mro()
method to be overloaded. This is a genuinely useful feature for dealing with metaclasses whose classes must support inheritance. See "Example" below.
I wrote a mypy
plugin for type-checking instances of my metaclass. I was able to model its semantics almost correctly with the existing plugin hooks, except for one thing — customizing the MRO.
The best way I can get my type-checker unblocked is by adding a plugin hook for customizing the MRO. My idea is roughly this:
- Move
calculate_class_mro
to be a member ofSemanticAnalyzerPass2
- Add a plugin hook that gets to customize the computed MRO.
@JukkaL, does this sound like a feature you would take?
Example of needing to customize the MRO:
- My metaclass
M
injects a implementation-detail baseM_classname_base
into each class it creates.M
's semantics demand thatM_classname_base
be at the very end of the MRO (to allow overloading of its features). - Let us define
class A(metaclass=M)
andclass B(A)
. - Each class injects its own base:
M_A_base
andM_B_base
. That means thatB
actually has both implementation-detail bases. - Unfortunately,
M_A_base
andM_B_base
conflict, andM_B_base
ends up afterM_A_base
in the MRO, which is the opposite of what you want (child must overload parent, not vice versa). - At runtime,
M.mro()
can simply remove theA
-produced base fromB
's MRO, and all is well. - In current
mypy
, removingM_A_base
fromB
's MRO seems impossible.
Cc: @carljm, if you're curious.
Metadata
Metadata
Assignees
Labels
No labels