From d86f8dcef6959e0199929d4b6cbe0a5f3f60a0ae Mon Sep 17 00:00:00 2001 From: Splines Date: Tue, 4 Feb 2025 17:46:53 +0100 Subject: [PATCH 1/2] Fix module exec error by adding it to sys.modules beforehand --- manimlib/extract_scene.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/manimlib/extract_scene.py b/manimlib/extract_scene.py index 28e22256..88e77091 100644 --- a/manimlib/extract_scene.py +++ b/manimlib/extract_scene.py @@ -174,7 +174,17 @@ def insert_embed_line_to_module(module: Module, run_config: Dict) -> None: # Execute the code, which presumably redefines the user's # scene to include this embed line, within the relevant module. - code_object = compile(new_code, module.__name__, 'exec') + # Note that we add the user-module to sys.modules to please Python builtins + # that rely on cls.__module__ to be not None (which would be the case if + # the module was not in sys.modules). See #2307. + if module.__name__ in sys.modules: + log.error( + "Module name is already used by Manim itself, " + "please use a different name" + ) + sys.exit(2) + sys.modules[module.__name__] = module + code_object = compile(new_code, module.__name__, "exec") exec(code_object, module.__dict__) From 02ddf45664dfed3b95a47d009dda3bdfd3ccd239 Mon Sep 17 00:00:00 2001 From: Splines Date: Tue, 4 Feb 2025 17:47:54 +0100 Subject: [PATCH 2/2] Improve method name and docstrings --- manimlib/extract_scene.py | 7 +++++-- manimlib/scene/scene_embed.py | 4 ++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/manimlib/extract_scene.py b/manimlib/extract_scene.py index 88e77091..ef93c12d 100644 --- a/manimlib/extract_scene.py +++ b/manimlib/extract_scene.py @@ -143,8 +143,11 @@ def get_indent(code_lines: list[str], line_number: int) -> str: return n_spaces * " " -def insert_embed_line_to_module(module: Module, run_config: Dict) -> None: +def insert_embed_line_to_module_exec(module: Module, run_config: Dict) -> None: """ + Loads the user code, inserts a self.embed() line at the given line_number + and executes the code. + 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 construct method. If there is an argument passed in, it will insert the line after @@ -191,7 +194,7 @@ def insert_embed_line_to_module(module: Module, run_config: Dict) -> None: def get_module(run_config: Dict) -> Module: module = ModuleLoader.get_module(run_config.file_name, run_config.is_reload) if run_config.embed_line: - insert_embed_line_to_module(module, run_config) + insert_embed_line_to_module_exec(module, run_config) return module diff --git a/manimlib/scene/scene_embed.py b/manimlib/scene/scene_embed.py index 429693dd..930e4c30 100644 --- a/manimlib/scene/scene_embed.py +++ b/manimlib/scene/scene_embed.py @@ -118,8 +118,8 @@ class InteractiveSceneEmbed: open during the reload. If `embed_line` is provided, the scene will be reloaded at that line - number. This corresponds to the `linemarker` param of the - `extract_scene.insert_embed_line_to_module()` method. + number. This corresponds to the `line_number` param of the + `extract_scene.insert_embed_line_to_module_exec()` method. Before reload, the scene is cleared and the entire state is reset, such that we can start from a clean slate. This is taken care of by the