Skip to content

Commit

Permalink
Fix Typing (ManimCommunity#3086)
Browse files Browse the repository at this point in the history
* first draft of color class + starting library conversion

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* changed everything to Manim color todo: figure out circular dependency in utils

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* first working draft of new color version

* resolving conflicts

* resolving conflicts

* resolving conflicts

* resolving conflicts

* resolving conflicts

* changed default internal value of ManimColor to np.ndarray[float]

* starting to fix tests

* fixed more tests and changed precision of manim color

* removed premature color conversion

* fixed some more tests

* final test changes

* fix doctests

* fix for 3.8

* fixing ManimColor string representation

* removing some unneccesary conversions

* moved community constants to manim_colors.py and added more color standards

* Added typing.py and typed bezier.py, core.py, constants.py  fully

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* fixed codeql complaints

* add type ignore for np.allclose

* fixed import in three_dimensions

* added ignore for F401 back again in flake

* added typings to coordinate_systems.py

* Few improvements to `graphing/coordinate_systems.py`

* added some typings to mobject/geometry/line.py

* updated typings for mobject/geometry/line.py

* Add missing imports to `line.py`

* added typings to three_dimensions.py

* Use `FunctionOverride` for animation overrides

Fix type signature of `set_color_by_gradient`

* Remove `TYPE_CHECKING` check

Doc is failing

* Revert "Remove `TYPE_CHECKING` check"

Fails due to circular import

* Use `Self` in `coordinate_systems.py`

* Typehinted mobject.py and updated manim.typing.py

* Typed VMobject

* Type-hinted manim.mobject.geometry

* math.cos->np.cos, etc & fixed incorrect typehints

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* fix missing annotations import

* TypeAlias fix in typing.py

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Add ignore errors again to mypy because commits are not possible like this

* Fix last typing issues

* Update docs

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Only type check manim

* Try fixing pre-commit

* fix merge

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Fix compat

* Fix compat again

* Fix imports compat

* Use union syntax

* Use union syntax

* Fix reduce_across_dimension

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Various test and merge fixes

* Doc fixes

* Last doc fix

* Revert usage of np over math

* Bump numpy version

* Remove obsolete duplicate example

* Fixed Incorrect Typehint in manim.constants

* Fix docstring typo

* More fixes

Use mypy.ini instead of .mypy.ini
Fix more docstrings
Improve types in utils and constants

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* docs fixes

* Add internal aliases

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* fix compat

* line lengths in .rst file, formatting, typos

* add docstring for space_ops:cross2d

* add some more arrow tip typings (in a non-circular import causing way)

* yes, this can be deleted

* fix formatting of example

* added docstring to bezier::inverse_interpolation

* added docstring + test for bezier::match_interpolate

* some improvements in coordinate_systems

* Vector -> Vector3

* replaced np.ndarray with more appropriate type hints

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Apply feedback

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* revert to previous (new) version

* fix doctest

* fix ReST errors

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Alex Lembcke <[email protected]>
Co-authored-by: Viicos <[email protected]>
Co-authored-by: JasonGrace2282 <[email protected]>
Co-authored-by: Benjamin Hackl <[email protected]>
  • Loading branch information
6 people authored Nov 3, 2023
1 parent 25bb381 commit d77a47a
Show file tree
Hide file tree
Showing 34 changed files with 2,156 additions and 1,347 deletions.
7 changes: 4 additions & 3 deletions .flake8
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
[flake8]
# Exclude the grpc generated code
exclude = ./manim/grpc/gen/*
exclude = ./manim/grpc/gen/*, __pycache__,.git,
per-file-ignores = __init__.py:F401
max-complexity = 15
max-line-length = 88
statistics = True
Expand All @@ -9,7 +10,7 @@ rst-roles = attr,class,func,meth,mod,obj,ref,doc,exc
rst-directives = manim, SEEALSO, seealso
docstring-convention=numpy

select = A,A00,B,B9,C4,C90,D,E,F,F,PT,RST,SIM,W
select = A,A00,B,B9,C4,C90,D,E,F,F,PT,RST,SIM,W,F401

# General Compatibility
extend-ignore = E203, W503, D202, D212, D213, D404
Expand Down Expand Up @@ -40,4 +41,4 @@ extend-ignore = E203, W503, D202, D212, D213, D404

# Plug-in: flake8-rst-docstrings
RST201, RST203, RST210, RST212, RST213, RST215,
RST301, RST303,
RST301, RST303, RST499
3 changes: 2 additions & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ repos:
flake8-simplify==0.14.1,
]
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.4.1
rev: v1.5.1
hooks:
- id: mypy
additional_dependencies:
Expand All @@ -69,6 +69,7 @@ repos:
types-requests,
types-setuptools,
]
files: ^manim/

- repo: https://github.com/codespell-project/codespell
rev: v2.2.5
Expand Down
110 changes: 44 additions & 66 deletions docs/source/contributing/typings.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,102 +2,80 @@
Adding Typings
==============

.. warning::
This section is still a work in progress.

Adding type hints to functions and parameters
---------------------------------------------

.. warning::
This section is still a work in progress.
Manim is currently in the process of adding type hints into the library. In this
section, you will find information about the standards used and some general
guidelines.

If you've never used type hints before, this is a good place to get started:
https://realpython.com/python-type-checking/#hello-types.

When adding type hints to manim, there are some guidelines that should be followed:
Typing standards
~~~~~~~~~~~~~~~~

* Coordinates have the typehint ``Sequence[float]``, e.g.
Manim uses `mypy`_ to type check its codebase. You will find a list of
configuration values in the ``mypy.ini`` configuration file.

.. code:: py
To be able to use the newest typing features not available in the lowest
supported Python version, make use of `typing_extensions`_.

def set_points_as_corners(self, points: Sequence[float]) -> "VMobject":
"""Given an array of points, set them as corner of the Vmobject."""
To be able to use the new Union syntax (``|``) and builtins subscripting, use
the ``from __future__ import annotations`` import.

* ``**kwargs`` has no typehint
.. _mypy: https://mypy-lang.org/
.. _typing_extensions: https://pypi.org/project/typing-extensions/

* Mobjects have the typehint "Mobject", e.g.
Typing guidelines
~~~~~~~~~~~~~~~~~

.. code:: py
* Manim has a dedicated :mod:`~.typing` module where type aliases are provided.
Most of them may seem redundant, in particular the ones related to ``numpy``.
This is in anticipation of the support for shape type hinting
(`related issue <https://github.com/numpy/numpy/issues/16544>`_). Besides the
pending shape support, using the correct type aliases will help users understand
which shape should be used.

def match_color(self, mobject: "Mobject"):
"""Match the color with the color of another :class:`~.Mobject`."""
return self.set_color(mobject.get_color())
* Colors have the typehint ``Color``, e.g.

.. code:: py
def set_color(self, color: Color = YELLOW_C, family: bool = True):
"""Condition is function which takes in one arguments, (x, y, z)."""
* As ``float`` and ``Union[int, float]`` are the same, use only ``float``

* For numpy arrays use the typehint ``np.ndarray``

* 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. )
* Always use a type hint of ``None`` for functions that does not return
a value (this also applies to ``__init__``), e.g.:

.. code:: py
def height(self, value) -> None:
self.scale_to_fit_height(value)
* Parameters that are None by default should get the type hint ``Optional``

.. code:: py
* For variables representing paths, use the ``StrPath`` or ``StrOrBytesPath``
type alias defined in the :mod:`~.typing` module.

def rotate(
self,
angle,
axis=OUT,
about_point: Optional[Sequence[float]] = None,
**kwargs,
):
pass
* ``*args`` and ``**kwargs`` shouldn't be left untyped (in most cases you can
use ``Any``).

* Following `PEP 484 <https://peps.python.org/pep-0484/#the-numeric-tower>`_,
use ``float`` instead of ``int | float``.

* The ``__init__()`` method always should have None as its return type.

* Functions and lambda functions should get the typehint ``Callable``
* Mobjects have the typehint ``Mobject``, e.g.:

.. code:: py
rate_func: Callable[[float], float] = lambda t: smooth(1 - t)
* Assuming that typical path objects are either Paths or strs, one can use the typehint ``typing.Union[str, pathlib.Path]``
def match_color(self, mobject: "Mobject"):
"""Match the color with the color of another :class:`~.Mobject`."""
return self.set_color(mobject.get_color())
.. note::
As a helper for tool for typesets, you can use `typestring-parser
<https://github.com/Dominik1123/typestring-parser>`_
which can be accessed by first installing it via ``pip`` - ``pip install typestring-parser`` and
then using ``from typestring_parser import parse``.
* Always parametrize generics (``list[int]`` instead of ``list``,
``type[Any]`` instead of ``type``, etc.). This also applies to callables:

.. doctest::
:options: +SKIP
.. code:: py
>>> from typestring_parser import parse
>>> parse("int")
<class 'int'>
>>> parse("int or str")
typing.Union[int, str]
>>> parse("list of str or str")
typing.Union[typing.List[str], str]
>>> parse("list of (int, str)")
typing.List[typing.Tuple[int, str]]
rate_func: Callable[[float], float] = lambda t: smooth(1 - t)
Missing Sections for typehints are:
-----------------------------------
* Tools for typehinting
* Link to MyPy

* Mypy and numpy import errors: https://realpython.com/python-type-checking/#running-mypy
* Where to find the alias
* When to use Object and when to use "Object".
* The use of a TypeVar on the type hints for copy().
* The definition and use of Protocols (like Sized, or Sequence, or Iterable...)
* When to use ``object`` vs ``Any``
* The use of a TypeVar on the type hints for ``copy()``.
* The definition and use of Protocols (like ``Sized``, ``Sequence``, ``Iterable``...)
1 change: 0 additions & 1 deletion manim/_config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
]

parser = make_config_parser()
logger: logging.Logger

# The logger can be accessed from anywhere as manim.logger, or as
# logging.getLogger("manim"). The console must be accessed as manim.console.
Expand Down
1 change: 1 addition & 0 deletions manim/_config/logger_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

if TYPE_CHECKING:
from pathlib import Path

HIGHLIGHTED_KEYWORDS = [ # these keywords are highlighted specially
"Played",
"animations",
Expand Down
4 changes: 2 additions & 2 deletions manim/_config/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@

from .. import constants
from ..constants import RendererType
from ..typing import StrPath
from ..utils.color import ManimColor
from ..utils.tex import TexTemplate, TexTemplateFromFile
from ..utils.tex_templates import TexTemplateLibrary


def config_file_paths() -> list[Path]:
Expand Down Expand Up @@ -76,7 +76,7 @@ def config_file_paths() -> list[Path]:


def make_config_parser(
custom_file: str | os.PathLike | None = None,
custom_file: StrPath | None = None,
) -> configparser.ConfigParser:
"""Make a :class:`ConfigParser` object and load any ``.cfg`` files.
Expand Down
1 change: 0 additions & 1 deletion manim/animation/changing.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

from typing import Callable

from manim._config import config
from manim.mobject.opengl.opengl_compatibility import ConvertToOpenGL
from manim.mobject.types.vectorized_mobject import VGroup, VMobject
from manim.utils.color import (
Expand Down
2 changes: 1 addition & 1 deletion manim/animation/creation.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ def construct(self):
from ..mobject.mobject import Group, Mobject
from ..mobject.types.vectorized_mobject import VMobject
from ..utils.bezier import integer_interpolate
from ..utils.rate_functions import double_smooth, linear, smooth
from ..utils.rate_functions import double_smooth, linear


class ShowPartial(Animation):
Expand Down
3 changes: 2 additions & 1 deletion manim/animation/indication.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ def construct(self):
from manim.mobject.geometry.line import Line
from manim.mobject.geometry.polygram import Rectangle
from manim.mobject.geometry.shape_matchers import SurroundingRectangle
from manim.scene.scene import Scene

from .. import config
from ..animation.animation import Animation
Expand Down Expand Up @@ -313,7 +314,7 @@ def _get_bounds(self, alpha: float) -> Tuple[float]:
lower = max(lower, 0)
return (lower, upper)

def clean_up_from_scene(self, scene: "Scene") -> None:
def clean_up_from_scene(self, scene: Scene) -> None:
super().clean_up_from_scene(scene)
for submob, start in self.get_all_families_zipped():
submob.pointwise_become_partial(start, 0, 1)
Expand Down
1 change: 0 additions & 1 deletion manim/camera/camera.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import itertools as it
import operator as op
import pathlib
import time
from functools import reduce
from typing import Any, Callable, Iterable

Expand Down
Loading

0 comments on commit d77a47a

Please sign in to comment.