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.
This commit is contained in:
parent
5ff8f3856b
commit
36f37c18b1
3 changed files with 40 additions and 9 deletions
|
@ -5,6 +5,7 @@ import tokenize
|
||||||
import pathlib
|
import pathlib
|
||||||
import sys
|
import sys
|
||||||
import traceback
|
import traceback
|
||||||
|
import types
|
||||||
|
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser
|
||||||
|
|
||||||
|
@ -23,22 +24,33 @@ def main():
|
||||||
import_base(pathlib.Path(__file__).parent / "base")
|
import_base(pathlib.Path(__file__).parent / "base")
|
||||||
|
|
||||||
if args.file:
|
if args.file:
|
||||||
with open(args.file) as f:
|
script_path = pathlib.Path(args.file).absolute()
|
||||||
german_code = f.read()
|
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)
|
python_code = parse_german_code(german_code)
|
||||||
|
|
||||||
|
# Compile the transpiled Python code
|
||||||
code_object = compile(
|
code_object = compile(
|
||||||
python_code,
|
python_code,
|
||||||
pathlib.Path(args.file).absolute(),
|
str(script_path),
|
||||||
"exec",
|
"exec",
|
||||||
dont_inherit=True,
|
dont_inherit=True,
|
||||||
optimize=0,
|
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:
|
try:
|
||||||
exec(code_object, {"__file__": pathlib.Path(args.file).absolute()})
|
# Execute the compiled code within the module's namespace
|
||||||
except Ausnahme as e: # noqa: F821
|
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
|
# Extract traceback information, excluding frames related to the interpreter
|
||||||
tb = e.__traceback__
|
tb = e.__traceback__
|
||||||
while tb is not None:
|
while tb is not None:
|
||||||
|
@ -61,6 +73,5 @@ def main():
|
||||||
else:
|
else:
|
||||||
interpreter()
|
interpreter()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
sys.exit(main())
|
sys.exit(main())
|
|
@ -34,6 +34,7 @@ dictionary = {
|
||||||
# Try / Except
|
# Try / Except
|
||||||
"versuche": "try",
|
"versuche": "try",
|
||||||
"außer": "except",
|
"außer": "except",
|
||||||
|
"ausgenommen": "except",
|
||||||
"fange": "except",
|
"fange": "except",
|
||||||
"schließlich": "finally",
|
"schließlich": "finally",
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@ import importlib.util
|
||||||
import importlib.machinery
|
import importlib.machinery
|
||||||
import os
|
import os
|
||||||
import tokenize
|
import tokenize
|
||||||
import pathlib
|
|
||||||
import sys
|
import sys
|
||||||
import builtins
|
import builtins
|
||||||
|
|
||||||
|
@ -50,6 +49,26 @@ class DeuthonModuleFinder(importlib.abc.MetaPathFinder):
|
||||||
self.extension = extension
|
self.extension = extension
|
||||||
|
|
||||||
def find_spec(self, fullname, path, target=None):
|
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
|
# Check inside the wrappers directory first
|
||||||
deu_wrapper_path = os.path.join(
|
deu_wrapper_path = os.path.join(
|
||||||
self.wrappers_directory, fullname + self.extension
|
self.wrappers_directory, fullname + self.extension
|
||||||
|
@ -76,7 +95,7 @@ class DeuthonModuleFinder(importlib.abc.MetaPathFinder):
|
||||||
return spec
|
return spec
|
||||||
|
|
||||||
# If it's not a wrapper, look for a .deu file
|
# 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:
|
if deu_path:
|
||||||
loader = DeuthonSourceLoader(fullname, deu_path)
|
loader = DeuthonSourceLoader(fullname, deu_path)
|
||||||
spec = importlib.util.spec_from_loader(fullname, loader, origin=deu_path)
|
spec = importlib.util.spec_from_loader(fullname, loader, origin=deu_path)
|
||||||
|
|
Loading…
Reference in a new issue