Ejemplo n.º 1
0
def visit_ClassDef(
        state: State,
        node: ast.ClassDef,
        parent: ast.AST,
) -> Iterable[Tuple[Offset, TokenFunc]]:
    if state.settings.min_version < (3,):
        return

    for decorator in node.decorator_list:
        if (
                isinstance(decorator, ast.Call) and
                is_name_attr(
                    decorator.func,
                    state.from_imports,
                    'six',
                    ('add_metaclass',),
                ) and
                not has_starargs(decorator)
        ):
            yield ast_to_offset(decorator), _fix_add_metaclass

    if (
            len(node.bases) == 1 and
            isinstance(node.bases[0], ast.Call) and
            is_name_attr(
                node.bases[0].func,
                state.from_imports,
                'six',
                ('with_metaclass',),
            ) and
            not has_starargs(node.bases[0])
    ):
        yield ast_to_offset(node.bases[0]), _fix_with_metaclass
Ejemplo n.º 2
0
def visit_Call(
    state: State,
    node: ast.Call,
    parent: ast.AST,
) -> Iterable[Tuple[Offset, TokenFunc]]:
    if (state.settings.min_version >= (3, )
            and isinstance(node.func, ast.Name) and node.func.id == 'open'
            and not has_starargs(node)):
        if len(node.args) >= 2 and isinstance(node.args[1], ast.Str):
            if (node.args[1].s in U_MODE_REPLACE or
                (len(node.args) == 2 and node.args[1].s in U_MODE_REMOVE)):
                func = functools.partial(
                    _fix_open_mode,
                    arg_idx=1,
                )
                yield ast_to_offset(node), func
        elif node.keywords and (len(node.keywords) + len(node.args) > 1):
            mode = next(
                (FunctionArg(n, keyword.value)
                 for n, keyword in enumerate(node.keywords)
                 if keyword.arg == 'mode'),
                None,
            )
            if (mode is not None and isinstance(mode.value, ast.Str)
                    and (mode.value.s in U_MODE_REMOVE
                         or mode.value.s in U_MODE_REPLACE)):
                func = functools.partial(
                    _fix_open_mode,
                    arg_idx=len(node.args) + mode.arg_idx,
                )
                yield ast_to_offset(node), func
Ejemplo n.º 3
0
    def visit_Assign(self, node: ast.Assign) -> None:
        if (
                # NT = ...("NT", ...)
                len(node.targets) == 1 and
                isinstance(node.targets[0], ast.Name) and
                isinstance(node.value, ast.Call) and
                len(node.value.args) >= 1 and
                isinstance(node.value.args[0], ast.Str) and
                node.targets[0].id == node.value.args[0].s and
                not has_starargs(node.value)
        ):
            if (
                    self._is_attr(
                        node.value.func, {'typing'}, 'NamedTuple',
                    ) and
                    len(node.value.args) == 2 and
                    not node.value.keywords and
                    isinstance(node.value.args[1], (ast.List, ast.Tuple)) and
                    len(node.value.args[1].elts) > 0 and
                    all(
                        isinstance(tup, ast.Tuple) and
                        len(tup.elts) == 2 and
                        isinstance(tup.elts[0], ast.Str) and
                        tup.elts[0].s.isidentifier() and
                        tup.elts[0].s not in KEYWORDS
                        for tup in node.value.args[1].elts
                    )
            ):
                self.named_tuples[ast_to_offset(node)] = node.value
            elif (
                    self._is_attr(
                        node.value.func,
                        {'typing', 'typing_extensions'},
                        'TypedDict',
                    ) and
                    len(node.value.args) == 1 and
                    len(node.value.keywords) > 0
            ):
                self.kw_typed_dicts[ast_to_offset(node)] = node.value
            elif (
                    self._is_attr(
                        node.value.func,
                        {'typing', 'typing_extensions'},
                        'TypedDict',
                    ) and
                    len(node.value.args) == 2 and
                    not node.value.keywords and
                    isinstance(node.value.args[1], ast.Dict) and
                    node.value.args[1].keys and
                    all(
                        isinstance(k, ast.Str) and
                        k.s.isidentifier() and
                        k.s not in KEYWORDS
                        for k in node.value.args[1].keys
                    )
            ):
                self.dict_typed_dicts[ast_to_offset(node)] = node.value

        self.generic_visit(node)
Ejemplo n.º 4
0
def is_a_native_literal_call(
    node: ast.Call,
    from_imports: Dict[str, Set[str]],
) -> bool:
    return ((is_name_attr(node.func, from_imports, 'six', SIX_NATIVE_STR)
             or isinstance(node.func, ast.Name) and node.func.id == 'str')
            and not node.keywords and not has_starargs(node)
            and (len(node.args) == 0 or
                 (len(node.args) == 1 and isinstance(node.args[0], ast.Str))))
Ejemplo n.º 5
0
    def _parse(self, node: ast.Call) -> Optional[Tuple[DotFormatPart, ...]]:
        if not (isinstance(node.func, ast.Attribute)
                and isinstance(node.func.value, ast.Str)
                and node.func.attr == 'format' and not has_starargs(node)):
            return None

        try:
            return parse_format(node.func.value.s)
        except ValueError:
            return None
Ejemplo n.º 6
0
def visit_Call(
    state: State,
    node: ast.Call,
    parent: ast.AST,
) -> Iterable[Tuple[Offset, TokenFunc]]:
    if (state.settings.min_version >= (3, )
            and isinstance(node.func, ast.Attribute)
            and isinstance(node.func.value, ast.Str)
            and node.func.attr == 'encode' and not has_starargs(node)
            and len(node.args) == 1 and isinstance(node.args[0], ast.Str)
            and is_codec(node.args[0].s, 'utf-8')):
        yield ast_to_offset(node), _fix_default_encoding
Ejemplo n.º 7
0
def visit_Call(
    state: State,
    node: ast.Call,
    parent: ast.AST,
) -> Iterable[Tuple[Offset, TokenFunc]]:
    if (state.settings.min_version >= (3, )
            and isinstance(node.func, ast.Name) and node.func.id == 'open'
            and not has_starargs(node) and len(node.args) >= 2
            and isinstance(node.args[1], ast.Str)
            and (node.args[1].s in U_MODE_REPLACE or
                 (len(node.args) == 2 and node.args[1].s in U_MODE_REMOVE))):
        yield ast_to_offset(node), _fix_open_mode
Ejemplo n.º 8
0
def visit_Call(
    state: State,
    node: ast.Call,
    parent: ast.AST,
) -> Iterable[Tuple[Offset, TokenFunc]]:
    if state.settings.min_version < (3, ):
        return

    if isinstance(node.func, ast.Name):
        name = node.func.id
    elif isinstance(node.func, ast.Attribute):
        name = node.func.attr
    else:
        return

    if (is_name_attr(
            node.func,
            state.from_imports,
            'six',
        ('iteritems', 'iterkeys', 'itervalues'),
    ) and node.args and not has_starargs(node) and
            # parent is next(...)
            isinstance(parent, ast.Call) and isinstance(parent.func, ast.Name)
            and parent.func.id == 'next'):
        func = functools.partial(
            find_and_replace_call,
            template=f'iter({SIX_CALLS[name]})',
        )
        yield ast_to_offset(node), func
    elif (is_name_attr(node.func, state.from_imports, 'six', SIX_CALLS)
          and node.args and not has_starargs(node)):
        if isinstance(node.args[0], _EXPR_NEEDS_PARENS):
            parens: Tuple[int, ...] = (0, )
        else:
            parens = ()
        func = functools.partial(
            find_and_replace_call,
            template=SIX_CALLS[name],
            parens=parens,
        )
        yield ast_to_offset(node), func
    elif (is_name_attr(
            node.func,
            state.from_imports,
            'six',
        ('int2byte', ),
    ) and node.args and not has_starargs(node)):
        func = functools.partial(
            find_and_replace_call,
            template=SIX_INT2BYTE_TMPL,
        )
        yield ast_to_offset(node), func
    elif (state.settings.min_version >= (3, ) and is_name_attr(
            node.func,
            state.from_imports,
            'six',
        ('b', 'ensure_binary'),
    ) and not node.keywords and not has_starargs(node) and len(node.args) == 1
          and isinstance(node.args[0], ast.Str)):
        yield ast_to_offset(node), _fix_six_b
    elif (isinstance(parent, ast.Expr) and is_name_attr(
            node.func,
            state.from_imports,
            'six',
        ('raise_from', ),
    ) and node.args and not has_starargs(node)):
        func = functools.partial(
            find_and_replace_call,
            template=RAISE_FROM_TMPL,
        )
        yield ast_to_offset(node), func
    elif (isinstance(parent, ast.Expr) and is_name_attr(
            node.func,
            state.from_imports,
            'six',
        ('reraise', ),
    )):
        if len(node.args) == 2 and not has_starargs(node):
            func = functools.partial(
                find_and_replace_call,
                template=RERAISE_2_TMPL,
            )
            yield ast_to_offset(node), func
        elif len(node.args) == 3 and not has_starargs(node):
            func = functools.partial(
                find_and_replace_call,
                template=RERAISE_3_TMPL,
            )
            yield ast_to_offset(node), func
        elif (len(node.args) == 1 and isinstance(node.args[0], ast.Starred)
              and isinstance(node.args[0].value, ast.Call) and is_name_attr(
                  node.args[0].value.func,
                  state.from_imports,
                  'sys',
                  ('exc_info', ),
              )):
            func = functools.partial(
                find_and_replace_call,
                template=RERAISE_TMPL,
            )
            yield ast_to_offset(node), func