check_support; Attribute()
This commit is contained in:
parent
0281d68cb4
commit
c620d0b014
@ -1,9 +1,10 @@
|
||||
from tests.test_utils import *
|
||||
|
||||
from trace_commentor.check import Check
|
||||
|
||||
def test():
|
||||
|
||||
@Commentor()
|
||||
# @Commentor()
|
||||
@Check()
|
||||
def target(a, d=1, *b, c, k=1):
|
||||
return a + k
|
||||
|
||||
|
||||
@ -13,6 +13,7 @@ def test_constant():
|
||||
x = 2
|
||||
print(x == 2)
|
||||
"""
|
||||
<callable> : print
|
||||
True : x == 2
|
||||
None : print(x == 2)
|
||||
"""
|
||||
@ -64,7 +65,7 @@ def test_if():
|
||||
def test_for():
|
||||
|
||||
with closing(StringIO()) as f:
|
||||
@Commentor(f)
|
||||
@Commentor(f, _exit=False, check=False)
|
||||
def target():
|
||||
odds = []
|
||||
# return only odd numbers - 1,3,5,7,9
|
||||
@ -101,6 +102,8 @@ def test_for():
|
||||
# continue # skipped
|
||||
# odds.append(x)
|
||||
"""
|
||||
[] : odds
|
||||
<callable> : odds.append
|
||||
1 : x
|
||||
None : odds.append(x)
|
||||
"""
|
||||
@ -125,6 +128,8 @@ def test_for():
|
||||
# continue # skipped
|
||||
# odds.append(x)
|
||||
"""
|
||||
[1] : odds
|
||||
<callable> : odds.append
|
||||
3 : x
|
||||
None : odds.append(x)
|
||||
"""
|
||||
@ -149,6 +154,8 @@ def test_for():
|
||||
# continue # skipped
|
||||
# odds.append(x)
|
||||
"""
|
||||
[1, 3] : odds
|
||||
<callable> : odds.append
|
||||
5 : x
|
||||
None : odds.append(x)
|
||||
"""
|
||||
@ -173,6 +180,8 @@ def test_for():
|
||||
# continue # skipped
|
||||
# odds.append(x)
|
||||
"""
|
||||
[1, 3, 5] : odds
|
||||
<callable> : odds.append
|
||||
7 : x
|
||||
None : odds.append(x)
|
||||
"""
|
||||
@ -197,6 +206,8 @@ def test_for():
|
||||
continue # skipped
|
||||
odds.append(x)
|
||||
"""
|
||||
[1, 3, 5, 7] : odds
|
||||
<callable> : odds.append
|
||||
9 : x
|
||||
None : odds.append(x)
|
||||
"""
|
||||
|
||||
@ -17,7 +17,7 @@ def test_return():
|
||||
|
||||
with closing(StringIO()) as f:
|
||||
|
||||
@Commentor(f)
|
||||
@Commentor(f, _exit=False)
|
||||
def target():
|
||||
a = 1
|
||||
return a + 1
|
||||
|
||||
@ -46,6 +46,7 @@ def test_call_print():
|
||||
def target():
|
||||
print('This line will be printed.')
|
||||
"""
|
||||
<callable> : print
|
||||
None : print('This line will be printed.')
|
||||
"""
|
||||
''')
|
||||
|
||||
@ -14,6 +14,7 @@ def test_assign():
|
||||
myint = 7
|
||||
print(myint)
|
||||
"""
|
||||
<callable> : print
|
||||
7 : myint
|
||||
None : print(myint)
|
||||
"""
|
||||
|
||||
@ -9,12 +9,12 @@ from functools import wraps
|
||||
from . import handlers
|
||||
from . import formatters
|
||||
from . import flags
|
||||
from .utils import sign, to_source, comment_to_file
|
||||
from .utils import sign, to_source, comment_to_file, isinstance_noexcept
|
||||
|
||||
|
||||
class Commentor(object):
|
||||
|
||||
def __init__(self, output="<stderr>", _globals=dict(), fmt=[]) -> None:
|
||||
def __init__(self, output="<stderr>", _globals=dict(), fmt=[], check=True, _exit=True) -> None:
|
||||
self._locals = dict()
|
||||
self._globals = dict().update(_globals)
|
||||
self._return = None
|
||||
@ -25,6 +25,8 @@ class Commentor(object):
|
||||
self.state = flags.SOURCE
|
||||
self.file = output
|
||||
self._stack_event = flags.NORMAL
|
||||
self._exit = _exit
|
||||
self._check = check
|
||||
|
||||
def __call__(self, func):
|
||||
|
||||
@ -32,6 +34,8 @@ class Commentor(object):
|
||||
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 self._check: self.check_support()
|
||||
|
||||
pt = getfullargspec(func)
|
||||
|
||||
if flags.DEBUG:
|
||||
@ -71,6 +75,8 @@ class Commentor(object):
|
||||
# output {
|
||||
comments = "\n".join(self._lines)
|
||||
if comment_to_file(comments, file=self.file):
|
||||
if self._exit:
|
||||
exit(0)
|
||||
return self._return
|
||||
else:
|
||||
return comments
|
||||
@ -102,7 +108,9 @@ class Commentor(object):
|
||||
|
||||
def get_formatter(self, obj):
|
||||
for typ, fmt in self._formatters:
|
||||
if isinstance(obj, typ):
|
||||
if isinstance_noexcept(obj, typ):
|
||||
return fmt
|
||||
elif callable(typ) and typ(obj):
|
||||
return fmt
|
||||
else:
|
||||
return repr
|
||||
@ -128,3 +136,17 @@ class Commentor(object):
|
||||
self.__append('"""')
|
||||
if line is not None:
|
||||
return self.__append(sign(line, 2))
|
||||
|
||||
def check_support(self):
|
||||
unimpl = []
|
||||
for node in ast.walk(self.root):
|
||||
if node.__class__ in flags.HANDLER_FREE_NODES:
|
||||
continue
|
||||
node_type = node.__class__.__name__
|
||||
handler = getattr(handlers, node_type, None)
|
||||
if handler is None:
|
||||
unimpl.append(node_type)
|
||||
|
||||
if unimpl:
|
||||
print("Unsupported nodes: ", ", ".join(unimpl))
|
||||
exit(0)
|
||||
|
||||
@ -21,3 +21,10 @@ APPEND_SOURCE_BY_THEMSELVES = [
|
||||
ASSIGN_SILENT = [
|
||||
ast.Constant, ast.List
|
||||
]
|
||||
|
||||
HANDLER_FREE_NODES = [
|
||||
ast.Add, ast.Sub, ast.Mult, ast.Div, ast.FloorDiv, ast.Mod, ast.LShift, ast.RShift, ast.BitOr, ast.BitXor, ast.BitAnd, ast.MatMult,
|
||||
ast.Eq, ast.NotEq, ast.Lt, ast.LtE, ast.Gt, ast.GtE, ast.Is, ast.IsNot, ast.In, ast.NotIn,
|
||||
ast.Load, ast.Store,
|
||||
ast.arg, ast.arguments, ast.keyword,
|
||||
]
|
||||
|
||||
@ -1 +1,7 @@
|
||||
LIST = []
|
||||
def fmt_callable(fn):
|
||||
return "<callable>"
|
||||
|
||||
|
||||
LIST = [
|
||||
(callable, fmt_callable),
|
||||
]
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
from .definitions import FunctionDef, Return
|
||||
from .statements import Pass, Assign
|
||||
from .expressions import Expr, BinOp, Call, Compare
|
||||
from .expressions import Expr, BinOp, Call, Compare, Attribute
|
||||
from .literals import Constant, Tuple, List
|
||||
from .variables import Name
|
||||
from .control_flow import If, For, Continue, Break
|
||||
|
||||
@ -12,8 +12,13 @@ def Compare(self, cmtor):
|
||||
cmtor.append_comment(cmtor.eval(self))
|
||||
|
||||
def Call(self, cmtor):
|
||||
cmtor.process(self.func)
|
||||
for arg in self.args:
|
||||
cmtor.process(arg)
|
||||
for kwarg in self.keywords:
|
||||
cmtor.process(kwarg)
|
||||
cmtor.append_comment(cmtor.eval(self))
|
||||
|
||||
def Attribute(self, cmtor):
|
||||
cmtor.process(self.value)
|
||||
cmtor.append_comment(cmtor.eval(self))
|
||||
|
||||
@ -26,6 +26,10 @@ def to_source(node):
|
||||
return src
|
||||
|
||||
|
||||
def dump(node, file=sys.stderr):
|
||||
print(ast.dump(node, indent=4), file=file)
|
||||
|
||||
|
||||
def comment_to_file(code, file: str) -> bool:
|
||||
if file == "<return>":
|
||||
return False
|
||||
@ -49,3 +53,10 @@ def comment_to_file(code, file: str) -> bool:
|
||||
else:
|
||||
raise NotImplementedError(f"Unknown file protocal {file}")
|
||||
return True
|
||||
|
||||
|
||||
def isinstance_noexcept(_obj, _class_or_tuple):
|
||||
try:
|
||||
return isinstance(_obj, _class_or_tuple)
|
||||
except TypeError:
|
||||
return False
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user