manim 0.17.0__py3-none-any.whl → 0.19.1__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.
- manim/__init__.py +11 -6
- manim/__main__.py +62 -19
- manim/_config/__init__.py +10 -9
- manim/_config/cli_colors.py +26 -9
- manim/_config/default.cfg +1 -3
- manim/_config/logger_utils.py +23 -13
- manim/_config/utils.py +662 -468
- manim/animation/animation.py +164 -18
- manim/animation/changing.py +34 -23
- manim/animation/composition.py +265 -67
- manim/animation/creation.py +208 -26
- manim/animation/fading.py +16 -18
- manim/animation/growing.py +35 -15
- manim/animation/indication.py +150 -76
- manim/animation/movement.py +56 -22
- manim/animation/numbers.py +64 -6
- manim/animation/rotation.py +78 -7
- manim/animation/specialized.py +6 -7
- manim/animation/speedmodifier.py +13 -10
- manim/animation/transform.py +14 -11
- manim/animation/transform_matching_parts.py +3 -4
- manim/animation/updaters/mobject_update_utils.py +152 -30
- manim/animation/updaters/update.py +10 -7
- manim/camera/camera.py +182 -118
- manim/camera/mapping_camera.py +34 -3
- manim/camera/moving_camera.py +95 -74
- manim/camera/multi_camera.py +23 -15
- manim/camera/three_d_camera.py +70 -52
- manim/cli/__init__.py +17 -0
- manim/cli/cfg/group.py +76 -44
- manim/cli/checkhealth/checks.py +192 -0
- manim/cli/checkhealth/commands.py +90 -0
- manim/cli/default_group.py +158 -25
- manim/cli/init/commands.py +33 -25
- manim/cli/plugins/commands.py +16 -3
- manim/cli/render/commands.py +72 -60
- manim/cli/render/ease_of_access_options.py +4 -3
- manim/cli/render/global_options.py +59 -17
- manim/cli/render/output_options.py +6 -5
- manim/cli/render/render_options.py +98 -33
- manim/constants.py +109 -59
- manim/data_structures.py +31 -0
- manim/mobject/frame.py +8 -5
- manim/mobject/geometry/__init__.py +1 -0
- manim/mobject/geometry/arc.py +277 -135
- manim/mobject/geometry/boolean_ops.py +32 -31
- manim/mobject/geometry/labeled.py +376 -0
- manim/mobject/geometry/line.py +192 -87
- manim/mobject/geometry/polygram.py +224 -58
- manim/mobject/geometry/shape_matchers.py +61 -25
- manim/mobject/geometry/tips.py +122 -48
- manim/mobject/graph.py +1027 -419
- manim/mobject/graphing/coordinate_systems.py +533 -278
- manim/mobject/graphing/functions.py +53 -32
- manim/mobject/graphing/number_line.py +123 -65
- manim/mobject/graphing/probability.py +88 -62
- manim/mobject/graphing/scale.py +33 -19
- manim/mobject/logo.py +118 -28
- manim/mobject/matrix.py +87 -83
- manim/mobject/mobject.py +912 -442
- manim/mobject/opengl/dot_cloud.py +16 -5
- manim/mobject/opengl/opengl_compatibility.py +4 -2
- manim/mobject/opengl/opengl_geometry.py +254 -153
- manim/mobject/opengl/opengl_image_mobject.py +3 -1
- manim/mobject/opengl/opengl_mobject.py +779 -482
- manim/mobject/opengl/opengl_point_cloud_mobject.py +41 -14
- manim/mobject/opengl/opengl_surface.py +14 -92
- manim/mobject/opengl/opengl_three_dimensions.py +12 -8
- manim/mobject/opengl/opengl_vectorized_mobject.py +98 -100
- manim/mobject/svg/brace.py +173 -41
- manim/mobject/svg/svg_mobject.py +139 -53
- manim/mobject/table.py +61 -68
- manim/mobject/text/code_mobject.py +193 -539
- manim/mobject/text/numbers.py +81 -34
- manim/mobject/text/tex_mobject.py +130 -78
- manim/mobject/text/text_mobject.py +288 -164
- manim/mobject/three_d/polyhedra.py +111 -13
- manim/mobject/three_d/three_d_utils.py +17 -8
- manim/mobject/three_d/three_dimensions.py +239 -106
- manim/mobject/types/image_mobject.py +50 -30
- manim/mobject/types/point_cloud_mobject.py +120 -75
- manim/mobject/types/vectorized_mobject.py +841 -408
- manim/mobject/value_tracker.py +105 -38
- manim/mobject/vector_field.py +50 -31
- manim/opengl/__init__.py +3 -3
- manim/plugins/__init__.py +14 -1
- manim/plugins/plugins_flags.py +10 -14
- manim/renderer/cairo_renderer.py +65 -50
- manim/renderer/opengl_renderer.py +89 -69
- manim/renderer/opengl_renderer_window.py +39 -18
- manim/renderer/shader.py +123 -87
- manim/renderer/shader_wrapper.py +44 -28
- manim/renderer/vectorized_mobject_rendering.py +38 -10
- manim/scene/moving_camera_scene.py +32 -3
- manim/scene/scene.py +507 -242
- manim/scene/scene_file_writer.py +371 -220
- manim/scene/section.py +20 -16
- manim/scene/three_d_scene.py +14 -22
- manim/scene/vector_space_scene.py +223 -129
- manim/scene/zoomed_scene.py +46 -41
- manim/typing.py +990 -0
- manim/utils/bezier.py +1823 -371
- manim/utils/caching.py +12 -5
- manim/utils/color/AS2700.py +236 -0
- manim/utils/color/BS381.py +318 -0
- manim/utils/color/DVIPSNAMES.py +96 -0
- manim/utils/color/SVGNAMES.py +179 -0
- manim/utils/color/X11.py +533 -0
- manim/utils/color/XKCD.py +952 -0
- manim/utils/color/__init__.py +61 -0
- manim/utils/color/core.py +1667 -0
- manim/utils/color/manim_colors.py +218 -0
- manim/utils/commands.py +48 -20
- manim/utils/config_ops.py +39 -19
- manim/utils/debug.py +8 -7
- manim/utils/deprecation.py +86 -39
- manim/utils/docbuild/__init__.py +17 -0
- manim/utils/docbuild/autoaliasattr_directive.py +236 -0
- manim/utils/docbuild/autocolor_directive.py +99 -0
- manim/utils/docbuild/manim_directive.py +94 -41
- manim/utils/docbuild/module_parsing.py +245 -0
- manim/utils/exceptions.py +6 -0
- manim/utils/family.py +5 -3
- manim/utils/family_ops.py +17 -4
- manim/utils/file_ops.py +27 -17
- manim/utils/hashing.py +55 -45
- manim/utils/images.py +13 -7
- manim/utils/ipython_magic.py +13 -7
- manim/utils/iterables.py +163 -120
- manim/utils/module_ops.py +66 -24
- manim/utils/opengl.py +77 -24
- manim/utils/parameter_parsing.py +32 -0
- manim/utils/paths.py +30 -33
- manim/utils/polylabel.py +235 -0
- manim/utils/qhull.py +218 -0
- manim/utils/rate_functions.py +98 -32
- manim/utils/simple_functions.py +25 -33
- manim/utils/sounds.py +7 -1
- manim/utils/space_ops.py +188 -115
- manim/utils/testing/__init__.py +17 -0
- manim/utils/testing/_frames_testers.py +13 -8
- manim/utils/testing/_show_diff.py +5 -3
- manim/utils/testing/_test_class_makers.py +34 -18
- manim/utils/testing/frames_comparison.py +37 -19
- manim/utils/tex.py +130 -198
- manim/utils/tex_file_writing.py +77 -47
- manim/utils/tex_templates.py +2 -1
- manim/utils/unit.py +6 -5
- {manim-0.17.0.dist-info → manim-0.19.1.dist-info}/METADATA +64 -65
- manim-0.19.1.dist-info/RECORD +220 -0
- {manim-0.17.0.dist-info → manim-0.19.1.dist-info}/WHEEL +1 -1
- manim-0.19.1.dist-info/entry_points.txt +3 -0
- {manim-0.17.0.dist-info → manim-0.19.1.dist-info/licenses}/LICENSE.community +1 -1
- manim/cli/new/group.py +0 -189
- manim/communitycolors.py +0 -9
- manim/gui/__init__.py +0 -0
- manim/gui/gui.py +0 -82
- manim/plugins/import_plugins.py +0 -43
- manim/utils/color.py +0 -552
- manim-0.17.0.dist-info/RECORD +0 -206
- manim-0.17.0.dist-info/entry_points.txt +0 -4
- /manim/cli/{new → checkhealth}/__init__.py +0 -0
- {manim-0.17.0.dist-info → manim-0.19.1.dist-info/licenses}/LICENSE +0 -0
manim/__init__.py
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env python
|
|
2
|
-
|
|
3
|
-
|
|
4
2
|
from __future__ import annotations
|
|
5
3
|
|
|
6
|
-
import
|
|
7
|
-
|
|
8
|
-
__version__: str = pkg_resources.get_distribution(__name__).version
|
|
4
|
+
from importlib.metadata import PackageNotFoundError, version
|
|
9
5
|
|
|
6
|
+
# Use installed distribution version if available; otherwise fall back to a
|
|
7
|
+
# sensible default so that importing from a source checkout works without an
|
|
8
|
+
# editable install (pip install -e .).
|
|
9
|
+
try:
|
|
10
|
+
__version__ = version(__name__)
|
|
11
|
+
except PackageNotFoundError:
|
|
12
|
+
# Package is not installed; provide a fallback version string.
|
|
13
|
+
__version__ = "0.0.0+unknown"
|
|
10
14
|
|
|
11
|
-
import sys
|
|
12
15
|
|
|
13
16
|
# isort: off
|
|
14
17
|
|
|
@@ -20,6 +23,7 @@ from ._config import *
|
|
|
20
23
|
from .utils.commands import *
|
|
21
24
|
|
|
22
25
|
# isort: on
|
|
26
|
+
import numpy as np
|
|
23
27
|
|
|
24
28
|
from .animation.animation import *
|
|
25
29
|
from .animation.changing import *
|
|
@@ -46,6 +50,7 @@ from .constants import *
|
|
|
46
50
|
from .mobject.frame import *
|
|
47
51
|
from .mobject.geometry.arc import *
|
|
48
52
|
from .mobject.geometry.boolean_ops import *
|
|
53
|
+
from .mobject.geometry.labeled import *
|
|
49
54
|
from .mobject.geometry.line import *
|
|
50
55
|
from .mobject.geometry.polygram import *
|
|
51
56
|
from .mobject.geometry.shape_matchers import *
|
manim/__main__.py
CHANGED
|
@@ -1,26 +1,54 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
import sys
|
|
4
|
-
|
|
5
3
|
import click
|
|
6
4
|
import cloup
|
|
7
5
|
|
|
8
|
-
from
|
|
9
|
-
from .
|
|
10
|
-
from .cli.
|
|
11
|
-
from .cli.
|
|
12
|
-
from .cli.
|
|
13
|
-
from .cli.
|
|
14
|
-
from .cli.
|
|
15
|
-
from .
|
|
6
|
+
from manim import __version__
|
|
7
|
+
from manim._config import cli_ctx_settings, console
|
|
8
|
+
from manim.cli.cfg.group import cfg
|
|
9
|
+
from manim.cli.checkhealth.commands import checkhealth
|
|
10
|
+
from manim.cli.default_group import DefaultGroup
|
|
11
|
+
from manim.cli.init.commands import init
|
|
12
|
+
from manim.cli.plugins.commands import plugins
|
|
13
|
+
from manim.cli.render.commands import render
|
|
14
|
+
from manim.constants import EPILOG
|
|
15
|
+
|
|
16
16
|
|
|
17
|
+
def show_splash(ctx: click.Context, param: click.Option, value: str | None) -> None:
|
|
18
|
+
"""When giving a value by console, show an initial message with the Manim
|
|
19
|
+
version before executing any other command: ``Manim Community vA.B.C``.
|
|
17
20
|
|
|
18
|
-
|
|
21
|
+
Parameters
|
|
22
|
+
----------
|
|
23
|
+
ctx
|
|
24
|
+
The Click context.
|
|
25
|
+
param
|
|
26
|
+
A Click option.
|
|
27
|
+
value
|
|
28
|
+
A string value given by console, or None.
|
|
29
|
+
"""
|
|
19
30
|
if value:
|
|
20
|
-
|
|
31
|
+
console.print(f"Manim Community [green]v{__version__}[/green]\n")
|
|
32
|
+
|
|
21
33
|
|
|
34
|
+
def print_version_and_exit(
|
|
35
|
+
ctx: click.Context, param: click.Option, value: str | None
|
|
36
|
+
) -> None:
|
|
37
|
+
"""Same as :func:`show_splash`, but also exit when giving a value by
|
|
38
|
+
console.
|
|
22
39
|
|
|
23
|
-
|
|
40
|
+
Parameters
|
|
41
|
+
----------
|
|
42
|
+
ctx
|
|
43
|
+
The Click context.
|
|
44
|
+
param
|
|
45
|
+
A Click option.
|
|
46
|
+
value
|
|
47
|
+
A string value given by console, or None.
|
|
48
|
+
"""
|
|
49
|
+
show_splash(ctx, param, value)
|
|
50
|
+
if value:
|
|
51
|
+
ctx.exit()
|
|
24
52
|
|
|
25
53
|
|
|
26
54
|
@cloup.group(
|
|
@@ -34,24 +62,39 @@ console.print(f"Manim Community [green]v{__version__}[/green]\n")
|
|
|
34
62
|
"is specified. Run 'manim render --help' if you would like to know what the "
|
|
35
63
|
f"'-ql' or '-p' flags do, for example.\n\n{EPILOG}",
|
|
36
64
|
)
|
|
37
|
-
@
|
|
65
|
+
@cloup.option(
|
|
38
66
|
"--version",
|
|
39
67
|
is_flag=True,
|
|
40
68
|
help="Show version and exit.",
|
|
41
|
-
callback=
|
|
69
|
+
callback=print_version_and_exit,
|
|
42
70
|
is_eager=True,
|
|
43
71
|
expose_value=False,
|
|
44
72
|
)
|
|
45
|
-
@click.
|
|
46
|
-
|
|
47
|
-
|
|
73
|
+
@click.option(
|
|
74
|
+
"--show-splash/--hide-splash",
|
|
75
|
+
is_flag=True,
|
|
76
|
+
default=True,
|
|
77
|
+
help="Print splash message with version information.",
|
|
78
|
+
callback=show_splash,
|
|
79
|
+
is_eager=True,
|
|
80
|
+
expose_value=False,
|
|
81
|
+
)
|
|
82
|
+
@cloup.pass_context
|
|
83
|
+
def main(ctx: click.Context) -> None:
|
|
84
|
+
"""The entry point for Manim.
|
|
85
|
+
|
|
86
|
+
Parameters
|
|
87
|
+
----------
|
|
88
|
+
ctx
|
|
89
|
+
The Click context.
|
|
90
|
+
"""
|
|
48
91
|
pass
|
|
49
92
|
|
|
50
93
|
|
|
94
|
+
main.add_command(checkhealth)
|
|
51
95
|
main.add_command(cfg)
|
|
52
96
|
main.add_command(plugins)
|
|
53
97
|
main.add_command(init)
|
|
54
|
-
main.add_command(new)
|
|
55
98
|
main.add_command(render)
|
|
56
99
|
|
|
57
100
|
if __name__ == "__main__":
|
manim/_config/__init__.py
CHANGED
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import logging
|
|
6
|
-
from
|
|
6
|
+
from collections.abc import Generator
|
|
7
|
+
from contextlib import contextmanager
|
|
8
|
+
from typing import Any
|
|
7
9
|
|
|
8
10
|
from .cli_colors import parse_cli_ctx
|
|
9
11
|
from .logger_utils import make_logger
|
|
@@ -20,12 +22,10 @@ __all__ = [
|
|
|
20
22
|
]
|
|
21
23
|
|
|
22
24
|
parser = make_config_parser()
|
|
23
|
-
logger: logging.Logger
|
|
24
25
|
|
|
25
|
-
#
|
|
26
|
-
#
|
|
27
|
-
#
|
|
28
|
-
# Use error_console to print errors so that it outputs to stderr.
|
|
26
|
+
# Logger usage: accessible globally as `manim.logger` or via `logging.getLogger("manim")`.
|
|
27
|
+
# For printing, use `manim.console.print()` instead of the built-in `print()`.
|
|
28
|
+
# For error output, use `error_console`, which prints to stderr.
|
|
29
29
|
logger, console, error_console = make_logger(
|
|
30
30
|
parser["logger"],
|
|
31
31
|
parser["CLI"]["verbosity"],
|
|
@@ -36,13 +36,15 @@ logging.getLogger("PIL").setLevel(logging.INFO)
|
|
|
36
36
|
logging.getLogger("matplotlib").setLevel(logging.INFO)
|
|
37
37
|
|
|
38
38
|
config = ManimConfig().digest_parser(parser)
|
|
39
|
+
# TODO: to be used in the future - see PR #620
|
|
40
|
+
# https://github.com/ManimCommunity/manim/pull/620
|
|
39
41
|
frame = ManimFrame(config)
|
|
40
42
|
|
|
41
43
|
|
|
42
44
|
# This has to go here because it needs access to this module's config
|
|
43
45
|
@contextmanager
|
|
44
|
-
def tempconfig(temp: ManimConfig | dict) ->
|
|
45
|
-
"""
|
|
46
|
+
def tempconfig(temp: ManimConfig | dict[str, Any]) -> Generator[None, None, None]:
|
|
47
|
+
"""Temporarily modifies the global ``config`` object using a context manager.
|
|
46
48
|
|
|
47
49
|
Inside the ``with`` statement, the modified config will be used. After
|
|
48
50
|
context manager exits, the config will be restored to its original state.
|
|
@@ -65,7 +67,6 @@ def tempconfig(temp: ManimConfig | dict) -> _GeneratorContextManager:
|
|
|
65
67
|
8.0
|
|
66
68
|
>>> with tempconfig({"frame_height": 100.0}):
|
|
67
69
|
... print(config["frame_height"])
|
|
68
|
-
...
|
|
69
70
|
100.0
|
|
70
71
|
>>> config["frame_height"]
|
|
71
72
|
8.0
|
manim/_config/cli_colors.py
CHANGED
|
@@ -1,10 +1,21 @@
|
|
|
1
|
+
"""Parses CLI context settings from the configuration file and returns a Cloup Context settings dictionary.
|
|
2
|
+
|
|
3
|
+
This module reads configuration values for help formatting, theme styles, and alignment options
|
|
4
|
+
used when rendering command-line interfaces in Manim.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
1
9
|
import configparser
|
|
10
|
+
from typing import Any
|
|
2
11
|
|
|
3
12
|
from cloup import Context, HelpFormatter, HelpTheme, Style
|
|
4
13
|
|
|
14
|
+
__all__ = ["parse_cli_ctx"]
|
|
5
15
|
|
|
6
|
-
|
|
7
|
-
|
|
16
|
+
|
|
17
|
+
def parse_cli_ctx(parser: configparser.SectionProxy) -> dict[str, Any]:
|
|
18
|
+
formatter_settings: dict[str, str | int | None] = {
|
|
8
19
|
"indent_increment": int(parser["indent_increment"]),
|
|
9
20
|
"width": int(parser["width"]),
|
|
10
21
|
"col1_max_width": int(parser["col1_max_width"]),
|
|
@@ -23,6 +34,7 @@ def parse_cli_ctx(parser: configparser.ConfigParser) -> Context:
|
|
|
23
34
|
"col2",
|
|
24
35
|
"epilog",
|
|
25
36
|
}
|
|
37
|
+
# Extract and apply any style-related keys defined in the config section.
|
|
26
38
|
for k, v in parser.items():
|
|
27
39
|
if k in theme_keys and v:
|
|
28
40
|
theme_settings.update({k: Style(v)})
|
|
@@ -30,21 +42,26 @@ def parse_cli_ctx(parser: configparser.ConfigParser) -> Context:
|
|
|
30
42
|
formatter = {}
|
|
31
43
|
theme = parser["theme"] if parser["theme"] else None
|
|
32
44
|
if theme is None:
|
|
33
|
-
formatter = HelpFormatter
|
|
34
|
-
theme=HelpTheme(**theme_settings),
|
|
45
|
+
formatter = HelpFormatter.settings(
|
|
46
|
+
theme=HelpTheme(**theme_settings),
|
|
47
|
+
**formatter_settings,
|
|
35
48
|
)
|
|
36
49
|
elif theme.lower() == "dark":
|
|
37
|
-
formatter = HelpFormatter
|
|
38
|
-
theme=HelpTheme.dark().with_(**theme_settings),
|
|
50
|
+
formatter = HelpFormatter.settings(
|
|
51
|
+
theme=HelpTheme.dark().with_(**theme_settings),
|
|
52
|
+
**formatter_settings,
|
|
39
53
|
)
|
|
40
54
|
elif theme.lower() == "light":
|
|
41
|
-
formatter = HelpFormatter
|
|
42
|
-
theme=HelpTheme.light().with_(**theme_settings),
|
|
55
|
+
formatter = HelpFormatter.settings(
|
|
56
|
+
theme=HelpTheme.light().with_(**theme_settings),
|
|
57
|
+
**formatter_settings,
|
|
43
58
|
)
|
|
44
59
|
|
|
45
|
-
|
|
60
|
+
return_val: dict[str, Any] = Context.settings(
|
|
46
61
|
align_option_groups=parser["align_option_groups"].lower() == "true",
|
|
47
62
|
align_sections=parser["align_sections"].lower() == "true",
|
|
48
63
|
show_constraints=True,
|
|
49
64
|
formatter_settings=formatter,
|
|
50
65
|
)
|
|
66
|
+
|
|
67
|
+
return return_val
|
manim/_config/default.cfg
CHANGED
|
@@ -221,9 +221,7 @@ repr_number = green
|
|
|
221
221
|
# Uncomment the following line to manually set the loglevel for ffmpeg. See
|
|
222
222
|
# ffmpeg manpage for accepted values
|
|
223
223
|
loglevel = ERROR
|
|
224
|
-
# defaults to the one present in path
|
|
225
|
-
ffmpeg_executable = ffmpeg
|
|
226
224
|
|
|
227
225
|
[jupyter]
|
|
228
|
-
media_embed =
|
|
226
|
+
media_embed = False
|
|
229
227
|
media_width = 60%%
|
manim/_config/logger_utils.py
CHANGED
|
@@ -9,14 +9,14 @@ Both ``logger`` and ``console`` use the ``rich`` library to produce rich text
|
|
|
9
9
|
format.
|
|
10
10
|
|
|
11
11
|
"""
|
|
12
|
+
|
|
12
13
|
from __future__ import annotations
|
|
13
14
|
|
|
14
15
|
import configparser
|
|
15
16
|
import copy
|
|
16
17
|
import json
|
|
17
18
|
import logging
|
|
18
|
-
import
|
|
19
|
-
from typing import TYPE_CHECKING
|
|
19
|
+
from typing import TYPE_CHECKING, Any
|
|
20
20
|
|
|
21
21
|
from rich import color, errors
|
|
22
22
|
from rich import print as printf
|
|
@@ -26,6 +26,9 @@ from rich.theme import Theme
|
|
|
26
26
|
|
|
27
27
|
if TYPE_CHECKING:
|
|
28
28
|
from pathlib import Path
|
|
29
|
+
|
|
30
|
+
__all__ = ["make_logger", "parse_theme", "set_file_logger", "JSONFormatter"]
|
|
31
|
+
|
|
29
32
|
HIGHLIGHTED_KEYWORDS = [ # these keywords are highlighted specially
|
|
30
33
|
"Played",
|
|
31
34
|
"animations",
|
|
@@ -49,9 +52,9 @@ Loading the default color configuration.[/logging.level.error]
|
|
|
49
52
|
|
|
50
53
|
|
|
51
54
|
def make_logger(
|
|
52
|
-
parser: configparser.
|
|
55
|
+
parser: configparser.SectionProxy,
|
|
53
56
|
verbosity: str,
|
|
54
|
-
) -> tuple[logging.Logger, Console]:
|
|
57
|
+
) -> tuple[logging.Logger, Console, Console]:
|
|
55
58
|
"""Make the manim logger and console.
|
|
56
59
|
|
|
57
60
|
Parameters
|
|
@@ -83,25 +86,29 @@ def make_logger(
|
|
|
83
86
|
theme = parse_theme(parser)
|
|
84
87
|
console = Console(theme=theme)
|
|
85
88
|
|
|
86
|
-
|
|
87
|
-
error_console = Console(theme=theme, file=sys.stderr)
|
|
89
|
+
error_console = Console(theme=theme, stderr=True)
|
|
88
90
|
|
|
89
91
|
# set the rich handler
|
|
90
|
-
RichHandler.KEYWORDS = HIGHLIGHTED_KEYWORDS
|
|
91
92
|
rich_handler = RichHandler(
|
|
92
93
|
console=console,
|
|
93
|
-
show_time=parser.getboolean("log_timestamps"),
|
|
94
|
+
show_time=parser.getboolean("log_timestamps", fallback=False),
|
|
95
|
+
keywords=HIGHLIGHTED_KEYWORDS,
|
|
94
96
|
)
|
|
95
97
|
|
|
96
98
|
# finally, the logger
|
|
97
99
|
logger = logging.getLogger("manim")
|
|
98
100
|
logger.addHandler(rich_handler)
|
|
99
101
|
logger.setLevel(verbosity)
|
|
102
|
+
logger.propagate = False
|
|
103
|
+
|
|
104
|
+
if not (libav_logger := logging.getLogger()).hasHandlers():
|
|
105
|
+
libav_logger.addHandler(rich_handler)
|
|
106
|
+
libav_logger.setLevel(verbosity)
|
|
100
107
|
|
|
101
108
|
return logger, console, error_console
|
|
102
109
|
|
|
103
110
|
|
|
104
|
-
def parse_theme(parser: configparser.
|
|
111
|
+
def parse_theme(parser: configparser.SectionProxy) -> Theme | None:
|
|
105
112
|
"""Configure the rich style of logger and console output.
|
|
106
113
|
|
|
107
114
|
Parameters
|
|
@@ -119,7 +126,7 @@ def parse_theme(parser: configparser.ConfigParser) -> Theme:
|
|
|
119
126
|
:func:`make_logger`.
|
|
120
127
|
|
|
121
128
|
"""
|
|
122
|
-
theme = {key.replace("_", "."): parser[key] for key in parser}
|
|
129
|
+
theme: dict[str, Any] = {key.replace("_", "."): parser[key] for key in parser}
|
|
123
130
|
|
|
124
131
|
theme["log.width"] = None if theme["log.width"] == "-1" else int(theme["log.width"])
|
|
125
132
|
theme["log.height"] = (
|
|
@@ -177,12 +184,15 @@ class JSONFormatter(logging.Formatter):
|
|
|
177
184
|
|
|
178
185
|
"""
|
|
179
186
|
|
|
180
|
-
def format(self, record:
|
|
187
|
+
def format(self, record: logging.LogRecord) -> str:
|
|
181
188
|
"""Format the record in a custom JSON format."""
|
|
182
189
|
record_c = copy.deepcopy(record)
|
|
183
190
|
if record_c.args:
|
|
184
|
-
|
|
185
|
-
record_c.args
|
|
191
|
+
if isinstance(record_c.args, dict):
|
|
192
|
+
for arg in record_c.args:
|
|
193
|
+
record_c.args[arg] = "<>"
|
|
194
|
+
else:
|
|
195
|
+
record_c.args = ("<>",) * len(record_c.args)
|
|
186
196
|
return json.dumps(
|
|
187
197
|
{
|
|
188
198
|
"levelname": record_c.levelname,
|