def pop_format_context(self, expl_expr):
"""Format the %-formatted string with current format context.
The expl_expr should be an ast.Str instance constructed from
the %-placeholders created by .explanation_param(). This will
add the required code to format said string to .on_failure and
return the ast.Name instance of the formatted string.
"""
current = self.stack.pop()
if self.stack:
self.explanation_specifiers = self.stack[-1]
keys = [ast.Str(key) for key in current.keys()]
format_dict = ast.Dict(keys, list(current.values()))
form = ast.BinOp(expl_expr, ast.Mod(), format_dict)
name = "@py_format" + str(next(self.variable_counter))
self.on_failure.append(ast.Assign([ast.Name(name, ast.Store())], form))
return ast.Name(name, ast.Load())
python类Store()的实例源码
def checkGlobalIds(a, l):
if not isinstance(a, ast.AST):
return
elif type(a) in [ ast.Load, ast.Store, ast.Del, ast.AugLoad, ast.AugStore, ast.Param ]:
return
if not hasattr(a, "global_id"):
addedNodes = ["propagatedVariable", "orderedBinOp",
"augAssignVal", "augAssignBinOp",
"combinedConditional", "combinedConditionalOp",
"multiCompPart", "multiCompOp",
"second_global_id", "moved_line",
# above this line has individualize functions. below does not.
"addedNot", "addedNotOp", "addedOther", "addedOtherOp",
"collapsedExpr", "removedLines",
"helperVar", "helperReturn",
"typeCastFunction", ]
for t in addedNodes:
if hasattr(a, t):
break
else: # only enter the else if none of the provided types are an attribute of a
log("canonicalize\tcheckGlobalIds\tNo global id: " + str(l) + "," + str(a.__dict__) + "," + printFunction(a, 0), "bug")
for f in ast.iter_child_nodes(a):
checkGlobalIds(f, l + [type(a)])
def pop_format_context(self, expl_expr):
"""Format the %-formatted string with current format context.
The expl_expr should be an ast.Str instance constructed from
the %-placeholders created by .explanation_param(). This will
add the required code to format said string to .on_failure and
return the ast.Name instance of the formatted string.
"""
current = self.stack.pop()
if self.stack:
self.explanation_specifiers = self.stack[-1]
keys = [ast.Str(key) for key in current.keys()]
format_dict = ast.Dict(keys, list(current.values()))
form = ast.BinOp(expl_expr, ast.Mod(), format_dict)
name = "@py_format" + str(next(self.variable_counter))
self.on_failure.append(ast.Assign([ast.Name(name, ast.Store())], form))
return ast.Name(name, ast.Load())
def _add_aliases(self, node):
"""
We delegate to this method instead of using visit_alias() to have
access to line numbers and to filter imports from __future__.
"""
assert isinstance(node, (ast.Import, ast.ImportFrom))
for name_and_alias in node.names:
# Store only top-level module name ("os.path" -> "os").
# We can't easily detect when "os.path" is used.
name = name_and_alias.name.partition('.')[0]
alias = name_and_alias.asname
self._define(
self.defined_imports, alias or name, node,
confidence=90, ignore=_ignore_import)
if alias is not None:
self.used_names.add(name_and_alias.name)
def test_classdef(self):
def cls(bases=None, keywords=None, starargs=None, kwargs=None,
body=None, decorator_list=None):
if bases is None:
bases = []
if keywords is None:
keywords = []
if body is None:
body = [ast.Pass()]
if decorator_list is None:
decorator_list = []
return ast.ClassDef("myclass", bases, keywords, starargs,
kwargs, body, decorator_list)
self.stmt(cls(bases=[ast.Name("x", ast.Store())]),
"must have Load context")
self.stmt(cls(keywords=[ast.keyword("x", ast.Name("x", ast.Store()))]),
"must have Load context")
self.stmt(cls(starargs=ast.Name("x", ast.Store())),
"must have Load context")
self.stmt(cls(kwargs=ast.Name("x", ast.Store())),
"must have Load context")
self.stmt(cls(body=[]), "empty body on ClassDef")
self.stmt(cls(body=[None]), "None disallowed")
self.stmt(cls(decorator_list=[ast.Name("x", ast.Store())]),
"must have Load context")
def test_subscript(self):
sub = ast.Subscript(ast.Name("x", ast.Store()), ast.Index(ast.Num(3)),
ast.Load())
self.expr(sub, "must have Load context")
x = ast.Name("x", ast.Load())
sub = ast.Subscript(x, ast.Index(ast.Name("y", ast.Store())),
ast.Load())
self.expr(sub, "must have Load context")
s = ast.Name("x", ast.Store())
for args in (s, None, None), (None, s, None), (None, None, s):
sl = ast.Slice(*args)
self.expr(ast.Subscript(x, sl, ast.Load()),
"must have Load context")
sl = ast.ExtSlice([])
self.expr(ast.Subscript(x, sl, ast.Load()), "empty dims on ExtSlice")
sl = ast.ExtSlice([ast.Index(s)])
self.expr(ast.Subscript(x, sl, ast.Load()), "must have Load context")
def pop_format_context(self, expl_expr):
"""Format the %-formatted string with current format context.
The expl_expr should be an ast.Str instance constructed from
the %-placeholders created by .explanation_param(). This will
add the required code to format said string to .on_failure and
return the ast.Name instance of the formatted string.
"""
current = self.stack.pop()
if self.stack:
self.explanation_specifiers = self.stack[-1]
keys = [ast.Str(key) for key in current.keys()]
format_dict = ast.Dict(keys, list(current.values()))
form = ast.BinOp(expl_expr, ast.Mod(), format_dict)
name = "@py_format" + str(next(self.variable_counter))
self.on_failure.append(ast.Assign([ast.Name(name, ast.Store())], form))
return ast.Name(name, ast.Load())
def pop_format_context(self, expl_expr):
"""Format the %-formatted string with current format context.
The expl_expr should be an ast.Str instance constructed from
the %-placeholders created by .explanation_param(). This will
add the required code to format said string to .on_failure and
return the ast.Name instance of the formatted string.
"""
current = self.stack.pop()
if self.stack:
self.explanation_specifiers = self.stack[-1]
keys = [ast.Str(key) for key in current.keys()]
format_dict = ast.Dict(keys, list(current.values()))
form = ast.BinOp(expl_expr, ast.Mod(), format_dict)
name = "@py_format" + str(next(self.variable_counter))
self.on_failure.append(ast.Assign([ast.Name(name, ast.Store())], form))
return ast.Name(name, ast.Load())
def _namespace_set(self, node, value, unset=False):
if value is not UNSET:
if isinstance(node, ast.Name) and isinstance(node.ctx, ast.Store):
names = (node.id,)
else:
names = get_ast_names(node)
value = UNSET
else:
names = get_ast_names(node)
if names is None:
if self.namespace.enter_unknown_state():
self.log(node,
"enter unknown namespace state: "
"don't support assignment %s",
compact_dump(node))
return False
for name in names:
if unset:
self.namespace.unset(name)
else:
self.namespace.set(name, value)
return True
def to_source_any(n):
"""
Convert AST node to string, handling all node types, without fixing comments.
"""
try:
return astor.to_source(n)
except AttributeError:
pass
cls = n.__class__
if cls in astor.misc.all_symbols:
return astor.misc.all_symbols[cls]
def wrap(s):
return '___' + s + '___'
extra_d = {ast.Load: wrap('load'),
ast.Store: wrap('store'),
ast.Del: wrap('del'),
ast.AugLoad: wrap('augload'),
ast.AugStore: wrap('augstore'),
ast.Param: wrap('param'),
ast.keyword: wrap('keyword')}
if cls in extra_d:
return extra_d[cls]
raise AttributeError('unknown node type {}'.format(cls))
def NAME(self, node):
"""
Handle occurrence of Name (which can be a load/store/delete access.)
"""
# Locate the name in locals / function / globals scopes.
if isinstance(node.ctx, (ast.Load, ast.AugLoad)):
self.handleNodeLoad(node)
if (node.id == 'locals' and isinstance(self.scope, FunctionScope)
and isinstance(node.parent, ast.Call)):
# we are doing locals() call in current scope
self.scope.usesLocals = True
elif isinstance(node.ctx, (ast.Store, ast.AugStore)):
self.handleNodeStore(node)
elif isinstance(node.ctx, ast.Del):
self.handleNodeDelete(node)
else:
# must be a Param context -- this only happens for names in function
# arguments, but these aren't dispatched through here
raise RuntimeError("Got impossible expression context: %r" % (node.ctx,))
def TUPLE(self, node):
if not PY2 and isinstance(node.ctx, ast.Store):
# Python 3 advanced tuple unpacking: a, *b, c = d.
# Only one starred expression is allowed, and no more than 1<<8
# assignments are allowed before a stared expression. There is
# also a limit of 1<<24 expressions after the starred expression,
# which is impossible to test due to memory restrictions, but we
# add it here anyway
has_starred = False
star_loc = -1
for i, n in enumerate(node.elts):
if isinstance(n, ast.Starred):
if has_starred:
self.report(messages.TwoStarredExpressions, node)
# The SyntaxError doesn't distinguish two from more
# than two.
break
has_starred = True
star_loc = i
if star_loc >= 1 << 8 or len(node.elts) - star_loc - 1 >= 1 << 24:
self.report(messages.TooManyExpressionsInStarredAssignment, node)
self.handleChildren(node)
def subs(root, **kwargs):
'''Substitute ast.Name nodes for numbers in root using the mapping in
kwargs. Returns a new copy of root.
'''
root = copy.deepcopy(root)
class Transformer(ast.NodeTransformer):
def visit_FunctionDef(self, node):
return node
def visit_Name(self, node):
if node.id in kwargs and not isinstance(node.ctx, ast.Store):
replacement = kwargs[node.id]
if isinstance(replacement, int):
return ast.copy_location(ast.Num(n=replacement), node)
else:
return copy.copy(replacement)
else:
return node
return Transformer().visit(root)
def test_classdef(self):
def cls(bases=None, keywords=None, starargs=None, kwargs=None,
body=None, decorator_list=None):
if bases is None:
bases = []
if keywords is None:
keywords = []
if body is None:
body = [ast.Pass()]
if decorator_list is None:
decorator_list = []
return ast.ClassDef("myclass", bases, keywords, starargs,
kwargs, body, decorator_list)
self.stmt(cls(bases=[ast.Name("x", ast.Store())]),
"must have Load context")
self.stmt(cls(keywords=[ast.keyword("x", ast.Name("x", ast.Store()))]),
"must have Load context")
self.stmt(cls(starargs=ast.Name("x", ast.Store())),
"must have Load context")
self.stmt(cls(kwargs=ast.Name("x", ast.Store())),
"must have Load context")
self.stmt(cls(body=[]), "empty body on ClassDef")
self.stmt(cls(body=[None]), "None disallowed")
self.stmt(cls(decorator_list=[ast.Name("x", ast.Store())]),
"must have Load context")
def test_subscript(self):
sub = ast.Subscript(ast.Name("x", ast.Store()), ast.Index(ast.Num(3)),
ast.Load())
self.expr(sub, "must have Load context")
x = ast.Name("x", ast.Load())
sub = ast.Subscript(x, ast.Index(ast.Name("y", ast.Store())),
ast.Load())
self.expr(sub, "must have Load context")
s = ast.Name("x", ast.Store())
for args in (s, None, None), (None, s, None), (None, None, s):
sl = ast.Slice(*args)
self.expr(ast.Subscript(x, sl, ast.Load()),
"must have Load context")
sl = ast.ExtSlice([])
self.expr(ast.Subscript(x, sl, ast.Load()), "empty dims on ExtSlice")
sl = ast.ExtSlice([ast.Index(s)])
self.expr(ast.Subscript(x, sl, ast.Load()), "must have Load context")
def visit_Assert(self, node):
"""Replace assertions with augmented assignments."""
self.max_score += 1
return ast.AugAssign(
op=ast.Add(),
target=ast.Name(
id=self.score_var_name,
ctx=ast.Store()
),
value=ast.Call(
args=[node.test],
func=ast.Name(
id='bool',
ctx=ast.Load()
),
keywords=[],
kwargs=None,
starargs=None
)
)
def NAME(self, node):
"""
Handle occurrence of Name (which can be a load/store/delete access.)
"""
# Locate the name in locals / function / globals scopes.
if isinstance(node.ctx, (ast.Load, ast.AugLoad)):
self.handleNodeLoad(node)
if (node.id == 'locals' and isinstance(self.scope, FunctionScope)
and isinstance(node.parent, ast.Call)):
# we are doing locals() call in current scope
self.scope.usesLocals = True
elif isinstance(node.ctx, (ast.Store, ast.AugStore)):
self.handleNodeStore(node)
elif isinstance(node.ctx, ast.Del):
self.handleNodeDelete(node)
else:
# must be a Param context -- this only happens for names in function
# arguments, but these aren't dispatched through here
raise RuntimeError("Got impossible expression context: %r" % (node.ctx,))
def TUPLE(self, node):
if not PY2 and isinstance(node.ctx, ast.Store):
# Python 3 advanced tuple unpacking: a, *b, c = d.
# Only one starred expression is allowed, and no more than 1<<8
# assignments are allowed before a stared expression. There is
# also a limit of 1<<24 expressions after the starred expression,
# which is impossible to test due to memory restrictions, but we
# add it here anyway
has_starred = False
star_loc = -1
for i, n in enumerate(node.elts):
if isinstance(n, ast.Starred):
if has_starred:
self.report(messages.TwoStarredExpressions, node)
# The SyntaxError doesn't distinguish two from more
# than two.
break
has_starred = True
star_loc = i
if star_loc >= 1 << 8 or len(node.elts) - star_loc - 1 >= 1 << 24:
self.report(messages.TooManyExpressionsInStarredAssignment, node)
self.handleChildren(node)
def test_classdef(self):
def cls(bases=None, keywords=None, starargs=None, kwargs=None,
body=None, decorator_list=None):
if bases is None:
bases = []
if keywords is None:
keywords = []
if body is None:
body = [ast.Pass()]
if decorator_list is None:
decorator_list = []
return ast.ClassDef("myclass", bases, keywords, starargs,
kwargs, body, decorator_list)
self.stmt(cls(bases=[ast.Name("x", ast.Store())]),
"must have Load context")
self.stmt(cls(keywords=[ast.keyword("x", ast.Name("x", ast.Store()))]),
"must have Load context")
self.stmt(cls(starargs=ast.Name("x", ast.Store())),
"must have Load context")
self.stmt(cls(kwargs=ast.Name("x", ast.Store())),
"must have Load context")
self.stmt(cls(body=[]), "empty body on ClassDef")
self.stmt(cls(body=[None]), "None disallowed")
self.stmt(cls(decorator_list=[ast.Name("x", ast.Store())]),
"must have Load context")
def test_subscript(self):
sub = ast.Subscript(ast.Name("x", ast.Store()), ast.Index(ast.Num(3)),
ast.Load())
self.expr(sub, "must have Load context")
x = ast.Name("x", ast.Load())
sub = ast.Subscript(x, ast.Index(ast.Name("y", ast.Store())),
ast.Load())
self.expr(sub, "must have Load context")
s = ast.Name("x", ast.Store())
for args in (s, None, None), (None, s, None), (None, None, s):
sl = ast.Slice(*args)
self.expr(ast.Subscript(x, sl, ast.Load()),
"must have Load context")
sl = ast.ExtSlice([])
self.expr(ast.Subscript(x, sl, ast.Load()), "empty dims on ExtSlice")
sl = ast.ExtSlice([ast.Index(s)])
self.expr(ast.Subscript(x, sl, ast.Load()), "must have Load context")
def pop_format_context(self, expl_expr):
"""Format the %-formatted string with current format context.
The expl_expr should be an ast.Str instance constructed from
the %-placeholders created by .explanation_param(). This will
add the required code to format said string to .on_failure and
return the ast.Name instance of the formatted string.
"""
current = self.stack.pop()
if self.stack:
self.explanation_specifiers = self.stack[-1]
keys = [ast.Str(key) for key in current.keys()]
format_dict = ast.Dict(keys, list(current.values()))
form = ast.BinOp(expl_expr, ast.Mod(), format_dict)
name = "@py_format" + str(next(self.variable_counter))
self.on_failure.append(ast.Assign([ast.Name(name, ast.Store())], form))
return ast.Name(name, ast.Load())
def visit(self, node):
if type(node) in (list, str, type(None), ast.Store, ast.Load):
return
if isinstance(node, (int, str)):
self.write(str(node))
return
name = node.__class__.__name__
try:
walker = getattr(self, 'visit_' + name)
except AttributeError:
print()
print('node:', name, file=sys.stderr)
print('data:', node.__dict__, file=sys.stderr)
astor.dump(node)
raise NotImplementedError('node type not supported: %s' % name)
walker(node)
def NAME(self, node):
"""
Handle occurrence of Name (which can be a load/store/delete access.)
"""
# Locate the name in locals / function / globals scopes.
if isinstance(node.ctx, (ast.Load, ast.AugLoad)):
self.handleNodeLoad(node)
if (node.id == 'locals' and isinstance(self.scope, FunctionScope)
and isinstance(node.parent, ast.Call)):
# we are doing locals() call in current scope
self.scope.usesLocals = True
elif isinstance(node.ctx, (ast.Store, ast.AugStore)):
self.handleNodeStore(node)
elif isinstance(node.ctx, ast.Del):
self.handleNodeDelete(node)
else:
# must be a Param context -- this only happens for names in function
# arguments, but these aren't dispatched through here
raise RuntimeError("Got impossible expression context: %r" % (node.ctx,))
def maybe_assignment(*expr_fns):
if len(expr_fns) == 1:
node0 = expr_fns[0](ast.Load())
stmt = ast.Expr(node0)
else:
lhses = [fn(ast.Store()) for fn in expr_fns[:-1]]
node0 = lhses[0]
stmt = ast.Assign(lhses, expr_fns[-1](ast.Load()))
return ast.copy_location(stmt, node0)
def visit_Attribute(self, t):
self(t.value)
self.check_identifier(t.attr)
if isinstance(t.ctx, ast.Load): pass
elif isinstance(t.ctx, ast.Store): pass
else: assert False, "Only loads and stores are supported: %r" % (t,)
def visit_Subscript(self, t):
self(t.value)
if isinstance(t.slice, ast.Index):
if isinstance(t.ctx, ast.Load): pass
elif isinstance(t.ctx, ast.Store): pass
else: assert False, "Only loads and stores are supported: %r" % (t,)
self(t.slice.value)
else:
assert False, "Only simple subscripts are supported: %r" % (t,)
def visit_Name(self, t):
self.check_identifier(t.id)
if isinstance(t.ctx, ast.Load): pass
elif isinstance(t.ctx, ast.Store): pass
else: assert False, "Only loads and stores are supported: %r" % (t,)
def visit_sequence(self, t):
self(t.elts)
# XXX make sure there are no stars in elts
if isinstance(t.ctx, ast.Load): pass
elif isinstance(t.ctx, ast.Store): pass
else: assert False, "Only loads and stores are supported: %r" % (t,)
def visit_sequence(self, t, build_op):
if isinstance(t.ctx, ast.Load):
return self(t.elts) + build_op(len(t.elts))
elif isinstance(t.ctx, ast.Store):
return op.UNPACK_SEQUENCE(len(t.elts)) + self(t.elts)
else:
assert False
def visit_Name(self, t):
if isinstance(t.ctx, ast.Load): self.uses.add(t.id)
elif isinstance(t.ctx, ast.Store): self.defs.add(t.id)
else: assert False