def for_header_to_tuple( target, target_type, iter_) -> t.Tuple[typed_ast3.Assign, typed_ast3.AST, typed_ast3.AST]: if match_range_call(iter_): begin, end, step = inferred_range_args(iter_) # raise NotImplementedError('TODO') else: raise NotImplementedError( 'only range() iterator in for loops is currently supported') if target_type is None: init = typed_ast3.Assign(targets=[target], value=begin, type_comment=None) else: init = typed_ast3.AnnAssign(target=target, annotation=target_type, value=begin, simple=True) condition = typed_ast3.Compare(left=target, ops=[typed_ast3.Lt()], comparators=[end]) increment = typed_ast3.AugAssign(target=target, op=typed_ast3.Add(), value=step) return init, condition, increment
def visit_Assign(self, node): #astpretty.pprint(node) #Assign(expr* targets, expr value) #AnnAssign(expr target, expr annotation, expr? value, int simple) res = node targets, value = node.targets, node.value lineno = node.lineno if lineno in self.line2shape: assert len(targets) == 1 target = targets[0] shape = self.line2shape[lineno] ann = ast.Str(s=f'{shape}', kind='', lineno=lineno, col_offset=node.col_offset) #print("\n===>", astpretty.pprint(node, indent=' ')) res = ast.AnnAssign(target=target, annotation=ann, value=value, simple=1, lineno=lineno, col_offset=node.col_offset) return res
def visit_node(self, node): if isinstance(node, typed_ast3.For) and node.target.id == var \ and node.type_comment is not None: node.type_comment = None declaration = typed_ast3.AnnAssign( target=node.target, value=None, annotation=node.resolved_type_comment) raise ValueError(declaration)
def visit_Decl(self, node) -> t.Union[typed_ast3.AnnAssign, # pylint: disable=invalid-name t.Tuple[str, typed_ast3.arguments, typed_ast3.AST]]: """Transform Decl.""" name = node.name assert isinstance(name, str), type(name) quals = node.quals if quals: _LOG.warning('ignoring unsupported C grammar: %s', quals) storage = [self.visit(subnode) for subnode in node.storage] if storage: raise NotImplementedError(_node_debug(node.storage), str(storage)) funcspec = [self.visit(subnode) for subnode in node.funcspec] if funcspec: raise NotImplementedError(_node_debug(node.funcspec), str(funcspec)) type_data = self.visit(node.type) assert isinstance(type_data, tuple) assert len(type_data) == DECL_DATA_LENGTHS[type(node.type)], (type(node.type), type_data) init = self.visit(node.init) if init is not None: assert isinstance(node.type, INITIALIZABLE_DECLARATIONS) # assert isinstance(node.type, c_ast.TypeDecl), type(node.type) # raise NotImplementedError(_node_debug(node.init), str(init)) bitsize = self.visit(node.bitsize) if bitsize is not None: raise NotImplementedError(_node_debug(node.bitsize), str(bitsize)) _ = self.visit(node.coord) if init is not None or isinstance(node.type, INITIALIZABLE_DECLARATIONS): name_, type_ = type_data assert name_ == name return typed_ast3.AnnAssign(target=typed_ast3.Name(id=name_, ctx=typed_ast3.Store()), annotation=type_, value=init, simple=1) if isinstance(node.type, (c_ast.FuncDecl,)): return type_data return self.generic_visit(node)
def visit_Typedef(self, node): # pylint: disable=invalid-name """Transform Typedef.""" name = node.name assert isinstance(name, str), type(name) quals = node.quals if quals: _LOG.warning('ignoring unsupported C grammar: %s', quals) assert node.storage == ['typedef'], node.storage name_, type_ = self.visit(node.type) assert name == name_, (name, name_) _ = self.visit(node.coord) return typed_ast3.AnnAssign(target=typed_ast3.Name(name, typed_ast3.Store()), value=type_, annotation=typed_ast3.Name('type', typed_ast3.Load()), simple=1)
def _r_assign(assign, body): assert body.type in (syms.file_input, syms.suite) if len(assign.targets) != 1: # Type aliases and old-style var type comments cannot have multiple # targets. return [] if assign.type_comment: # old-style variable type comment, let's treat it exactly like # a new-style annotated assignment tc = parse_type_comment(assign.type_comment) annassign = ast3.AnnAssign( target=assign.targets[0], annotation=tc, value=assign.value, simple=False, ) return reapply(annassign, body) if not isinstance(assign.targets[0], ast3.Name): # Type aliases cannot be attributes, etc. return [] name = assign.targets[0].id value = convert_annotation(assign.value) value.prefix = " " for child in flatten_some(body.children): if child.type != syms.simple_stmt: continue maybe_expr = child.children[0] if maybe_expr.type != syms.expr_stmt: continue expr = maybe_expr.children if (isinstance(expr[0], Leaf) and expr[0].type == token.NAME and expr[0].value == name and expr[1] == _eq): actual_value = expr[2] if value != actual_value: value_str = minimize_whitespace(str(value)) actual_value_str = minimize_whitespace(str(actual_value)) raise ValueError( f"incompatible existing alias {name!r}. Expected: " + f"{value_str!r}, actual: {actual_value_str!r}") break else: # We need to defer placing aliases because we need to place them # relative to their usage, and the type annotations likely come after # in the .pyi file. def lazy_aliasing() -> None: # We should find the first place where the alias is used and put it # right above. This way we don't need to look at the value at all. _, prefix = get_offset_and_prefix(body, skip_assignments=True) name_node = Leaf(token.NAME, name) for _offset, stmt in enumerate(body.children): if name_used_in_node(stmt, name_node): break else: _offset = -1 body.children.insert( _offset, Node( syms.simple_stmt, [ Node( syms.expr_stmt, [ Leaf(token.NAME, name), new(_eq), value, ], ), new(_newline), ], prefix=prefix.lstrip('\n'), ), ) return [lazy_aliasing] return []