Copied the experiments implementation to the macros file
Is more robust
This commit is contained in:
parent
2bb2bd2034
commit
6859f89c9c
|
|
@ -1,4 +1,5 @@
|
|||
from ast import *
|
||||
from ast import (Assign, Name, Attribute, Expr, Num, Str, NameConstant, Load, Store)
|
||||
|
||||
|
||||
def document(sentences, to_source, **kw):
|
||||
""" This macro takes literal strings and converts them into:
|
||||
|
|
@ -7,41 +8,47 @@ def document(sentences, to_source, **kw):
|
|||
ID is the first target of the last assignment.
|
||||
type_hint is the assigned type and default value (only works for a few types)
|
||||
STRING is the literal string """
|
||||
cur_attr = None
|
||||
cur_value = None
|
||||
for n in range(len(sentences)):
|
||||
s = sentences[n]
|
||||
if isinstance(s, Assign):
|
||||
cur_target = s.targets[0]
|
||||
if isinstance(cur_target, Name):
|
||||
cur_attr = cur_target.id
|
||||
if not n:
|
||||
prev = s
|
||||
continue
|
||||
# The whole sentence is a string?
|
||||
if (isinstance(s, Expr) and isinstance(s.value, Str) and
|
||||
# and the previous is an assign
|
||||
isinstance(prev, Assign)): # noqa: E128
|
||||
# Apply it to the first target
|
||||
target = prev.targets[0]
|
||||
value = prev.value
|
||||
# Extract its name
|
||||
# variables and attributes are supported
|
||||
if isinstance(target, Name):
|
||||
name = target.id
|
||||
is_attr = False
|
||||
elif isinstance(cur_target, Attribute):
|
||||
cur_attr = cur_target.attr
|
||||
elif isinstance(target, Attribute):
|
||||
name = target.attr
|
||||
is_attr = True
|
||||
else:
|
||||
raise TypeError
|
||||
cur_value = s.value
|
||||
elif cur_attr and isinstance(s, Expr):
|
||||
if isinstance(s.value, Str):
|
||||
# Remove starting underscore
|
||||
if cur_attr[0] == '_':
|
||||
cur_attr = cur_attr[1:]
|
||||
# Create a _help_ID
|
||||
doc_id = '_help_'+cur_attr
|
||||
# Create the type hint for numbers, strings and booleans
|
||||
type_hint = ''
|
||||
if isinstance(cur_value, Num):
|
||||
type_hint = '[number={}]'.format(cur_value.n)
|
||||
elif isinstance(cur_value, Str):
|
||||
type_hint = "[string='{}']".format(cur_value.s)
|
||||
elif isinstance(cur_value, NameConstant) and isinstance(cur_value.value, bool):
|
||||
type_hint = '[boolean={}]'.format(str(cur_value.value).lower())
|
||||
# Transform the string into an assign for _help_ID
|
||||
if is_attr:
|
||||
cur_target = Attribute(value=Name(id='self', ctx=Load()), attr=doc_id, ctx=Store())
|
||||
else:
|
||||
cur_target = Name(id=doc_id, ctx=Store())
|
||||
sentences[n] = Assign(targets=[cur_target], value=Str(s=type_hint+s.value.s))
|
||||
continue
|
||||
# Remove starting underscore
|
||||
if name[0] == '_':
|
||||
name = name[1:]
|
||||
# Create a _help_ID
|
||||
doc_id = '_help_'+name
|
||||
# Create the type hint for numbers, strings and booleans
|
||||
type_hint = ''
|
||||
if isinstance(value, Num):
|
||||
type_hint = '[number={}]'.format(value.n)
|
||||
elif isinstance(value, Str):
|
||||
type_hint = "[string='{}']".format(value.s)
|
||||
elif isinstance(value, NameConstant) and isinstance(value.value, bool):
|
||||
type_hint = '[boolean={}]'.format(str(value.value).lower())
|
||||
# Transform the string into an assign for _help_ID
|
||||
if is_attr:
|
||||
target = Attribute(value=Name(id='self', ctx=Load()), attr=doc_id, ctx=Store())
|
||||
else:
|
||||
target = Name(id=doc_id, ctx=Store())
|
||||
sentences[n] = Assign(targets=[target], value=Str(s=type_hint+s.value.s))
|
||||
prev = s
|
||||
# Return the modified AST
|
||||
return sentences
|
||||
|
|
|
|||
Loading…
Reference in New Issue