manim 0.18.0.post0__py3-none-any.whl → 0.19.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of manim might be problematic. Click here for more details.

Files changed (146) hide show
  1. manim/__init__.py +3 -6
  2. manim/__main__.py +61 -20
  3. manim/_config/__init__.py +6 -3
  4. manim/_config/cli_colors.py +16 -8
  5. manim/_config/default.cfg +1 -3
  6. manim/_config/logger_utils.py +14 -8
  7. manim/_config/utils.py +651 -472
  8. manim/animation/animation.py +152 -5
  9. manim/animation/composition.py +80 -39
  10. manim/animation/creation.py +196 -14
  11. manim/animation/fading.py +5 -9
  12. manim/animation/indication.py +103 -47
  13. manim/animation/movement.py +22 -5
  14. manim/animation/rotation.py +3 -2
  15. manim/animation/specialized.py +4 -6
  16. manim/animation/speedmodifier.py +10 -5
  17. manim/animation/transform.py +4 -5
  18. manim/animation/transform_matching_parts.py +1 -1
  19. manim/animation/updaters/mobject_update_utils.py +17 -14
  20. manim/camera/camera.py +15 -6
  21. manim/cli/__init__.py +17 -0
  22. manim/cli/cfg/group.py +70 -44
  23. manim/cli/checkhealth/checks.py +93 -75
  24. manim/cli/checkhealth/commands.py +14 -5
  25. manim/cli/default_group.py +157 -25
  26. manim/cli/init/commands.py +32 -24
  27. manim/cli/plugins/commands.py +16 -3
  28. manim/cli/render/commands.py +72 -60
  29. manim/cli/render/ease_of_access_options.py +4 -3
  30. manim/cli/render/global_options.py +51 -15
  31. manim/cli/render/output_options.py +6 -5
  32. manim/cli/render/render_options.py +97 -32
  33. manim/constants.py +65 -19
  34. manim/gui/gui.py +2 -0
  35. manim/mobject/frame.py +0 -1
  36. manim/mobject/geometry/arc.py +112 -78
  37. manim/mobject/geometry/boolean_ops.py +32 -25
  38. manim/mobject/geometry/labeled.py +300 -77
  39. manim/mobject/geometry/line.py +132 -64
  40. manim/mobject/geometry/polygram.py +126 -30
  41. manim/mobject/geometry/shape_matchers.py +35 -15
  42. manim/mobject/geometry/tips.py +38 -29
  43. manim/mobject/graph.py +414 -133
  44. manim/mobject/graphing/coordinate_systems.py +126 -64
  45. manim/mobject/graphing/functions.py +25 -15
  46. manim/mobject/graphing/number_line.py +24 -10
  47. manim/mobject/graphing/probability.py +2 -10
  48. manim/mobject/graphing/scale.py +6 -5
  49. manim/mobject/matrix.py +17 -19
  50. manim/mobject/mobject.py +314 -165
  51. manim/mobject/opengl/opengl_compatibility.py +2 -0
  52. manim/mobject/opengl/opengl_geometry.py +30 -9
  53. manim/mobject/opengl/opengl_image_mobject.py +2 -0
  54. manim/mobject/opengl/opengl_mobject.py +509 -343
  55. manim/mobject/opengl/opengl_point_cloud_mobject.py +5 -7
  56. manim/mobject/opengl/opengl_surface.py +3 -2
  57. manim/mobject/opengl/opengl_three_dimensions.py +2 -0
  58. manim/mobject/opengl/opengl_vectorized_mobject.py +46 -79
  59. manim/mobject/svg/brace.py +63 -13
  60. manim/mobject/svg/svg_mobject.py +4 -3
  61. manim/mobject/table.py +11 -13
  62. manim/mobject/text/code_mobject.py +186 -548
  63. manim/mobject/text/numbers.py +9 -7
  64. manim/mobject/text/tex_mobject.py +23 -14
  65. manim/mobject/text/text_mobject.py +70 -24
  66. manim/mobject/three_d/polyhedra.py +98 -1
  67. manim/mobject/three_d/three_d_utils.py +4 -4
  68. manim/mobject/three_d/three_dimensions.py +62 -34
  69. manim/mobject/types/image_mobject.py +42 -24
  70. manim/mobject/types/point_cloud_mobject.py +105 -67
  71. manim/mobject/types/vectorized_mobject.py +496 -228
  72. manim/mobject/value_tracker.py +5 -4
  73. manim/mobject/vector_field.py +5 -5
  74. manim/opengl/__init__.py +3 -3
  75. manim/plugins/__init__.py +14 -1
  76. manim/plugins/plugins_flags.py +14 -8
  77. manim/renderer/cairo_renderer.py +20 -10
  78. manim/renderer/opengl_renderer.py +21 -23
  79. manim/renderer/opengl_renderer_window.py +2 -0
  80. manim/renderer/shader.py +2 -3
  81. manim/renderer/shader_wrapper.py +5 -2
  82. manim/renderer/vectorized_mobject_rendering.py +5 -0
  83. manim/scene/moving_camera_scene.py +23 -0
  84. manim/scene/scene.py +90 -43
  85. manim/scene/scene_file_writer.py +316 -165
  86. manim/scene/section.py +17 -15
  87. manim/scene/three_d_scene.py +13 -21
  88. manim/scene/vector_space_scene.py +22 -9
  89. manim/typing.py +830 -70
  90. manim/utils/bezier.py +1667 -399
  91. manim/utils/caching.py +13 -5
  92. manim/utils/color/AS2700.py +2 -0
  93. manim/utils/color/BS381.py +3 -0
  94. manim/utils/color/DVIPSNAMES.py +96 -0
  95. manim/utils/color/SVGNAMES.py +179 -0
  96. manim/utils/color/X11.py +3 -0
  97. manim/utils/color/XKCD.py +3 -0
  98. manim/utils/color/__init__.py +8 -5
  99. manim/utils/color/core.py +844 -309
  100. manim/utils/color/manim_colors.py +7 -9
  101. manim/utils/commands.py +48 -20
  102. manim/utils/config_ops.py +18 -13
  103. manim/utils/debug.py +8 -7
  104. manim/utils/deprecation.py +90 -40
  105. manim/utils/docbuild/__init__.py +17 -0
  106. manim/utils/docbuild/autoaliasattr_directive.py +234 -0
  107. manim/utils/docbuild/autocolor_directive.py +21 -17
  108. manim/utils/docbuild/manim_directive.py +50 -35
  109. manim/utils/docbuild/module_parsing.py +245 -0
  110. manim/utils/exceptions.py +6 -0
  111. manim/utils/family.py +5 -3
  112. manim/utils/family_ops.py +17 -4
  113. manim/utils/file_ops.py +26 -16
  114. manim/utils/hashing.py +9 -7
  115. manim/utils/images.py +10 -4
  116. manim/utils/ipython_magic.py +14 -8
  117. manim/utils/iterables.py +161 -119
  118. manim/utils/module_ops.py +57 -19
  119. manim/utils/opengl.py +83 -24
  120. manim/utils/parameter_parsing.py +32 -0
  121. manim/utils/paths.py +21 -23
  122. manim/utils/polylabel.py +168 -0
  123. manim/utils/qhull.py +218 -0
  124. manim/utils/rate_functions.py +74 -39
  125. manim/utils/simple_functions.py +24 -15
  126. manim/utils/sounds.py +7 -1
  127. manim/utils/space_ops.py +125 -69
  128. manim/utils/testing/__init__.py +17 -0
  129. manim/utils/testing/_frames_testers.py +13 -8
  130. manim/utils/testing/_show_diff.py +5 -3
  131. manim/utils/testing/_test_class_makers.py +33 -18
  132. manim/utils/testing/frames_comparison.py +27 -19
  133. manim/utils/tex.py +127 -197
  134. manim/utils/tex_file_writing.py +47 -45
  135. manim/utils/tex_templates.py +2 -1
  136. manim/utils/unit.py +6 -5
  137. {manim-0.18.0.post0.dist-info → manim-0.19.0.dist-info}/LICENSE.community +1 -1
  138. {manim-0.18.0.post0.dist-info → manim-0.19.0.dist-info}/METADATA +40 -39
  139. manim-0.19.0.dist-info/RECORD +221 -0
  140. {manim-0.18.0.post0.dist-info → manim-0.19.0.dist-info}/WHEEL +1 -1
  141. manim/cli/new/__init__.py +0 -0
  142. manim/cli/new/group.py +0 -189
  143. manim/plugins/import_plugins.py +0 -43
  144. manim-0.18.0.post0.dist-info/RECORD +0 -217
  145. {manim-0.18.0.post0.dist-info → manim-0.19.0.dist-info}/LICENSE +0 -0
  146. {manim-0.18.0.post0.dist-info → manim-0.19.0.dist-info}/entry_points.txt +0 -0
@@ -46,21 +46,22 @@ These colors form Manim's default color space.
46
46
  for line, char in zip(color_groups[0], "abcde"):
47
47
  color_groups.add(Text(char).scale(0.6).next_to(line, LEFT, buff=0.2))
48
48
 
49
- def named_lines_group(length, colors, names, text_colors, align_to_block):
49
+ def named_lines_group(length, color_names, labels, align_to_block):
50
+ colors = [getattr(Colors, color.upper()) for color in color_names]
50
51
  lines = VGroup(
51
52
  *[
52
53
  Line(
53
54
  ORIGIN,
54
55
  RIGHT * length,
55
56
  stroke_width=55,
56
- color=getattr(Colors, color.upper()),
57
+ color=color,
57
58
  )
58
59
  for color in colors
59
60
  ]
60
61
  ).arrange_submobjects(buff=0.6, direction=DOWN)
61
62
 
62
- for line, name, color in zip(lines, names, text_colors):
63
- line.add(Text(name, color=color).scale(0.6).move_to(line))
63
+ for line, name, color in zip(lines, labels, colors):
64
+ line.add(Text(name, color=color.contrasting()).scale(0.6).move_to(line))
64
65
  lines.next_to(color_groups, DOWN, buff=0.5).align_to(
65
66
  color_groups[align_to_block], LEFT
66
67
  )
@@ -79,7 +80,6 @@ These colors form Manim's default color space.
79
80
  3.2,
80
81
  other_colors,
81
82
  other_colors,
82
- [BLACK] * 4 + [WHITE] * 2,
83
83
  0,
84
84
  )
85
85
 
@@ -95,7 +95,6 @@ These colors form Manim's default color space.
95
95
  "darker_gray / gray_e",
96
96
  "black",
97
97
  ],
98
- [BLACK] * 3 + [WHITE] * 4,
99
98
  2,
100
99
  )
101
100
 
@@ -109,7 +108,6 @@ These colors form Manim's default color space.
109
108
  3.2,
110
109
  pure_colors,
111
110
  pure_colors,
112
- [BLACK, BLACK, WHITE],
113
111
  6,
114
112
  )
115
113
 
@@ -121,7 +119,7 @@ These colors form Manim's default color space.
121
119
 
122
120
  """
123
121
 
124
- from typing import List
122
+ from __future__ import annotations
125
123
 
126
124
  from .core import ManimColor
127
125
 
@@ -215,6 +213,6 @@ LOGO_BLUE = ManimColor("#525893")
215
213
  LOGO_RED = ManimColor("#E07A5F")
216
214
  LOGO_BLACK = ManimColor("#343434")
217
215
 
218
- _all_manim_colors: List[ManimColor] = [
216
+ _all_manim_colors: list[ManimColor] = [
219
217
  x for x in globals().values() if isinstance(x, ManimColor)
220
218
  ]
manim/utils/commands.py CHANGED
@@ -1,10 +1,14 @@
1
1
  from __future__ import annotations
2
2
 
3
- import json
4
3
  import os
4
+ from collections.abc import Generator
5
5
  from pathlib import Path
6
6
  from subprocess import run
7
- from typing import Generator
7
+ from typing import TypedDict
8
+
9
+ import av
10
+
11
+ from manim.typing import StrOrBytesPath
8
12
 
9
13
  __all__ = [
10
14
  "capture",
@@ -13,28 +17,52 @@ __all__ = [
13
17
  ]
14
18
 
15
19
 
16
- def capture(command, cwd=None, command_input=None):
17
- p = run(command, cwd=cwd, input=command_input, capture_output=True, text=True)
20
+ def capture(
21
+ command: str, cwd: StrOrBytesPath | None = None, command_input: str | None = None
22
+ ) -> tuple[str, str, int]:
23
+ p = run(
24
+ command,
25
+ cwd=cwd,
26
+ input=command_input,
27
+ capture_output=True,
28
+ text=True,
29
+ encoding="utf-8",
30
+ )
18
31
  out, err = p.stdout, p.stderr
19
32
  return out, err, p.returncode
20
33
 
21
34
 
22
- def get_video_metadata(path_to_video: str | os.PathLike) -> dict[str]:
23
- command = [
24
- "ffprobe",
25
- "-v",
26
- "error",
27
- "-select_streams",
28
- "v:0",
29
- "-show_entries",
30
- "stream=width,height,nb_frames,duration,avg_frame_rate,codec_name",
31
- "-print_format",
32
- "json",
33
- str(path_to_video),
34
- ]
35
- config, err, exitcode = capture(command)
36
- assert exitcode == 0, f"FFprobe error: {err}"
37
- return json.loads(config)["streams"][0]
35
+ class VideoMetadata(TypedDict):
36
+ width: int
37
+ height: int
38
+ nb_frames: str
39
+ duration: str
40
+ avg_frame_rate: str
41
+ codec_name: str
42
+ pix_fmt: str
43
+
44
+
45
+ def get_video_metadata(path_to_video: str | os.PathLike) -> VideoMetadata:
46
+ with av.open(str(path_to_video)) as container:
47
+ stream = container.streams.video[0]
48
+ ctxt = stream.codec_context
49
+ rate = stream.average_rate
50
+ if stream.duration is not None:
51
+ duration = float(stream.duration * stream.time_base)
52
+ num_frames = stream.frames
53
+ else:
54
+ num_frames = sum(1 for _ in container.decode(video=0))
55
+ duration = float(num_frames / stream.base_rate)
56
+
57
+ return {
58
+ "width": ctxt.width,
59
+ "height": ctxt.height,
60
+ "nb_frames": str(num_frames),
61
+ "duration": f"{duration:.6f}",
62
+ "avg_frame_rate": f"{rate.numerator}/{rate.denominator}", # Can be a Fraction
63
+ "codec_name": stream.codec_context.name,
64
+ "pix_fmt": stream.codec_context.pix_fmt,
65
+ }
38
66
 
39
67
 
40
68
  def get_dir_layout(dirpath: Path) -> Generator[str, None, None]:
manim/utils/config_ops.py CHANGED
@@ -10,11 +10,12 @@ __all__ = [
10
10
 
11
11
 
12
12
  import itertools as it
13
+ from typing import Any
13
14
 
14
- import numpy as np
15
+ import numpy.typing as npt
15
16
 
16
17
 
17
- def merge_dicts_recursively(*dicts):
18
+ def merge_dicts_recursively(*dicts: dict[Any, Any]) -> dict[Any, Any]:
18
19
  """
19
20
  Creates a dict whose keyset is the union of all the
20
21
  input dictionaries. The value for each key is based
@@ -24,7 +25,7 @@ def merge_dicts_recursively(*dicts):
24
25
 
25
26
  When values are dictionaries, it is applied recursively
26
27
  """
27
- result = {}
28
+ result: dict = {}
28
29
  all_items = it.chain(*(d.items() for d in dicts))
29
30
  for key, value in all_items:
30
31
  if key in result and isinstance(result[key], dict) and isinstance(value, dict):
@@ -34,7 +35,9 @@ def merge_dicts_recursively(*dicts):
34
35
  return result
35
36
 
36
37
 
37
- def update_dict_recursively(current_dict, *others):
38
+ def update_dict_recursively(
39
+ current_dict: dict[Any, Any], *others: dict[Any, Any]
40
+ ) -> None:
38
41
  updated_dict = merge_dicts_recursively(current_dict, *others)
39
42
  current_dict.update(updated_dict)
40
43
 
@@ -44,7 +47,7 @@ def update_dict_recursively(current_dict, *others):
44
47
 
45
48
 
46
49
  class DictAsObject:
47
- def __init__(self, dictin):
50
+ def __init__(self, dictin: dict[str, Any]):
48
51
  self.__dict__ = dictin
49
52
 
50
53
 
@@ -53,13 +56,14 @@ class _Data:
53
56
  self.data attributes must be arrays.
54
57
  """
55
58
 
56
- def __set_name__(self, obj, name):
59
+ def __set_name__(self, obj: Any, name: str) -> None:
57
60
  self.name = name
58
61
 
59
- def __get__(self, obj, owner):
60
- return obj.data[self.name]
62
+ def __get__(self, obj: Any, owner: Any) -> npt.NDArray[Any]:
63
+ value: npt.NDArray[Any] = obj.data[self.name]
64
+ return value
61
65
 
62
- def __set__(self, obj, array: np.ndarray):
66
+ def __set__(self, obj: Any, array: npt.NDArray[Any]) -> None:
63
67
  obj.data[self.name] = array
64
68
 
65
69
 
@@ -68,11 +72,12 @@ class _Uniforms:
68
72
  self.uniforms attributes must be floats.
69
73
  """
70
74
 
71
- def __set_name__(self, obj, name):
75
+ def __set_name__(self, obj: Any, name: str) -> None:
72
76
  self.name = name
73
77
 
74
- def __get__(self, obj, owner):
75
- return obj.__dict__["uniforms"][self.name]
78
+ def __get__(self, obj: Any, owner: Any) -> float:
79
+ val: float = obj.__dict__["uniforms"][self.name]
80
+ return val
76
81
 
77
- def __set__(self, obj, num: float):
82
+ def __set__(self, obj: Any, num: float) -> None:
78
83
  obj.__dict__["uniforms"][self.name] = num
manim/utils/debug.py CHANGED
@@ -1,19 +1,21 @@
1
1
  """Debugging utilities."""
2
2
 
3
-
4
3
  from __future__ import annotations
5
4
 
6
5
  __all__ = ["print_family", "index_labels"]
7
6
 
8
7
 
8
+ from typing import Any
9
+
9
10
  from manim.mobject.mobject import Mobject
10
11
  from manim.mobject.text.numbers import Integer
12
+ from manim.utils.color import ManimColor
11
13
 
12
14
  from ..mobject.types.vectorized_mobject import VGroup
13
15
  from .color import BLACK
14
16
 
15
17
 
16
- def print_family(mobject, n_tabs=0):
18
+ def print_family(mobject: Mobject, n_tabs: int = 0) -> None:
17
19
  """For debugging purposes"""
18
20
  print("\t" * n_tabs, mobject, id(mobject))
19
21
  for submob in mobject.submobjects:
@@ -23,10 +25,10 @@ def print_family(mobject, n_tabs=0):
23
25
  def index_labels(
24
26
  mobject: Mobject,
25
27
  label_height: float = 0.15,
26
- background_stroke_width=5,
27
- background_stroke_color=BLACK,
28
- **kwargs,
29
- ):
28
+ background_stroke_width: float = 5,
29
+ background_stroke_color: ManimColor = BLACK,
30
+ **kwargs: Any,
31
+ ) -> VGroup:
30
32
  r"""Returns a :class:`~.VGroup` of :class:`~.Integer` mobjects
31
33
  that shows the index of each submobject.
32
34
 
@@ -68,7 +70,6 @@ def index_labels(
68
70
 
69
71
  self.add(text, indices)
70
72
  """
71
-
72
73
  labels = VGroup()
73
74
  for n, submob in enumerate(mobject):
74
75
  label = Integer(n, **kwargs)
@@ -6,15 +6,17 @@ __all__ = ["deprecated", "deprecated_params"]
6
6
 
7
7
 
8
8
  import inspect
9
+ import logging
9
10
  import re
10
- from typing import Any, Callable, Iterable
11
+ from collections.abc import Iterable
12
+ from typing import Any, Callable, TypeVar, overload
11
13
 
12
14
  from decorator import decorate, decorator
13
15
 
14
- from .. import logger
16
+ logger = logging.getLogger("manim")
15
17
 
16
18
 
17
- def _get_callable_info(callable: Callable) -> tuple[str, str]:
19
+ def _get_callable_info(callable_: Callable[..., Any], /) -> tuple[str, str]:
18
20
  """Returns type and name of a callable.
19
21
 
20
22
  Parameters
@@ -28,8 +30,8 @@ def _get_callable_info(callable: Callable) -> tuple[str, str]:
28
30
  The type and name of the callable. Type can can be one of "class", "method" (for
29
31
  functions defined in classes) or "function"). For methods, name is Class.method.
30
32
  """
31
- what = type(callable).__name__
32
- name = callable.__qualname__
33
+ what = type(callable_).__name__
34
+ name = callable_.__qualname__
33
35
  if what == "function" and "." in name:
34
36
  what = "method"
35
37
  elif what != "function":
@@ -38,9 +40,9 @@ def _get_callable_info(callable: Callable) -> tuple[str, str]:
38
40
 
39
41
 
40
42
  def _deprecation_text_component(
41
- since: str | None,
42
- until: str | None,
43
- message: str,
43
+ since: str | None = None,
44
+ until: str | None = None,
45
+ message: str | None = None,
44
46
  ) -> str:
45
47
  """Generates a text component used in deprecation messages.
46
48
 
@@ -68,13 +70,37 @@ def _deprecation_text_component(
68
70
  return f"deprecated {since}and {until}.{msg}"
69
71
 
70
72
 
73
+ # TODO: Use ParamSpec to type decorated functions when Python 3.9 is out of life
74
+ T = TypeVar("T")
75
+
76
+
77
+ @overload
78
+ def deprecated(
79
+ func: Callable[..., T],
80
+ since: str | None = None,
81
+ until: str | None = None,
82
+ replacement: str | None = None,
83
+ message: str | None = "",
84
+ ) -> Callable[..., T]: ...
85
+
86
+
87
+ @overload
88
+ def deprecated(
89
+ func: None = None,
90
+ since: str | None = None,
91
+ until: str | None = None,
92
+ replacement: str | None = None,
93
+ message: str | None = "",
94
+ ) -> Callable[[Callable[..., T]], Callable[..., T]]: ...
95
+
96
+
71
97
  def deprecated(
72
- func: Callable = None,
98
+ func: Callable[..., T] | None = None,
73
99
  since: str | None = None,
74
100
  until: str | None = None,
75
101
  replacement: str | None = None,
76
102
  message: str | None = "",
77
- ) -> Callable:
103
+ ) -> Callable[..., T] | Callable[[Callable[..., T]], Callable[..., T]]:
78
104
  """Decorator to mark a callable as deprecated.
79
105
 
80
106
  The decorated callable will cause a warning when used. The docstring of the
@@ -104,10 +130,12 @@ def deprecated(
104
130
 
105
131
  from manim.utils.deprecation import deprecated
106
132
 
133
+
107
134
  @deprecated
108
135
  def foo(**kwargs):
109
136
  pass
110
137
 
138
+
111
139
  @deprecated
112
140
  class Bar:
113
141
  def __init__(self):
@@ -117,6 +145,7 @@ def deprecated(
117
145
  def baz(self):
118
146
  pass
119
147
 
148
+
120
149
  foo()
121
150
  # WARNING The function foo has been deprecated and may be removed in a later version.
122
151
 
@@ -130,15 +159,14 @@ def deprecated(
130
159
 
131
160
  from manim.utils.deprecation import deprecated
132
161
 
162
+
133
163
  @deprecated(
134
- since="v0.2",
135
- until="v0.4",
136
- replacement="bar",
137
- message="It is cooler."
164
+ since="v0.2", until="v0.4", replacement="bar", message="It is cooler."
138
165
  )
139
166
  def foo():
140
167
  pass
141
168
 
169
+
142
170
  foo()
143
171
  # WARNING The function foo has been deprecated since v0.2 and is expected to be removed after v0.4. Use bar instead. It is cooler.
144
172
 
@@ -146,10 +174,12 @@ def deprecated(
146
174
 
147
175
  from manim.utils.deprecation import deprecated
148
176
 
177
+
149
178
  @deprecated(since="05/01/2021", until="06/01/2021")
150
179
  def foo():
151
180
  pass
152
181
 
182
+
153
183
  foo()
154
184
  # WARNING The function foo has been deprecated since 05/01/2021 and is expected to be removed after 06/01/2021.
155
185
 
@@ -183,7 +213,7 @@ def deprecated(
183
213
  deprecated = _deprecation_text_component(since, until, msg)
184
214
  return f"The {what} {name} has been {deprecated}"
185
215
 
186
- def deprecate_docs(func: Callable):
216
+ def deprecate_docs(func: Callable) -> None:
187
217
  """Adjust docstring to indicate the deprecation.
188
218
 
189
219
  Parameters
@@ -195,7 +225,7 @@ def deprecated(
195
225
  doc_string = func.__doc__ or ""
196
226
  func.__doc__ = f"{doc_string}\n\n.. attention:: Deprecated\n {warning}"
197
227
 
198
- def deprecate(func: Callable, *args, **kwargs):
228
+ def deprecate(func: Callable[..., T], *args: Any, **kwargs: Any) -> T:
199
229
  """The actual decorator used to extend the callables behavior.
200
230
 
201
231
  Logs a warning message.
@@ -220,7 +250,10 @@ def deprecated(
220
250
 
221
251
  if type(func).__name__ != "function":
222
252
  deprecate_docs(func)
223
- func.__init__ = decorate(func.__init__, deprecate)
253
+ # The following line raises this mypy error:
254
+ # Accessing "__init__" on an instance is unsound, since instance.__init__
255
+ # could be from an incompatible subclass [misc]</pre>
256
+ func.__init__ = decorate(func.__init__, deprecate) # type: ignore[misc]
224
257
  return func
225
258
 
226
259
  func = decorate(func, deprecate)
@@ -232,10 +265,10 @@ def deprecated_params(
232
265
  params: str | Iterable[str] | None = None,
233
266
  since: str | None = None,
234
267
  until: str | None = None,
235
- message: str | None = "",
268
+ message: str = "",
236
269
  redirections: None
237
270
  | (Iterable[tuple[str, str] | Callable[..., dict[str, Any]]]) = None,
238
- ) -> Callable:
271
+ ) -> Callable[..., T]:
239
272
  """Decorator to mark parameters of a callable as deprecated.
240
273
 
241
274
  It can also be used to automatically redirect deprecated parameter values to their
@@ -285,10 +318,12 @@ def deprecated_params(
285
318
 
286
319
  from manim.utils.deprecation import deprecated_params
287
320
 
321
+
288
322
  @deprecated_params(params="a, b, c")
289
323
  def foo(**kwargs):
290
324
  pass
291
325
 
326
+
292
327
  foo(x=2, y=3, z=4)
293
328
  # No warning
294
329
 
@@ -299,15 +334,17 @@ def deprecated_params(
299
334
 
300
335
  from manim.utils.deprecation import deprecated_params
301
336
 
337
+
302
338
  @deprecated_params(
303
339
  params="a, b, c",
304
340
  since="v0.2",
305
341
  until="v0.4",
306
- message="The letters x, y, z are cooler."
342
+ message="The letters x, y, z are cooler.",
307
343
  )
308
344
  def foo(**kwargs):
309
345
  pass
310
346
 
347
+
311
348
  foo(a=2)
312
349
  # WARNING The parameter a of method foo has been deprecated since v0.2 and is expected to be removed after v0.4. The letters x, y, z are cooler.
313
350
 
@@ -315,14 +352,18 @@ def deprecated_params(
315
352
 
316
353
  from manim.utils.deprecation import deprecated_params
317
354
 
318
- @deprecated_params(redirections=[
319
- # Two ways to redirect one parameter to another:
320
- ("old_param", "new_param"),
321
- lambda old_param2: {"new_param22": old_param2}
322
- ])
355
+
356
+ @deprecated_params(
357
+ redirections=[
358
+ # Two ways to redirect one parameter to another:
359
+ ("old_param", "new_param"),
360
+ lambda old_param2: {"new_param22": old_param2},
361
+ ]
362
+ )
323
363
  def foo(**kwargs):
324
364
  return kwargs
325
365
 
366
+
326
367
  foo(x=1, old_param=2)
327
368
  # WARNING The parameter old_param of method foo has been deprecated and may be removed in a later version.
328
369
  # returns {"x": 1, "new_param": 2}
@@ -331,12 +372,14 @@ def deprecated_params(
331
372
 
332
373
  from manim.utils.deprecation import deprecated_params
333
374
 
334
- @deprecated_params(redirections=[
335
- lambda runtime_in_ms: {"run_time": runtime_in_ms / 1000}
336
- ])
375
+
376
+ @deprecated_params(
377
+ redirections=[lambda runtime_in_ms: {"run_time": runtime_in_ms / 1000}]
378
+ )
337
379
  def foo(**kwargs):
338
380
  return kwargs
339
381
 
382
+
340
383
  foo(runtime_in_ms=500)
341
384
  # WARNING The parameter runtime_in_ms of method foo has been deprecated and may be removed in a later version.
342
385
  # returns {"run_time": 0.5}
@@ -345,12 +388,14 @@ def deprecated_params(
345
388
 
346
389
  from manim.utils.deprecation import deprecated_params
347
390
 
348
- @deprecated_params(redirections=[
349
- lambda buff_x=1, buff_y=1: {"buff": (buff_x, buff_y)}
350
- ])
391
+
392
+ @deprecated_params(
393
+ redirections=[lambda buff_x=1, buff_y=1: {"buff": (buff_x, buff_y)}]
394
+ )
351
395
  def foo(**kwargs):
352
396
  return kwargs
353
397
 
398
+
354
399
  foo(buff_x=2)
355
400
  # WARNING The parameter buff_x of method foo has been deprecated and may be removed in a later version.
356
401
  # returns {"buff": (2, 1)}
@@ -359,18 +404,23 @@ def deprecated_params(
359
404
 
360
405
  from manim.utils.deprecation import deprecated_params
361
406
 
362
- @deprecated_params(redirections=[
363
- lambda buff=1: {"buff_x": buff[0], "buff_y": buff[1]} if isinstance(buff, tuple)
364
- else {"buff_x": buff, "buff_y": buff}
365
- ])
407
+
408
+ @deprecated_params(
409
+ redirections=[
410
+ lambda buff=1: {"buff_x": buff[0], "buff_y": buff[1]}
411
+ if isinstance(buff, tuple)
412
+ else {"buff_x": buff, "buff_y": buff}
413
+ ]
414
+ )
366
415
  def foo(**kwargs):
367
416
  return kwargs
368
417
 
418
+
369
419
  foo(buff=0)
370
420
  # WARNING The parameter buff of method foo has been deprecated and may be removed in a later version.
371
421
  # returns {"buff_x": 0, buff_y: 0}
372
422
 
373
- foo(buff=(1,2))
423
+ foo(buff=(1, 2))
374
424
  # WARNING The parameter buff of method foo has been deprecated and may be removed in a later version.
375
425
  # returns {"buff_x": 1, buff_y: 2}
376
426
 
@@ -405,7 +455,7 @@ def deprecated_params(
405
455
 
406
456
  redirections = list(redirections)
407
457
 
408
- def warning_msg(func: Callable, used: list[str]):
458
+ def warning_msg(func: Callable[..., T], used: list[str]) -> str:
409
459
  """Generate the deprecation warning message.
410
460
 
411
461
  Parameters
@@ -428,7 +478,7 @@ def deprecated_params(
428
478
  deprecated = _deprecation_text_component(since, until, message)
429
479
  return f"The parameter{parameter_s} {used_} of {what} {name} {has_have_been} {deprecated}"
430
480
 
431
- def redirect_params(kwargs: dict, used: list[str]):
481
+ def redirect_params(kwargs: dict[str, Any], used: list[str]) -> None:
432
482
  """Adjust the keyword arguments as defined by the redirections.
433
483
 
434
484
  Parameters
@@ -452,7 +502,7 @@ def deprecated_params(
452
502
  if len(redirector_args) > 0:
453
503
  kwargs.update(redirector(**redirector_args))
454
504
 
455
- def deprecate_params(func, *args, **kwargs):
505
+ def deprecate_params(func: Callable[..., T], *args: Any, **kwargs: Any) -> T:
456
506
  """The actual decorator function used to extend the callables behavior.
457
507
 
458
508
  Logs a warning message when a deprecated parameter is used and redirects it if
@@ -484,4 +534,4 @@ def deprecated_params(
484
534
  redirect_params(kwargs, used)
485
535
  return func(*args, **kwargs)
486
536
 
487
- return decorator(deprecate_params)
537
+ return decorator(deprecate_params) # type: ignore[return-value]
@@ -0,0 +1,17 @@
1
+ """Utilities for building the Manim documentation.
2
+
3
+ For more information about the Manim documentation building, see:
4
+
5
+ - :doc:`/contributing/development`, specifically the ``Documentation``
6
+ bullet point under :ref:`polishing-changes-and-submitting-a-pull-request`
7
+ - :doc:`/contributing/docs`
8
+
9
+ .. autosummary::
10
+ :toctree: ../reference
11
+
12
+ autoaliasattr_directive
13
+ autocolor_directive
14
+ manim_directive
15
+ module_parsing
16
+
17
+ """