Skip to content

Commit b0238c5

Browse files
authored
Improve flake8-bugbear (#13829)
1 parent f65bdc1 commit b0238c5

File tree

3 files changed

+311
-12
lines changed

3 files changed

+311
-12
lines changed
Original file line numberDiff line numberDiff line change
@@ -1 +1,37 @@
1-
bugbear.BugBearChecker.__getattr__
1+
# Autogenerated methods using @attr.* decorators
2+
bugbear.B040CaughtException.__attrs_attrs__
3+
bugbear.B040CaughtException.__attrs_own_setattr__
4+
bugbear.B040CaughtException.__match_args__
5+
bugbear.B041VariableKeyType.__attrs_attrs__
6+
bugbear.B041VariableKeyType.__match_args__
7+
bugbear.BugBearChecker.__attrs_attrs__
8+
bugbear.BugBearChecker.__ge__
9+
bugbear.BugBearChecker.__gt__
10+
bugbear.BugBearChecker.__le__
11+
bugbear.BugBearChecker.__lt__
12+
bugbear.BugBearChecker.__match_args__
13+
bugbear.BugBearVisitor.__attrs_attrs__
14+
bugbear.BugBearVisitor.__ge__
15+
bugbear.BugBearVisitor.__gt__
16+
bugbear.BugBearVisitor.__le__
17+
bugbear.BugBearVisitor.__lt__
18+
bugbear.BugBearVisitor.__match_args__
19+
bugbear.NameFinder.__attrs_attrs__
20+
bugbear.NameFinder.__ge__
21+
bugbear.NameFinder.__gt__
22+
bugbear.NameFinder.__le__
23+
bugbear.NameFinder.__lt__
24+
bugbear.NameFinder.__match_args__
25+
bugbear.NamedExprFinder.__attrs_attrs__
26+
bugbear.NamedExprFinder.__ge__
27+
bugbear.NamedExprFinder.__gt__
28+
bugbear.NamedExprFinder.__le__
29+
bugbear.NamedExprFinder.__lt__
30+
bugbear.NamedExprFinder.__match_args__
31+
# >= Python 3.13
32+
bugbear.B040CaughtException.__replace__
33+
bugbear.B041VariableKeyType.__replace__
34+
bugbear.BugBearChecker.__replace__
35+
bugbear.BugBearVisitor.__replace__
36+
bugbear.NameFinder.__replace__
37+
bugbear.NamedExprFinder.__replace__

stubs/flake8-bugbear/METADATA.toml

-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,2 @@
11
version = "24.12.12"
22
upstream_repository = "https://github.com/PyCQA/flake8-bugbear"
3-
partial_stub = true
4-
5-
[tool.stubtest]
6-
ignore_missing_stub = true

stubs/flake8-bugbear/bugbear.pyi

+274-7
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,38 @@
11
import argparse
22
import ast
3+
import sys
34
from _typeshed import Incomplete
4-
from collections.abc import Sequence
5-
from typing import Any
5+
from collections.abc import Callable, Generator, Iterable, Sequence
6+
from functools import partial
7+
from logging import Logger
8+
from typing import Any, ClassVar, Final, Literal, NamedTuple, overload
9+
10+
__version__: Final[str]
11+
LOG: Logger
12+
CONTEXTFUL_NODES: Final[tuple[type[ast.AST], ...]]
13+
FUNCTION_NODES: Final[tuple[type[ast.AST], ...]]
14+
B908_pytest_functions: Final[set[str]]
15+
B908_unittest_methods: Final[set[str]]
16+
B902_default_decorators: Final[set[str]]
17+
18+
class Context(NamedTuple):
19+
node: ast.AST
20+
stack: list[str]
621

722
class BugBearChecker:
8-
name: str
9-
version: str
23+
name: ClassVar[str]
24+
version: ClassVar[str]
1025
tree: ast.AST | None
1126
filename: str
1227
lines: Sequence[str] | None
1328
max_line_length: int
1429
visitor: ast.NodeVisitor
1530
options: argparse.Namespace | None
16-
def run(self) -> None: ...
31+
def run(self) -> Generator[error]: ...
32+
def gen_line_based_checks(self) -> Generator[error]: ...
33+
@classmethod
34+
def adapt_error(cls, e: error) -> tuple[int, int, str, type[BugBearChecker]]: ...
35+
def load_file(self) -> None: ...
1736
@staticmethod
1837
def add_options(optmanager: Any) -> None: ...
1938
def __init__(
@@ -24,6 +43,254 @@ class BugBearChecker:
2443
max_line_length: int = ...,
2544
options: argparse.Namespace | None = ...,
2645
) -> None: ...
27-
def __getattr__(self, name: str) -> Incomplete: ... # incomplete (other attributes are normally not accessed)
46+
def should_warn(self, code: str) -> bool: ...
47+
48+
def names_from_assignments(assign_target: ast.AST) -> Generator[str]: ...
49+
def children_in_scope(node: ast.AST) -> Generator[ast.AST]: ...
50+
def walk_list(nodes: Iterable[ast.AST]) -> Generator[ast.AST]: ...
51+
52+
class ExceptBaseExceptionVisitor(ast.NodeVisitor):
53+
root: ast.ExceptHandler
54+
def __init__(self, except_node: ast.ExceptHandler) -> None: ...
55+
def re_raised(self) -> bool: ...
56+
def visit_Raise(self, node: ast.Raise) -> Incomplete | None: ...
57+
def visit_ExceptHandler(self, node: ast.ExceptHandler) -> Incomplete | None: ...
58+
59+
class B040CaughtException:
60+
name: str
61+
has_note: bool
62+
def __init__(self, name: str, has_note: bool) -> None: ...
63+
64+
class B041UnhandledKeyType: ...
65+
66+
class B041VariableKeyType:
67+
name: str
68+
def __init__(self, name: str) -> None: ...
69+
70+
class BugBearVisitor(ast.NodeVisitor):
71+
NODE_WINDOW_SIZE: ClassVar[int] = 4
72+
in_trystar: str
73+
def __init__(
74+
self,
75+
filename: str,
76+
lines: Sequence[str] | None,
77+
b008_b039_extend_immutable_calls: set[str] = ...,
78+
b902_classmethod_decorators: set[str] = ...,
79+
node_window: list[ast.AST] = ...,
80+
errors: list[error] = ...,
81+
contexts: list[Context] = ...,
82+
b040_caught_exception: B040CaughtException | None = None,
83+
in_trystar: str = "",
84+
) -> None: ...
85+
@property
86+
def node_stack(self) -> list[Context]: ...
87+
def in_class_init(self) -> bool: ...
88+
def visit_Return(self, node: ast.Return) -> None: ...
89+
def visit_Yield(self, node: ast.Yield) -> None: ...
90+
def visit_YieldFrom(self, node: ast.YieldFrom) -> None: ...
91+
def visit(self, node: ast.AST) -> None: ...
92+
def visit_ExceptHandler(self, node: ast.ExceptHandler) -> None: ...
93+
def visit_UAdd(self, node: ast.UAdd) -> None: ...
94+
def visit_Call(self, node: ast.Call) -> None: ...
95+
def visit_Module(self, node: ast.Module) -> None: ...
96+
def visit_Assign(self, node: ast.Assign) -> None: ...
97+
def visit_For(self, node: ast.For) -> None: ...
98+
def visit_AsyncFor(self, node: ast.AsyncFor) -> None: ...
99+
def visit_While(self, node: ast.While) -> None: ...
100+
def visit_ListComp(self, node: ast.ListComp) -> None: ...
101+
def visit_SetComp(self, node: ast.SetComp) -> None: ...
102+
def visit_DictComp(self, node: ast.DictComp) -> None: ...
103+
def visit_GeneratorExp(self, node: ast.GeneratorExp) -> None: ...
104+
def visit_Assert(self, node: ast.Assert) -> None: ...
105+
def visit_AsyncFunctionDef(self, node: ast.AsyncFunctionDef) -> None: ...
106+
def visit_FunctionDef(self, node: ast.FunctionDef) -> None: ...
107+
def visit_ClassDef(self, node: ast.ClassDef) -> None: ...
108+
def visit_Try(self, node: ast.Try) -> None: ...
109+
if sys.version_info >= (3, 11):
110+
def visit_TryStar(self, node: ast.TryStar) -> None: ...
111+
else:
112+
def visit_TryStar(self, node: ast.Try) -> None: ...
113+
114+
def visit_Compare(self, node: ast.Compare) -> None: ...
115+
def visit_Raise(self, node: ast.Raise) -> None: ...
116+
def visit_With(self, node: ast.With) -> None: ...
117+
def visit_JoinedStr(self, node: ast.JoinedStr) -> None: ...
118+
def visit_AnnAssign(self, node: ast.AnnAssign) -> None: ...
119+
def visit_Import(self, node: ast.Import) -> None: ...
120+
def visit_ImportFrom(self, node: ast.ImportFrom) -> None: ...
121+
def visit_Set(self, node: ast.Set) -> None: ...
122+
def visit_Dict(self, node: ast.Dict) -> None: ...
123+
def check_for_b041(self, node: ast.Dict) -> None: ...
124+
def check_for_b005(self, node: ast.Import | ast.ImportFrom | ast.Call) -> None: ...
125+
def check_for_b006_and_b008(self, node: ast.FunctionDef | ast.AsyncFunctionDef) -> None: ...
126+
def check_for_b039(self, node: ast.Call) -> None: ...
127+
def check_for_b007(self, node: ast.For | ast.AsyncFor) -> None: ...
128+
def check_for_b011(self, node: ast.Assert) -> None: ...
129+
if sys.version_info >= (3, 11):
130+
def check_for_b012(self, node: ast.Try | ast.TryStar) -> None: ...
131+
else:
132+
def check_for_b012(self, node: ast.Try) -> None: ...
133+
134+
def check_for_b013_b014_b029_b030(self, node: ast.ExceptHandler) -> list[str]: ...
135+
def check_for_b015(self, node: ast.Compare) -> None: ...
136+
def check_for_b016(self, node: ast.Raise) -> None: ...
137+
def check_for_b017(self, node: ast.With | ast.AsyncWith) -> None: ...
138+
def check_for_b019(self, node: ast.FunctionDef | ast.AsyncFunctionDef) -> None: ...
139+
def check_for_b020(self, node: ast.For | ast.AsyncFor | ast.comprehension) -> None: ...
140+
def check_for_b023(self, loop_node: ast.For | ast.AsyncFor | ast.comprehension) -> None: ...
141+
def check_for_b024_and_b027(self, node: ast.ClassDef) -> None: ...
142+
def check_for_b026(self, call: ast.Call) -> None: ...
143+
def check_for_b031(self, loop_node: ast.For | ast.AsyncFor) -> None: ...
144+
def check_for_b035(self, node: ast.DictComp) -> None: ...
145+
def check_for_b040_add_note(self, node: ast.Attribute) -> bool: ...
146+
def check_for_b040_usage(self, node: ast.expr | None) -> None: ...
147+
def check_for_b904(self, node: ast.Raise) -> None: ...
148+
def walk_function_body(
149+
self, node: ast.FunctionDef | ast.AsyncFunctionDef
150+
) -> tuple[ast.FunctionDef | ast.AsyncFunctionDef, ast.stmt]: ...
151+
def check_for_b901(self, node: ast.FunctionDef | ast.AsyncFunctionDef) -> None: ...
152+
@overload
153+
@classmethod
154+
def find_decorator_name(cls, d: ast.Name | ast.Attribute | ast.Call) -> str: ...
155+
@overload
156+
@classmethod
157+
def find_decorator_name(cls, d: ast.AST) -> str | None: ...
158+
def check_for_b902(self, node: ast.FunctionDef | ast.AsyncFunctionDef) -> None: ...
159+
def check_for_b903(self, node: ast.ClassDef) -> None: ...
160+
def check_for_b018(self, node: ast.Expr) -> None: ...
161+
def check_for_b021(self, node: ast.AsyncFunctionDef | ast.FunctionDef | ast.ClassDef | ast.Module) -> None: ...
162+
def check_for_b022(self, node: ast.With | ast.AsyncWith) -> None: ...
163+
def check_for_b908(self, node: ast.With) -> None: ...
164+
def check_for_b025(self, node: ast.Try) -> None: ...
165+
def check_for_b905(self, node: ast.Call) -> None: ...
166+
def check_for_b906(self, node: ast.FunctionDef) -> None: ...
167+
def check_for_b907(self, node: ast.JoinedStr) -> None: ...
168+
def check_for_b028(self, node: ast.Call) -> None: ...
169+
def check_for_b032(self, node: ast.AnnAssign) -> None: ...
170+
def check_for_b033(self, node: ast.Set | ast.List | ast.Tuple) -> None: ...
171+
def check_for_b034(self, node: ast.Call) -> None: ...
172+
def check_for_b909(self, node: ast.For) -> None: ...
173+
def check_for_b910(self, node: ast.Call) -> None: ...
174+
def check_for_b911(self, node: ast.Call) -> None: ...
175+
176+
def compose_call_path(node: ast.expr) -> Generator[str]: ...
177+
def is_name(node: ast.expr, name: str) -> bool: ...
178+
179+
class B909Checker(ast.NodeVisitor):
180+
MUTATING_FUNCTIONS: ClassVar[tuple[str, ...]]
181+
name: str
182+
key: str
183+
mutations: dict[int, list[ast.AST]]
184+
def __init__(self, name: str, key: str) -> None: ...
185+
def visit_Assign(self, node: ast.Assign) -> None: ...
186+
def visit_AugAssign(self, node: ast.AugAssign) -> None: ...
187+
def visit_Delete(self, node: ast.Delete) -> None: ...
188+
def visit_Call(self, node: ast.Call) -> None: ...
189+
def visit_If(self, node: ast.If) -> None: ...
190+
def visit(self, node: ast.AST | list[ast.AST]) -> Any: ...
191+
192+
class NameFinder(ast.NodeVisitor):
193+
names: dict[str, list[ast.Name]]
194+
def __init__(self, names: dict[str, list[ast.Name]] = ...) -> None: ...
195+
def visit_Name(self, node: ast.Name) -> None: ...
196+
def visit(self, node: ast.AST | list[ast.AST]) -> Any: ...
197+
198+
class NamedExprFinder(ast.NodeVisitor):
199+
names: dict[str, list[ast.Name]]
200+
def __init__(self, names: dict[str, list[ast.Name]] = ...) -> None: ...
201+
def visit_NamedExpr(self, node: ast.NamedExpr) -> None: ...
202+
def visit(self, node: ast.AST | list[ast.AST]) -> Any: ...
203+
204+
class FunctionDefDefaultsVisitor(ast.NodeVisitor):
205+
def __init__(
206+
self,
207+
error_code_calls: partial[error],
208+
error_code_literals: partial[error],
209+
b008_b039_extend_immutable_calls: set[str] | None = None,
210+
) -> None: ...
211+
def visit_mutable_literal_or_comprehension(
212+
self, node: ast.List | ast.Dict | ast.Set | ast.ListComp | ast.DictComp | ast.SetComp
213+
) -> None: ...
214+
def visit_Call(self, node: ast.Call) -> None: ...
215+
def visit_Lambda(self, node: ast.Lambda) -> None: ...
216+
def visit(self, node: ast.AST | list[ast.AST]) -> None: ...
217+
218+
class B020NameFinder(NameFinder):
219+
def visit_GeneratorExp(self, node: ast.GeneratorExp) -> None: ...
220+
def visit_ListComp(self, node: ast.ListComp) -> None: ...
221+
def visit_DictComp(self, node: ast.DictComp) -> None: ...
222+
def visit_comprehension(self, node: ast.comprehension) -> None: ...
223+
def visit_Lambda(self, node: ast.Lambda) -> None: ...
224+
225+
class error(NamedTuple):
226+
lineno: int
227+
col: int
228+
message: str
229+
type: type[BugBearChecker]
230+
vars: tuple[Incomplete]
28231

29-
def __getattr__(name: str) -> Incomplete: ...
232+
Error: Callable[..., partial[error]]
233+
B001: partial[error]
234+
B002: partial[error]
235+
B003: partial[error]
236+
B004: partial[error]
237+
B005: partial[error]
238+
B005_METHODS: Final[set[str]]
239+
B006: partial[error]
240+
B006_MUTABLE_LITERALS: Final[tuple[Literal["Dict"], Literal["List"], Literal["Set"]]]
241+
B006_MUTABLE_COMPREHENSIONS: Final[tuple[Literal["ListComp"], Literal["DictComp"], Literal["SetComp"]]]
242+
B006_MUTABLE_CALLS: Final[set[str]]
243+
B007: partial[error]
244+
B008: partial[error]
245+
B008_IMMUTABLE_CALLS: Final[set[str]]
246+
B009: partial[error]
247+
B010: partial[error]
248+
B011: partial[error]
249+
B012: partial[error]
250+
B013: partial[error]
251+
B014: partial[error]
252+
B014_REDUNDANT_EXCEPTIONS: Final[dict[Literal["OSError", "ValueError"], set[str]]]
253+
B015: partial[error]
254+
B016: partial[error]
255+
B017: partial[error]
256+
B018: partial[error]
257+
B019: partial[error]
258+
B019_CACHES: Final[set[str]]
259+
B020: partial[error]
260+
B021: partial[error]
261+
B022: partial[error]
262+
B023: partial[error]
263+
B024: partial[error]
264+
B025: partial[error]
265+
B026: partial[error]
266+
B027: partial[error]
267+
B028: partial[error]
268+
B029: partial[error]
269+
B030: partial[error]
270+
B031: partial[error]
271+
B032: partial[error]
272+
B033: partial[error]
273+
B034: partial[error]
274+
B035: partial[error]
275+
B036: partial[error]
276+
B037: partial[error]
277+
B039: partial[error]
278+
B040: partial[error]
279+
B041: partial[error]
280+
B901: partial[error]
281+
B902: partial[error]
282+
B902_IMPLICIT_CLASSMETHODS: Final[set[str]]
283+
B902_SELF: Final[list[str]]
284+
B902_CLS: Final[list[str]]
285+
B902_METACLS: Final[list[str]]
286+
B903: partial[error]
287+
B904: partial[error]
288+
B905: partial[error]
289+
B906: partial[error]
290+
B907: partial[error]
291+
B908: partial[error]
292+
B909: partial[error]
293+
B910: partial[error]
294+
B911: partial[error]
295+
B950: partial[error]
296+
disabled_by_default: Final[list[str]]

0 commit comments

Comments
 (0)