mirror of
https://github.com/3b1b/manim.git
synced 2025-08-01 06:22:54 +08:00
Don't write new file when inserting embed line
Instead, load the relevant module of the true file, and execute the modified code within that. This also cleans up some of the previous now-unnecessary code around get_module_with_inserted_embed_line
This commit is contained in:
@ -207,20 +207,18 @@ def get_manim_dir():
|
|||||||
return os.path.abspath(os.path.join(manimlib_dir, ".."))
|
return os.path.abspath(os.path.join(manimlib_dir, ".."))
|
||||||
|
|
||||||
|
|
||||||
def get_indent(code_lines: list[str], line_number: int):
|
def get_indent(code_lines: list[str], line_number: int) -> str:
|
||||||
for line in code_lines[line_number:0:-1]:
|
for line in code_lines[line_number - 1::-1]:
|
||||||
if len(line.strip()) == 0:
|
if len(line.strip()) == 0:
|
||||||
continue
|
continue
|
||||||
n_spaces = len(line) - len(line.lstrip())
|
n_spaces = len(line) - len(line.lstrip())
|
||||||
if line.endswith(":"):
|
if line.endswith(":"):
|
||||||
n_spaces += 4
|
n_spaces += 4
|
||||||
return n_spaces
|
return n_spaces * " "
|
||||||
return 0
|
return ""
|
||||||
|
|
||||||
|
|
||||||
def get_module_with_inserted_embed_line(
|
def get_module_with_inserted_embed_line(file_name: str, line_number: int):
|
||||||
file_name: str, scene_name: str, line_number: int
|
|
||||||
):
|
|
||||||
"""
|
"""
|
||||||
This is hacky, but convenient. When user includes the argument "-e", it will try
|
This is hacky, but convenient. When user includes the argument "-e", it will try
|
||||||
to recreate a file that inserts the line `self.embed()` into the end of the scene's
|
to recreate a file that inserts the line `self.embed()` into the end of the scene's
|
||||||
@ -229,31 +227,18 @@ def get_module_with_inserted_embed_line(
|
|||||||
"""
|
"""
|
||||||
lines = Path(file_name).read_text().splitlines()
|
lines = Path(file_name).read_text().splitlines()
|
||||||
|
|
||||||
scene_line_numbers = [
|
# Add the relevant embed line to the code
|
||||||
n for n, line in enumerate(lines)
|
indent = get_indent(lines, line_number)
|
||||||
if line.startswith("class SurfaceTest")
|
lines.insert(line_number, indent + "self.embed()")
|
||||||
]
|
new_code = "\n".join(lines)
|
||||||
if len(scene_line_numbers) == 0:
|
|
||||||
log.error(f"No scene {scene_name}")
|
|
||||||
return
|
|
||||||
scene_line_number = scene_line_numbers[0]
|
|
||||||
|
|
||||||
n_spaces = get_indent(lines, line_number - 1)
|
|
||||||
inserted_line = " " * n_spaces + "self.embed()"
|
|
||||||
new_lines = list(lines)
|
|
||||||
new_lines.insert(line_number, inserted_line)
|
|
||||||
new_file = file_name.replace(".py", "_insert_embed.py")
|
|
||||||
|
|
||||||
Path(new_file).write_text("\n".join(new_lines))
|
|
||||||
|
|
||||||
|
# Load the module for the original file, then exectue the new code within
|
||||||
|
# it, which should redefined the scene to have the inserted embed line
|
||||||
from manimlib.reload_manager import reload_manager
|
from manimlib.reload_manager import reload_manager
|
||||||
module = ModuleLoader.get_module(new_file, is_during_reload=reload_manager.is_reload)
|
module = ModuleLoader.get_module(file_name, is_during_reload=reload_manager.is_reload)
|
||||||
# This is to pretend the module imported from the edited lines
|
|
||||||
# of code actually comes from the original file.
|
|
||||||
module.__file__ = file_name
|
|
||||||
|
|
||||||
os.remove(new_file)
|
|
||||||
|
|
||||||
|
code_object = compile(new_code, module.__name__, 'exec')
|
||||||
|
exec(code_object, module.__dict__)
|
||||||
return module
|
return module
|
||||||
|
|
||||||
|
|
||||||
@ -261,9 +246,7 @@ def get_scene_module(args: Namespace) -> Module:
|
|||||||
if args.embed is None:
|
if args.embed is None:
|
||||||
return ModuleLoader.get_module(args.file)
|
return ModuleLoader.get_module(args.file)
|
||||||
else:
|
else:
|
||||||
return get_module_with_inserted_embed_line(
|
return get_module_with_inserted_embed_line(args.file, int(args.embed))
|
||||||
args.file, args.scene_names[0], int(args.embed)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def load_yaml(file_path: str):
|
def load_yaml(file_path: str):
|
||||||
|
@ -76,10 +76,7 @@ class ModuleLoader:
|
|||||||
builtins.__import__ = tracked_import
|
builtins.__import__ = tracked_import
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Remove the "_insert_embed" suffix from the module name
|
|
||||||
module_name = module.__name__
|
module_name = module.__name__
|
||||||
if module.__name__.endswith("_insert_embed"):
|
|
||||||
module_name = module_name[:-13]
|
|
||||||
log.debug('Reloading module "%s"', module_name)
|
log.debug('Reloading module "%s"', module_name)
|
||||||
|
|
||||||
spec.loader.exec_module(module)
|
spec.loader.exec_module(module)
|
||||||
|
Reference in New Issue
Block a user