|
2 | 2 | Adding Typings
|
3 | 3 | ==============
|
4 | 4 |
|
| 5 | +.. warning:: |
| 6 | + This section is still a work in progress. |
| 7 | + |
5 | 8 | Adding type hints to functions and parameters
|
6 | 9 | ---------------------------------------------
|
7 | 10 |
|
8 |
| -.. warning:: |
9 |
| - This section is still a work in progress. |
| 11 | +Manim is currently in the process of adding type hints into the library. In this |
| 12 | +section, you will find information about the standards used and some general |
| 13 | +guidelines. |
10 | 14 |
|
11 | 15 | If you've never used type hints before, this is a good place to get started:
|
12 | 16 | https://realpython.com/python-type-checking/#hello-types.
|
13 | 17 |
|
14 |
| -When adding type hints to manim, there are some guidelines that should be followed: |
| 18 | +Typing standards |
| 19 | +~~~~~~~~~~~~~~~~ |
15 | 20 |
|
16 |
| -* Coordinates have the typehint ``Sequence[float]``, e.g. |
| 21 | +Manim uses `mypy`_ to type check its codebase. You will find a list of |
| 22 | +configuration values in the ``mypy.ini`` configuration file. |
17 | 23 |
|
18 |
| -.. code:: py |
| 24 | +To be able to use the newest typing features not available in the lowest |
| 25 | +supported Python version, make use of `typing_extensions`_. |
19 | 26 |
|
20 |
| - def set_points_as_corners(self, points: Sequence[float]) -> "VMobject": |
21 |
| - """Given an array of points, set them as corner of the Vmobject.""" |
| 27 | +To be able to use the new Union syntax (``|``) and builtins subscripting, use |
| 28 | +the ``from __future__ import annotations`` import. |
22 | 29 |
|
23 |
| -* ``**kwargs`` has no typehint |
| 30 | +.. _mypy: https://mypy-lang.org/ |
| 31 | +.. _typing_extensions: https://pypi.org/project/typing-extensions/ |
24 | 32 |
|
25 |
| -* Mobjects have the typehint "Mobject", e.g. |
| 33 | +Typing guidelines |
| 34 | +~~~~~~~~~~~~~~~~~ |
26 | 35 |
|
27 |
| -.. code:: py |
| 36 | +* Manim has a dedicated :mod:`~.typing` module where type aliases are provided. |
| 37 | + Most of them may seem redundant, in particular the ones related to ``numpy``. |
| 38 | + This is in anticipation of the support for shape type hinting |
| 39 | + (`related issue <https://github.com/numpy/numpy/issues/16544>`_). Besides the |
| 40 | + pending shape support, using the correct type aliases will help users understand |
| 41 | + which shape should be used. |
28 | 42 |
|
29 |
| - def match_color(self, mobject: "Mobject"): |
30 |
| - """Match the color with the color of another :class:`~.Mobject`.""" |
31 |
| - return self.set_color(mobject.get_color()) |
32 |
| -
|
33 |
| -* Colors have the typehint ``Color``, e.g. |
34 |
| - |
35 |
| -.. code:: py |
36 |
| -
|
37 |
| - def set_color(self, color: Color = YELLOW_C, family: bool = True): |
38 |
| - """Condition is function which takes in one arguments, (x, y, z).""" |
39 |
| -
|
40 |
| -* As ``float`` and ``Union[int, float]`` are the same, use only ``float`` |
41 |
| - |
42 |
| -* For numpy arrays use the typehint ``np.ndarray`` |
43 |
| - |
44 |
| -* Functions that does not return a value should get the type hint ``None``. (This annotations help catch the kinds of subtle bugs where you are trying to use a meaningless return value. ) |
| 43 | +* Always use a type hint of ``None`` for functions that does not return |
| 44 | + a value (this also applies to ``__init__``), e.g.: |
45 | 45 |
|
46 | 46 | .. code:: py
|
47 | 47 |
|
48 | 48 | def height(self, value) -> None:
|
49 | 49 | self.scale_to_fit_height(value)
|
50 | 50 |
|
51 |
| -* Parameters that are None by default should get the type hint ``Optional`` |
52 |
| - |
53 |
| -.. code:: py |
| 51 | +* For variables representing paths, use the ``StrPath`` or ``StrOrBytesPath`` |
| 52 | + type alias defined in the :mod:`~.typing` module. |
54 | 53 |
|
55 |
| - def rotate( |
56 |
| - self, |
57 |
| - angle, |
58 |
| - axis=OUT, |
59 |
| - about_point: Optional[Sequence[float]] = None, |
60 |
| - **kwargs, |
61 |
| - ): |
62 |
| - pass |
| 54 | +* ``*args`` and ``**kwargs`` shouldn't be left untyped (in most cases you can |
| 55 | + use ``Any``). |
63 | 56 |
|
| 57 | +* Following `PEP 484 <https://peps.python.org/pep-0484/#the-numeric-tower>`_, |
| 58 | + use ``float`` instead of ``int | float``. |
64 | 59 |
|
65 |
| -* The ``__init__()`` method always should have None as its return type. |
66 |
| - |
67 |
| -* Functions and lambda functions should get the typehint ``Callable`` |
| 60 | +* Mobjects have the typehint ``Mobject``, e.g.: |
68 | 61 |
|
69 | 62 | .. code:: py
|
70 | 63 |
|
71 |
| - rate_func: Callable[[float], float] = lambda t: smooth(1 - t) |
72 |
| -
|
73 |
| -
|
74 |
| -* Assuming that typical path objects are either Paths or strs, one can use the typehint ``typing.Union[str, pathlib.Path]`` |
| 64 | + def match_color(self, mobject: "Mobject"): |
| 65 | + """Match the color with the color of another :class:`~.Mobject`.""" |
| 66 | + return self.set_color(mobject.get_color()) |
75 | 67 |
|
76 |
| -.. note:: |
77 |
| - As a helper for tool for typesets, you can use `typestring-parser |
78 |
| - <https://github.com/Dominik1123/typestring-parser>`_ |
79 |
| - which can be accessed by first installing it via ``pip`` - ``pip install typestring-parser`` and |
80 |
| - then using ``from typestring_parser import parse``. |
| 68 | +* Always parametrize generics (``list[int]`` instead of ``list``, |
| 69 | + ``type[Any]`` instead of ``type``, etc.). This also applies to callables: |
81 | 70 |
|
82 |
| -.. doctest:: |
83 |
| - :options: +SKIP |
| 71 | +.. code:: py |
84 | 72 |
|
85 |
| - >>> from typestring_parser import parse |
86 |
| - >>> parse("int") |
87 |
| - <class 'int'> |
88 |
| - >>> parse("int or str") |
89 |
| - typing.Union[int, str] |
90 |
| - >>> parse("list of str or str") |
91 |
| - typing.Union[typing.List[str], str] |
92 |
| - >>> parse("list of (int, str)") |
93 |
| - typing.List[typing.Tuple[int, str]] |
| 73 | + rate_func: Callable[[float], float] = lambda t: smooth(1 - t) |
94 | 74 |
|
95 | 75 | Missing Sections for typehints are:
|
96 | 76 | -----------------------------------
|
97 |
| -* Tools for typehinting |
98 |
| -* Link to MyPy |
| 77 | + |
99 | 78 | * Mypy and numpy import errors: https://realpython.com/python-type-checking/#running-mypy
|
100 |
| -* Where to find the alias |
101 |
| -* When to use Object and when to use "Object". |
102 |
| -* The use of a TypeVar on the type hints for copy(). |
103 |
| -* The definition and use of Protocols (like Sized, or Sequence, or Iterable...) |
| 79 | +* When to use ``object`` vs ``Any`` |
| 80 | +* The use of a TypeVar on the type hints for ``copy()``. |
| 81 | +* The definition and use of Protocols (like ``Sized``, ``Sequence``, ``Iterable``...) |
0 commit comments