def visit_Call_35(self, call):
"""
visit `ast.Call` nodes on Python3.5 and after
"""
new_func, func_expl = self.visit(call.func)
arg_expls = []
new_args = []
new_kwargs = []
for arg in call.args:
res, expl = self.visit(arg)
arg_expls.append(expl)
new_args.append(res)
for keyword in call.keywords:
res, expl = self.visit(keyword.value)
new_kwargs.append(ast.keyword(keyword.arg, res))
if keyword.arg:
arg_expls.append(keyword.arg + "=" + expl)
else: ## **args have `arg` keywords with an .arg of None
arg_expls.append("**" + expl)
expl = "%s(%s)" % (func_expl, ', '.join(arg_expls))
new_call = ast.Call(new_func, new_args, new_kwargs)
res = self.assign(new_call)
res_expl = self.explanation_param(self.display(res))
outer_expl = "%s\n{%s = %s\n}" % (res_expl, res_expl, expl)
return res, outer_expl
python类keyword()的实例源码
def visit_Call_legacy(self, call):
"""
visit `ast.Call nodes on 3.4 and below`
"""
new_func, func_expl = self.visit(call.func)
arg_expls = []
new_args = []
new_kwargs = []
new_star = new_kwarg = None
for arg in call.args:
res, expl = self.visit(arg)
new_args.append(res)
arg_expls.append(expl)
for keyword in call.keywords:
res, expl = self.visit(keyword.value)
new_kwargs.append(ast.keyword(keyword.arg, res))
arg_expls.append(keyword.arg + "=" + expl)
if call.starargs:
new_star, expl = self.visit(call.starargs)
arg_expls.append("*" + expl)
if call.kwargs:
new_kwarg, expl = self.visit(call.kwargs)
arg_expls.append("**" + expl)
expl = "%s(%s)" % (func_expl, ', '.join(arg_expls))
new_call = ast.Call(new_func, new_args, new_kwargs,
new_star, new_kwarg)
res = self.assign(new_call)
res_expl = self.explanation_param(self.display(res))
outer_expl = "%s\n{%s = %s\n}" % (res_expl, res_expl, expl)
return res, outer_expl
# ast.Call signature changed on 3.5,
# conditionally change which methods is named
# visit_Call depending on Python version
def get_keywords(callsite):
if not isinstance(callsite, ast.Call):
raise ValueError("ast.Call expected, got %s" % type(callsite))
keywords = callsite.keywords
if sys.version_info < (3, 5) and callsite.kwargs is not None:
keywords = keywords.copy()
keywords.append(ast.keyword(arg=None, value=callsite.kwargs))
return keywords
def apply_functions_xform(self, root):
class Transformer(self.MyTransformer):
def visit_FunctionDef(self_t, node):
""" Don't recurse into user defined functions """
return node
def visit_Module(self_t, node):
class Visitor(ast.NodeVisitor):
def visit_Module(self_v, node):
self_v.defined_function_names = []
self_v.generic_visit(node)
def visit_FunctionDef(self_v, node):
self_v.defined_function_names.append(node.name)
v = Visitor()
v.visit(node)
self_t.defined_function_names = v.defined_function_names
self_t.generic_visit(node)
return node
def visit_Expr(self_t, node):
if u.is_set_to_user_defined_function(node):
var_name = node.value.func.value.id
call_node = node.value.args[0]
function_name = call_node.func.id
assert function_name in self_t.defined_function_names, \
"Attempting to use undefined function: %s" % function_name
call_node.args.insert(0, ast.Name(id="%s_tensor" % function_name))
call_node.func = ast.Attribute(value=ast.Name(id="tpt"),
attr="apply_factor")
scope = "%s_apply_factor" % var_name
call_node.keywords = [ast.keyword(arg="scope", value=ast.Str(s=scope))]
return node
return Transformer().visit(root)
def test_iter_child_nodes(self):
node = ast.parse("spam(23, 42, eggs='leek')", mode='eval')
self.assertEqual(len(list(ast.iter_child_nodes(node.body))), 4)
iterator = ast.iter_child_nodes(node.body)
self.assertEqual(next(iterator).id, 'spam')
self.assertEqual(next(iterator).n, 23)
self.assertEqual(next(iterator).n, 42)
self.assertEqual(ast.dump(next(iterator)),
"keyword(arg='eggs', value=Str(s='leek'))"
)
def __init__(self, operators=None, functions=None, names=None):
"""
Create the evaluator instance. Set up valid operators (+,-, etc)
functions (add, random, get_val, whatever) and names. """
if not operators:
operators = DEFAULT_OPERATORS
if not functions:
functions = DEFAULT_FUNCTIONS
if not names:
names = DEFAULT_NAMES
self.operators = operators
self.functions = functions
self.names = names
self.nodes = {
ast.Num: self._eval_num,
ast.Str: self._eval_str,
ast.Name: self._eval_name,
ast.UnaryOp: self._eval_unaryop,
ast.BinOp: self._eval_binop,
ast.BoolOp: self._eval_boolop,
ast.Compare: self._eval_compare,
ast.IfExp: self._eval_ifexp,
ast.Call: self._eval_call,
ast.keyword: self._eval_keyword,
ast.Subscript: self._eval_subscript,
ast.Attribute: self._eval_attribute,
ast.Index: self._eval_index,
ast.Slice: self._eval_slice,
}
# py3k stuff:
if hasattr(ast, 'NameConstant'):
self.nodes[ast.NameConstant] = self._eval_nameconstant
elif isinstance(self.names, dict) and "None" not in self.names:
self.names["None"] = None
def auto_symbol(tokens, local_dict, global_dict):
"""Inserts calls to ``Symbol`` for undefined variables."""
result = []
prevTok = (None, None)
tokens.append((None, None)) # so zip traverses all tokens
for tok, nextTok in zip(tokens, tokens[1:]):
tokNum, tokVal = tok
nextTokNum, nextTokVal = nextTok
if tokNum == NAME:
name = tokVal
if (name in ['True', 'False', 'None']
or iskeyword(name)
or name in local_dict
# Don't convert attribute access
or (prevTok[0] == OP and prevTok[1] == '.')
# Don't convert keyword arguments
or (prevTok[0] == OP and prevTok[1] in ('(', ',')
and nextTokNum == OP and nextTokVal == '=')):
result.append((NAME, name))
continue
elif name in global_dict:
obj = global_dict[name]
if isinstance(obj, (Basic, type)) or callable(obj):
result.append((NAME, name))
continue
result.extend([
(NAME, 'Symbol'),
(OP, '('),
(NAME, repr(str(name))),
(OP, ')'),
])
else:
result.append((tokNum, tokVal))
prevTok = (tokNum, tokVal)
return result
def make_pydata_entry(key, value):
return FavaCode(
keyword(arg=key, value=value.get_ast()),
[value])
def create_super_call(self, node):
super_call = utils.create_ast('super().{}()'.format(node.name)).body[0]
for arg in node.args.args[1:-len(node.args.defaults) or None]:
super_call.value.args.append(ast.Name(id=arg.arg, ctx=ast.Load()))
for arg, default in zip(node.args.args[-len(node.args.defaults):], node.args.defaults):
super_call.value.keywords.append(ast.keyword(arg=arg.arg, value=default))
for arg, default in zip(node.args.kwonlyargs, node.args.kw_defaults):
super_call.value.keywords.append(ast.keyword(arg=arg.arg, value=default))
if node.args.vararg:
self.add_vararg_to_super_call(super_call, node.args.vararg)
if node.args.kwarg:
self.add_kwarg_to_super_call(super_call, node.args.kwarg)
return super_call
def add_kwarg_to_super_call(super_call, kwarg):
super_call.value.keywords.append(ast.keyword(arg=None, value=ast.Name(id=kwarg.arg, ctx=ast.Load())))
def test_iter_child_nodes(self):
node = ast.parse("spam(23, 42, eggs='leek')", mode='eval')
self.assertEqual(len(list(ast.iter_child_nodes(node.body))), 4)
iterator = ast.iter_child_nodes(node.body)
self.assertEqual(next(iterator).id, 'spam')
self.assertEqual(next(iterator).n, 23)
self.assertEqual(next(iterator).n, 42)
self.assertEqual(ast.dump(next(iterator)),
"keyword(arg='eggs', value=Str(s='leek'))"
)
def visit_Call_35(self, call):
"""
visit `ast.Call` nodes on Python3.5 and after
"""
new_func, func_expl = self.visit(call.func)
arg_expls = []
new_args = []
new_kwargs = []
for arg in call.args:
res, expl = self.visit(arg)
arg_expls.append(expl)
new_args.append(res)
for keyword in call.keywords:
res, expl = self.visit(keyword.value)
new_kwargs.append(ast.keyword(keyword.arg, res))
if keyword.arg:
arg_expls.append(keyword.arg + "=" + expl)
else: ## **args have `arg` keywords with an .arg of None
arg_expls.append("**" + expl)
expl = "%s(%s)" % (func_expl, ', '.join(arg_expls))
new_call = ast.Call(new_func, new_args, new_kwargs)
res = self.assign(new_call)
res_expl = self.explanation_param(self.display(res))
outer_expl = "%s\n{%s = %s\n}" % (res_expl, res_expl, expl)
return res, outer_expl
def visit_Call_legacy(self, call):
"""
visit `ast.Call nodes on 3.4 and below`
"""
new_func, func_expl = self.visit(call.func)
arg_expls = []
new_args = []
new_kwargs = []
new_star = new_kwarg = None
for arg in call.args:
res, expl = self.visit(arg)
new_args.append(res)
arg_expls.append(expl)
for keyword in call.keywords:
res, expl = self.visit(keyword.value)
new_kwargs.append(ast.keyword(keyword.arg, res))
arg_expls.append(keyword.arg + "=" + expl)
if call.starargs:
new_star, expl = self.visit(call.starargs)
arg_expls.append("*" + expl)
if call.kwargs:
new_kwarg, expl = self.visit(call.kwargs)
arg_expls.append("**" + expl)
expl = "%s(%s)" % (func_expl, ', '.join(arg_expls))
new_call = ast.Call(new_func, new_args, new_kwargs,
new_star, new_kwarg)
res = self.assign(new_call)
res_expl = self.explanation_param(self.display(res))
outer_expl = "%s\n{%s = %s\n}" % (res_expl, res_expl, expl)
return res, outer_expl
# ast.Call signature changed on 3.5,
# conditionally change which methods is named
# visit_Call depending on Python version
def peval_call(state, ctx, func, args=[], keywords=[]):
assert all(type(arg) != ast.Starred for arg in args)
assert all(kw.arg is not None for kw in keywords)
keyword_expressions = [kw.value for kw in keywords]
state, results = map_peval_expression(
state, dict(func=func, args=args, keywords=keyword_expressions), ctx)
if all_known_values_or_none(results):
values = map_get_value(results)
kwds = {kw.arg: value for kw, value in zip(keywords, values['keywords'])}
success, value = try_eval_call(
values['func'], args=values['args'], keywords=kwds)
if success:
return state, KnownValue(value=value)
state, nodes = map_reify(state, results)
# restoring the keyword list
nodes['keywords'] = [
ast.keyword(arg=kw.arg, value=expr)
for kw, expr in zip(keywords, nodes['keywords'])]
return state, ast.Call(**nodes)
def jinja2_autoescape_false(context):
# check type just to be safe
if isinstance(context.call_function_name_qual, str):
qualname_list = context.call_function_name_qual.split('.')
func = qualname_list[-1]
if 'jinja2' in qualname_list and func == 'Environment':
for node in ast.walk(context.node):
if isinstance(node, ast.keyword):
# definite autoescape = False
if (getattr(node, 'arg', None) == 'autoescape' and
(getattr(node.value, 'id', None) == 'False' or
getattr(node.value, 'value', None) is False)):
return bandit.Issue(
severity=bandit.HIGH,
confidence=bandit.HIGH,
text="Using jinja2 templates with autoescape="
"False is dangerous and can lead to XSS. "
"Use autoescape=True or use the "
"select_autoescape function to mitigate XSS "
"vulnerabilities."
)
# found autoescape
if getattr(node, 'arg', None) == 'autoescape':
value = getattr(node, 'value', None)
if (getattr(value, 'id', None) == 'True' or
getattr(value, 'value', None) is True):
return
# Check if select_autoescape function is used.
elif isinstance(value, ast.Call) and getattr(
value.func, 'id', None) == 'select_autoescape':
return
else:
return bandit.Issue(
severity=bandit.HIGH,
confidence=bandit.MEDIUM,
text="Using jinja2 templates with autoescape="
"False is dangerous and can lead to XSS. "
"Ensure autoescape=True or use the "
"select_autoescape function to mitigate "
"XSS vulnerabilities."
)
# We haven't found a keyword named autoescape, indicating default
# behavior
return bandit.Issue(
severity=bandit.HIGH,
confidence=bandit.HIGH,
text="By default, jinja2 sets autoescape to False. Consider "
"using autoescape=True or use the select_autoescape "
"function to mitigate XSS vulnerabilities."
)
expr.py 文件源码
项目:PyDataLondon29-EmbarrassinglyParallelDAWithAWSLambda
作者: SignalMedia
项目源码
文件源码
阅读 28
收藏 0
点赞 0
评论 0
def visit_Call_35(self, node, side=None, **kwargs):
""" in 3.5 the starargs attribute was changed to be more flexible,
#11097 """
if isinstance(node.func, ast.Attribute):
res = self.visit_Attribute(node.func)
elif not isinstance(node.func, ast.Name):
raise TypeError("Only named functions are supported")
else:
try:
res = self.visit(node.func)
except UndefinedVariableError:
# Check if this is a supported function name
try:
res = FuncNode(node.func.id)
except ValueError:
# Raise original error
raise
if res is None:
raise ValueError("Invalid function call {0}".format(node.func.id))
if hasattr(res, 'value'):
res = res.value
if isinstance(res, FuncNode):
new_args = [self.visit(arg) for arg in node.args]
if node.keywords:
raise TypeError("Function \"{0}\" does not support keyword "
"arguments".format(res.name))
return res(*new_args, **kwargs)
else:
new_args = [self.visit(arg).value for arg in node.args]
for key in node.keywords:
if not isinstance(key, ast.keyword):
raise ValueError("keyword error in function call "
"'{0}'".format(node.func.id))
if key.arg:
# TODO: bug?
kwargs.append(ast.keyword(
keyword.arg, self.visit(keyword.value))) # noqa
return self.const_type(res(*new_args, **kwargs), self.env)
expr.py 文件源码
项目:PyDataLondon29-EmbarrassinglyParallelDAWithAWSLambda
作者: SignalMedia
项目源码
文件源码
阅读 28
收藏 0
点赞 0
评论 0
def visit_Call_legacy(self, node, side=None, **kwargs):
# this can happen with: datetime.datetime
if isinstance(node.func, ast.Attribute):
res = self.visit_Attribute(node.func)
elif not isinstance(node.func, ast.Name):
raise TypeError("Only named functions are supported")
else:
try:
res = self.visit(node.func)
except UndefinedVariableError:
# Check if this is a supported function name
try:
res = FuncNode(node.func.id)
except ValueError:
# Raise original error
raise
if res is None:
raise ValueError("Invalid function call {0}".format(node.func.id))
if hasattr(res, 'value'):
res = res.value
if isinstance(res, FuncNode):
args = [self.visit(targ) for targ in node.args]
if node.starargs is not None:
args += self.visit(node.starargs)
if node.keywords or node.kwargs:
raise TypeError("Function \"{0}\" does not support keyword "
"arguments".format(res.name))
return res(*args, **kwargs)
else:
args = [self.visit(targ).value for targ in node.args]
if node.starargs is not None:
args += self.visit(node.starargs).value
keywords = {}
for key in node.keywords:
if not isinstance(key, ast.keyword):
raise ValueError("keyword error in function call "
"'{0}'".format(node.func.id))
keywords[key.arg] = self.visit(key.value).value
if node.kwargs is not None:
keywords.update(self.visit(node.kwargs).value)
return self.const_type(res(*args, **keywords), self.env)
def visit_BinOp(self, node):
if node.op.__class__ in self.operators:
sympy_class = self.operators[node.op.__class__]
right = self.visit(node.right)
left = self.visit(node.left)
if isinstance(node.left, ast.UnaryOp) and (isinstance(node.right, ast.UnaryOp) == 0) and sympy_class in ('Mul',):
left, right = right, left
if isinstance(node.op, ast.Sub):
right = ast.UnaryOp(op=ast.USub(), operand=right)
if isinstance(node.op, ast.Div):
if isinstance(node.left, ast.UnaryOp):
if isinstance(node.right,ast.UnaryOp):
left, right = right, left
left = ast.Call(
func=ast.Name(id='Pow', ctx=ast.Load()),
args=[left, ast.UnaryOp(op=ast.USub(), operand=ast.Num(1))],
keywords=[ast.keyword(arg='evaluate', value=ast.Name(id='False', ctx=ast.Load()))],
starargs=None,
kwargs=None
)
else:
right = ast.Call(
func=ast.Name(id='Pow', ctx=ast.Load()),
args=[right, ast.UnaryOp(op=ast.USub(), operand=ast.Num(1))],
keywords=[ast.keyword(arg='evaluate', value=ast.Name(id='False', ctx=ast.Load()))],
starargs=None,
kwargs=None
)
new_node = ast.Call(
func=ast.Name(id=sympy_class, ctx=ast.Load()),
args=[left, right],
keywords=[ast.keyword(arg='evaluate', value=ast.Name(id='False', ctx=ast.Load()))],
starargs=None,
kwargs=None
)
if sympy_class in ('Add', 'Mul'):
# Denest Add or Mul as appropriate
new_node.args = self.flatten(new_node.args, sympy_class)
return new_node
return node