Fixing files with few typing (mypy) errors (#4263)

* Fixed mypy errors in several files with a few errors in each file.

* Fixed a few easy mypy errors.

* Fix mypy issues in animation/changing.py

* Handled mypy issues in _config/cli_colors.py

* Handled mypy issues in mobject/logo.py

* Handling mypy errors in fading.py

* Removed a default parameter (scene = None) in the method clean_up_from_scene in the class FadeOut

* Handled mypy errors in graphing/scale.py

* Handled a few mypy errors in updaters/update.py

* Handled mypy errors in three_d_utils.py

* Updated mypy.ini to check more files

* Avoid a circular import loop.

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

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

* Update manim/animation/changing.py

Co-authored-by: Francisco Manríquez Novoa <49853152+chopan050@users.noreply.github.com>

* Update manim/animation/changing.py

Co-authored-by: Francisco Manríquez Novoa <49853152+chopan050@users.noreply.github.com>

* Update manim/animation/changing.py

Co-authored-by: Francisco Manríquez Novoa <49853152+chopan050@users.noreply.github.com>

* Update manim/mobject/logo.py

Co-authored-by: Francisco Manríquez Novoa <49853152+chopan050@users.noreply.github.com>

* Update manim/animation/changing.py

Co-authored-by: Francisco Manríquez Novoa <49853152+chopan050@users.noreply.github.com>

* Update manim/animation/changing.py

Co-authored-by: Francisco Manríquez Novoa <49853152+chopan050@users.noreply.github.com>

* Update manim/animation/changing.py

Cleaner way to indicate the float type

Co-authored-by: Francisco Manríquez Novoa <49853152+chopan050@users.noreply.github.com>

* Update manim/animation/changing.py

Co-authored-by: Francisco Manríquez Novoa <49853152+chopan050@users.noreply.github.com>

* Updated the type annotations of MoveAlongPath and ChangingDecimal

* Suggestions from review by chopan50

* Fix missing import.

* Update mypy.ini

Co-authored-by: Francisco Manríquez Novoa <49853152+chopan050@users.noreply.github.com>

* Update mypy.ini

Co-authored-by: Francisco Manríquez Novoa <49853152+chopan050@users.noreply.github.com>

* Update mypy.ini

Co-authored-by: Francisco Manríquez Novoa <49853152+chopan050@users.noreply.github.com>

* Update mypy.ini

Co-authored-by: Francisco Manríquez Novoa <49853152+chopan050@users.noreply.github.com>

* Updated mypy.ini

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Francisco Manríquez Novoa <49853152+chopan050@users.noreply.github.com>
This commit is contained in:
Henrik Skov Midtiby 2025-06-23 14:08:00 +02:00 committed by GitHub
commit 325fa08a72
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 141 additions and 74 deletions

View file

@ -9,7 +9,7 @@ __all__ = ["parse_cli_ctx"]
def parse_cli_ctx(parser: configparser.SectionProxy) -> dict[str, Any]:
formatter_settings: dict[str, str | int] = {
formatter_settings: dict[str, str | int | None] = {
"indent_increment": int(parser["indent_increment"]),
"width": int(parser["width"]),
"col1_max_width": int(parser["col1_max_width"]),
@ -37,22 +37,24 @@ def parse_cli_ctx(parser: configparser.SectionProxy) -> dict[str, Any]:
if theme is None:
formatter = HelpFormatter.settings(
theme=HelpTheme(**theme_settings),
**formatter_settings, # type: ignore[arg-type]
**formatter_settings,
)
elif theme.lower() == "dark":
formatter = HelpFormatter.settings(
theme=HelpTheme.dark().with_(**theme_settings),
**formatter_settings, # type: ignore[arg-type]
**formatter_settings,
)
elif theme.lower() == "light":
formatter = HelpFormatter.settings(
theme=HelpTheme.light().with_(**theme_settings),
**formatter_settings, # type: ignore[arg-type]
**formatter_settings,
)
return Context.settings(
return_val: dict[str, Any] = Context.settings(
align_option_groups=parser["align_option_groups"].lower() == "true",
align_sections=parser["align_sections"].lower() == "true",
show_constraints=True,
formatter_settings=formatter,
)
return return_val

View file

@ -4,8 +4,12 @@ from __future__ import annotations
__all__ = ["AnimatedBoundary", "TracedPath"]
from collections.abc import Sequence
from typing import Callable
from typing_extensions import Any, Self
from manim.mobject.mobject import Mobject
from manim.mobject.opengl.opengl_compatibility import ConvertToOpenGL
from manim.mobject.types.vectorized_mobject import VGroup, VMobject
from manim.utils.color import (
@ -16,7 +20,7 @@ from manim.utils.color import (
WHITE,
ParsableManimColor,
)
from manim.utils.rate_functions import smooth
from manim.utils.rate_functions import RateFunction, smooth
class AnimatedBoundary(VGroup):
@ -38,14 +42,14 @@ class AnimatedBoundary(VGroup):
def __init__(
self,
vmobject,
colors=[BLUE_D, BLUE_B, BLUE_E, GREY_BROWN],
max_stroke_width=3,
cycle_rate=0.5,
back_and_forth=True,
draw_rate_func=smooth,
fade_rate_func=smooth,
**kwargs,
vmobject: VMobject,
colors: Sequence[ParsableManimColor] = [BLUE_D, BLUE_B, BLUE_E, GREY_BROWN],
max_stroke_width: float = 3,
cycle_rate: float = 0.5,
back_and_forth: bool = True,
draw_rate_func: RateFunction = smooth,
fade_rate_func: RateFunction = smooth,
**kwargs: Any,
):
super().__init__(**kwargs)
self.colors = colors
@ -59,10 +63,10 @@ class AnimatedBoundary(VGroup):
vmobject.copy().set_style(stroke_width=0, fill_opacity=0) for x in range(2)
]
self.add(*self.boundary_copies)
self.total_time = 0
self.total_time = 0.0
self.add_updater(lambda m, dt: self.update_boundary_copies(dt))
def update_boundary_copies(self, dt):
def update_boundary_copies(self, dt: float) -> None:
# Not actual time, but something which passes at
# an altered rate to make the implementation below
# cleaner
@ -78,9 +82,9 @@ class AnimatedBoundary(VGroup):
fade_alpha = self.fade_rate_func(alpha)
if self.back_and_forth and int(time) % 2 == 1:
bounds = (1 - draw_alpha, 1)
bounds = (1.0 - draw_alpha, 1.0)
else:
bounds = (0, draw_alpha)
bounds = (0.0, draw_alpha)
self.full_family_become_partial(growing, vmobject, *bounds)
growing.set_stroke(colors[index], width=msw)
@ -90,7 +94,9 @@ class AnimatedBoundary(VGroup):
self.total_time += dt
def full_family_become_partial(self, mob1, mob2, a, b):
def full_family_become_partial(
self, mob1: VMobject, mob2: VMobject, a: float, b: float
) -> Self:
family1 = mob1.family_members_with_points()
family2 = mob2.family_members_with_points()
for sm1, sm2 in zip(family1, family2):
@ -146,20 +152,21 @@ class TracedPath(VMobject, metaclass=ConvertToOpenGL):
stroke_width: float = 2,
stroke_color: ParsableManimColor | None = WHITE,
dissipating_time: float | None = None,
**kwargs,
):
**kwargs: Any,
) -> None:
super().__init__(stroke_color=stroke_color, stroke_width=stroke_width, **kwargs)
self.traced_point_func = traced_point_func
self.dissipating_time = dissipating_time
self.time = 1 if self.dissipating_time else None
self.time = 1.0 if self.dissipating_time else None
self.add_updater(self.update_path)
def update_path(self, mob, dt):
def update_path(self, mob: Mobject, dt: float) -> None:
new_point = self.traced_point_func()
if not self.has_points():
self.start_new_path(new_point)
self.add_line_to(new_point)
if self.dissipating_time:
assert self.time is not None
self.time += dt
if self.time - 1 > self.dissipating_time:
nppcc = self.n_points_per_curve

View file

@ -20,6 +20,7 @@ __all__ = [
]
import numpy as np
from typing_extensions import Any
from manim.mobject.opengl.opengl_mobject import OpenGLMobject
@ -53,7 +54,7 @@ class _Fade(Transform):
shift: np.ndarray | None = None,
target_position: np.ndarray | Mobject | None = None,
scale: float = 1,
**kwargs,
**kwargs: Any,
) -> None:
if not mobjects:
raise ValueError("At least one mobject must be passed.")
@ -85,7 +86,7 @@ class _Fade(Transform):
Mobject
The faded, shifted and scaled copy of the mobject.
"""
faded_mobject = self.mobject.copy()
faded_mobject: Mobject = self.mobject.copy() # type: ignore[assignment]
faded_mobject.fade(1)
direction_modifier = -1 if fadeIn and not self.point_target else 1
faded_mobject.shift(self.shift_vector * direction_modifier)
@ -131,13 +132,13 @@ class FadeIn(_Fade):
"""
def __init__(self, *mobjects: Mobject, **kwargs) -> None:
def __init__(self, *mobjects: Mobject, **kwargs: Any) -> None:
super().__init__(*mobjects, introducer=True, **kwargs)
def create_target(self):
return self.mobject
def create_target(self) -> Mobject:
return self.mobject # type: ignore[return-value]
def create_starting_mobject(self):
def create_starting_mobject(self) -> Mobject:
return self._create_faded_mobject(fadeIn=True)
@ -179,12 +180,12 @@ class FadeOut(_Fade):
"""
def __init__(self, *mobjects: Mobject, **kwargs) -> None:
def __init__(self, *mobjects: Mobject, **kwargs: Any) -> None:
super().__init__(*mobjects, remover=True, **kwargs)
def create_target(self):
def create_target(self) -> Mobject:
return self._create_faded_mobject(fadeIn=False)
def clean_up_from_scene(self, scene: Scene = None) -> None:
def clean_up_from_scene(self, scene: Scene) -> None:
super().clean_up_from_scene(scene)
self.interpolate(0)

View file

@ -171,7 +171,7 @@ class MoveAlongPath(Animation):
self,
mobject: Mobject,
path: VMobject,
suspend_mobject_updating: bool | None = False,
suspend_mobject_updating: bool = False,
**kwargs,
) -> None:
self.path = path

View file

@ -7,6 +7,8 @@ __all__ = ["ChangingDecimal", "ChangeDecimalToValue"]
import typing
from typing_extensions import Any
from manim.mobject.text.numbers import DecimalNumber
from ..animation.animation import Animation
@ -18,8 +20,8 @@ class ChangingDecimal(Animation):
self,
decimal_mob: DecimalNumber,
number_update_func: typing.Callable[[float], float],
suspend_mobject_updating: bool | None = False,
**kwargs,
suspend_mobject_updating: bool = False,
**kwargs: Any,
) -> None:
self.check_validity_of_input(decimal_mob)
self.number_update_func = number_update_func
@ -32,12 +34,12 @@ class ChangingDecimal(Animation):
raise TypeError("ChangingDecimal can only take in a DecimalNumber")
def interpolate_mobject(self, alpha: float) -> None:
self.mobject.set_value(self.number_update_func(self.rate_func(alpha)))
self.mobject.set_value(self.number_update_func(self.rate_func(alpha))) # type: ignore[attr-defined]
class ChangeDecimalToValue(ChangingDecimal):
def __init__(
self, decimal_mob: DecimalNumber, target_number: int, **kwargs
self, decimal_mob: DecimalNumber, target_number: int, **kwargs: Any
) -> None:
start_number = decimal_mob.number
super().__init__(

View file

@ -8,6 +8,7 @@ from collections.abc import Sequence
from typing import TYPE_CHECKING, Callable
import numpy as np
from typing_extensions import Any
from ..animation.animation import Animation
from ..animation.transform import Transform
@ -94,7 +95,7 @@ class Rotating(Animation):
about_edge: np.ndarray | None = None,
run_time: float = 5,
rate_func: Callable[[float], float] = linear,
**kwargs,
**kwargs: Any,
) -> None:
self.angle = angle
self.axis = axis
@ -159,7 +160,7 @@ class Rotate(Transform):
axis: np.ndarray = OUT,
about_point: Sequence[float] | None = None,
about_edge: Sequence[float] | None = None,
**kwargs,
**kwargs: Any,
) -> None:
if "path_arc" not in kwargs:
kwargs["path_arc"] = angle

View file

@ -6,6 +6,7 @@ from collections.abc import Sequence
from typing import Any
from manim.animation.transform import Restore
from manim.mobject.mobject import Mobject
from ..constants import *
from .composition import LaggedStart
@ -50,7 +51,7 @@ class Broadcast(LaggedStart):
def __init__(
self,
mobject,
mobject: Mobject,
focal_point: Sequence[float] = ORIGIN,
n_mobs: int = 5,
initial_opacity: float = 1,

View file

@ -7,6 +7,9 @@ __all__ = ["UpdateFromFunc", "UpdateFromAlphaFunc", "MaintainPositionRelativeTo"
import operator as op
import typing
from typing import Callable
from typing_extensions import Any
from manim.animation.animation import Animation
@ -24,9 +27,9 @@ class UpdateFromFunc(Animation):
def __init__(
self,
mobject: Mobject,
update_function: typing.Callable[[Mobject], typing.Any],
update_function: Callable[[Mobject], Any],
suspend_mobject_updating: bool = False,
**kwargs,
**kwargs: Any,
) -> None:
self.update_function = update_function
super().__init__(
@ -34,16 +37,18 @@ class UpdateFromFunc(Animation):
)
def interpolate_mobject(self, alpha: float) -> None:
self.update_function(self.mobject)
self.update_function(self.mobject) # type: ignore[arg-type]
class UpdateFromAlphaFunc(UpdateFromFunc):
def interpolate_mobject(self, alpha: float) -> None:
self.update_function(self.mobject, self.rate_func(alpha))
self.update_function(self.mobject, self.rate_func(alpha)) # type: ignore[call-arg, arg-type]
class MaintainPositionRelativeTo(Animation):
def __init__(self, mobject: Mobject, tracked_mobject: Mobject, **kwargs) -> None:
def __init__(
self, mobject: Mobject, tracked_mobject: Mobject, **kwargs: Any
) -> None:
self.tracked_mobject = tracked_mobject
self.diff = op.sub(
mobject.get_center(),

View file

@ -8,17 +8,21 @@ __all__ = [
]
from typing_extensions import Any
from manim.mobject.geometry.polygram import Rectangle
from .. import config
class ScreenRectangle(Rectangle):
def __init__(self, aspect_ratio=16.0 / 9.0, height=4, **kwargs):
def __init__(
self, aspect_ratio: float = 16.0 / 9.0, height: float = 4, **kwargs: Any
) -> None:
super().__init__(width=aspect_ratio * height, height=height, **kwargs)
@property
def aspect_ratio(self):
def aspect_ratio(self) -> float:
"""The aspect ratio.
When set, the width is stretched to accommodate
@ -27,11 +31,11 @@ class ScreenRectangle(Rectangle):
return self.width / self.height
@aspect_ratio.setter
def aspect_ratio(self, value):
def aspect_ratio(self, value: float) -> None:
self.stretch_to_fit_width(value * self.height)
class FullScreenRectangle(ScreenRectangle):
def __init__(self, **kwargs):
def __init__(self, **kwargs: Any) -> None:
super().__init__(**kwargs)
self.height = config["frame_height"]

View file

@ -139,18 +139,20 @@ class LogBase(_ScaleBase):
def function(self, value: float) -> float:
"""Scales the value to fit it to a logarithmic scale.``self.function(5)==10**5``"""
return self.base**value
return_value: float = self.base**value
return return_value
def inverse_function(self, value: float) -> float:
"""Inverse of ``function``. The value must be greater than 0"""
if isinstance(value, np.ndarray):
condition = value.any() <= 0
def func(value, base):
return np.log(value) / np.log(base)
def func(value: float, base: float) -> float:
return_value: float = np.log(value) / np.log(base)
return return_value
else:
condition = value <= 0
func = math.log
func = math.log # type: ignore[assignment]
if condition:
raise ValueError(
@ -163,8 +165,8 @@ class LogBase(_ScaleBase):
self,
val_range: Iterable[float],
unit_decimal_places: int = 0,
**base_config: dict[str, Any],
) -> list[Mobject]:
**base_config: Any,
) -> list[Integer]:
"""Produces custom :class:`~.Integer` labels in the form of ``10^2``.
Parameters

View file

@ -5,10 +5,13 @@ from __future__ import annotations
__all__ = ["ManimBanner"]
import svgelements as se
from typing_extensions import Any
from manim.animation.updaters.update import UpdateFromAlphaFunc
from manim.mobject.geometry.arc import Circle
from manim.mobject.geometry.polygram import Square, Triangle
from manim.mobject.mobject import Mobject
from manim.typing import Vector3D
from .. import constants as cst
from ..animation.animation import override_animation
@ -146,7 +149,7 @@ class ManimBanner(VGroup):
m_height_over_anim_height = 0.75748
self.font_color = "#ece6e2" if dark_theme else "#343434"
self.scale_factor = 1
self.scale_factor = 1.0
self.M = VMobjectFromSVGPath(MANIM_SVG_PATHS[0]).flip(cst.RIGHT).center()
self.M.set(stroke_width=0).scale(
@ -180,7 +183,7 @@ class ManimBanner(VGroup):
# and thus not yet added to the submobjects of self.
self.anim = anim
def scale(self, scale_factor: float, **kwargs) -> ManimBanner:
def scale(self, scale_factor: float, **kwargs: Any) -> ManimBanner:
"""Scale the banner by the specified scale factor.
Parameters
@ -219,7 +222,7 @@ class ManimBanner(VGroup):
lag_ratio=0.1,
)
def expand(self, run_time: float = 1.5, direction="center") -> Succession:
def expand(self, run_time: float = 1.5, direction: str = "center") -> Succession:
"""An animation that expands Manim's logo into its banner.
The returned animation transforms the banner from its initial
@ -277,7 +280,7 @@ class ManimBanner(VGroup):
self.M.save_state()
left_group = VGroup(self.M, self.anim, m_clone)
def shift(vector):
def shift(vector: Vector3D) -> None:
self.shapes.restore()
left_group.align_to(self.M.saved_state, cst.LEFT)
if direction == "right":
@ -288,7 +291,7 @@ class ManimBanner(VGroup):
elif direction == "left":
left_group.shift(-vector)
def slide_and_uncover(mob, alpha):
def slide_and_uncover(mob: Mobject, alpha: float) -> None:
shift(alpha * (m_shape_offset + shape_sliding_overshoot) * cst.RIGHT)
# Add letters when they are covered
@ -305,7 +308,7 @@ class ManimBanner(VGroup):
mob.shapes.save_state()
mob.M.save_state()
def slide_back(mob, alpha):
def slide_back(mob: Mobject, alpha: float) -> None:
if alpha == 0:
m_clone.set_opacity(1)
m_clone.move_to(mob.anim[-1])

View file

@ -24,35 +24,39 @@ from manim.utils.space_ops import get_unit_normal
if TYPE_CHECKING:
from manim.typing import Point3D, Vector3D
from ..types.vectorized_mobject import VMobject
def get_3d_vmob_gradient_start_and_end_points(vmob) -> tuple[Point3D, Point3D]:
def get_3d_vmob_gradient_start_and_end_points(
vmob: VMobject,
) -> tuple[Point3D, Point3D]:
return (
get_3d_vmob_start_corner(vmob),
get_3d_vmob_end_corner(vmob),
)
def get_3d_vmob_start_corner_index(vmob) -> Literal[0]:
def get_3d_vmob_start_corner_index(vmob: VMobject) -> Literal[0]:
return 0
def get_3d_vmob_end_corner_index(vmob) -> int:
def get_3d_vmob_end_corner_index(vmob: VMobject) -> int:
return ((len(vmob.points) - 1) // 6) * 3
def get_3d_vmob_start_corner(vmob) -> Point3D:
def get_3d_vmob_start_corner(vmob: VMobject) -> Point3D:
if vmob.get_num_points() == 0:
return np.array(ORIGIN)
return vmob.points[get_3d_vmob_start_corner_index(vmob)]
def get_3d_vmob_end_corner(vmob) -> Point3D:
def get_3d_vmob_end_corner(vmob: VMobject) -> Point3D:
if vmob.get_num_points() == 0:
return np.array(ORIGIN)
return vmob.points[get_3d_vmob_end_corner_index(vmob)]
def get_3d_vmob_unit_normal(vmob, point_index: int) -> Vector3D:
def get_3d_vmob_unit_normal(vmob: VMobject, point_index: int) -> Vector3D:
n_points = vmob.get_num_points()
if len(vmob.get_anchors()) <= 2:
return np.array(UP)
@ -68,9 +72,9 @@ def get_3d_vmob_unit_normal(vmob, point_index: int) -> Vector3D:
return unit_normal
def get_3d_vmob_start_corner_unit_normal(vmob) -> Vector3D:
def get_3d_vmob_start_corner_unit_normal(vmob: VMobject) -> Vector3D:
return get_3d_vmob_unit_normal(vmob, get_3d_vmob_start_corner_index(vmob))
def get_3d_vmob_end_corner_unit_normal(vmob) -> Vector3D:
def get_3d_vmob_end_corner_unit_normal(vmob: VMobject) -> Vector3D:
return get_3d_vmob_unit_normal(vmob, get_3d_vmob_end_corner_index(vmob))

View file

@ -89,7 +89,10 @@ from __future__ import annotations
__all__ = ["MovingCameraScene"]
from typing_extensions import Any
from manim.animation.animation import Animation
from manim.mobject.mobject import Mobject
from ..camera.moving_camera import MovingCamera
from ..scene.scene import Scene
@ -111,10 +114,12 @@ class MovingCameraScene(Scene):
:class:`.MovingCamera`
"""
def __init__(self, camera_class=MovingCamera, **kwargs):
def __init__(
self, camera_class: type[MovingCamera] = MovingCamera, **kwargs: Any
) -> None:
super().__init__(camera_class=camera_class, **kwargs)
def get_moving_mobjects(self, *animations: Animation):
def get_moving_mobjects(self, *animations: Animation) -> list[Mobject]:
"""
This method returns a list of all of the Mobjects in the Scene that
are moving, that are also in the animations passed.

View file

@ -829,7 +829,7 @@ class Scene:
self.foreground_mobjects = []
return self
def get_moving_mobjects(self, *animations: Animation):
def get_moving_mobjects(self, *animations: Animation) -> list[Mobject]:
"""
Gets all moving mobjects in the passed animation(s).

View file

@ -100,5 +100,5 @@ class Section:
**video_metadata,
)
def __repr__(self):
def __repr__(self) -> str:
return f"<Section '{self.name}' stored in '{self.video}'>"

View file

@ -52,12 +52,27 @@ warn_return_any = True
ignore_errors = True
disable_error_code = return-value
[mypy-manim._config.cli_colors]
ignore_errors = False
[mypy-manim._config.logger_utils]
ignore_errors = False
[mypy-manim.animation.*]
ignore_errors = True
[mypy-manim.animation.changing]
ignore_errors = False
[mypy-manim.animation.fading]
ignore_errors = False
[mypy-manim.animation.numbers]
ignore_errors = False
[mypy-manim.animation.updaters.update]
ignore_errors = False
[mypy-manim.camera.*]
ignore_errors = True
@ -73,18 +88,33 @@ ignore_errors = True
[mypy-manim.mobject.*]
ignore_errors = True
[mypy-manim.mobject.text.code_mobject]
[mypy-manim.mobject.frame]
ignore_errors = False
[mypy-manim.mobject.geometry.*]
ignore_errors = True
[mypy-manim.mobject.graphing.scale]
ignore_errors = False
[mypy-manim.mobject.text.code_mobject]
ignore_errors = False
[mypy-manim.mobject.three_d.three_d_utils]
ignore_errors = False
[mypy-manim.renderer.*]
ignore_errors = True
[mypy-manim.scene.*]
ignore_errors = True
[mypy-manim.scene.moving_camera_scene]
ignore_errors = False
[mypy-manim.scene.section]
ignore_errors = False
[mypy-manim.utils.hashing.*]
ignore_errors = True