def _element_type(self, sequence_type):
if isinstance(sequence_type, list):
if sequence_type[0] == 'Dictionary':
return sequence_type[2]
elif sequence_type[0] == 'List':
return sequence_type[1]
elif sequence_type == 'String':
return 'String'
python类List()的实例源码
def visit_For(self, node):
"""
For(expr target, expr iter, stmt* body, stmt* orelse)
"""
if not isinstance(node.target, (ast.Name,ast.Tuple, ast.List)):
raise RubyError("argument decomposition in 'for' loop is not supported")
#if isinstance(node.target, ast.Tuple):
#print self.visit(node.iter) #or Variable (String case)
#if isinstance(node.iter, ast.Str):
self._tuple_type = '()'
for_target = self.visit(node.target)
self._tuple_type = '[]'
#if isinstance(node.iter, (ast.Tuple, ast.List)):
# for_iter = "[%s]" % self.visit(node.iter)
#else:
# for_iter = self.visit(node.iter)
# ast.Tuple, ast.List, ast.*
for_iter = self.visit(node.iter)
iter_dummy = self.new_dummy()
orelse_dummy = self.new_dummy()
exc_dummy = self.new_dummy()
self.write("for %s in %s" % (for_target, for_iter))
self.indent()
for stmt in node.body:
self.visit(stmt)
self.dedent()
self.write("end")
if node.orelse:
self.write("if (%s) {" % orelse_dummy)
self.indent()
for stmt in node.orelse:
self.visit(stmt)
self.dedent()
self.write("}")
def visit_GeneratorExp(self, node):
"""
GeneratorExp(expr elt, comprehension* generators)
"""
#if isinstance(node.generators[0].iter, (ast.Tuple, ast.List)):
# i = "[%s]" % self.visit(node.generators[0].iter)
#else:
# i = self.visit(node.generators[0].iter)
i = self.visit(node.generators[0].iter) # ast.Tuple, ast.List, ast.*
t = self.visit(node.generators[0].target)
""" <Python> [x**2 for x in [1,2]]
<Ruby> [1, 2].map{|x| x**2} """
return "%s.map{|%s| %s}" % (i, t, self.visit(node.elt))
def visit_ListComp(self, node):
"""
ListComp(expr elt, comprehension* generators)
"""
#if isinstance(node.generators[0].iter, (ast.Tuple, ast.List)):
# i = "[%s]" % self.visit(node.generators[0].iter)
#else:
# i = self.visit(node.generators[0].iter)
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> [x**2 for x in [1,2]]
<Ruby> [1, 2].map{|x| x**2} """
return "%s.map{|%s| %s}" % (i, t, self.visit(node.elt))
else:
""" <Python> [x**2 for x in [1,2] if x > 1]
<Ruby> [1, 2].select {|x| x > 1 }.map{|x| x**2} """
return "%s.select{|%s| %s}.map{|%s| %s}" % \
(i, t, self.visit(node.generators[0].ifs[0]), t, \
self.visit(node.elt))
def visit_Call(self, node):
if (
isinstance(node.func, ast.Name) and
node.func.id == 'dict' and
len(node.args) == 1 and
not _has_kwargs(node) and
isinstance(node.args[0], (ast.ListComp, ast.GeneratorExp)) and
isinstance(node.args[0].elt, (ast.Tuple, ast.List)) and
len(node.args[0].elt.elts) == 2
):
arg, = node.args
key = Offset(node.func.lineno, node.func.col_offset)
self.dicts[key] = arg
self.generic_visit(node)
def generate_list(self, node, ext_info):
for x in node.elts:
if isinstance(x, ast.List):
raise SyntaxNotSupportError(
"Multiple dimension array is not support in shellscript language."
)
return '(%s)' % ' '.join([self.dispatch(x, ext_info) for x in node.elts])
def get_type(self, node):
if isinstance(node, ast.BinOp):
left_type = self.get_type(node.left)
right_type = self.get_type(node.right)
if isinstance(node.op, ast.Add):
if left_type.is_number and right_type.is_number:
return Type.NUMBER
else:
return Type.STRING
elif left_type.is_number and right_type.is_number:
return Type.NUMBER
else:
raise CompileError("Can not '%s' operator with string." % node.op.__class__.__name__)
elif isinstance(node, ast.UnaryOp):
if isinstance(operand, ast.Num):
return Type.NUMBER
else:
raise SyntaxNotSupportError("Not support unary operator except number.")
elif isinstance(node, ast.Num):
return Type.NUMBER
elif isinstance(node, ast.Str):
return Type.STRING
elif isinstance(node, ast.List):
return Type.LIST
elif isinstance(node, ast.Call):
args_type = [self.get_type(arg) for arg in node.args]
return self.get_function_return_type(node.func.id, args_type)
elif isinstance(node, ast.Name):
return self.variables[node.id].var_type
def visit_BoolOp(self, boolop):
res_var = self.variable()
expl_list = self.assign(ast.List([], ast.Load()))
app = ast.Attribute(expl_list, "append", ast.Load())
is_or = int(isinstance(boolop.op, ast.Or))
body = save = self.statements
fail_save = self.on_failure
levels = len(boolop.values) - 1
self.push_format_context()
# Process each operand, short-circuting if needed.
for i, v in enumerate(boolop.values):
if i:
fail_inner = []
# cond is set in a prior loop iteration below
self.on_failure.append(ast.If(cond, fail_inner, [])) # noqa
self.on_failure = fail_inner
self.push_format_context()
res, expl = self.visit(v)
body.append(ast.Assign([ast.Name(res_var, ast.Store())], res))
expl_format = self.pop_format_context(ast.Str(expl))
call = ast_Call(app, [expl_format], [])
self.on_failure.append(ast.Expr(call))
if i < levels:
cond = res
if is_or:
cond = ast.UnaryOp(ast.Not(), cond)
inner = []
self.statements.append(ast.If(cond, inner, []))
self.statements = body = inner
self.statements = save
self.on_failure = fail_save
expl_template = self.helper("format_boolop", expl_list, ast.Num(is_or))
expl = self.pop_format_context(expl_template)
return ast.Name(res_var, ast.Load()), self.explanation_param(expl)
def get_expr_value_src_dst(src_node, dst_node, name):
test_node = None
if isinstance(name, ast.Name):
name = name.id
if isinstance(dst_node, ast.Name) and dst_node.id == name:
test_node = src_node
elif isinstance(dst_node, (ast.List, ast.Tuple)) and isinstance(src_node, (ast.List, ast.Tuple)):
targets = [elt.id for elt in dst_node.elts if isinstance(elt, ast.Name)]
if name in targets:
test_node = src_node.elts[targets.index(name)]
return test_node
def test_starred(self):
left = ast.List([ast.Starred(ast.Name("x", ast.Load()), ast.Store())],
ast.Store())
assign = ast.Assign([left], ast.Num(4))
self.stmt(assign, "must have Store context")
def test_list(self):
self._sequence(ast.List)
def visit_BoolOp(self, boolop):
res_var = self.variable()
expl_list = self.assign(ast.List([], ast.Load()))
app = ast.Attribute(expl_list, "append", ast.Load())
is_or = int(isinstance(boolop.op, ast.Or))
body = save = self.statements
fail_save = self.on_failure
levels = len(boolop.values) - 1
self.push_format_context()
# Process each operand, short-circuting if needed.
for i, v in enumerate(boolop.values):
if i:
fail_inner = []
# cond is set in a prior loop iteration below
self.on_failure.append(ast.If(cond, fail_inner, [])) # noqa
self.on_failure = fail_inner
self.push_format_context()
res, expl = self.visit(v)
body.append(ast.Assign([ast.Name(res_var, ast.Store())], res))
expl_format = self.pop_format_context(ast.Str(expl))
call = ast_Call(app, [expl_format], [])
self.on_failure.append(ast.Expr(call))
if i < levels:
cond = res
if is_or:
cond = ast.UnaryOp(ast.Not(), cond)
inner = []
self.statements.append(ast.If(cond, inner, []))
self.statements = body = inner
self.statements = save
self.on_failure = fail_save
expl_template = self.helper("format_boolop", expl_list, ast.Num(is_or))
expl = self.pop_format_context(expl_template)
return ast.Name(res_var, ast.Load()), self.explanation_param(expl)
def visit_BoolOp(self, boolop):
res_var = self.variable()
expl_list = self.assign(ast.List([], ast.Load()))
app = ast.Attribute(expl_list, "append", ast.Load())
is_or = int(isinstance(boolop.op, ast.Or))
body = save = self.statements
fail_save = self.on_failure
levels = len(boolop.values) - 1
self.push_format_context()
# Process each operand, short-circuting if needed.
for i, v in enumerate(boolop.values):
if i:
fail_inner = []
# cond is set in a prior loop iteration below
self.on_failure.append(ast.If(cond, fail_inner, [])) # noqa
self.on_failure = fail_inner
self.push_format_context()
res, expl = self.visit(v)
body.append(ast.Assign([ast.Name(res_var, ast.Store())], res))
expl_format = self.pop_format_context(ast.Str(expl))
call = ast_Call(app, [expl_format], [])
self.on_failure.append(ast.Expr(call))
if i < levels:
cond = res
if is_or:
cond = ast.UnaryOp(ast.Not(), cond)
inner = []
self.statements.append(ast.If(cond, inner, []))
self.statements = body = inner
self.statements = save
self.on_failure = fail_save
expl_template = self.helper("format_boolop", expl_list, ast.Num(is_or))
expl = self.pop_format_context(expl_template)
return ast.Name(res_var, ast.Load()), self.explanation_param(expl)
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 _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 __init__(self, name, source, scope):
if '__all__' in scope and isinstance(source, ast.AugAssign):
self.names = list(scope['__all__'].names)
else:
self.names = []
if isinstance(source.value, (ast.List, ast.Tuple)):
for node in source.value.elts:
if isinstance(node, ast.Str):
self.names.append(node.s)
super(ExportBinding, self).__init__(name, source)
def getParent(self, node):
# Lookup the first parent which is not Tuple, List or Starred
while True:
node = node.parent
if not hasattr(node, 'elts') and not hasattr(node, 'ctx'):
return node
def check_empty_list(node):
if not isinstance(node, ast.List):
return
if len(node.elts) == 0:
yield (node.lineno, 'init by []')
def test_starred(self):
left = ast.List([ast.Starred(ast.Name("x", ast.Load()), ast.Store())],
ast.Store())
assign = ast.Assign([left], ast.Num(4))
self.stmt(assign, "must have Store context")
def test_list(self):
self._sequence(ast.List)