@@ -48,11 +48,13 @@ can be assigned to (similar to using ``__slots__``)::
48
48
Inheritance
49
49
-----------
50
50
51
- Only single inheritance is supported (except for :ref: `traits
52
- <trait-types>`). Most non-native classes can't be used as base
53
- classes.
51
+ Only single inheritance is supported from native classes (except for
52
+ :ref: `traits <trait-types >`). Most non-native extension classes can't
53
+ be used as base classes, but regular Python classes can be used as
54
+ base classes unless they use unsupported metaclasses (see below for
55
+ more about this).
54
56
55
- These non-native classes can be used as base classes of native
57
+ These non-native extension classes can be used as base classes of native
56
58
classes:
57
59
58
60
* ``object ``
@@ -63,8 +65,6 @@ classes:
63
65
* ``IndexError ``
64
66
* ``LookupError ``
65
67
* ``UserWarning ``
66
- * ``typing.NamedTuple ``
67
- * ``enum.Enum ``
68
68
69
69
By default, a non-native class can't inherit a native class, and you
70
70
can't inherit from a native class outside the compilation unit that
@@ -89,6 +89,15 @@ You need to install ``mypy-extensions`` to use ``@mypyc_attr``:
89
89
90
90
pip install --upgrade mypy-extensions
91
91
92
+ Additionally, mypyc recognizes these base classes as special, and
93
+ understands how they alter the behavior of classes (including native
94
+ classes) that subclass them:
95
+
96
+ * ``typing.NamedTuple ``
97
+ * ``typing.Generic ``
98
+ * ``typing.Protocol ``
99
+ * ``enum.Enum ``
100
+
92
101
Class variables
93
102
---------------
94
103
@@ -145,7 +154,8 @@ behavior is too dynamic. You can use these metaclasses, however:
145
154
.. note ::
146
155
147
156
If a class definition uses an unsupported metaclass, *mypyc
148
- compiles the class into a regular Python class *.
157
+ compiles the class into a regular Python class * (non-native
158
+ class).
149
159
150
160
Class decorators
151
161
----------------
@@ -165,7 +175,63 @@ efficient as pure native classes.
165
175
.. note ::
166
176
167
177
If a class definition uses an unsupported class decorator, *mypyc
168
- compiles the class into a regular Python class *.
178
+ compiles the class into a regular Python class * (non-native class).
179
+
180
+ Defining non-native classes
181
+ ---------------------------
182
+
183
+ You can use the ``@mypy_extensions.mypyc_attr(...) `` class decorator
184
+ with an argument ``native_class=False `` to explicitly define normal
185
+ Python classes (non-native classes)::
186
+
187
+ from mypy_extensions import mypyc_attr
188
+
189
+ @mypyc_attr(native_class=False)
190
+ class NonNative:
191
+ def __init__(self) -> None:
192
+ self.attr = 1
193
+
194
+ setattr(NonNative, "extra", 1) # Ok
195
+
196
+ This only has an effect in classes compiled using mypyc. Non-native
197
+ classes are significantly less efficient than native classes, but they
198
+ are sometimes necessary to work around the limitations of native classes.
199
+
200
+ Non-native classes can use arbitrary metaclasses and class decorators,
201
+ and they support flexible multiple inheritance. Mypyc will still
202
+ generate a compile-time error if you try to assign to a method, or an
203
+ attribute that is not defined in a class body, since these are static
204
+ type errors detected by mypy::
205
+
206
+ o = NonNative()
207
+ o.extra = "x" # Static type error: "extra" not defined
208
+
209
+ However, these operations still work at runtime, including in modules
210
+ that are not compiled using mypyc. You can also use ``setattr `` and
211
+ ``getattr `` for dynamic access of arbitrary attributes. Expressions
212
+ with an ``Any `` type are also not type checked statically, allowing
213
+ access to arbitrary attributes::
214
+
215
+ a: Any = o
216
+ a.extra = "x" # Ok
217
+
218
+ setattr(o, "extra", "y") # Also ok
219
+
220
+ Implicit non-native classes
221
+ ---------------------------
222
+
223
+ If a compiled class uses an unsupported metaclass or an unsupported
224
+ class decorator, it will implicitly be a non-native class, as
225
+ discussed above. You can still use ``@mypyc_attr(native_class=False) ``
226
+ to explicitly mark it as a non-native class.
227
+
228
+ Explicit native classes
229
+ -----------------------
230
+
231
+ You can use ``@mypyc_attr(native_class=True) `` to explicitly declare a
232
+ class as a native class. It will be a compile-time error if mypyc
233
+ can't compile the class as a native class. You can use this to avoid
234
+ accidentally defining implicit non-native classes.
169
235
170
236
Deleting attributes
171
237
-------------------
0 commit comments