Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add type hints according to PEP 484 and PEP 604 #1736

Merged
merged 34 commits into from
Mar 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
6e292da
chore: add type hints to manimlib.utils
TonyCrane Feb 12, 2022
3502563
chore: fix type hint of bezier
TonyCrane Feb 13, 2022
e781133
chore: add type hints to manimlib.mobject.mobject
TonyCrane Feb 13, 2022
7f8216b
chore: replace some iterable with npt.ArrayLike
TonyCrane Feb 13, 2022
19187ea
chore: add type hints to manimlib.mobject.types
TonyCrane Feb 13, 2022
992e61d
style: rename Color type to ManimColor
TonyCrane Feb 13, 2022
1064e2b
chore: add type hints to manimlib.camera
TonyCrane Feb 13, 2022
9a8aee4
chore: add type hints to manimlib.event_handler
TonyCrane Feb 13, 2022
960463d
docs: remove support for python 3.6
TonyCrane Feb 13, 2022
a0ed9ed
resolve conflict
TonyCrane Feb 14, 2022
e39f81c
Merge branch '3b1b-master'
TonyCrane Feb 14, 2022
7fb6f35
fix: fix some bugs caused by type hints and imports
TonyCrane Feb 14, 2022
09ce471
Merge branch '3b1b:master' into master
TonyCrane Feb 14, 2022
be5de32
chore: add type hints to manimlib.scene
TonyCrane Feb 14, 2022
62cab9f
chore: re-add type hint for EventListener
TonyCrane Feb 14, 2022
66caf0c
chore: only import some classes when type checking
TonyCrane Feb 14, 2022
9bdcc8b
style: remove quotes of annotations according to PEP 563
TonyCrane Feb 14, 2022
61c70b4
remove unnecessary import
TonyCrane Feb 14, 2022
773e013
chore: add type hints to manimlib.mobject.svg
TonyCrane Feb 14, 2022
3744844
fix: fix type hint of set_array_by_interpolation
TonyCrane Feb 15, 2022
4c16bfc
chore: add type hints to manimlib.mobject
TonyCrane Feb 15, 2022
db71ed1
fix: fix type hint of remove_empty_value
TonyCrane Feb 15, 2022
91ffdeb
chore: add type hints to manimlib.shader_wrapper
TonyCrane Feb 15, 2022
f085e6c
chore: add type hints to manimlib.window
TonyCrane Feb 15, 2022
d19e0cb
fix: remove import before future
TonyCrane Feb 15, 2022
41c4023
chore: add type hints to manimlib.animation
TonyCrane Feb 15, 2022
854f7cd
fix: remove type alias import in indication.py
TonyCrane Feb 15, 2022
0e4d415
workflow: only build wheels for python 3.7+
TonyCrane Feb 15, 2022
9f3b404
resolve conflict and add type hints for it
TonyCrane Feb 16, 2022
a08e9b0
Merge branch 'update'
TonyCrane Feb 16, 2022
37b5483
Merge branch 'master' into master
TonyCrane Feb 16, 2022
05bee01
chore: update type hint of SVGMobject
TonyCrane Feb 16, 2022
4fbe948
style: insert an empty line after import
TonyCrane Feb 16, 2022
f690164
Merge branch 'master' into master
3b1b Mar 22, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python: ["py36", "py37", "py38", "py39", "py310"]
python: ["py37", "py38", "py39", "py310"]

steps:
- uses: actions/checkout@v2
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Note, there are two versions of manim. This repository began as a personal proj
>
> **Note**: To install manim directly through pip, please pay attention to the name of the installed package. This repository is ManimGL of 3b1b. The package name is `manimgl` instead of `manim` or `manimlib`. Please use `pip install manimgl` to install the version in this repository.

Manim runs on Python 3.6 or higher (Python 3.8 is recommended).
Manim runs on Python 3.7 or higher.

System requirements are [FFmpeg](https://ffmpeg.org/), [OpenGL](https://www.opengl.org/) and [LaTeX](https://www.latex-project.org) (optional, if you want to use LaTeX).
For Linux, [Pango](https://pango.gnome.org) along with its development headers are required. See instruction [here](https://github.com/ManimCommunity/ManimPango#building).
Expand Down
2 changes: 1 addition & 1 deletion docs/source/getting_started/installation.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Installation
============

Manim runs on Python 3.6 or higher (Python 3.8 is recommended).
Manim runs on Python 3.7 or higher.

System requirements are:

Expand Down
62 changes: 40 additions & 22 deletions manimlib/animation/animation.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
from __future__ import annotations

from copy import deepcopy
from typing import Callable

from manimlib.mobject.mobject import _AnimationBuilder
from manimlib.mobject.mobject import Mobject
from manimlib.utils.config_ops import digest_config
from manimlib.utils.rate_functions import smooth
from manimlib.utils.simple_functions import clip

from typing import TYPE_CHECKING

if TYPE_CHECKING:
from manimlib.scene.scene import Scene


DEFAULT_ANIMATION_RUN_TIME = 1.0
DEFAULT_ANIMATION_LAG_RATIO = 0
Expand All @@ -29,17 +37,17 @@ class Animation(object):
"suspend_mobject_updating": True,
}

def __init__(self, mobject, **kwargs):
def __init__(self, mobject: Mobject, **kwargs):
assert(isinstance(mobject, Mobject))
digest_config(self, kwargs)
self.mobject = mobject

def __str__(self):
def __str__(self) -> str:
if self.name:
return self.name
return self.__class__.__name__ + str(self.mobject)

def begin(self):
def begin(self) -> None:
# This is called right as an animation is being
# played. As much initialization as possible,
# especially any mobject copying, should live in
Expand All @@ -56,32 +64,32 @@ def begin(self):
self.families = list(self.get_all_families_zipped())
self.interpolate(0)

def finish(self):
def finish(self) -> None:
self.interpolate(self.final_alpha_value)
if self.suspend_mobject_updating:
self.mobject.resume_updating()

def clean_up_from_scene(self, scene):
def clean_up_from_scene(self, scene: Scene) -> None:
if self.is_remover():
scene.remove(self.mobject)

def create_starting_mobject(self):
def create_starting_mobject(self) -> Mobject:
# Keep track of where the mobject starts
return self.mobject.copy()

def get_all_mobjects(self):
def get_all_mobjects(self) -> tuple[Mobject, Mobject]:
"""
Ordering must match the ording of arguments to interpolate_submobject
"""
return self.mobject, self.starting_mobject

def get_all_families_zipped(self):
def get_all_families_zipped(self) -> zip[tuple[Mobject]]:
return zip(*[
mob.get_family()
for mob in self.get_all_mobjects()
])

def update_mobjects(self, dt):
def update_mobjects(self, dt: float) -> None:
"""
Updates things like starting_mobject, and (for
Transforms) target_mobject. Note, since typically
Expand All @@ -92,7 +100,7 @@ def update_mobjects(self, dt):
for mob in self.get_all_mobjects_to_update():
mob.update(dt)

def get_all_mobjects_to_update(self):
def get_all_mobjects_to_update(self) -> list[Mobject]:
# The surrounding scene typically handles
# updating of self.mobject. Besides, in
# most cases its updating is suspended anyway
Expand All @@ -109,27 +117,37 @@ def update_config(self, **kwargs):
return self

# Methods for interpolation, the mean of an Animation
def interpolate(self, alpha):
def interpolate(self, alpha: float) -> None:
alpha = clip(alpha, 0, 1)
self.interpolate_mobject(self.rate_func(alpha))

def update(self, alpha):
def update(self, alpha: float) -> None:
"""
This method shouldn't exist, but it's here to
keep many old scenes from breaking
"""
self.interpolate(alpha)

def interpolate_mobject(self, alpha):
def interpolate_mobject(self, alpha: float) -> None:
for i, mobs in enumerate(self.families):
sub_alpha = self.get_sub_alpha(alpha, i, len(self.families))
self.interpolate_submobject(*mobs, sub_alpha)

def interpolate_submobject(self, submobject, starting_sumobject, alpha):
def interpolate_submobject(
self,
submobject: Mobject,
starting_submobject: Mobject,
alpha: float
):
# Typically ipmlemented by subclass
pass

def get_sub_alpha(self, alpha, index, num_submobjects):
def get_sub_alpha(
self,
alpha: float,
index: int,
num_submobjects: int
) -> float:
# TODO, make this more understanable, and/or combine
# its functionality with AnimationGroup's method
# build_animations_with_timings
Expand All @@ -140,29 +158,29 @@ def get_sub_alpha(self, alpha, index, num_submobjects):
return clip((value - lower), 0, 1)

# Getters and setters
def set_run_time(self, run_time):
def set_run_time(self, run_time: float):
self.run_time = run_time
return self

def get_run_time(self):
def get_run_time(self) -> float:
return self.run_time

def set_rate_func(self, rate_func):
def set_rate_func(self, rate_func: Callable[[float], float]):
self.rate_func = rate_func
return self

def get_rate_func(self):
def get_rate_func(self) -> Callable[[float], float]:
return self.rate_func

def set_name(self, name):
def set_name(self, name: str):
self.name = name
return self

def is_remover(self):
def is_remover(self) -> bool:
return self.remover


def prepare_animation(anim):
def prepare_animation(anim: Animation | _AnimationBuilder):
if isinstance(anim, _AnimationBuilder):
return anim.build()

Expand Down
43 changes: 29 additions & 14 deletions manimlib/animation/composition.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
from __future__ import annotations

import numpy as np
from typing import Callable

from manimlib.animation.animation import Animation, prepare_animation
from manimlib.mobject.mobject import Group
Expand All @@ -9,6 +12,12 @@
from manimlib.utils.rate_functions import linear
from manimlib.utils.simple_functions import clip

from typing import TYPE_CHECKING

if TYPE_CHECKING:
from manimlib.scene.scene import Scene
from manimlib.mobject.mobject import Mobject


DEFAULT_LAGGED_START_LAG_RATIO = 0.05

Expand All @@ -27,7 +36,7 @@ class AnimationGroup(Animation):
"group": None,
}

def __init__(self, *animations, **kwargs):
def __init__(self, *animations: Animation, **kwargs):
digest_config(self, kwargs)
self.animations = [prepare_animation(anim) for anim in animations]
if self.group is None:
Expand All @@ -37,27 +46,27 @@ def __init__(self, *animations, **kwargs):
self.init_run_time()
Animation.__init__(self, self.group, **kwargs)

def get_all_mobjects(self):
def get_all_mobjects(self) -> Group:
return self.group

def begin(self):
def begin(self) -> None:
for anim in self.animations:
anim.begin()
# self.init_run_time()

def finish(self):
def finish(self) -> None:
for anim in self.animations:
anim.finish()

def clean_up_from_scene(self, scene):
def clean_up_from_scene(self, scene: Scene) -> None:
for anim in self.animations:
anim.clean_up_from_scene(scene)

def update_mobjects(self, dt):
def update_mobjects(self, dt: float) -> None:
for anim in self.animations:
anim.update_mobjects(dt)

def init_run_time(self):
def init_run_time(self) -> None:
self.build_animations_with_timings()
if self.anims_with_timings:
self.max_end_time = np.max([
Expand All @@ -68,7 +77,7 @@ def init_run_time(self):
if self.run_time is None:
self.run_time = self.max_end_time

def build_animations_with_timings(self):
def build_animations_with_timings(self) -> None:
"""
Creates a list of triplets of the form
(anim, start_time, end_time)
Expand All @@ -87,7 +96,7 @@ def build_animations_with_timings(self):
start_time, end_time, self.lag_ratio
)

def interpolate(self, alpha):
def interpolate(self, alpha: float) -> None:
# Note, if the run_time of AnimationGroup has been
# set to something other than its default, these
# times might not correspond to actual times,
Expand All @@ -111,19 +120,19 @@ class Succession(AnimationGroup):
"lag_ratio": 1,
}

def begin(self):
def begin(self) -> None:
assert(len(self.animations) > 0)
self.init_run_time()
self.active_animation = self.animations[0]
self.active_animation.begin()

def finish(self):
def finish(self) -> None:
self.active_animation.finish()

def update_mobjects(self, dt):
def update_mobjects(self, dt: float) -> None:
self.active_animation.update_mobjects(dt)

def interpolate(self, alpha):
def interpolate(self, alpha: float) -> None:
index, subalpha = integer_interpolate(
0, len(self.animations), alpha
)
Expand All @@ -146,7 +155,13 @@ class LaggedStartMap(LaggedStart):
"run_time": 2,
}

def __init__(self, AnimationClass, mobject, arg_creator=None, **kwargs):
def __init__(
self,
AnimationClass: type,
mobject: Mobject,
arg_creator: Callable[[Mobject], tuple] | None = None,
**kwargs
):
args_list = []
for submob in mobject:
if arg_creator:
Expand Down
Loading