Skip to content

Commit d6f7653

Browse files
authored
Merge pull request #543 from ManimCommunity/refactor-config-subpkg
Refactor config subpkg
2 parents d586b11 + 182ff88 commit d6f7653

File tree

13 files changed

+794
-616
lines changed

13 files changed

+794
-616
lines changed

manim/__main__.py

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,16 @@
33
import sys
44
import traceback
55

6-
from . import logger, file_writer_config
7-
from .config.config import camera_config, args
8-
from .config import cfg_subcmds
9-
from .utils.module_ops import (
6+
from manim import constants, logger, console, config, file_writer_config
7+
from manim import Scene
8+
from manim.utils.module_ops import (
109
get_module,
1110
get_scene_classes_from_module,
1211
get_scenes_to_render,
1312
)
14-
from .utils.file_ops import open_file as open_media_file
15-
from .grpc.impl import frame_server_impl
13+
from manim.utils.file_ops import open_file as open_media_file
14+
from manim.grpc.impl import frame_server_impl
15+
from manim.config.main_utils import *
1616

1717

1818
def open_file_if_needed(file_writer):
@@ -49,26 +49,38 @@ def open_file_if_needed(file_writer):
4949

5050

5151
def main():
52-
if hasattr(args, "subcommands"):
53-
if "cfg" in args.subcommands:
54-
if args.cfg_subcommand is not None:
55-
subcommand = args.cfg_subcommand
56-
if subcommand == "write":
52+
args = parse_args(sys.argv)
53+
54+
if hasattr(args, "cmd"):
55+
if args.cmd == "cfg":
56+
if args.subcmd:
57+
from manim.config import cfg_subcmds
58+
59+
if args.subcmd == "write":
5760
cfg_subcmds.write(args.level, args.open)
58-
elif subcommand == "show":
61+
elif args.subcmd == "show":
5962
cfg_subcmds.show()
60-
elif subcommand == "export":
63+
elif args.subcmd == "export":
6164
cfg_subcmds.export(args.dir)
6265
else:
63-
logger.error("No argument provided; Exiting...")
66+
logger.error("No subcommand provided; Exiting...")
67+
68+
# elif args.cmd == "some_other_cmd":
69+
# something_else_here()
6470

6571
else:
72+
update_config_with_cli(args)
73+
init_dirs(file_writer_config)
74+
75+
if file_writer_config["log_to_file"]:
76+
set_file_logger()
77+
6678
module = get_module(file_writer_config["input_file"])
6779
all_scene_classes = get_scene_classes_from_module(module)
6880
scene_classes_to_render = get_scenes_to_render(all_scene_classes)
6981
for SceneClass in scene_classes_to_render:
7082
try:
71-
if camera_config["use_js_renderer"]:
83+
if config["use_js_renderer"]:
7284
frame_server_impl.get(SceneClass).start()
7385
else:
7486
scene = SceneClass()

manim/config/__init__.py

Lines changed: 67 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,73 @@
1-
# Note that the global config dict is called 'config', just like the module
2-
# itself. That's why we import the module first with a different name
3-
# (_config), and then the dict.
4-
from . import config as _config
5-
from .config import config, tempconfig, file_writer_config, camera_config
6-
from .logger import logger, console
1+
import logging
2+
from contextlib import contextmanager
3+
4+
from .utils import make_config_parser, make_logger, make_config, make_file_writer_config
75

86
__all__ = [
9-
"_config",
7+
"logger",
8+
"console",
109
"config",
11-
"tempconfig",
1210
"file_writer_config",
1311
"camera_config",
14-
"logger",
15-
"console",
12+
"tempconfig",
1613
]
14+
15+
parser = make_config_parser()
16+
17+
# The logger can be accessed from anywhere as manim.logger, or as
18+
# logging.getLogger("manim"). The console must be accessed as manim.console.
19+
# Throughout the codebase, use manim.console.print() instead of print().
20+
logger, console = make_logger(parser["logger"], parser["CLI"]["verbosity"])
21+
# TODO: temporary to have a clean terminal output when working with PIL or matplotlib
22+
logging.getLogger("PIL").setLevel(logging.INFO)
23+
logging.getLogger("matplotlib").setLevel(logging.INFO)
24+
25+
config = make_config(parser)
26+
camera_config = config
27+
file_writer_config = make_file_writer_config(parser, config)
28+
29+
30+
# This has to go here because it needs access to this module's config
31+
@contextmanager
32+
def tempconfig(temp):
33+
"""Context manager that temporarily modifies the global config dict.
34+
35+
The code block inside the ``with`` statement will use the modified config.
36+
After the code block, the config will be restored to its original value.
37+
38+
Parameters
39+
----------
40+
41+
temp : :class:`dict`
42+
A dictionary whose keys will be used to temporarily update the global
43+
config.
44+
45+
Examples
46+
--------
47+
Use ``with tempconfig({...})`` to temporarily change the default values of
48+
certain objects.
49+
50+
.. code_block:: python
51+
52+
c = Camera()
53+
c.frame_width == config['frame_width'] # -> True
54+
with tempconfig({'frame_width': 100}):
55+
c = Camera()
56+
c.frame_width == config['frame_width'] # -> False
57+
c.frame_width == 100 # -> True
58+
59+
"""
60+
global config
61+
original = config.copy()
62+
63+
temp = {k: v for k, v in temp.items() if k in original}
64+
65+
# In order to change the config that every module has acces to, use
66+
# update(), DO NOT use assignment. Assigning config = some_dict will just
67+
# make the local variable named config point to a new dictionary, it will
68+
# NOT change the dictionary that every module has a reference to.
69+
config.update(temp)
70+
try:
71+
yield
72+
finally:
73+
config.update(original) # update, not assignment!

manim/config/cfg_subcmds.py

Lines changed: 24 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,22 @@
66
The functions below can be called via the `manim cfg` subcommand.
77
88
"""
9+
910
import os
10-
import configparser
1111
from ast import literal_eval
1212

13-
from .config_utils import _run_config, _paths_config_file, finalized_configs_dict
14-
from ..utils.file_ops import guarantee_existence, open_file
15-
16-
from rich.console import Console
17-
from rich.style import Style
18-
from rich.errors import StyleSyntaxError
13+
from manim import logger, console, config
14+
from manim.config.utils import config_file_paths, make_config_parser
15+
from manim.utils.file_ops import guarantee_existence, open_file
1916

2017
__all__ = ["write", "show", "export"]
2118

22-
RICH_COLOUR_INSTRUCTIONS = """[red]The default colour is used by the input statement.
19+
RICH_COLOUR_INSTRUCTIONS = """
20+
[red]The default colour is used by the input statement.
2321
If left empty, the default colour will be used.[/red]
24-
[magenta] For a full list of styles, visit[/magenta] [green]https://rich.readthedocs.io/en/latest/style.html[/green]"""
22+
[magenta] For a full list of styles, visit[/magenta] [green]https://rich.readthedocs.io/en/latest/style.html[/green]
23+
"""
2524
RICH_NON_STYLE_ENTRIES = ["log.width", "log.height", "log.timestamps"]
26-
console = Console()
2725

2826

2927
def value_from_string(value):
@@ -114,8 +112,7 @@ def replace_keys(default):
114112

115113

116114
def write(level=None, openfile=False):
117-
config = _run_config()[1]
118-
config_paths = _paths_config_file() + [os.path.abspath("manim.cfg")]
115+
config_paths = config_file_paths()
119116
console.print(
120117
"[yellow bold]Manim Configuration File Writer[/yellow bold]", justify="center"
121118
)
@@ -127,11 +124,12 @@ def write(level=None, openfile=False):
127124
CWD_CONFIG_MSG = f"""A configuration file at [yellow]{config_paths[2]}[/yellow] has been created.
128125
To save your config please save that file and place it in your current working directory, from where you run the manim command."""
129126

127+
parser = make_config_parser()
130128
if not openfile:
131129
action = "save this as"
132-
for category in config:
130+
for category in parser:
133131
console.print(f"{category}", style="bold green underline")
134-
default = config[category]
132+
default = parser[category]
135133
if category == "logger":
136134
console.print(RICH_COLOUR_INSTRUCTIONS)
137135
default = replace_keys(default)
@@ -178,7 +176,7 @@ def write(level=None, openfile=False):
178176

179177
default = replace_keys(default) if category == "logger" else default
180178

181-
config[category] = dict(default)
179+
parser[category] = dict(default)
182180

183181
else:
184182
action = "open"
@@ -194,40 +192,37 @@ def write(level=None, openfile=False):
194192
action_to_userpath = ""
195193

196194
if action_to_userpath.lower() == "y" or level == "user":
197-
cfg_file_path = os.path.join(
198-
guarantee_existence(os.path.dirname(config_paths[1])), "manim.cfg"
199-
)
195+
cfg_file_path = config_paths[1]
196+
guarantee_existence(config_paths[1].parents[0])
200197
console.print(USER_CONFIG_MSG)
201198
else:
202-
cfg_file_path = os.path.join(
203-
guarantee_existence(os.path.dirname(config_paths[2])), "manim.cfg"
204-
)
199+
cfg_file_path = config_paths[2]
200+
guarantee_existence(config_paths[2].parents[0])
205201
console.print(CWD_CONFIG_MSG)
206202
with open(cfg_file_path, "w") as fp:
207-
config.write(fp)
203+
parser.write(fp)
208204
if openfile:
209205
open_file(cfg_file_path)
210206

211207

212208
def show():
213-
current_config = finalized_configs_dict()
209+
parser = make_config_parser()
214210
rich_non_style_entries = [a.replace(".", "_") for a in RICH_NON_STYLE_ENTRIES]
215-
for category in current_config:
211+
for category in parser:
216212
console.print(f"{category}", style="bold green underline")
217-
for entry in current_config[category]:
213+
for entry in parser[category]:
218214
if category == "logger" and entry not in rich_non_style_entries:
219215
console.print(f"{entry} :", end="")
220216
console.print(
221-
f" {current_config[category][entry]}",
222-
style=current_config[category][entry],
217+
f" {parser[category][entry]}",
218+
style=parser[category][entry],
223219
)
224220
else:
225-
console.print(f"{entry} : {current_config[category][entry]}")
221+
console.print(f"{entry} : {parser[category][entry]}")
226222
console.print("\n")
227223

228224

229225
def export(path):
230-
config = _run_config()[1]
231226
if os.path.abspath(path) == os.path.abspath(os.getcwd()):
232227
console.print(
233228
"""You are reading the config from the same directory you are exporting to.

0 commit comments

Comments
 (0)