@@ -48,11 +48,13 @@ can be assigned to (similar to using ``__slots__``)::
4848Inheritance
4949-----------
5050
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).
5456
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
5658classes:
5759
5860* ``object ``
@@ -63,8 +65,6 @@ classes:
6365* ``IndexError ``
6466* ``LookupError ``
6567* ``UserWarning ``
66- * ``typing.NamedTuple ``
67- * ``enum.Enum ``
6868
6969By default, a non-native class can't inherit a native class, and you
7070can'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``:
8989
9090 pip install --upgrade mypy-extensions
9191
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+
92101Class variables
93102---------------
94103
@@ -145,7 +154,8 @@ behavior is too dynamic. You can use these metaclasses, however:
145154.. note ::
146155
147156 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).
149159
150160Class decorators
151161----------------
@@ -165,7 +175,63 @@ efficient as pure native classes.
165175.. note ::
166176
167177 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.
169235
170236Deleting attributes
171237-------------------
0 commit comments