我们从Python开源项目中,提取了以下42个代码示例,用于说明如何使用ast.Dict()。
def __init__(self, expr, context): self.expr = expr self.context = context self.expr_table = { LLLnode: self.get_expr, ast.Num: self.number, ast.Str: self.string, ast.NameConstant: self.constants, ast.Name: self.variables, ast.Attribute: self.attribute, ast.Subscript: self.subscript, ast.BinOp: self.arithmetic, ast.Compare: self.compare, ast.BoolOp: self.boolean_operations, ast.UnaryOp: self.unary_operations, ast.Call: self.call, ast.List: self.list_literals, ast.Dict: self.struct_literals, ast.Tuple: self.tuple_literals, } expr_type = self.expr.__class__ if expr_type in self.expr_table: self.lll_node = self.expr_table[expr_type]() else: raise Exception("Unsupported operator: %r" % ast.dump(self.expr))
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 _process_function_signature(stmt, arg_names, static_env): return_type = Ellipsis if isinstance(stmt, ast.Expr): value = stmt.value if isinstance(value, ast.BinOp): left, op, right = value.left, value.op, value.right if isinstance(op, ast.RShift): arg_types = fn._process_argument_signature(left, arg_names, static_env) return_type = static_env.eval_expr_ast(right) else: return None elif isinstance(value, ast.Dict) or isinstance(value, ast.Set): arg_types = fn._process_argument_signature(value, arg_names, static_env) else: return None else: return None if arg_types is None: return None return (arg_types, return_type)
def astFormat(x, gid=None): """Given a value, turn it into an AST if it's a constant; otherwise, leave it alone.""" if type(x) in [int, float, complex]: return ast.Num(x) elif type(x) == bool or x == None: return ast.NameConstant(x) elif type(x) == type: types = { bool : "bool", int : "int", float : "float", complex : "complex", str : "str", bytes : "bytes", unicode : "unicode", list : "list", tuple : "tuple", dict : "dict" } return ast.Name(types[x], ast.Load()) elif type(x) == str: # str or unicode return ast.Str(x) elif type(x) == bytes: return ast.Bytes(x) elif type(x) == list: elts = [astFormat(val) for val in x] return ast.List(elts, ast.Load()) elif type(x) == dict: keys = [] vals = [] for key in x: keys.append(astFormat(key)) vals.append(astFormat(x[key])) return ast.Dict(keys, vals) elif type(x) == tuple: elts = [astFormat(val) for val in x] return ast.Tuple(elts, ast.Load()) elif type(x) == set: elts = [astFormat(val) for val in x] if len(elts) == 0: # needs to be a call instead return ast.Call(ast.Name("set", ast.Load()), [], []) else: return ast.Set(elts) elif type(x) == slice: return ast.Slice(astFormat(x.start), astFormat(x.stop), astFormat(x.step)) elif isinstance(x, ast.AST): return x # Do not change if it's not constant! else: log("astTools\tastFormat\t" + str(type(x)) + "," + str(x),"bug") return None
def visit_Dict(self, node): """ Dict(expr* keys, expr* values) """ els = [] for k, v in zip(node.keys, node.values): if isinstance(k, ast.Name): els.append('"%s" => %s' % (self.visit(k), self.visit(v))) else: # ast.Str, ast.Num if self._dict_format == True: # ast.Str els.append("%s: %s" % (self.visit(k), self.visit(v))) else: # ast.Str, ast.Num els.append("%s => %s" % (self.visit(k), self.visit(v))) return "{%s}" % (", ".join(els))
def test_dict(self): d = ast.Dict([], [ast.Name("x", ast.Load())]) self.expr(d, "same number of keys as values") d = ast.Dict([None], [ast.Name("x", ast.Load())]) self.expr(d, "None disallowed") d = ast.Dict([ast.Name("x", ast.Load())], [None]) self.expr(d, "None disallowed")
def _get_assign_names(targets, load_names, store_names): for target in targets: orig_target = target target = _get_ast_name_node(target) if (isinstance(target, ast.Name) and isinstance(target.ctx, ast.Store)): # 'x = value': store name 'x' store_names.add(target.id) elif (isinstance(target, ast.Name) and isinstance(target.ctx, ast.Load)): # 'obj.attr = value': load name 'obj' load_names.add(target.id) elif isinstance(target, ast.Tuple): # x, y = ... _get_assign_names(target.elts, load_names, store_names) elif isinstance(target, ast.Constant): # '(1).__class__ = MyInt': it raises a TypeError raise ComplexAssignment(orig_target) elif isinstance(target, (ast.Dict, ast.List)): # '{...}[key] = ...', '[...][index] = ...' pass elif isinstance(target, ast.Call): # 'globals()[key] = value' # 'type(mock)._mock_check_sig = checksig' raise ComplexAssignment(orig_target) else: raise Exception("unsupported assign target: %s" % ast.dump(target))
def optimize_iterable(self, node): # it's already a constant, nothing to do if isinstance(node, ast.Constant): return # remplace empty dict (create at runtime) with an empty tuple # (constant) if isinstance(node, ast.Dict) and not node.keys: return self.new_constant(node, ()) # FIXME: optimize dict? value = get_literal(node, types=(list, set), constant_items=True) if value is UNSET: return if not value: # replace empty iterable with an empty tuple return self.new_constant(node, ()) if len(value) > self.config.max_seq_len: return if isinstance(value, list): return self.new_constant(node, tuple(value)) if isinstance(value, set): return self.new_constant(node, frozenset(value))
def _new_constant(node, value): if isinstance(value, ast.AST): # convenient shortcut: return the AST object unchanged return value # FIXME: test the config directly here? if value is None: new_node = ast.Constant(value=None) elif isinstance(value, (bool, int, float, complex, str, bytes)): new_node = ast.Constant(value=value) elif isinstance(value, (tuple, frozenset)): if not _is_constant(value): raise TypeError("container items are not constant: %r" % (value,)) new_node = ast.Constant(value=value) elif isinstance(value, list): elts = [_new_constant(node, elt) for elt in value] new_node = ast.List(elts=elts, ctx=ast.Load()) elif isinstance(value, dict): keys = [] values = [] for key, value in value.items(): keys.append(_new_constant(node, key)) values.append(_new_constant(node, value)) new_node = ast.Dict(keys=keys, values=values, ctx=ast.Load()) elif isinstance(value, set): elts = [_new_constant(node, elt) for elt in value] new_node = ast.Set(elts=elts, ctx=ast.Load()) else: raise TypeError("unknown type: %s" % type(value).__name__) copy_lineno(node, new_node) return new_node # FIXME: use functools.singledispatch?
def check_empty_dict(node): if not isinstance(node, ast.Dict): return if len(node.keys) == 0 and len(node.values) == 0: yield (node.lineno, 'init by {}')
def _check_string_formatting(self, node): [lhs, rhs] = [node.left, node.right] if isinstance(lhs, ast.Str): lhs = lhs.s else: return if isinstance(rhs, ast.Tuple): if sys.version_info >= (3, 5): if any(isinstance(elt, ast.Starred) for elt in rhs.elts): # pylint: disable=no-member return rhs = tuple( elt.s if isinstance(elt, ast.Str) else 0 for elt in rhs.elts ) elif isinstance(rhs, ast.Dict): new_rhs = {} for key, value in zip(rhs.keys, rhs.values): if isinstance(key, ast.Str): key = key.s else: return if isinstance(value, ast.Str): value = value.s else: value = 0 new_rhs[key] = value rhs = new_rhs elif isinstance(rhs, ast.Str): rhs = rhs.s elif isinstance(rhs, ast.Num): rhs = 0 else: return try: lhs % rhs except KeyError as exc: yield self.tag(node, 'string-formatting-error', 'missing key', str(exc)) except Exception as exc: # pylint: disable=broad-except yield self.tag(node, 'string-formatting-error', str(exc))
def __init__(self, operators=None, functions=None, names=None): super(EvalWithCompoundTypes, self).__init__(operators, functions, names) self.functions.update( list=list, tuple=tuple, dict=dict, set=set) self.nodes.update({ ast.Dict: self._eval_dict, ast.Tuple: self._eval_tuple, ast.List: self._eval_list, ast.Set: self._eval_set })
def find_dict_index(dict_node, key): """Given a key, find the index of the corresponding dict entry.""" assert dict_node.__class__ is ast.Dict, ast_err_msg(dict_node) indices = [i for i, n in enumerate(dict_node.keys) if n.__class__ is ast.Str and n.s == key] assert len(indices) < 2, ( 'Found redundant dict entries for key "%s"' % key) return indices[0] if indices else None
def ast_dict_index(dnode, key): """Search an ast.Dict for the argument key, and return its index.""" idx = [i for i in range(len(dnode.keys)) if ( type(dnode.keys[i]) is ast.Str and dnode.keys[i].s == key)] if not idx: return -1 elif len(idx) > 1: raise gclient_utils.Error('Multiple dict entries with same key in AST') return idx[-1]
def ast2str(node, indent=0): """Return a pretty-printed rendition of an ast.Node.""" t = type(node) if t is ast.Module: return '\n'.join([ast2str(x, indent) for x in node.body]) elif t is ast.Assign: return ((' ' * indent) + ' = '.join([ast2str(x) for x in node.targets] + [ast2str(node.value, indent)]) + '\n') elif t is ast.Name: return node.id elif t is ast.List: if not node.elts: return '[]' elif len(node.elts) == 1: return '[' + ast2str(node.elts[0], indent) + ']' return ('[\n' + (' ' * (indent + 1)) + (',\n' + (' ' * (indent + 1))).join( [ast2str(x, indent + 1) for x in node.elts]) + '\n' + (' ' * indent) + ']') elif t is ast.Dict: if not node.keys: return '{}' elif len(node.keys) == 1: return '{%s: %s}' % (ast2str(node.keys[0]), ast2str(node.values[0], indent + 1)) return ('{\n' + (' ' * (indent + 1)) + (',\n' + (' ' * (indent + 1))).join( ['%s: %s' % (ast2str(node.keys[i]), ast2str(node.values[i], indent + 1)) for i in range(len(node.keys))]) + '\n' + (' ' * indent) + '}') elif t is ast.Str: return "'%s'" % node.s else: raise gclient_utils.Error("Unexpected AST node at line %d, column %d: %s" % (node.lineno, node.col_offset, t))
def _get_ordered_child_nodes(node): if isinstance(node, ast.Dict): children = [] for i in range(len(node.keys)): children.append(node.keys[i]) children.append(node.values[i]) return children elif isinstance(node, ast.Call): children = [node.func] + node.args for kw in node.keywords: children.append(kw.value) # TODO: take care of Python 3.5 updates (eg. args=[Starred] and keywords) if hasattr(node, "starargs") and node.starargs is not None: children.append(node.starargs) if hasattr(node, "kwargs") and node.kwargs is not None: children.append(node.kwargs) children.sort(key=lambda x: (x.lineno, x.col_offset)) return children elif isinstance(node, ast.arguments): children = node.args + node.kwonlyargs + node.kw_defaults + node.defaults if node.vararg is not None: children.append(node.vararg) if node.kwarg is not None: children.append(node.kwarg) children.sort(key=lambda x: (x.lineno, x.col_offset)) return children else: return ast.iter_child_nodes(node)
def resolve_attr_id(node): if isinstance(node, (ast.Attribute, ast.Subscript)): value_id = None if isinstance(node.value, (ast.Name, ast.Attribute, ast.Subscript)): value_id = resolve_attr_id(node.value) elif isinstance(node.value, ast.Call): value_id = resolve_attr_id(node.value) elif isinstance(node.value, ast.Str): value_id = 'str' elif isinstance(node.value, ast.Bytes): value_id = 'bytes' elif isinstance(node.value, (ast.List, ast.ListComp)): value_id = 'list' elif isinstance(node.value, ast.Tuple): value_id = 'tuple' elif isinstance(node.value, (ast.Set, ast.SetComp)): value_id = 'set' elif isinstance(node.value, (ast.Dict, ast.DictComp)): value_id = 'dict' else: raise SyntaxError( 'unsupport type: {}'.format(ast.dump(node.value)) ) if isinstance(node, ast.Attribute): return '{}.{}'.format(value_id, node.attr) elif isinstance(node, ast.Subscript): slice = None if isinstance(node.slice.value, ast.Str): slice = node.slice.value.s elif isinstance(node.slice.value, ast.Num): slice = node.slice.value.n elif isinstance(node.slice.value, ast.Name): slice = resolve_attr_id(node.slice.value) return '{}[{}]'.format(value_id, slice) elif isinstance(node, ast.Call): return '{}()'.format(resolve_attr_id(node.func)) return node.id
def _process_argument_signature(value, arg_names, static_env): arg_types = [] if isinstance(value, ast.Dict): keys, values = value.keys, value.values n_keys = len(keys) n_args = len(arg_names) if n_keys != n_args: raise _errors.TyError( "Function specifies {0} arguments, " "but function signature specifies {1} arguments." .format(n_args, n_keys), value) for key, value, arg_name in zip(keys, values, arg_names): if not isinstance(key, ast.Name): raise _errors.TyError( "Argument name must be an identiifer.", key) sig_arg_name = key.id if sig_arg_name != arg_name: raise _errors.TyError( "Function specifies argument name {0}, but function " "signature specifies argument name {1}." .format(arg_name, key), key) arg_types.append(static_env.eval_expr_ast(value)) elif isinstance(value, ast.Set): elts = value.elts n_elts = len(elts) n_args = len(arg_names) if n_elts != n_args: raise _errors.TyError( "Function specifies {0} arguments, but function" "signature specifies {1} arguments." .format(n_args, n_elts), value) for elt in elts: arg_types.append(static_env.eval_expr_ast(elt)) else: raise _errors.TyError( "Argument signature must have the form of either a set " "or dict literal.", value) return tuple(arg_types)
def safe_eval(node_or_string, env): """ Safely evaluate an expression node or a string containing a Python expression. The string or node provided may only consist of the following Python literal structures: strings, numbers, tuples, lists, dicts, booleans, and None. """ _safe_names = {'None': None, 'True': True, 'False': False} _safe_names.update(env) if isinstance(node_or_string, basestring): node_or_string = ast.parse(node_or_string, mode='eval') if isinstance(node_or_string, ast.Expression): node_or_string = node_or_string.body def _convert(node): if isinstance(node, ast.Str): return node.s elif isinstance(node, ast.Num): return node.n elif isinstance(node, ast.Tuple): return tuple(map(_convert, node.elts)) elif isinstance(node, ast.List): return list(map(_convert, node.elts)) elif isinstance(node, ast.Dict): return dict((_convert(k), _convert(v)) for k, v in zip(node.keys, node.values)) elif isinstance(node, ast.Name): if node.id in _safe_names: return _safe_names[node.id] elif isinstance(node, ast.BinOp) and \ isinstance(node.op, (ast.Add, ast.Sub)) and \ isinstance(node.right, ast.Num) and \ isinstance(node.right.n, complex) and \ isinstance(node.left, ast.Num) and \ isinstance(node.left.n, (int, long, float)): left = node.left.n right = node.right.n if isinstance(node.op, ast.Add): return left + right else: return left - right raise ValueError('malformed string') return _convert(node_or_string)
def safe_eval(node_or_string, env): """ Safely evaluate an expression node or a string containing a Python expression. The string or node provided may only consist of the following Python literal structures: strings, numbers, tuples, lists, dicts, booleans, and None. """ _safe_names = {'None': None, 'True': True, 'False': False} _safe_names.update(env) if isinstance(node_or_string, basestring): node_or_string = ast_parse(node_or_string, mode='eval') if isinstance(node_or_string, ast.Expression): node_or_string = node_or_string.body def _convert(node): if isinstance(node, ast.Str): return node.s elif isinstance(node, ast.Num): return node.n elif isinstance(node, ast.Tuple): return tuple(map(_convert, node.elts)) elif isinstance(node, ast.List): return list(map(_convert, node.elts)) elif isinstance(node, ast.Dict): return dict((_convert(k), _convert(v)) for k, v in zip(node.keys, node.values)) elif isinstance(node, ast.Name): if node.id in _safe_names: return _safe_names[node.id] elif isinstance(node, ast.BinOp) and \ isinstance(node.op, (Add, Sub)) and \ isinstance(node.right, Num) and \ isinstance(node.right.n, complex) and \ isinstance(node.left, Num) and \ isinstance(node.left.n, (int, long, float)): left = node.left.n right = node.right.n if isinstance(node.op, Add): return left + right else: return left - right raise ValueError('malformed string') return _convert(node_or_string)
def test__get_literal_value(self): new_context = context.Context() value = ast.Num(42) expected = value.n self.assertEqual(expected, new_context._get_literal_value(value)) value = ast.Str('spam') expected = value.s self.assertEqual(expected, new_context._get_literal_value(value)) value = ast.List([ast.Str('spam'), ast.Num(42)], ast.Load()) expected = [ast.Str('spam').s, ast.Num(42).n] self.assertListEqual(expected, new_context._get_literal_value(value)) value = ast.Tuple([ast.Str('spam'), ast.Num(42)], ast.Load()) expected = (ast.Str('spam').s, ast.Num(42).n) self.assertTupleEqual(expected, new_context._get_literal_value(value)) value = ast.Set([ast.Str('spam'), ast.Num(42)]) expected = set([ast.Str('spam').s, ast.Num(42).n]) self.assertSetEqual(expected, new_context._get_literal_value(value)) value = ast.Dict(['spam', 'eggs'], [42, 'foo']) expected = dict(spam=42, eggs='foo') self.assertDictEqual(expected, new_context._get_literal_value(value)) value = ast.Ellipsis() self.assertIsNone(new_context._get_literal_value(value)) value = ast.Name('spam', ast.Load()) expected = value.id self.assertEqual(expected, new_context._get_literal_value(value)) if six.PY3: value = ast.NameConstant(True) expected = str(value.value) self.assertEqual(expected, new_context._get_literal_value(value)) if six.PY3: value = ast.Bytes(b'spam') expected = value.s self.assertEqual(expected, new_context._get_literal_value(value)) self.assertIsNone(new_context._get_literal_value(None))
def _get_literal(node, constant_items=False): use_literal = (not constant_items) value = get_constant(node) if value is not UNSET: return value if isinstance(node, ast.Tuple) and use_literal: elts = _get_node_list(node.elts, literal=True) if elts is UNSET: return UNSET return list(elts) if isinstance(node, ast.List): elts = _get_node_list(node.elts, literal=use_literal) if elts is UNSET: return UNSET return list(elts) if isinstance(node, ast.Set): # elements must be hashable elts = _get_node_list(node.elts) if elts is UNSET: return UNSET return set(elts) if isinstance(node, ast.Dict): # FIXME: this code is slow, only do it when get_literal() is # called with types==dict (or dict in types) # keys musts be hashable keys = _get_node_list(node.keys) if keys is UNSET: return UNSET values = _get_node_list(node.values, literal=use_literal) if values is UNSET: return UNSET return dict(zip(keys, values)) return UNSET
def infer(node, context, solver, from_call=False): """Infer the type of a given AST node""" if isinstance(node, ast.Num): return infer_numeric(node, solver) elif isinstance(node, ast.Str): return solver.z3_types.string elif (sys.version_info[0] >= 3 and sys.version_info[1] >= 6 and (isinstance(node, ast.FormattedValue) or isinstance(node, ast.JoinedStr))): # Formatted strings were introduced in Python 3.6 return solver.z3_types.string elif isinstance(node, ast.Bytes): return solver.z3_types.bytes elif isinstance(node, ast.List): return infer_list(node, context, solver) elif isinstance(node, ast.Dict): return infer_dict(node, context, solver) elif isinstance(node, ast.Tuple): return infer_tuple(node, context, solver) elif isinstance(node, ast.NameConstant): return infer_name_constant(node, solver) elif isinstance(node, ast.Set): return infer_set(node, context, solver) elif isinstance(node, ast.BinOp): return infer_binary_operation(node, context, solver) elif isinstance(node, ast.BoolOp): return infer_boolean_operation(node, context, solver) elif isinstance(node, ast.UnaryOp): return infer_unary_operation(node, context, solver) elif isinstance(node, ast.IfExp): return infer_if_expression(node, context, solver) elif isinstance(node, ast.Subscript): return infer_subscript(node, context, solver) elif sys.version_info[0] >= 3 and sys.version_info[1] >= 5 and isinstance(node, ast.Await): # Await and Async were introduced in Python 3.5 return infer(node.value, context, solver) elif isinstance(node, ast.Yield): return infer(node.value, context, solver) elif isinstance(node, ast.Compare): return infer_compare(node, context, solver) elif isinstance(node, ast.Name): return infer_name(node, context) elif isinstance(node, ast.ListComp): return infer_sequence_comprehension(node, solver.z3_types.list, context, solver) elif isinstance(node, ast.SetComp): return infer_sequence_comprehension(node, solver.z3_types.set, context, solver) elif isinstance(node, ast.DictComp): return infer_dict_comprehension(node, context, solver) elif isinstance(node, ast.Call): return infer_func_call(node, context, solver) elif isinstance(node, ast.Attribute): return infer_attribute(node, context, from_call, solver) elif isinstance(node, ast.Lambda): return _infer_lambda(node, context, solver) raise NotImplementedError("Inference for expression {} is not implemented yet.".format(type(node).__name__))
def dangerous_source_assignment(self, n): """ Look at an the right hand side of an assignment to determine if dangerous. Right now this only means flask request object represented in a few ways. """ # xx = True/False/None, skip em if isinstance(n, ast.Name): return False if isinstance(n, ast.Dict): # other side is a Dict return False if isinstance(n, ast.Subscript): # xx = request.args['foo'] if hasattr(n, "value") and hasattr(n.value, "value"): if hasattr(n.value.value, "id") and n.value.value.id == "request": return True # xx = dictname[some_var_as_key] if hasattr(n, "value") and not hasattr(n.value, "value"): # Lots of work could be done here but it is hard.. punting. # Need to do more inside-func analysis like with assigns but for dict keys return False else: # Could be rhs here is an object, ex: # trips_required = fuel_cards_config.trips_required[g.user.flow_type_name.lower()] return False #print '\n\n' #print astpp.dump(n) #raise Exception("some wonky case nammed in source assignment") # xx = request.args.get('foo') is an ast.Call() if isinstance(n, ast.Call): if hasattr(n.func, "value") and hasattr(n.func.value, "value") and hasattr(n.func.value.value, 'id'): if n.func.value.value.id == 'request': return True # xxx = flask.request.headers.get('Host') if hasattr(n.func, "value") and hasattr(n.func.value, "value") \ and hasattr(n.func.value.value, "value") \ and hasattr(n.func.value.value.value, 'id') \ and hasattr(n.func.value.value, 'attr'): if n.func.value.value.value.id == 'flask' and n.func.value.value.attr == 'request': return True return False
def calculate( expr: str, *, replace_num_to_decimal: bool=True ): node = ast.parse(expr, filename='<ast>', mode='exec') local: Dict[str, Any] = {} if replace_num_to_decimal: Transformer().visit(node) ast.fix_missing_locations(node) en = ExtractNames() en.visit(node) names = en.names if '__result__' in names: raise SyntaxError('assign __result__ value is not allowed.') Validator(names).visit(node) last = node.body[-1] expect_result = False result = None if isinstance(last, TYPE_EXPR): expect_result = True node.body[-1] = ast.Assign( targets=[ast.Name(id='__result__', ctx=ast.Store())], value=last.value ) ast.fix_missing_locations(node) exec(compile(node, filename='<ast>', mode='exec'), GLOBAL_CONTEXT, local) if expect_result: result = local['__result__'] del local['__result__'] if isinstance(result, Iterable) and \ not isinstance(result, BUILTIN_ITERABLE): result = list(result) return result, local
def _gclient_eval(node_or_string, global_scope, filename='<unknown>'): """Safely evaluates a single expression. Returns the result.""" _allowed_names = {'None': None, 'True': True, 'False': False} if isinstance(node_or_string, basestring): node_or_string = ast.parse(node_or_string, filename=filename, mode='eval') if isinstance(node_or_string, ast.Expression): node_or_string = node_or_string.body def _convert(node): if isinstance(node, ast.Str): return node.s elif isinstance(node, ast.Num): return node.n elif isinstance(node, ast.Tuple): return tuple(map(_convert, node.elts)) elif isinstance(node, ast.List): return list(map(_convert, node.elts)) elif isinstance(node, ast.Dict): return collections.OrderedDict( (_convert(k), _convert(v)) for k, v in zip(node.keys, node.values)) elif isinstance(node, ast.Name): if node.id not in _allowed_names: raise ValueError( 'invalid name %r (file %r, line %s)' % ( node.id, filename, getattr(node, 'lineno', '<unknown>'))) return _allowed_names[node.id] elif isinstance(node, ast.Call): if not isinstance(node.func, ast.Name): raise ValueError( 'invalid call: func should be a name (file %r, line %s)' % ( filename, getattr(node, 'lineno', '<unknown>'))) if node.keywords or node.starargs or node.kwargs: raise ValueError( 'invalid call: use only regular args (file %r, line %s)' % ( filename, getattr(node, 'lineno', '<unknown>'))) args = map(_convert, node.args) return global_scope[node.func.id](*args) elif isinstance(node, ast.BinOp) and isinstance(node.op, ast.Add): return _convert(node.left) + _convert(node.right) elif isinstance(node, ast.BinOp) and isinstance(node.op, ast.Mod): return _convert(node.left) % _convert(node.right) else: raise ValueError( 'unexpected AST node: %s %s (file %r, line %s)' % ( node, ast.dump(node), filename, getattr(node, 'lineno', '<unknown>'))) return _convert(node_or_string)