Skip to content

Commit aebeeb8

Browse files
committed
tests/cpydiff/core_class: Document limitations of __init_subclass__.
Signed-off-by: Anson Mansfield <amansfield@mantaro.com>
1 parent e9e81b2 commit aebeeb8

File tree

3 files changed

+138
-0
lines changed

3 files changed

+138
-0
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
"""
2+
categories: Core,Classes
3+
description: Keyword arguments are not passed to __init_subclass__.
4+
cause: Micropython doesn't allow kwargs in a base class list.
5+
workaround: Unknown
6+
"""
7+
8+
9+
class Philosopher:
10+
def __init_subclass__(cls, default_name, **kwargs):
11+
super().__init_subclass__(**kwargs)
12+
cls.default_name = default_name
13+
14+
15+
class AustralianPhilosopher(Philosopher, default_name="Bruce"):
16+
pass
17+
18+
19+
print(AustralianPhilosopher.default_name)
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
"""
2+
categories: Core,Classes
3+
description: Micropython calls __init_subclass__ directly for all direct base classes.
4+
cause: Micropython can't rely on __init_subclass__ implementations calling super().__init_subclass__() to recurse through ancestor classes like CPython.
5+
workaround: Omit calling super().__init_subclass__() in __init_subclass__ implementations.
6+
"""
7+
8+
9+
# In CPython, only the first base__init_subclass__
10+
class A1:
11+
a = "A1"
12+
13+
def __init_subclass__(cls):
14+
print("A1 init_subclass", cls.__name__)
15+
cls.aa = "AA"
16+
17+
print("class A1")
18+
19+
20+
class B1:
21+
b = "B1"
22+
23+
def __init_subclass__(cls):
24+
print("B1 init_subclass", cls.__name__)
25+
cls.bb = "BB"
26+
27+
print("class B1")
28+
29+
30+
class C1(A1, B1):
31+
c = "C1"
32+
print("class C1")
33+
34+
35+
# In CPython it's specified to call super().__init_subclass__() in __init_subclass__.
36+
# But the presence of super() makes the invocation of __init_subclass__ fail.
37+
class A2:
38+
a = "A2"
39+
40+
@classmethod
41+
def __init_subclass__(cls):
42+
super().__init_subclass__()
43+
print("A2 init_subclass", cls.__name__)
44+
cls.aa = "AA"
45+
46+
print("class A2")
47+
48+
49+
class B2:
50+
b = "B2"
51+
52+
@classmethod
53+
def __init_subclass__(cls):
54+
super().__init_subclass__()
55+
print("B2 init_subclass", cls.__name__)
56+
cls.bb = "BB"
57+
58+
print("class B2")
59+
60+
61+
class C2(A2, B2):
62+
c = "C2"
63+
print("class C2")
64+
65+
66+
def print_check_all_attrs(obj, name: str, attrs: "list[str]"):
67+
for attr in attrs:
68+
print(name, attr, getattr(obj, attr, "missing"))
69+
70+
71+
print_check_all_attrs(A1, "A1", ["a", "aa", "b", "bb", "c"])
72+
print_check_all_attrs(B1, "B1", ["a", "aa", "b", "bb", "c"])
73+
print_check_all_attrs(C1, "C1", ["a", "aa", "b", "bb", "c"])
74+
75+
print_check_all_attrs(A2, "A2", ["a", "aa", "b", "bb", "c"])
76+
print_check_all_attrs(B2, "B2", ["a", "aa", "b", "bb", "c"])
77+
print_check_all_attrs(C2, "C2", ["a", "aa", "b", "bb", "c"])
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
"""
2+
categories: Core,Classes
3+
description: Micropython can't recurse through base classes for __init_subclass__.
4+
cause: Micropython doesn't support super() inside classmethods.
5+
workaround: Unknown
6+
"""
7+
8+
9+
class A:
10+
a = "A"
11+
12+
def __init_subclass__(cls):
13+
print("A init_subclass", cls.__name__)
14+
cls.aa = "AA"
15+
16+
print("class A")
17+
18+
19+
class B(A):
20+
b = "B"
21+
22+
def __init_subclass__(cls):
23+
super().__init_subclass__()
24+
print("B init_subclass", cls.__name__)
25+
cls.bb = "BB"
26+
27+
print("class B")
28+
29+
30+
class C(B):
31+
c = "C"
32+
print("class C")
33+
34+
35+
def print_check_all_attrs(obj, name: str, attrs: "list[str]"):
36+
for attr in attrs:
37+
print(name, attr, getattr(obj, attr, "missing"))
38+
39+
40+
print_check_all_attrs(A, "A", ["a", "aa", "b", "bb", "c"])
41+
print_check_all_attrs(B, "B", ["a", "aa", "b", "bb", "c"])
42+
print_check_all_attrs(C, "C", ["a", "aa", "b", "bb", "c"])

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy