def make_list_comp(self, get_iter, for_iter): block = self.make_block(for_iter.to, inclusive=False, raise_=False) jump_abs = block.pop() assert jump_abs.opname == 'JUMP_ABSOLUTE', jump_abs.opname jump_map = {for_iter.i:for_iter.to} stmnts = self.decompile_block(block, stack_items=[None], jump_map=jump_map).stmnt() if len(stmnts) > 1: assign = stmnts.pop(0) assert len(stmnts) == 1 assert isinstance(assign, _ast.Assign) list_expr = self.pop_ast_item() # empty ast.List object list_ = self.pop_ast_item() ifs = [] elt = refactor_ifs(stmnts[0], ifs) assert len(assign.targets) == 1 generators = [_ast.comprehension(target=assign.targets[0], iter=list_expr, ifs=ifs, lineno=get_iter.lineno, col_offset=0)] if isinstance(list_, _ast.Assign): comp = _ast.comprehension(target=list_.targets[0], iter=None, ifs=ifs, lineno=get_iter.lineno, col_offset=0) generators.insert(0, comp) list_comp = _ast.ListComp(elt=elt, generators=generators, lineno=get_iter.lineno, col_offset=0) else: list_expr = self.pop_ast_item() list_comp = stmnts[0] generators = list_comp.generators # empty ast.List object list_ = self.pop_ast_item() if not isinstance(list_, _ast.Assign): comp = _ast.comprehension(target=list_.targets[0], iter=None, ifs=[], lineno=get_iter.lineno, col_offset=0) generators.insert(0, comp) generators[0].iter = list_expr self.push_ast_item(list_comp)
def extract_listcomp(self, function, sequence): assert len(function.body) == 1 assert isinstance(function.body[0], _ast.Return) value = function.body[0].value assert isinstance(value, _ast.ListComp) generators = list(value.generators) for generator in generators: if generator.iter.id == '.0': generator.iter = sequence setcomp = _ast.ListComp(elt=value.elt, generators=generators, lineno=value.lineno, col_offset=0) self.push_ast_item(setcomp)
def ListComp(left_side, for_part, in_part, *ifs): """Creates _ast.ListComp nodes. 'left_side' for 'for_part' in 'in_part' if 'ifs' Args: left_side: leftmost side of the expression. for_part: The part after '[left_side] for ' in_part: The part after '[left_side] for [for_part] in ' *ifs: Any if statements that come at the end. Returns: {_ast.ListComp} """ left_side = _WrapWithName(left_side, ctx_type=CtxEnum.LOAD) for_part = _WrapWithName(for_part, ctx_type=CtxEnum.STORE) in_part = _WrapWithName(in_part, ctx_type=CtxEnum.LOAD) return _ast.ListComp(elt=left_side, generators=[comprehension(for_part, in_part, *ifs)])
def test_bug_null_in_objspace_type(self): import ast code = ast.Expression( lineno=1, col_offset=1, body=ast.ListComp( lineno=1, col_offset=1, elt=ast.Call(lineno=1, col_offset=1, func=ast.Name(lineno=1, col_offset=1, id='str', ctx=ast.Load(lineno=1, col_offset=1)), args=[ ast.Name(lineno=1, col_offset=1, id='x', ctx=ast.Load(lineno=1, col_offset=1)) ], keywords=[]), generators=[ ast.comprehension( lineno=1, col_offset=1, target=ast.Name(lineno=1, col_offset=1, id='x', ctx=ast.Store(lineno=1, col_offset=1)), iter=ast.List( lineno=1, col_offset=1, elts=[ast.Num(lineno=1, col_offset=1, n=23)], ctx=ast.Load( lineno=1, col_offset=1, )), ifs=[]) ])) compile(code, '<template>', 'eval')
def visit_listcomp(self, node: _ast.ListComp): # elt, generators result: List[Any] = [] current_gen = node.generators[0] if current_gen.__class__ == _ast.comprehension: for val in self._run(current_gen.iter): self.assign(current_gen.target, val) add = True for cond in current_gen.ifs: add = add and self._run(cond) if add: if len(node.generators) > 1: r = self.visit_listcomp( _ast.ListComp( elt=node.elt, generators=node.generators[1:], )) result += r else: r = self._run(node.elt) result.append(r) self.delete(current_gen.target) return result