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))
python类Tuple()的实例源码
def visit_Assign(self, node):
rhs_visitor = RHSVisitor()
rhs_visitor.visit(node.value)
if isinstance(node.targets[0], ast.Tuple): # x,y = [1,2]
if isinstance(node.value, ast.Tuple):
return self.assign_tuple_target(node, rhs_visitor.result)
elif isinstance(node.value, ast.Call):
call = None
for element in node.targets[0].elts:
label = LabelVisitor()
label.visit(element)
call = self.assignment_call_node(label.result, node)
return call
elif len(node.targets) > 1: # x = y = 3
return self.assign_multi_target(node, rhs_visitor.result)
else:
if isinstance(node.value, ast.Call): # x = call()
label = LabelVisitor()
label.visit(node.targets[0])
return self.assignment_call_node(label.result, node)
else: # x = 4
label = LabelVisitor()
label.visit(node)
return self.append_node(AssignmentNode(label.result, self.extract_left_hand_side(node.targets[0]), node, rhs_visitor.result, line_number = node.lineno, path=self.filenames[-1]))
def mapVariable(a, varId, assn):
"""Map the variable assignment into the function, if it's needed"""
if type(a) != ast.FunctionDef:
return a
for arg in a.args.args:
if arg.arg == varId:
return a # overriden by local variable
for i in range(len(a.body)):
line = a.body[i]
if type(line) == ast.Assign:
for target in line.targets:
if type(target) == ast.Name and target.id == varId:
break
elif type(target) in [ast.Tuple, ast.List]:
for elt in target.elts:
if type(elt) == ast.Name and elt.id == varId:
break
if countVariables(line, varId) > 0:
a.body[i:i+1] = [deepcopy(assn), line]
break
return a
def _translate_in(self, element, sequence, location):
sequence_node = self._translate_node(sequence)
element_node = self._translate_node(element)
if not (
sequence_node['pseudo_type'] == 'String' and element_node['pseudo_type'] == 'String' or\
isinstance(sequence_node['pseudo_type'], list) and sequence_node['pseudo_type'][0] != 'Tuple' and sequence_node['pseudo_type'][1] == element_node['pseudo_type']):
raise type_check_error('expected the left side of in to has the element type of the sequence, in supported for string and sequences which are not tuples',
location, self.lines[location[0]],
wrong_type=element_node['pseudo_type'])
return {
'type': 'standard_method_call',
'receiver': sequence_node,
'message': 'include?',
'args': [element_node],
'pseudo_type': 'Boolean'
}
def get_version():
with open(os.path.join('settei', 'version.py')) as f:
tree = ast.parse(f.read(), f.name)
for node in ast.walk(tree):
if not (isinstance(node, ast.Assign) and len(node.targets) == 1):
continue
target, = node.targets
value = node.value
if not (isinstance(target, ast.Name) and
target.id == 'VERSION_INFO' and
isinstance(value, ast.Tuple)):
continue
elts = value.elts
if any(not isinstance(elt, ast.Num) for elt in elts):
continue
return '.'.join(str(elt.n) for elt in elts)
def visit_DictComp(self, node):
"""
DictComp(expr key, expr value, comprehension* generators)
"""
i = self.visit(node.generators[0].iter) # ast.Tuple, ast.List, ast.*
if isinstance(node.generators[0].target, ast.Name):
t = self.visit(node.generators[0].target)
else:
# ast.Tuple
self._tuple_type = ''
t = self.visit(node.generators[0].target)
self._tuple_type = '[]'
if len(node.generators[0].ifs) == 0:
""" <Python> {key: data for key, data in {'a': 7}.items()}
<Ruby> {'a', 7}.to_a.map{|key, data| [key, data]}.to_h """
return "%s.map{|%s|[%s, %s]}.to_h" % (i, t, self.visit(node.key), self.visit(node.value))
else:
""" <Python> {key: data for key, data in {'a': 7}.items() if data > 6}
<Ruby> {'a', 7}.to_a.select{|key, data| data > 6}.map{|key, data| [key, data]}.to_h """
return "%s.select{|%s| %s}.map{|%s|[%s, %s]}.to_h" % \
(i, t, self.visit(node.generators[0].ifs[0]), t, \
self.visit(node.key), self.visit(node.value))
def parse_args(args):
arg_list = []
for arg in args:
if isinstance(arg, ast.Str):
arg_list.append("%s" % arg.s)
elif isinstance(arg, ast.Name):
value = arg.id
if value == "None":
arg_list.append(None)
else:
arg_list.append(value)
elif isinstance(arg, ast.Num):
arg_list.append(arg.n)
elif isinstance(arg, ast.List):
arg_list.append(parse_args(arg.elts))
elif isinstance(arg, ast.Tuple):
arg_list.append(tuple(parse_args(arg.elts)))
elif isinstance(arg, ast.Attribute):
arg_list.append(str(arg.value.id) + "." + str(arg.attr))
else:
print(arg, type(arg))
return arg_list
def visit_Call(self, node):
if (
isinstance(node.func, ast.Name) and
node.func.id == 'set' and
len(node.args) == 1 and
not _has_kwargs(node) and
isinstance(node.args[0], SET_TRANSFORM)
):
arg, = node.args
key = Offset(node.func.lineno, node.func.col_offset)
if (
isinstance(arg, (ast.List, ast.Tuple)) and
len(arg.elts) == 0
):
self.set_empty_literals[key] = arg
else:
self.sets[key] = arg
self.generic_visit(node)
def _adjust_arg(tokens, i, arg):
# Adjust `arg` to be the position of the first element.
# listcomps, generators, and tuples already point to the first element
if isinstance(arg, ast.List) and not isinstance(arg.elts[0], ast.Tuple):
arg = arg.elts[0]
elif isinstance(arg, ast.List):
# If the first element is a tuple, the ast lies to us about its col
# offset. We must find the first `(` token after the start of the
# list element.
while not _is_arg(tokens[i], arg):
i += 1
while tokens[i].src != '(':
i += 1
arg = copy.copy(arg.elts[0])
arg.lineno = tokens[i].line
arg.col_offset = tokens[i].utf8_byte_offset
return arg
def specialize_constant(node, value):
if value is None or isinstance(value, bool):
new_node = ast.NameConstant(value=value)
elif isinstance(value, (int, float, complex)):
new_node = ast.Num(n=value)
elif isinstance(value, str):
new_node = ast.Str(s=value)
elif isinstance(value, bytes):
new_node = ast.Bytes(s=value)
elif isinstance(value, tuple):
elts = [specialize_constant(node, elt) for elt in value]
new_node = ast.Tuple(elts=elts, ctx=ast.Load())
else:
raise ValueError("unknown constant: %r" % value)
fatoptimizer.tools.copy_lineno(node, new_node)
return new_node
def get_ast_names(node):
node = _get_ast_name_node(node)
if isinstance(node, ast.Name):
return (node.id,)
if isinstance(node, ast.Tuple):
names = []
for item in node.elts:
item_names = get_ast_names(item)
if item_names is None:
return None
names.extend(item_names)
return names
# unknown node type: return None
def convert_to_value(item):
if isinstance(item, ast.Str):
return item.s
elif hasattr(ast, 'Bytes') and isinstance(item, ast.Bytes):
return item.s
elif isinstance(item, ast.Tuple):
return tuple(convert_to_value(i) for i in item.elts)
elif isinstance(item, ast.Num):
return item.n
elif isinstance(item, ast.Name):
result = VariableKey(item=item)
constants_lookup = {
'True': True,
'False': False,
'None': None,
}
return constants_lookup.get(
result.name,
result,
)
elif (not PY33) and isinstance(item, ast.NameConstant):
# None, True, False are nameconstants in python3, but names in 2
return item.value
else:
return UnhandledKeyType()
def TRY(self, node):
handler_names = []
# List the exception handlers
for i, handler in enumerate(node.handlers):
if isinstance(handler.type, ast.Tuple):
for exc_type in handler.type.elts:
handler_names.append(getNodeName(exc_type))
elif handler.type:
handler_names.append(getNodeName(handler.type))
if handler.type is None and i < len(node.handlers) - 1:
self.report(messages.DefaultExceptNotLast, handler)
# Memorize the except handlers and process the body
self.exceptHandlers.append(handler_names)
for child in node.body:
self.handleNode(child, node)
self.exceptHandlers.pop()
# Process the other nodes: "except:", "else:", "finally:"
self.handleChildren(node, omit='body')
def check_reshape(node):
if not isinstance(node, ast.Call):
return
if not isinstance(node.func, ast.Attribute):
return
if isinstance(node.func.value, ast.Name) and \
node.func.value.id in {'np', 'cupy', 'F'}:
return
if not node.func.attr == 'reshape':
return
if len(node.args) > 1:
yield (node.lineno, 'reshape(A, B, ...)')
if len(node.args) == 1 and \
isinstance(node.args[0], ast.Tuple) and \
len(node.args[0].elts) == 1:
yield (node.lineno, 'reshape((A,))')
def check_transpose(node):
if not isinstance(node, ast.Call):
return
if not isinstance(node.func, ast.Attribute):
return
if isinstance(node.func.value, ast.Name) and \
node.func.value.id in {'np', 'cupy', 'F'}:
return
if not node.func.attr == 'transpose':
return
if len(node.args) > 1:
yield (node.lineno, 'transpose(A, B, ...)')
if len(node.args) == 1 and \
isinstance(node.args[0], ast.Tuple) and \
len(node.args[0].elts) == 1:
yield (node.lineno, 'transpose((A,))')
def generic_visit(self, node):
super(NodeTransformer, self).generic_visit(node)
if hasattr(node, 'body') and type(node.body) is list:
returns = [i for i, child in enumerate(node.body) if type(child) is ast.Return]
if len(returns) > 0:
for wait in self.get_waits():
node.body.insert(returns[0], wait)
inserts = []
for i, child in enumerate(node.body):
if type(child) is ast.Expr and self.is_concurrent_call(child.value):
self.encounter_call(child.value)
elif self.is_valid_assignment(child):
call = child.value
self.encounter_call(call)
name = child.targets[0].value
self.arguments.add(SchedulerRewriter.top_level_name(name))
index = child.targets[0].slice.value
call.func = ast.Attribute(call.func, 'assign', ast.Load())
call.args = [ast.Tuple([name, index], ast.Load())] + call.args
node.body[i] = ast.Expr(call)
elif self.references_arg(child):
inserts.insert(0, i)
for index in inserts:
for wait in self.get_waits():
node.body.insert(index, wait)
def visit_ExceptHandler(self, node):
node_name = None
if isinstance(node.name, ast.Name):
# Python 2
node_name = node.name.id
elif isinstance(node.name, str):
# Python 3
node_name = node.name
if node_name in builtin_exception_types:
yield self.tag(node, 'except-shadows-builtin', node_name)
if node.type is None:
ex_types = []
elif isinstance(node.type, ast.Tuple):
ex_types = list(node.type.elts)
else:
ex_types = [node.type]
for ex_type in ex_types:
while isinstance(ex_type, ast.BinOp):
ex_type = ex_type.left
if isinstance(ex_type, ast.Str):
yield self.tag(node, 'string-exception')
break
for t in self.generic_visit(node):
yield t
def parse_grouped_expr(self):
self.next()
if self.cur_is(token.RPAREN):
expr = ast.Tuple(self.cur_tok, [])
return expr
expr = self.parse_expr(LOWEST)
if self.peek_is(token.COMMA):
self.next()
self.next()
expr = ast.Tuple(expr.token, [expr] + self.parse_expr_list(token.RPAREN))
if type(expr) != ast.Tuple and not self.expect(token.RPAREN):
return None
return expr
def _delete_element(target, context, lineno, solver):
"""Remove (if needed) a target from the context
Cases:
- del var_name: remove its type mapping from the context directly.
- del subscript:
* Tuple/String --> Immutable. Raise exception.
* List/Dict --> Do nothing to the context.
"""
if isinstance(target, (ast.Tuple, ast.List)): # Multiple deletions
for elem in target.elts:
_delete_element(elem, context, lineno, solver)
elif isinstance(target, ast.Name):
context.delete_type(target.id)
elif isinstance(target, ast.Subscript):
expr.infer(target, context, solver)
indexed_type = expr.infer(target.value, context, solver)
solver.add(axioms.delete_subscript(indexed_type, solver.z3_types),
fail_message="Deletion in line {}".format(lineno))
elif isinstance(target, ast.Attribute):
raise NotImplementedError("Attribute deletion is not supported.")
def _infer_for(node, context, solver):
"""Infer the type for a for loop node
Limitation:
- The iterable can't be a tuple.
For example: the following is not allowed:
for x in (1, 2.0, "string"):
....
"""
iter_type = expr.infer(node.iter, context, solver)
# Infer the target in the loop, inside the global context
# Cases:
# - Var name. Ex: for i in range(5)..
# - Tuple. Ex: for (a,b) in [(1,"st"), (3,"st2")]..
# - List. Ex: for [a,b] in [(1, "st"), (3, "st2")]..
target_type = solver.new_z3_const("for_target")
solver.add(axioms.for_loop(iter_type, target_type, solver.z3_types),
fail_message="For loop in line {}".format(node.lineno))
_infer_assignment_target(node.target, context, target_type, solver)
return _infer_control_flow(node, context, solver)
def visit_Try(self, node):
handlers = {}
for handler in node.handlers:
if isinstance(handler.type, ast.Tuple):
# of form -- except TypeError, KeyError
for el in handler.type.elts:
handlers[el.id] = self.parse_handler(handler)
else:
# either general handler, or single error handler
k = 'all' if not handler.type else handler.type.id
handlers[k] = self.parse_handler(handler)
self.out.append({
"node": node,
"body": node.body,
"orelse": node.orelse or None,
"finalbody": node.finalbody or None,
"handlers": handlers,
})
def convert_to_value(item):
if isinstance(item, ast.Str):
return item.s
elif hasattr(ast, 'Bytes') and isinstance(item, ast.Bytes):
return item.s
elif isinstance(item, ast.Tuple):
return tuple(convert_to_value(i) for i in item.elts)
elif isinstance(item, ast.Num):
return item.n
elif isinstance(item, ast.Name):
result = VariableKey(item=item)
constants_lookup = {
'True': True,
'False': False,
'None': None,
}
return constants_lookup.get(
result.name,
result,
)
elif (not PY33) and isinstance(item, ast.NameConstant):
# None, True, False are nameconstants in python3, but names in 2
return item.value
else:
return UnhandledKeyType()
def TRY(self, node):
handler_names = []
# List the exception handlers
for i, handler in enumerate(node.handlers):
if isinstance(handler.type, ast.Tuple):
for exc_type in handler.type.elts:
handler_names.append(getNodeName(exc_type))
elif handler.type:
handler_names.append(getNodeName(handler.type))
if handler.type is None and i < len(node.handlers) - 1:
self.report(messages.DefaultExceptNotLast, handler)
# Memorize the except handlers and process the body
self.exceptHandlers.append(handler_names)
for child in node.body:
self.handleNode(child, node)
self.exceptHandlers.pop()
# Process the other nodes: "except:", "else:", "finally:"
self.handleChildren(node, omit='body')
def Call_isinstance(t, x):
"""Translate ``isinstance(foo, Bar)`` to ``foo instanceof Bar`` and
``isinstance(Foo, (Bar, Zoo))`` to ``foo instanceof Bar || foo instanceof
Zoo``.
AST dump of the latter::
Call(args=[Name(ctx=Load(),
id='foo'),
Tuple(ctx=Load(),
elts=[Name(ctx=Load(),
id='Bar'),
Name(ctx=Load(),
id='Zoo')])],
func=Name(ctx=Load(),
id='isinstance'),
keywords=[])
"""
if (isinstance(x.func, ast.Name) and x.func.id == 'isinstance'):
assert len(x.args) == 2
return _build_call_isinstance(x.args[0], x.args[1])
def Call_issubclass(t, x):
"""Translate ``issubclass(Foo, Bar)`` to ``Foo.prototype instanceof Bar``.
"""
with switch(x):
if ast.Call(func=ast.Name(id='issubclass'), args=[target, classes]):
tproto = q[ast_literal[target].prototype]
if isinstance(classes, (ast.Tuple, ast.List, ast.Set)):
classes = classes.elts
else:
classes = [classes]
prev = None
for c in classes:
cur = q[ast_literal[c].prototype.isPrototypeOf(
ast_literal[tproto])]
if prev is not None:
cur = q[ast_literal[prev] or ast_literal[cur]]
prev = cur
return JSExpressionStatement(cur)
def TRY(self, node):
handler_names = []
# List the exception handlers
for handler in node.handlers:
if isinstance(handler.type, ast.Tuple):
for exc_type in handler.type.elts:
handler_names.append(getNodeName(exc_type))
elif handler.type:
handler_names.append(getNodeName(handler.type))
# Memorize the except handlers and process the body
self.exceptHandlers.append(handler_names)
for child in node.body:
self.handleNode(child, node)
self.exceptHandlers.pop()
# Process the other nodes: "except:", "else:", "finally:"
self.handleChildren(node, omit='body')
def version():
path = 'pypika/__init__.py'
with open(path, 'rU') as file:
t = compile(file.read(), path, 'exec', ast.PyCF_ONLY_AST)
for node in (n for n in t.body if isinstance(n, ast.Assign)):
if len(node.targets) == 1:
name = node.targets[0]
if isinstance(name, ast.Name) and \
name.id in ('__version__', '__version_info__', 'VERSION'):
v = node.value
if isinstance(v, ast.Str):
return v.s
if isinstance(v, ast.Tuple):
r = []
for e in v.elts:
if isinstance(e, ast.Str):
r.append(e.s)
elif isinstance(e, ast.Num):
r.append(str(e.n))
return '.'.join(r)
def translate_Call_constructor(self, ctx, e):
args, keywords = e.args, e.keywords
idx = self.idx
elt_translation = []
idx_mapping = []
for i, arg in enumerate(args):
elt_translation.append(ctx.translate(arg))
n = _util.odict_idx_of(idx, i)
idx_mapping.append(n)
for keyword in keywords:
label = keyword.arg
value = keyword.value
elt_translation.append(ctx.translate(value))
n = _util.odict_idx_of(idx, label)
idx_mapping.append(n)
arg_translation = ast.Tuple(elts=elt_translation)
return ast.copy_location(_labeled_translation(idx_mapping,
arg_translation),
e)
def subscript(self):
sub = Expr.parse_variable_location(self.expr.value, self.context)
if isinstance(sub.typ, (MappingType, ListType)):
if 'value' not in vars(self.expr.slice):
raise StructureException("Array access must access a single element, not a slice", self.expr)
index = Expr.parse_value_expr(self.expr.slice.value, self.context)
elif isinstance(sub.typ, TupleType):
if not isinstance(self.expr.slice.value, ast.Num) or self.expr.slice.value.n < 0 or self.expr.slice.value.n >= len(sub.typ.members):
raise TypeMismatchException("Tuple index invalid", self.expr.slice.value)
index = self.expr.slice.value.n
else:
raise TypeMismatchException("Bad subscript attempt", self.expr.value)
o = add_variable_offset(sub, index)
o.mutable = sub.mutable
return o
def tuple_literals(self):
if not len(self.expr.elts):
raise StructureException("Tuple must have elements", self.expr)
o = []
for elt in self.expr.elts:
o.append(Expr(elt, self.context).lll_node)
return LLLnode.from_list(["multi"] + o, typ=TupleType(o), pos=getpos(self.expr))
# Parse an expression that results in a value