← index #6094PR #15511
Related · high · value 1.180
QUERY · ISSUE

metaclass

openby allyourcodeopened 2020-05-30updated 2025-11-04
py-core

I see that MP does not (yet) support metaclasses (per item #6 on https://github.com/micropython/micropython/wiki/Differences#differences-by-design). It sounds like the MP developers would like to add this feature some day, but it's not clear to me how strongly they feel about that.

Obviously, people do not directly make use of this feature very often. Nevertheless, it is very powerful, and people DO benefit from libraries that do use it directly. I am working on a library that works in CPython, but because it hinges on a metaclass, I was disappointed to find that it doesn't work on MP.

My hopes in posting this are to

a) Solicit the thoughts of the MP developers on where this feature lies in their priority queue.
b) Let others provide "me too!" feedback.
c) Vent my frustration.

PS: Thank you for MP! Being able to use (u)asyncio is truly a godsend.

CANDIDATE · PULL REQUEST

py/objtype: Add basic __init_subclass__ metaclass support.

closedby AJMansfieldopened 2024-07-20updated 2025-02-21
py-core

Summary

This PR adds partial support for the __init_subclass__ data model method defined in PEP487, and gates this added features behind a new feature flag, MICROPY_PY_METACLASSES.
While this PR does not implement "full" metaclasses, it does implement the main mechanism used in practice for most types of meta-class-like class customization.

The behavior implemented here varies from the CPython behavior for two reasons:

  • Due to #15509, user-written __init_subclass__ implementations are not able to recursively call super().__init_subclass__() the way PEP487 specifies. Therefore, this implementation applies a workaround: instead of invoking __init_subclass__ only for the last base class, it invokes it on all direct base classes.
  • Micropython does not support passing kwargs as bases of a class, therefore __init_subclass__ currently has no kwargs functionality.

This PR uses #15503 as its base to ensure the __init_subclass__ code remains in the correct order with __set_name__ in order to match CPython. It also adds MICROPY_PY_METACLASSES as an alternative condition for enabling #15503's functionality, for the rare cases of metaclass code that relies on __set_name__ class customization but doesn't need the per-lookup overhead of descriptors.

Testing

This PR includes a test verifying this feature, and three cpydiff's precisely outlining the mismatch with CPython. I've also manually verified the functionality using the unix port.

Trade-offs and Alternatives

This increases code size, but only when the corresponding feature flag is enabled.

Keyboard

j / / n
next pair
k / / p
previous pair
1 / / h
show query pane
2 / / l
show candidate pane
c
copy suggested comment
r
toggle reasoning
g i
go to index
?
show this help
esc
close overlays

press ? or esc to close

copied