From 36f37c18b1c94017f4da7882b0185e8fa1a3479a Mon Sep 17 00:00:00 2001 From: Kumi Date: Thu, 23 May 2024 14:47:24 +0200 Subject: [PATCH] feat: Enhance German code execution and import logic Introduced changes significantly improve how German code scripts are handled, ensuring a more robust and flexible execution environment. By wrapping the execution of transpiled code in a dedicated module, we facilitate a cleaner namespace management and mimic the natural Python script execution context more closely. This approach also allows for improved error handling and tracebacks that are more meaningful to the end-user. The addition of "ausgenommen" as an alternative to "except" in the dictionary broadens the tool's understanding of German code, enhancing its flexibility and user-friendliness. We've refined the module import mechanism to include a wider array of search paths, notably the script's directory and the current working directory, before falling back to the predefined wrappers directory. This enhancement makes the import process more intuitive and aligned with Python's standard behavior, ensuring that dependencies are resolved more reliably across diverse execution environments. These improvements collectively bolster the tool's usability, making it more accommodating for users running and developing German-translated Python scripts. --- src/deuthon/__main__.py | 25 ++++++++++++++++++------- src/deuthon/dictionary/__init__.py | 1 + src/deuthon/importer.py | 23 +++++++++++++++++++++-- 3 files changed, 40 insertions(+), 9 deletions(-) diff --git a/src/deuthon/__main__.py b/src/deuthon/__main__.py index 893ed2d..fefd73d 100755 --- a/src/deuthon/__main__.py +++ b/src/deuthon/__main__.py @@ -5,6 +5,7 @@ import tokenize import pathlib import sys import traceback +import types from argparse import ArgumentParser @@ -23,22 +24,33 @@ def main(): import_base(pathlib.Path(__file__).parent / "base") if args.file: - with open(args.file) as f: - german_code = f.read() + script_path = pathlib.Path(args.file).absolute() + script_dir = script_path.parent + # Read and transpile the German code + with open(script_path) as f: + german_code = f.read() python_code = parse_german_code(german_code) + # Compile the transpiled Python code code_object = compile( python_code, - pathlib.Path(args.file).absolute(), + str(script_path), "exec", dont_inherit=True, optimize=0, ) + # Create a module for the script and add it to sys.modules + module_name = "__haupt__" + script_module = types.ModuleType(module_name) + script_module.__file__ = str(script_path) + sys.modules[module_name] = script_module + try: - exec(code_object, {"__file__": pathlib.Path(args.file).absolute()}) - except Ausnahme as e: # noqa: F821 + # Execute the compiled code within the module's namespace + exec(code_object, script_module.__dict__) + except Exception as e: # Replace Ausnahme with Exception for general error handling # Extract traceback information, excluding frames related to the interpreter tb = e.__traceback__ while tb is not None: @@ -61,6 +73,5 @@ def main(): else: interpreter() - if __name__ == "__main__": - sys.exit(main()) + sys.exit(main()) \ No newline at end of file diff --git a/src/deuthon/dictionary/__init__.py b/src/deuthon/dictionary/__init__.py index c26faac..f6791c3 100644 --- a/src/deuthon/dictionary/__init__.py +++ b/src/deuthon/dictionary/__init__.py @@ -34,6 +34,7 @@ dictionary = { # Try / Except "versuche": "try", "außer": "except", + "ausgenommen": "except", "fange": "except", "schließlich": "finally", diff --git a/src/deuthon/importer.py b/src/deuthon/importer.py index 24fe002..b179247 100644 --- a/src/deuthon/importer.py +++ b/src/deuthon/importer.py @@ -3,7 +3,6 @@ import importlib.util import importlib.machinery import os import tokenize -import pathlib import sys import builtins @@ -50,6 +49,26 @@ class DeuthonModuleFinder(importlib.abc.MetaPathFinder): self.extension = extension def find_spec(self, fullname, path, target=None): + # Determine the search paths + search_paths = [] + + # Add the directory of the main script being executed + if "__haupt__" in sys.modules: + main_module = sys.modules["__haupt__"] + if hasattr(main_module, "__file__"): + script_dir = os.path.dirname(os.path.abspath(main_module.__file__)) + search_paths.append(script_dir) + + # Add any provided path + if path: + search_paths.extend(path) + + # Add the current working directory + search_paths.append(os.getcwd()) + + # Add the wrappers directory + search_paths.append(self.wrappers_directory) + # Check inside the wrappers directory first deu_wrapper_path = os.path.join( self.wrappers_directory, fullname + self.extension @@ -76,7 +95,7 @@ class DeuthonModuleFinder(importlib.abc.MetaPathFinder): return spec # If it's not a wrapper, look for a .deu file - deu_path = self._find_deu_file(fullname, path) + deu_path = self._find_deu_file(fullname, search_paths) if deu_path: loader = DeuthonSourceLoader(fullname, deu_path) spec = importlib.util.spec_from_loader(fullname, loader, origin=deu_path)