diff --git a/stubs/flake8-bugbear/@tests/stubtest_allowlist.txt b/stubs/flake8-bugbear/@tests/stubtest_allowlist.txt index 82f069091..a6bfcd8a7 100644 --- a/stubs/flake8-bugbear/@tests/stubtest_allowlist.txt +++ b/stubs/flake8-bugbear/@tests/stubtest_allowlist.txt @@ -1 +1,37 @@ -bugbear.BugBearChecker.__getattr__ +# Autogenerated methods using @attr.* decorators +bugbear.B040CaughtException.__attrs_attrs__ +bugbear.B040CaughtException.__attrs_own_setattr__ +bugbear.B040CaughtException.__match_args__ +bugbear.B041VariableKeyType.__attrs_attrs__ +bugbear.B041VariableKeyType.__match_args__ +bugbear.BugBearChecker.__attrs_attrs__ +bugbear.BugBearChecker.__ge__ +bugbear.BugBearChecker.__gt__ +bugbear.BugBearChecker.__le__ +bugbear.BugBearChecker.__lt__ +bugbear.BugBearChecker.__match_args__ +bugbear.BugBearVisitor.__attrs_attrs__ +bugbear.BugBearVisitor.__ge__ +bugbear.BugBearVisitor.__gt__ +bugbear.BugBearVisitor.__le__ +bugbear.BugBearVisitor.__lt__ +bugbear.BugBearVisitor.__match_args__ +bugbear.NameFinder.__attrs_attrs__ +bugbear.NameFinder.__ge__ +bugbear.NameFinder.__gt__ +bugbear.NameFinder.__le__ +bugbear.NameFinder.__lt__ +bugbear.NameFinder.__match_args__ +bugbear.NamedExprFinder.__attrs_attrs__ +bugbear.NamedExprFinder.__ge__ +bugbear.NamedExprFinder.__gt__ +bugbear.NamedExprFinder.__le__ +bugbear.NamedExprFinder.__lt__ +bugbear.NamedExprFinder.__match_args__ +# >= Python 3.13 +bugbear.B040CaughtException.__replace__ +bugbear.B041VariableKeyType.__replace__ +bugbear.BugBearChecker.__replace__ +bugbear.BugBearVisitor.__replace__ +bugbear.NameFinder.__replace__ +bugbear.NamedExprFinder.__replace__ diff --git a/stubs/flake8-bugbear/METADATA.toml b/stubs/flake8-bugbear/METADATA.toml index 34969cb41..13d13490a 100644 --- a/stubs/flake8-bugbear/METADATA.toml +++ b/stubs/flake8-bugbear/METADATA.toml @@ -1,6 +1,2 @@ version = "24.12.12" upstream_repository = "https://github.com/PyCQA/flake8-bugbear" -partial_stub = true - -[tool.stubtest] -ignore_missing_stub = true diff --git a/stubs/flake8-bugbear/bugbear.pyi b/stubs/flake8-bugbear/bugbear.pyi index d0b61fa80..3e7082395 100644 --- a/stubs/flake8-bugbear/bugbear.pyi +++ b/stubs/flake8-bugbear/bugbear.pyi @@ -1,19 +1,38 @@ import argparse import ast +import sys from _typeshed import Incomplete -from collections.abc import Sequence -from typing import Any +from collections.abc import Callable, Generator, Iterable, Sequence +from functools import partial +from logging import Logger +from typing import Any, ClassVar, Final, Literal, NamedTuple, overload + +__version__: Final[str] +LOG: Logger +CONTEXTFUL_NODES: Final[tuple[type[ast.AST], ...]] +FUNCTION_NODES: Final[tuple[type[ast.AST], ...]] +B908_pytest_functions: Final[set[str]] +B908_unittest_methods: Final[set[str]] +B902_default_decorators: Final[set[str]] + +class Context(NamedTuple): + node: ast.AST + stack: list[str] class BugBearChecker: - name: str - version: str + name: ClassVar[str] + version: ClassVar[str] tree: ast.AST | None filename: str lines: Sequence[str] | None max_line_length: int visitor: ast.NodeVisitor options: argparse.Namespace | None - def run(self) -> None: ... + def run(self) -> Generator[error]: ... + def gen_line_based_checks(self) -> Generator[error]: ... + @classmethod + def adapt_error(cls, e: error) -> tuple[int, int, str, type[BugBearChecker]]: ... + def load_file(self) -> None: ... @staticmethod def add_options(optmanager: Any) -> None: ... def __init__( @@ -24,6 +43,254 @@ class BugBearChecker: max_line_length: int = ..., options: argparse.Namespace | None = ..., ) -> None: ... - def __getattr__(self, name: str) -> Incomplete: ... # incomplete (other attributes are normally not accessed) + def should_warn(self, code: str) -> bool: ... -def __getattr__(name: str) -> Incomplete: ... +def names_from_assignments(assign_target: ast.AST) -> Generator[str]: ... +def children_in_scope(node: ast.AST) -> Generator[ast.AST]: ... +def walk_list(nodes: Iterable[ast.AST]) -> Generator[ast.AST]: ... + +class ExceptBaseExceptionVisitor(ast.NodeVisitor): + root: ast.ExceptHandler + def __init__(self, except_node: ast.ExceptHandler) -> None: ... + def re_raised(self) -> bool: ... + def visit_Raise(self, node: ast.Raise) -> Incomplete | None: ... + def visit_ExceptHandler(self, node: ast.ExceptHandler) -> Incomplete | None: ... + +class B040CaughtException: + name: str + has_note: bool + def __init__(self, name: str, has_note: bool) -> None: ... + +class B041UnhandledKeyType: ... + +class B041VariableKeyType: + name: str + def __init__(self, name: str) -> None: ... + +class BugBearVisitor(ast.NodeVisitor): + NODE_WINDOW_SIZE: ClassVar[int] = 4 + in_trystar: str + def __init__( + self, + filename: str, + lines: Sequence[str] | None, + b008_b039_extend_immutable_calls: set[str] = ..., + b902_classmethod_decorators: set[str] = ..., + node_window: list[ast.AST] = ..., + errors: list[error] = ..., + contexts: list[Context] = ..., + b040_caught_exception: B040CaughtException | None = None, + in_trystar: str = "", + ) -> None: ... + @property + def node_stack(self) -> list[Context]: ... + def in_class_init(self) -> bool: ... + def visit_Return(self, node: ast.Return) -> None: ... + def visit_Yield(self, node: ast.Yield) -> None: ... + def visit_YieldFrom(self, node: ast.YieldFrom) -> None: ... + def visit(self, node: ast.AST) -> None: ... + def visit_ExceptHandler(self, node: ast.ExceptHandler) -> None: ... + def visit_UAdd(self, node: ast.UAdd) -> None: ... + def visit_Call(self, node: ast.Call) -> None: ... + def visit_Module(self, node: ast.Module) -> None: ... + def visit_Assign(self, node: ast.Assign) -> None: ... + def visit_For(self, node: ast.For) -> None: ... + def visit_AsyncFor(self, node: ast.AsyncFor) -> None: ... + def visit_While(self, node: ast.While) -> None: ... + def visit_ListComp(self, node: ast.ListComp) -> None: ... + def visit_SetComp(self, node: ast.SetComp) -> None: ... + def visit_DictComp(self, node: ast.DictComp) -> None: ... + def visit_GeneratorExp(self, node: ast.GeneratorExp) -> None: ... + def visit_Assert(self, node: ast.Assert) -> None: ... + def visit_AsyncFunctionDef(self, node: ast.AsyncFunctionDef) -> None: ... + def visit_FunctionDef(self, node: ast.FunctionDef) -> None: ... + def visit_ClassDef(self, node: ast.ClassDef) -> None: ... + def visit_Try(self, node: ast.Try) -> None: ... + if sys.version_info >= (3, 11): + def visit_TryStar(self, node: ast.TryStar) -> None: ... + else: + def visit_TryStar(self, node: ast.Try) -> None: ... + + def visit_Compare(self, node: ast.Compare) -> None: ... + def visit_Raise(self, node: ast.Raise) -> None: ... + def visit_With(self, node: ast.With) -> None: ... + def visit_JoinedStr(self, node: ast.JoinedStr) -> None: ... + def visit_AnnAssign(self, node: ast.AnnAssign) -> None: ... + def visit_Import(self, node: ast.Import) -> None: ... + def visit_ImportFrom(self, node: ast.ImportFrom) -> None: ... + def visit_Set(self, node: ast.Set) -> None: ... + def visit_Dict(self, node: ast.Dict) -> None: ... + def check_for_b041(self, node: ast.Dict) -> None: ... + def check_for_b005(self, node: ast.Import | ast.ImportFrom | ast.Call) -> None: ... + def check_for_b006_and_b008(self, node: ast.FunctionDef | ast.AsyncFunctionDef) -> None: ... + def check_for_b039(self, node: ast.Call) -> None: ... + def check_for_b007(self, node: ast.For | ast.AsyncFor) -> None: ... + def check_for_b011(self, node: ast.Assert) -> None: ... + if sys.version_info >= (3, 11): + def check_for_b012(self, node: ast.Try | ast.TryStar) -> None: ... + else: + def check_for_b012(self, node: ast.Try) -> None: ... + + def check_for_b013_b014_b029_b030(self, node: ast.ExceptHandler) -> list[str]: ... + def check_for_b015(self, node: ast.Compare) -> None: ... + def check_for_b016(self, node: ast.Raise) -> None: ... + def check_for_b017(self, node: ast.With | ast.AsyncWith) -> None: ... + def check_for_b019(self, node: ast.FunctionDef | ast.AsyncFunctionDef) -> None: ... + def check_for_b020(self, node: ast.For | ast.AsyncFor | ast.comprehension) -> None: ... + def check_for_b023(self, loop_node: ast.For | ast.AsyncFor | ast.comprehension) -> None: ... + def check_for_b024_and_b027(self, node: ast.ClassDef) -> None: ... + def check_for_b026(self, call: ast.Call) -> None: ... + def check_for_b031(self, loop_node: ast.For | ast.AsyncFor) -> None: ... + def check_for_b035(self, node: ast.DictComp) -> None: ... + def check_for_b040_add_note(self, node: ast.Attribute) -> bool: ... + def check_for_b040_usage(self, node: ast.expr | None) -> None: ... + def check_for_b904(self, node: ast.Raise) -> None: ... + def walk_function_body( + self, node: ast.FunctionDef | ast.AsyncFunctionDef + ) -> tuple[ast.FunctionDef | ast.AsyncFunctionDef, ast.stmt]: ... + def check_for_b901(self, node: ast.FunctionDef | ast.AsyncFunctionDef) -> None: ... + @overload + @classmethod + def find_decorator_name(cls, d: ast.Name | ast.Attribute | ast.Call) -> str: ... + @overload + @classmethod + def find_decorator_name(cls, d: ast.AST) -> str | None: ... + def check_for_b902(self, node: ast.FunctionDef | ast.AsyncFunctionDef) -> None: ... + def check_for_b903(self, node: ast.ClassDef) -> None: ... + def check_for_b018(self, node: ast.Expr) -> None: ... + def check_for_b021(self, node: ast.AsyncFunctionDef | ast.FunctionDef | ast.ClassDef | ast.Module) -> None: ... + def check_for_b022(self, node: ast.With | ast.AsyncWith) -> None: ... + def check_for_b908(self, node: ast.With) -> None: ... + def check_for_b025(self, node: ast.Try) -> None: ... + def check_for_b905(self, node: ast.Call) -> None: ... + def check_for_b906(self, node: ast.FunctionDef) -> None: ... + def check_for_b907(self, node: ast.JoinedStr) -> None: ... + def check_for_b028(self, node: ast.Call) -> None: ... + def check_for_b032(self, node: ast.AnnAssign) -> None: ... + def check_for_b033(self, node: ast.Set | ast.List | ast.Tuple) -> None: ... + def check_for_b034(self, node: ast.Call) -> None: ... + def check_for_b909(self, node: ast.For) -> None: ... + def check_for_b910(self, node: ast.Call) -> None: ... + def check_for_b911(self, node: ast.Call) -> None: ... + +def compose_call_path(node: ast.expr) -> Generator[str]: ... +def is_name(node: ast.expr, name: str) -> bool: ... + +class B909Checker(ast.NodeVisitor): + MUTATING_FUNCTIONS: ClassVar[tuple[str, ...]] + name: str + key: str + mutations: dict[int, list[ast.AST]] + def __init__(self, name: str, key: str) -> None: ... + def visit_Assign(self, node: ast.Assign) -> None: ... + def visit_AugAssign(self, node: ast.AugAssign) -> None: ... + def visit_Delete(self, node: ast.Delete) -> None: ... + def visit_Call(self, node: ast.Call) -> None: ... + def visit_If(self, node: ast.If) -> None: ... + def visit(self, node: ast.AST | list[ast.AST]) -> Any: ... + +class NameFinder(ast.NodeVisitor): + names: dict[str, list[ast.Name]] + def __init__(self, names: dict[str, list[ast.Name]] = ...) -> None: ... + def visit_Name(self, node: ast.Name) -> None: ... + def visit(self, node: ast.AST | list[ast.AST]) -> Any: ... + +class NamedExprFinder(ast.NodeVisitor): + names: dict[str, list[ast.Name]] + def __init__(self, names: dict[str, list[ast.Name]] = ...) -> None: ... + def visit_NamedExpr(self, node: ast.NamedExpr) -> None: ... + def visit(self, node: ast.AST | list[ast.AST]) -> Any: ... + +class FunctionDefDefaultsVisitor(ast.NodeVisitor): + def __init__( + self, + error_code_calls: partial[error], + error_code_literals: partial[error], + b008_b039_extend_immutable_calls: set[str] | None = None, + ) -> None: ... + def visit_mutable_literal_or_comprehension( + self, node: ast.List | ast.Dict | ast.Set | ast.ListComp | ast.DictComp | ast.SetComp + ) -> None: ... + def visit_Call(self, node: ast.Call) -> None: ... + def visit_Lambda(self, node: ast.Lambda) -> None: ... + def visit(self, node: ast.AST | list[ast.AST]) -> None: ... + +class B020NameFinder(NameFinder): + def visit_GeneratorExp(self, node: ast.GeneratorExp) -> None: ... + def visit_ListComp(self, node: ast.ListComp) -> None: ... + def visit_DictComp(self, node: ast.DictComp) -> None: ... + def visit_comprehension(self, node: ast.comprehension) -> None: ... + def visit_Lambda(self, node: ast.Lambda) -> None: ... + +class error(NamedTuple): + lineno: int + col: int + message: str + type: type[BugBearChecker] + vars: tuple[Incomplete] + +Error: Callable[..., partial[error]] +B001: partial[error] +B002: partial[error] +B003: partial[error] +B004: partial[error] +B005: partial[error] +B005_METHODS: Final[set[str]] +B006: partial[error] +B006_MUTABLE_LITERALS: Final[tuple[Literal["Dict"], Literal["List"], Literal["Set"]]] +B006_MUTABLE_COMPREHENSIONS: Final[tuple[Literal["ListComp"], Literal["DictComp"], Literal["SetComp"]]] +B006_MUTABLE_CALLS: Final[set[str]] +B007: partial[error] +B008: partial[error] +B008_IMMUTABLE_CALLS: Final[set[str]] +B009: partial[error] +B010: partial[error] +B011: partial[error] +B012: partial[error] +B013: partial[error] +B014: partial[error] +B014_REDUNDANT_EXCEPTIONS: Final[dict[Literal["OSError", "ValueError"], set[str]]] +B015: partial[error] +B016: partial[error] +B017: partial[error] +B018: partial[error] +B019: partial[error] +B019_CACHES: Final[set[str]] +B020: partial[error] +B021: partial[error] +B022: partial[error] +B023: partial[error] +B024: partial[error] +B025: partial[error] +B026: partial[error] +B027: partial[error] +B028: partial[error] +B029: partial[error] +B030: partial[error] +B031: partial[error] +B032: partial[error] +B033: partial[error] +B034: partial[error] +B035: partial[error] +B036: partial[error] +B037: partial[error] +B039: partial[error] +B040: partial[error] +B041: partial[error] +B901: partial[error] +B902: partial[error] +B902_IMPLICIT_CLASSMETHODS: Final[set[str]] +B902_SELF: Final[list[str]] +B902_CLS: Final[list[str]] +B902_METACLS: Final[list[str]] +B903: partial[error] +B904: partial[error] +B905: partial[error] +B906: partial[error] +B907: partial[error] +B908: partial[error] +B909: partial[error] +B910: partial[error] +B911: partial[error] +B950: partial[error] +disabled_by_default: Final[list[str]]