.. _native-classes:

Native classes
==============

Classes in compiled modules are *native classes* by default (some
exceptions are discussed below). Native classes are compiled to C
extension classes, which have some important differences from normal
Python classes. Native classes are similar in many ways to built-in
types, such as ``int``, ``str``, and ``list``.

Immutable namespaces
--------------------

The type object namespace of native classes is mostly immutable (but
class variables can be assigned to)::

    class Cls:
        def method1(self) -> None:
            print("method1")

        def method2(self) -> None:
            print("method2")

    Cls.method1 = Cls.method2  # Error
    Cls.new_method = Cls.method2  # Error

Only attributes defined within a class definition (or in a base class)
can be assigned to (similar to using ``__slots__``)::

    class Cls:
        x: int

        def __init__(self, y: int) -> None:
            self.x = 0
            self.y = y

        def method(self) -> None:
            self.z = "x"

    o = Cls(0)
    print(o.x, o.y)  # OK
    o.z = "y"  # OK
    o.extra = 3  # Error: no attribute "extra"

.. _inheritance:

Inheritance
-----------

Only single inheritance is supported (except for :ref:`traits
<trait-types>`). Most non-native classes can't be used as base
classes.

These non-native classes can be used as base classes of native
classes:

* ``object``
* ``dict`` (and ``Dict[k, v]``)
* ``BaseException``
* ``Exception``
* ``ValueError``
* ``IndexError``
* ``LookupError``
* ``UserWarning``
* ``typing.NamedTuple``
* ``enum.Enum``

By default, a non-native class can't inherit a native class, and you
can't inherit from a native class outside the compilation unit that
defines the class. You can enable these through
``mypy_extensions.mypyc_attr``::

    from mypy_extensions import mypyc_attr

    @mypyc_attr(allow_interpreted_subclasses=True)
    class Cls:
        ...

Allowing interpreted subclasses has only minor impact on performance
of instances of the native class.  Accessing methods and attributes of
a *non-native* subclass (or a subclass defined in another compilation
unit) will be slower, since it needs to use the normal Python
attribute access mechanism.

You need to install ``mypy-extensions`` to use ``@mypyc_attr``:

.. code-block:: text

    pip install --upgrade mypy-extensions

Class variables
---------------

Class variables must be explicitly declared using ``attr: ClassVar``
or ``attr: ClassVar[<type>]``. You can't assign to a class variable
through an instance. Example::

    from typing import ClassVar

    class Cls:
        cv: ClassVar = 0

    Cls.cv = 2  # OK
    o = Cls()
    print(o.cv)  # OK (2)
    o.cv = 3  # Error!

.. tip::

    Constant class variables can be declared using ``typing.Final`` or
    ``typing.Final[<type>]``.

Generic native classes
----------------------

Native classes can be generic. Type variables are *erased* at runtime,
and instances don't keep track of type variable values.

Compiled code thus can't check the values of type variables when
performing runtime type checks. These checks are delayed to when
reading a value with a type variable type::

    from typing import TypeVar, Generic, cast

    T = TypeVar('T')

    class Box(Generic[T]):
        def __init__(self, item: T) -> None:
            self.item = item

    x = Box(1)  # Box[int]
    y = cast(Box[str], x)  # OK (type variable value not checked)
    y.item  # Runtime error: item is "int", but "str" expected

Metaclasses
-----------

Most metaclasses aren't supported with native classes, since their
behavior is too dynamic. You can use these metaclasses, however:

* ``abc.ABCMeta``
* ``typing.GenericMeta`` (used by ``typing.Generic``)

.. note::

   If a class definition uses an unsupported metaclass, *mypyc
   compiles the class into a regular Python class*.

Class decorators
----------------

Similar to metaclasses, most class decorators aren't supported with
native classes, as they are usually too dynamic. These class
decorators can be used with native classes, however:

* ``mypy_extensions.trait`` (for defining :ref:`trait types <trait-types>`)
* ``mypy_extensions.mypyc_attr`` (see :ref:`above <inheritance>`)
* ``dataclasses.dataclass``
* ``@attr.s(auto_attribs=True)``

Dataclasses and attrs classes have partial native support, and they aren't as
efficient as pure native classes.

.. note::

   If a class definition uses an unsupported class decorator, *mypyc
   compiles the class into a regular Python class*.

Deleting attributes
-------------------

By default, attributes defined in native classes can't be deleted. You
can explicitly allow certain attributes to be deleted by using
``__deletable__``::

   class Cls:
       x: int = 0
       y: int = 0
       other: int = 0

       __deletable__ = ['x', 'y']  # 'x' and 'y' can be deleted

   o = Cls()
   del o.x  # OK
   del o.y  # OK
   del o.other  # Error

You must initialize the ``__deletable__`` attribute in the class body,
using a list or a tuple expression with only string literal items that
refer to attributes. These are not valid::

   a = ['x', 'y']

   class Cls:
       x: int
       y: int

       __deletable__ = a  # Error: cannot use variable 'a'

   __deletable__ = ('a',)  # Error: not in a class body

Other properties
----------------

Instances of native classes don't usually have a ``__dict__`` attribute.
