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
@@ -1,28 +1,59 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import logging
3
4
  import re
5
+ import sys
4
6
  from typing import TYPE_CHECKING
5
7
 
6
- import click
7
- from cloup import option, option_group
8
-
9
- from ... import logger
8
+ from cloup import Choice, option, option_group
10
9
 
11
10
  if TYPE_CHECKING:
12
- from cloup._option_groups import OptionGroupDecorator
11
+ from click import Context, Option
12
+
13
+ __all__ = ["global_options"]
14
+
15
+ logger = logging.getLogger("manim")
16
+
17
+
18
+ def validate_gui_location(
19
+ ctx: Context, param: Option, value: str | None
20
+ ) -> tuple[int, int] | None:
21
+ """If the ``value`` string is given, extract from it the GUI location,
22
+ which should be in any of these formats: 'x;y', 'x,y' or 'x-y'.
13
23
 
24
+ Parameters
25
+ ----------
26
+ ctx
27
+ The Click context.
28
+ param
29
+ A Click option.
30
+ value
31
+ The optional string which will be parsed.
14
32
 
15
- def validate_gui_location(ctx, param, value):
16
- if value:
17
- try:
18
- x_offset, y_offset = map(int, re.split(r"[;,\-]", value))
19
- return (x_offset, y_offset)
20
- except Exception:
21
- logger.error("GUI location option is invalid.")
22
- exit()
33
+ Returns
34
+ -------
35
+ tuple[int, int] | None
36
+ If ``value`` is ``None``, the return value is ``None``. Otherwise, it's
37
+ the ``(x, y)`` location for the GUI.
23
38
 
39
+ Raises
40
+ ------
41
+ ValueError
42
+ If ``value`` has an invalid format.
43
+ """
44
+ if value is None:
45
+ return None
24
46
 
25
- global_options: OptionGroupDecorator = option_group(
47
+ try:
48
+ x_offset, y_offset = map(int, re.split(r"[;,\-]", value))
49
+ except Exception:
50
+ logger.error("GUI location option is invalid.")
51
+ sys.exit()
52
+
53
+ return (x_offset, y_offset)
54
+
55
+
56
+ global_options = option_group(
26
57
  "Global options",
27
58
  option(
28
59
  "-c",
@@ -53,7 +84,7 @@ global_options: OptionGroupDecorator = option_group(
53
84
  option(
54
85
  "-v",
55
86
  "--verbosity",
56
- type=click.Choice(
87
+ type=Choice(
57
88
  ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"],
58
89
  case_sensitive=False,
59
90
  ),
@@ -108,4 +139,9 @@ global_options: OptionGroupDecorator = option_group(
108
139
  help="Prevents deletion of .aux, .dvi, and .log files produced by Tex and MathTex.",
109
140
  default=False,
110
141
  ),
142
+ option(
143
+ "--preview_command",
144
+ help="The command used to preview the output file (for example vlc for video files)",
145
+ default="",
146
+ ),
111
147
  )
@@ -1,7 +1,8 @@
1
1
  from __future__ import annotations
2
2
 
3
- import click
4
- from cloup import option, option_group
3
+ from cloup import IntRange, Path, option, option_group
4
+
5
+ __all__ = ["output_options"]
5
6
 
6
7
  output_options = option_group(
7
8
  "Output options",
@@ -15,7 +16,7 @@ output_options = option_group(
15
16
  option(
16
17
  "-0",
17
18
  "--zero_pad",
18
- type=click.IntRange(0, 9),
19
+ type=IntRange(0, 9),
19
20
  default=None,
20
21
  help="Zero padding for PNG file names.",
21
22
  ),
@@ -27,13 +28,13 @@ output_options = option_group(
27
28
  ),
28
29
  option(
29
30
  "--media_dir",
30
- type=click.Path(),
31
+ type=Path(),
31
32
  default=None,
32
33
  help="Path to store rendered videos and latex.",
33
34
  ),
34
35
  option(
35
36
  "--log_dir",
36
- type=click.Path(),
37
+ type=Path(),
37
38
  help="Path to store render logs.",
38
39
  default=None,
39
40
  ),
@@ -1,39 +1,105 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import logging
3
4
  import re
5
+ import sys
6
+ from typing import TYPE_CHECKING
4
7
 
5
- import click
6
- from cloup import option, option_group
8
+ from cloup import Choice, option, option_group
7
9
 
8
10
  from manim.constants import QUALITIES, RendererType
9
11
 
10
- from ... import logger
12
+ if TYPE_CHECKING:
13
+ from click import Context, Option
11
14
 
15
+ __all__ = ["render_options"]
16
+
17
+ logger = logging.getLogger("manim")
18
+
19
+
20
+ def validate_scene_range(
21
+ ctx: Context, param: Option, value: str | None
22
+ ) -> tuple[int] | tuple[int, int] | None:
23
+ """If the ``value`` string is given, extract from it the scene range, which
24
+ should be in any of these formats: 'start', 'start;end', 'start,end' or
25
+ 'start-end'. Otherwise, return ``None``.
26
+
27
+ Parameters
28
+ ----------
29
+ ctx
30
+ The Click context.
31
+ param
32
+ A Click option.
33
+ value
34
+ The optional string which will be parsed.
35
+
36
+ Returns
37
+ -------
38
+ tuple[int] | tuple[int, int] | None
39
+ If ``value`` is ``None``, the return value is ``None``. Otherwise, it's
40
+ the scene range, given by a tuple which may contain a single value
41
+ ``start`` or two values ``start`` and ``end``.
42
+
43
+ Raises
44
+ ------
45
+ ValueError
46
+ If ``value`` has an invalid format.
47
+ """
48
+ if value is None:
49
+ return None
12
50
 
13
- def validate_scene_range(ctx, param, value):
14
51
  try:
15
52
  start = int(value)
16
53
  return (start,)
17
54
  except Exception:
18
55
  pass
19
56
 
20
- if value:
21
- try:
22
- start, end = map(int, re.split(r"[;,\-]", value))
23
- return start, end
24
- except Exception:
25
- logger.error("Couldn't determine a range for -n option.")
26
- exit()
57
+ try:
58
+ start, end = map(int, re.split(r"[;,\-]", value))
59
+ except Exception:
60
+ logger.error("Couldn't determine a range for -n option.")
61
+ sys.exit()
62
+
63
+ return start, end
64
+
65
+
66
+ def validate_resolution(
67
+ ctx: Context, param: Option, value: str | None
68
+ ) -> tuple[int, int] | None:
69
+ """If the ``value`` string is given, extract from it the resolution, which
70
+ should be in any of these formats: 'W;H', 'W,H' or 'W-H'. Otherwise, return
71
+ ``None``.
72
+
73
+ Parameters
74
+ ----------
75
+ ctx
76
+ The Click context.
77
+ param
78
+ A Click option.
79
+ value
80
+ The optional string which will be parsed.
81
+
82
+ Returns
83
+ -------
84
+ tuple[int, int] | None
85
+ If ``value`` is ``None``, the return value is ``None``. Otherwise, it's
86
+ the resolution as a ``(W, H)`` tuple.
87
+
88
+ Raises
89
+ ------
90
+ ValueError
91
+ If ``value`` has an invalid format.
92
+ """
93
+ if value is None:
94
+ return None
27
95
 
96
+ try:
97
+ width, height = map(int, re.split(r"[;,\-]", value))
98
+ except Exception:
99
+ logger.error("Resolution option is invalid.")
100
+ sys.exit()
28
101
 
29
- def validate_resolution(ctx, param, value):
30
- if value:
31
- try:
32
- start, end = map(int, re.split(r"[;,\-]", value))
33
- return (start, end)
34
- except Exception:
35
- logger.error("Resolution option is invalid.")
36
- exit()
102
+ return width, height
37
103
 
38
104
 
39
105
  render_options = option_group(
@@ -55,23 +121,29 @@ render_options = option_group(
55
121
  ),
56
122
  option(
57
123
  "--format",
58
- type=click.Choice(["png", "gif", "mp4", "webm", "mov"], case_sensitive=False),
124
+ type=Choice(["png", "gif", "mp4", "webm", "mov"], case_sensitive=False),
125
+ default=None,
126
+ ),
127
+ option(
128
+ "-s",
129
+ "--save_last_frame",
59
130
  default=None,
131
+ is_flag=True,
132
+ help="Render and save only the last frame of a scene as a PNG image.",
60
133
  ),
61
- option("-s", "--save_last_frame", is_flag=True, default=None),
62
134
  option(
63
135
  "-q",
64
136
  "--quality",
65
137
  default=None,
66
- type=click.Choice(
67
- list(reversed([q["flag"] for q in QUALITIES.values() if q["flag"]])), # type: ignore
138
+ type=Choice(
139
+ list(reversed([q["flag"] for q in QUALITIES.values() if q["flag"]])),
68
140
  case_sensitive=False,
69
141
  ),
70
142
  help="Render quality at the follow resolution framerates, respectively: "
71
143
  + ", ".join(
72
144
  reversed(
73
145
  [
74
- f'{q["pixel_width"]}x{q["pixel_height"]} {q["frame_rate"]}FPS'
146
+ f"{q['pixel_width']}x{q['pixel_height']} {q['frame_rate']}FPS"
75
147
  for q in QUALITIES.values()
76
148
  if q["flag"]
77
149
  ]
@@ -95,7 +167,7 @@ render_options = option_group(
95
167
  ),
96
168
  option(
97
169
  "--renderer",
98
- type=click.Choice(
170
+ type=Choice(
99
171
  [renderer_type.value for renderer_type in RendererType],
100
172
  case_sensitive=False,
101
173
  ),
@@ -122,13 +194,6 @@ render_options = option_group(
122
194
  is_flag=True,
123
195
  help="Save section videos in addition to movie file.",
124
196
  ),
125
- option(
126
- "-s",
127
- "--save_last_frame",
128
- default=None,
129
- is_flag=True,
130
- help="Save last frame as png (Deprecated).",
131
- ),
132
197
  option(
133
198
  "-t",
134
199
  "--transparent",
manim/constants.py CHANGED
@@ -1,16 +1,15 @@
1
- """
2
- Constant definitions.
3
- """
1
+ """Constant definitions."""
4
2
 
5
3
  from __future__ import annotations
6
4
 
7
5
  from enum import Enum
6
+ from typing import TypedDict
8
7
 
9
8
  import numpy as np
10
9
  from cloup import Context
11
10
  from PIL.Image import Resampling
12
11
 
13
- from manim.typing import Vector3
12
+ from manim.typing import Vector3D
14
13
 
15
14
  __all__ = [
16
15
  "SCENE_NOT_FOUND_MESSAGE",
@@ -76,6 +75,7 @@ __all__ = [
76
75
  "CTRL_VALUE",
77
76
  "RendererType",
78
77
  "LineJointType",
78
+ "CapStyleType",
79
79
  ]
80
80
  # Messages
81
81
 
@@ -122,43 +122,43 @@ RESAMPLING_ALGORITHMS = {
122
122
  }
123
123
 
124
124
  # Geometry: directions
125
- ORIGIN: Vector3 = np.array((0.0, 0.0, 0.0))
125
+ ORIGIN: Vector3D = np.array((0.0, 0.0, 0.0))
126
126
  """The center of the coordinate system."""
127
127
 
128
- UP: Vector3 = np.array((0.0, 1.0, 0.0))
128
+ UP: Vector3D = np.array((0.0, 1.0, 0.0))
129
129
  """One unit step in the positive Y direction."""
130
130
 
131
- DOWN: Vector3 = np.array((0.0, -1.0, 0.0))
131
+ DOWN: Vector3D = np.array((0.0, -1.0, 0.0))
132
132
  """One unit step in the negative Y direction."""
133
133
 
134
- RIGHT: Vector3 = np.array((1.0, 0.0, 0.0))
134
+ RIGHT: Vector3D = np.array((1.0, 0.0, 0.0))
135
135
  """One unit step in the positive X direction."""
136
136
 
137
- LEFT: Vector3 = np.array((-1.0, 0.0, 0.0))
137
+ LEFT: Vector3D = np.array((-1.0, 0.0, 0.0))
138
138
  """One unit step in the negative X direction."""
139
139
 
140
- IN: Vector3 = np.array((0.0, 0.0, -1.0))
140
+ IN: Vector3D = np.array((0.0, 0.0, -1.0))
141
141
  """One unit step in the negative Z direction."""
142
142
 
143
- OUT: Vector3 = np.array((0.0, 0.0, 1.0))
143
+ OUT: Vector3D = np.array((0.0, 0.0, 1.0))
144
144
  """One unit step in the positive Z direction."""
145
145
 
146
146
  # Geometry: axes
147
- X_AXIS: Vector3 = np.array((1.0, 0.0, 0.0))
148
- Y_AXIS: Vector3 = np.array((0.0, 1.0, 0.0))
149
- Z_AXIS: Vector3 = np.array((0.0, 0.0, 1.0))
147
+ X_AXIS: Vector3D = np.array((1.0, 0.0, 0.0))
148
+ Y_AXIS: Vector3D = np.array((0.0, 1.0, 0.0))
149
+ Z_AXIS: Vector3D = np.array((0.0, 0.0, 1.0))
150
150
 
151
151
  # Geometry: useful abbreviations for diagonals
152
- UL: Vector3 = UP + LEFT
152
+ UL: Vector3D = UP + LEFT
153
153
  """One step up plus one step left."""
154
154
 
155
- UR: Vector3 = UP + RIGHT
155
+ UR: Vector3D = UP + RIGHT
156
156
  """One step up plus one step right."""
157
157
 
158
- DL: Vector3 = DOWN + LEFT
158
+ DL: Vector3D = DOWN + LEFT
159
159
  """One step down plus one step left."""
160
160
 
161
- DR: Vector3 = DOWN + RIGHT
161
+ DR: Vector3D = DOWN + RIGHT
162
162
  """One step down plus one step right."""
163
163
 
164
164
  # Geometry
@@ -198,8 +198,16 @@ TAU = 2 * PI
198
198
  DEGREES = TAU / 360
199
199
  """The exchange rate between radians and degrees."""
200
200
 
201
+
202
+ class QualityDict(TypedDict):
203
+ flag: str | None
204
+ pixel_height: int
205
+ pixel_width: int
206
+ frame_rate: int
207
+
208
+
201
209
  # Video qualities
202
- QUALITIES: dict[str, dict[str, str | int | None]] = {
210
+ QUALITIES: dict[str, QualityDict] = {
203
211
  "fourk_quality": {
204
212
  "flag": "k",
205
213
  "pixel_height": 2160,
@@ -305,3 +313,41 @@ class LineJointType(Enum):
305
313
  ROUND = 1
306
314
  BEVEL = 2
307
315
  MITER = 3
316
+
317
+
318
+ class CapStyleType(Enum):
319
+ """Collection of available cap styles.
320
+
321
+ See the example below for a visual illustration of the different
322
+ cap styles.
323
+
324
+ Examples
325
+ --------
326
+
327
+ .. manim:: CapStyleVariants
328
+ :save_last_frame:
329
+
330
+ class CapStyleVariants(Scene):
331
+ def construct(self):
332
+ arcs = VGroup(*[
333
+ Arc(
334
+ radius=1,
335
+ start_angle=0,
336
+ angle=TAU / 4,
337
+ stroke_width=20,
338
+ color=GREEN,
339
+ cap_style=cap_style,
340
+ )
341
+ for cap_style in CapStyleType
342
+ ])
343
+ arcs.arrange(RIGHT, buff=1)
344
+ self.add(arcs)
345
+ for arc in arcs:
346
+ label = Text(arc.cap_style.name, font_size=24).next_to(arc, DOWN)
347
+ self.add(label)
348
+ """
349
+
350
+ AUTO = 0
351
+ ROUND = 1
352
+ BUTT = 2
353
+ SQUARE = 3
manim/gui/gui.py CHANGED
@@ -13,6 +13,8 @@ except ImportError:
13
13
  from .. import __version__, config
14
14
  from ..utils.module_ops import scene_classes_from_file
15
15
 
16
+ __all__ = ["configure_pygui"]
17
+
16
18
  if dearpygui_imported:
17
19
  dpg.create_context()
18
20
  window = dpg.generate_uuid()
manim/mobject/frame.py CHANGED
@@ -24,7 +24,6 @@ class ScreenRectangle(Rectangle):
24
24
  When set, the width is stretched to accommodate
25
25
  the new aspect ratio.
26
26
  """
27
-
28
27
  return self.width / self.height
29
28
 
30
29
  @aspect_ratio.setter