From e3094a65220f09dced3ead7b1cd73fa5d66274d8 Mon Sep 17 00:00:00 2001 From: Yuyao Huang Date: Fri, 19 Apr 2024 13:24:36 +0800 Subject: [PATCH] add Pass(), FunctionDef(); --- conda/env.yml | Bin 320 -> 380 bytes tests/test_definitions.py | 10 +++ trace_commentor/__init__.py | 1 + trace_commentor/commentor.py | 62 ++++++++++++++++++ trace_commentor/flags.py | 2 + trace_commentor/formatters/__init__.py | 1 + .../{interpretor => handlers}/README.md | 0 trace_commentor/handlers/__init__.py | 2 + trace_commentor/handlers/definitions.py | 9 +++ trace_commentor/handlers/statements.py | 2 + trace_commentor/parser.py | 32 --------- 11 files changed, 89 insertions(+), 32 deletions(-) create mode 100644 tests/test_definitions.py create mode 100644 trace_commentor/commentor.py create mode 100644 trace_commentor/flags.py create mode 100644 trace_commentor/formatters/__init__.py rename trace_commentor/{interpretor => handlers}/README.md (100%) create mode 100644 trace_commentor/handlers/__init__.py create mode 100644 trace_commentor/handlers/definitions.py create mode 100644 trace_commentor/handlers/statements.py delete mode 100644 trace_commentor/parser.py diff --git a/conda/env.yml b/conda/env.yml index 344a37a6eefe209c47adb5323922062107259978..bd3c40ba8e78266e2670db1bafa71df7789031ff 100644 GIT binary patch delta 37 rcmX@W^oMDJ$HX+giJwG7lNs_E@)%MW5*c(E(tzwDhIEG1iOzok<=+cn delta 9 Qcmeyvbbx7s$HbN&02Sl}rT_o{ diff --git a/tests/test_definitions.py b/tests/test_definitions.py new file mode 100644 index 0000000..39c1127 --- /dev/null +++ b/tests/test_definitions.py @@ -0,0 +1,10 @@ +from trace_commentor import Commentor + + +def test_function_def(): + + @Commentor() + def target(): + pass + + print(target()) diff --git a/trace_commentor/__init__.py b/trace_commentor/__init__.py index e69de29..421fb93 100644 --- a/trace_commentor/__init__.py +++ b/trace_commentor/__init__.py @@ -0,0 +1 @@ +from .commentor import Commentor diff --git a/trace_commentor/commentor.py b/trace_commentor/commentor.py new file mode 100644 index 0000000..a1ed5c1 --- /dev/null +++ b/trace_commentor/commentor.py @@ -0,0 +1,62 @@ +import inspect +import ast +import astor + +from inspect import getfullargspec +from functools import wraps + +from . import handlers +from . import formatters +from . import flags + + +class Commentor(object): + + def __init__(self, _formatters=[]) -> None: + self._locals = dict() + self._globals = dict() + self._formatters = _formatters + formatters.LIST + self._lines = [] + self.indent = 0 + + def __call__(self, func): + + raw_lines, start_lineno = inspect.getsourcelines(func) + self.indent = len(raw_lines[0]) - len(raw_lines[0].lstrip()) + unindented_source = ''.join([l[self.indent:] for l in raw_lines]) + self.root = ast.parse(unindented_source).body[0] + + if flags.DEBUG: + with open("test.log", "wt") as f: + print(ast.dump(self.root, indent=4), file=f) + + @wraps(func) + def proxy_func(*args, **kwargs): + self._locals = kwargs + self.process(self.root) + return "\n".join(self._lines) + + return proxy_func + + def process(self, node: ast.AST): + node_type = node.__class__.__name__ + handler = getattr(handlers, node_type, None) + if handler is None: + raise NotImplementedError(f"Unknown how to handle {node_type} node.") + return handler(node, self) + + def eval(self, node: ast.Expr): + src = astor.code_gen.to_source(node) + obj = eval(src, self._globals, self._locals) + fmt = self.get_formatter(obj) + return f"{fmt(obj)} : {src}" + + def get_formatter(self, obj): + for typ, fmt in self._formatters: + if isinstance(obj, typ): + return fmt + else: + return repr + + def append(self, line): + self._lines.append(" " * self.indent + str(line)) diff --git a/trace_commentor/flags.py b/trace_commentor/flags.py new file mode 100644 index 0000000..b82723c --- /dev/null +++ b/trace_commentor/flags.py @@ -0,0 +1,2 @@ +DEBUG = True +INDENT = 4 diff --git a/trace_commentor/formatters/__init__.py b/trace_commentor/formatters/__init__.py new file mode 100644 index 0000000..540235b --- /dev/null +++ b/trace_commentor/formatters/__init__.py @@ -0,0 +1 @@ +LIST = [] diff --git a/trace_commentor/interpretor/README.md b/trace_commentor/handlers/README.md similarity index 100% rename from trace_commentor/interpretor/README.md rename to trace_commentor/handlers/README.md diff --git a/trace_commentor/handlers/__init__.py b/trace_commentor/handlers/__init__.py new file mode 100644 index 0000000..0164848 --- /dev/null +++ b/trace_commentor/handlers/__init__.py @@ -0,0 +1,2 @@ +from .definitions import FunctionDef +from .statements import Pass diff --git a/trace_commentor/handlers/definitions.py b/trace_commentor/handlers/definitions.py new file mode 100644 index 0000000..a5b922a --- /dev/null +++ b/trace_commentor/handlers/definitions.py @@ -0,0 +1,9 @@ +from ..flags import INDENT + +def FunctionDef(self, cmtor): + cmtor.append("def function():") + cmtor.indent += INDENT + + if self is cmtor.root: + for stmt in self.body: + cmtor.process(stmt) diff --git a/trace_commentor/handlers/statements.py b/trace_commentor/handlers/statements.py new file mode 100644 index 0000000..a7e1ee2 --- /dev/null +++ b/trace_commentor/handlers/statements.py @@ -0,0 +1,2 @@ +def Pass(self, cmtor): + cmtor.append("pass") diff --git a/trace_commentor/parser.py b/trace_commentor/parser.py deleted file mode 100644 index a8ad6a4..0000000 --- a/trace_commentor/parser.py +++ /dev/null @@ -1,32 +0,0 @@ -import inspect -import ast -import astor - -# from .interpretor import exec_ast - - -class Parser(object): - - - def __init__(self) -> None: - pass - - def __call__(self, func, **_globals): - - raw_lines, start_lineno = inspect.getsourcelines(func) - indent_size = len(raw_lines[0]) - len(raw_lines[0].lstrip()) - unindented_source = ''.join([l[indent_size:] for l in raw_lines]) - root = ast.parse(unindented_source).body[0] - - def proxy_func(*args, **kwargs): - _locals = kwargs - # exec_ast(root, _locals, _globals) - import ipdb; ipdb.set_trace() - root = ast.parse(unindented_source).body[0] - ast.dump(root) - ... - - return proxy_func - - -analyse = Parser()