def visit_Call( state: State, node: ast.Call, ) -> Iterable[Tuple[Offset, TokenFunc]]: argnodes = [*node.args, *node.keywords] arg_offsets = set() has_starargs = False for argnode in argnodes: if isinstance(argnode, ast.Starred): has_starargs = True if isinstance(argnode, ast.keyword) and argnode.arg is None: has_starargs = True offset = ast_to_offset(argnode) # multiline strings have invalid position, ignore them if offset.utf8_byte_offset != -1: # pragma: no branch (cpy bug) arg_offsets.add(offset) # If the sole argument is a generator, don't add a trailing comma as # this breaks lib2to3 based tools only_a_generator = (len(argnodes) == 1 and isinstance(argnodes[0], ast.GeneratorExp)) if arg_offsets and not only_a_generator and not state.in_fstring: func = functools.partial( _fix_call, add_comma=not has_starargs or state.min_version >= (3, 5), arg_offsets=arg_offsets, ) yield ast_to_offset(node), func
def visit_FunctionDef( state: State, node: Union[ast.AsyncFunctionDef, ast.FunctionDef], ) -> Iterable[Tuple[Offset, TokenFunc]]: has_starargs = False args = [*getattr(node.args, 'posonlyargs', ()), *node.args.args] if node.args.vararg: args.append(node.args.vararg) has_starargs = True if node.args.kwarg: args.append(node.args.kwarg) has_starargs = True if node.args.kwonlyargs: args.extend(node.args.kwonlyargs) has_starargs = True arg_offsets = {ast_to_offset(arg) for arg in args} if arg_offsets: func = functools.partial( _fix_func, add_comma=not has_starargs or state.min_version >= (3, 6), arg_offsets=arg_offsets, ) yield ast_to_offset(node), func
def visit_ClassDef( state: State, node: ast.ClassDef, ) -> Iterable[Tuple[Offset, TokenFunc]]: # starargs are allowed in py3 class definitions, py35+ allows trailing # commas. py34 does not, but adding an option for this very obscure # case seems not worth it. args = [*node.bases, *node.keywords] arg_offsets = {ast_to_offset(arg) for arg in args} if arg_offsets: func = functools.partial(_fix_class, arg_offsets=arg_offsets) yield ast_to_offset(node), func
def visit_Tuple( state: State, node: ast.Tuple, ) -> Iterable[Tuple[Offset, TokenFunc]]: if node.elts: is_one_el = len(node.elts) == 1 if (ast_to_offset(node) == ast_to_offset(node.elts[0]) or # in < py38 tuples lie about offset -- later we must backtrack sys.version_info < (3, 8)): func = functools.partial(_fix_tuple, one_el_tuple=is_one_el) yield ast_to_offset(node), func else: # pragma: no cover (py38+) func = functools.partial(_fix_literal, one_el_tuple=is_one_el) yield ast_to_offset(node), func
def visit_Dict( state: State, node: ast.Dict, ) -> Iterable[Tuple[Offset, TokenFunc]]: if node.values: func = functools.partial(_fix_literal, one_el_tuple=False) yield ast_to_offset(node), func
def visit_ImportFrom( state: State, node: ast.ImportFrom, ) -> Iterable[Tuple[Offset, TokenFunc]]: yield ast_to_offset(node), _fix_import