mirror of https://github.com/astral-sh/ruff
[`flake8-bugbear`] Accept immutable slice default arguments (`B008`) (#21823)
Closes issue #21565 ## Summary As pointed out in the issue, slices are currently flagged by B008 but this behavior is incorrect because slices are immutable. ## Test Plan Added a test case in the "B006_B008.py" fixture. Sorry for the diff in the snapshots, the only thing that changes in those flies is the line numbers, though. You can also test this manually with this file: ```py # test_slice.py def c(d=slice(0, 3)): ... ``` ```sh > target/debug/ruff check tmp/test_slice.py --no-cache --select B008 All checks passed! ```
This commit is contained in:
parent
45fb3732a4
commit
2d3466eccf
|
|
@ -199,6 +199,9 @@ def bytes_okay(value=bytes(1)):
|
||||||
def int_okay(value=int("12")):
|
def int_okay(value=int("12")):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
# Allow immutable slice()
|
||||||
|
def slice_okay(value=slice(1,2)):
|
||||||
|
pass
|
||||||
|
|
||||||
# Allow immutable complex() value
|
# Allow immutable complex() value
|
||||||
def complex_okay(value=complex(1,2)):
|
def complex_okay(value=complex(1,2)):
|
||||||
|
|
|
||||||
|
|
@ -236,227 +236,227 @@ help: Replace with `None`; initialize within function
|
||||||
note: This is an unsafe fix and may change runtime behavior
|
note: This is an unsafe fix and may change runtime behavior
|
||||||
|
|
||||||
B006 [*] Do not use mutable data structures for argument defaults
|
B006 [*] Do not use mutable data structures for argument defaults
|
||||||
--> B006_B008.py:239:20
|
--> B006_B008.py:242:20
|
||||||
|
|
|
|
||||||
237 | # B006 and B008
|
240 | # B006 and B008
|
||||||
238 | # We should handle arbitrary nesting of these B008.
|
241 | # We should handle arbitrary nesting of these B008.
|
||||||
239 | def nested_combo(a=[float(3), dt.datetime.now()]):
|
242 | def nested_combo(a=[float(3), dt.datetime.now()]):
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
240 | pass
|
243 | pass
|
||||||
|
|
|
|
||||||
help: Replace with `None`; initialize within function
|
help: Replace with `None`; initialize within function
|
||||||
236 |
|
239 |
|
||||||
237 | # B006 and B008
|
240 | # B006 and B008
|
||||||
238 | # We should handle arbitrary nesting of these B008.
|
241 | # We should handle arbitrary nesting of these B008.
|
||||||
- def nested_combo(a=[float(3), dt.datetime.now()]):
|
- def nested_combo(a=[float(3), dt.datetime.now()]):
|
||||||
239 + def nested_combo(a=None):
|
242 + def nested_combo(a=None):
|
||||||
240 | pass
|
243 | pass
|
||||||
241 |
|
244 |
|
||||||
242 |
|
245 |
|
||||||
note: This is an unsafe fix and may change runtime behavior
|
note: This is an unsafe fix and may change runtime behavior
|
||||||
|
|
||||||
B006 [*] Do not use mutable data structures for argument defaults
|
B006 [*] Do not use mutable data structures for argument defaults
|
||||||
--> B006_B008.py:276:27
|
--> B006_B008.py:279:27
|
||||||
|
|
|
|
||||||
275 | def mutable_annotations(
|
278 | def mutable_annotations(
|
||||||
276 | a: list[int] | None = [],
|
279 | a: list[int] | None = [],
|
||||||
| ^^
|
| ^^
|
||||||
277 | b: Optional[Dict[int, int]] = {},
|
280 | b: Optional[Dict[int, int]] = {},
|
||||||
278 | c: Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
281 | c: Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
||||||
|
|
|
|
||||||
help: Replace with `None`; initialize within function
|
help: Replace with `None`; initialize within function
|
||||||
273 |
|
276 |
|
||||||
274 |
|
277 |
|
||||||
275 | def mutable_annotations(
|
278 | def mutable_annotations(
|
||||||
- a: list[int] | None = [],
|
- a: list[int] | None = [],
|
||||||
276 + a: list[int] | None = None,
|
279 + a: list[int] | None = None,
|
||||||
277 | b: Optional[Dict[int, int]] = {},
|
280 | b: Optional[Dict[int, int]] = {},
|
||||||
278 | c: Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
281 | c: Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
||||||
279 | d: typing_extensions.Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
282 | d: typing_extensions.Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
||||||
note: This is an unsafe fix and may change runtime behavior
|
note: This is an unsafe fix and may change runtime behavior
|
||||||
|
|
||||||
B006 [*] Do not use mutable data structures for argument defaults
|
B006 [*] Do not use mutable data structures for argument defaults
|
||||||
--> B006_B008.py:277:35
|
--> B006_B008.py:280:35
|
||||||
|
|
|
|
||||||
275 | def mutable_annotations(
|
278 | def mutable_annotations(
|
||||||
276 | a: list[int] | None = [],
|
279 | a: list[int] | None = [],
|
||||||
277 | b: Optional[Dict[int, int]] = {},
|
280 | b: Optional[Dict[int, int]] = {},
|
||||||
| ^^
|
| ^^
|
||||||
278 | c: Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
281 | c: Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
||||||
279 | d: typing_extensions.Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
282 | d: typing_extensions.Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
||||||
|
|
|
|
||||||
help: Replace with `None`; initialize within function
|
help: Replace with `None`; initialize within function
|
||||||
274 |
|
277 |
|
||||||
275 | def mutable_annotations(
|
278 | def mutable_annotations(
|
||||||
276 | a: list[int] | None = [],
|
279 | a: list[int] | None = [],
|
||||||
- b: Optional[Dict[int, int]] = {},
|
- b: Optional[Dict[int, int]] = {},
|
||||||
277 + b: Optional[Dict[int, int]] = None,
|
280 + b: Optional[Dict[int, int]] = None,
|
||||||
278 | c: Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
281 | c: Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
||||||
279 | d: typing_extensions.Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
282 | d: typing_extensions.Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
||||||
280 | ):
|
283 | ):
|
||||||
note: This is an unsafe fix and may change runtime behavior
|
note: This is an unsafe fix and may change runtime behavior
|
||||||
|
|
||||||
B006 [*] Do not use mutable data structures for argument defaults
|
B006 [*] Do not use mutable data structures for argument defaults
|
||||||
--> B006_B008.py:278:62
|
--> B006_B008.py:281:62
|
||||||
|
|
|
|
||||||
276 | a: list[int] | None = [],
|
279 | a: list[int] | None = [],
|
||||||
277 | b: Optional[Dict[int, int]] = {},
|
280 | b: Optional[Dict[int, int]] = {},
|
||||||
278 | c: Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
281 | c: Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
279 | d: typing_extensions.Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
282 | d: typing_extensions.Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
||||||
280 | ):
|
283 | ):
|
||||||
|
|
|
|
||||||
help: Replace with `None`; initialize within function
|
help: Replace with `None`; initialize within function
|
||||||
275 | def mutable_annotations(
|
278 | def mutable_annotations(
|
||||||
276 | a: list[int] | None = [],
|
279 | a: list[int] | None = [],
|
||||||
277 | b: Optional[Dict[int, int]] = {},
|
280 | b: Optional[Dict[int, int]] = {},
|
||||||
- c: Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
- c: Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
||||||
278 + c: Annotated[Union[Set[str], abc.Sized], "annotation"] = None,
|
281 + c: Annotated[Union[Set[str], abc.Sized], "annotation"] = None,
|
||||||
279 | d: typing_extensions.Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
282 | d: typing_extensions.Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
||||||
280 | ):
|
283 | ):
|
||||||
281 | pass
|
284 | pass
|
||||||
note: This is an unsafe fix and may change runtime behavior
|
note: This is an unsafe fix and may change runtime behavior
|
||||||
|
|
||||||
B006 [*] Do not use mutable data structures for argument defaults
|
B006 [*] Do not use mutable data structures for argument defaults
|
||||||
--> B006_B008.py:279:80
|
--> B006_B008.py:282:80
|
||||||
|
|
|
|
||||||
277 | b: Optional[Dict[int, int]] = {},
|
280 | b: Optional[Dict[int, int]] = {},
|
||||||
278 | c: Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
281 | c: Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
||||||
279 | d: typing_extensions.Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
282 | d: typing_extensions.Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
280 | ):
|
283 | ):
|
||||||
281 | pass
|
284 | pass
|
||||||
|
|
|
|
||||||
help: Replace with `None`; initialize within function
|
help: Replace with `None`; initialize within function
|
||||||
276 | a: list[int] | None = [],
|
279 | a: list[int] | None = [],
|
||||||
277 | b: Optional[Dict[int, int]] = {},
|
280 | b: Optional[Dict[int, int]] = {},
|
||||||
278 | c: Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
281 | c: Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
||||||
- d: typing_extensions.Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
- d: typing_extensions.Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
||||||
279 + d: typing_extensions.Annotated[Union[Set[str], abc.Sized], "annotation"] = None,
|
282 + d: typing_extensions.Annotated[Union[Set[str], abc.Sized], "annotation"] = None,
|
||||||
280 | ):
|
283 | ):
|
||||||
281 | pass
|
284 | pass
|
||||||
282 |
|
285 |
|
||||||
note: This is an unsafe fix and may change runtime behavior
|
note: This is an unsafe fix and may change runtime behavior
|
||||||
|
|
||||||
B006 [*] Do not use mutable data structures for argument defaults
|
B006 [*] Do not use mutable data structures for argument defaults
|
||||||
--> B006_B008.py:284:52
|
--> B006_B008.py:287:52
|
||||||
|
|
|
|
||||||
284 | def single_line_func_wrong(value: dict[str, str] = {}):
|
287 | def single_line_func_wrong(value: dict[str, str] = {}):
|
||||||
| ^^
|
| ^^
|
||||||
285 | """Docstring"""
|
288 | """Docstring"""
|
||||||
|
|
|
|
||||||
help: Replace with `None`; initialize within function
|
help: Replace with `None`; initialize within function
|
||||||
281 | pass
|
284 | pass
|
||||||
282 |
|
285 |
|
||||||
283 |
|
|
||||||
- def single_line_func_wrong(value: dict[str, str] = {}):
|
|
||||||
284 + def single_line_func_wrong(value: dict[str, str] = None):
|
|
||||||
285 | """Docstring"""
|
|
||||||
286 |
|
286 |
|
||||||
287 |
|
- def single_line_func_wrong(value: dict[str, str] = {}):
|
||||||
|
287 + def single_line_func_wrong(value: dict[str, str] = None):
|
||||||
|
288 | """Docstring"""
|
||||||
|
289 |
|
||||||
|
290 |
|
||||||
note: This is an unsafe fix and may change runtime behavior
|
note: This is an unsafe fix and may change runtime behavior
|
||||||
|
|
||||||
B006 [*] Do not use mutable data structures for argument defaults
|
B006 [*] Do not use mutable data structures for argument defaults
|
||||||
--> B006_B008.py:288:52
|
--> B006_B008.py:291:52
|
||||||
|
|
|
|
||||||
288 | def single_line_func_wrong(value: dict[str, str] = {}):
|
291 | def single_line_func_wrong(value: dict[str, str] = {}):
|
||||||
| ^^
|
| ^^
|
||||||
289 | """Docstring"""
|
292 | """Docstring"""
|
||||||
290 | ...
|
293 | ...
|
||||||
|
|
|
|
||||||
help: Replace with `None`; initialize within function
|
help: Replace with `None`; initialize within function
|
||||||
285 | """Docstring"""
|
288 | """Docstring"""
|
||||||
286 |
|
289 |
|
||||||
287 |
|
290 |
|
||||||
- def single_line_func_wrong(value: dict[str, str] = {}):
|
- def single_line_func_wrong(value: dict[str, str] = {}):
|
||||||
288 + def single_line_func_wrong(value: dict[str, str] = None):
|
291 + def single_line_func_wrong(value: dict[str, str] = None):
|
||||||
289 | """Docstring"""
|
292 | """Docstring"""
|
||||||
290 | ...
|
293 | ...
|
||||||
291 |
|
294 |
|
||||||
note: This is an unsafe fix and may change runtime behavior
|
note: This is an unsafe fix and may change runtime behavior
|
||||||
|
|
||||||
B006 [*] Do not use mutable data structures for argument defaults
|
B006 [*] Do not use mutable data structures for argument defaults
|
||||||
--> B006_B008.py:293:52
|
--> B006_B008.py:296:52
|
||||||
|
|
|
|
||||||
293 | def single_line_func_wrong(value: dict[str, str] = {}):
|
296 | def single_line_func_wrong(value: dict[str, str] = {}):
|
||||||
| ^^
|
| ^^
|
||||||
294 | """Docstring"""; ...
|
297 | """Docstring"""; ...
|
||||||
|
|
|
|
||||||
help: Replace with `None`; initialize within function
|
help: Replace with `None`; initialize within function
|
||||||
290 | ...
|
293 | ...
|
||||||
291 |
|
294 |
|
||||||
292 |
|
|
||||||
- def single_line_func_wrong(value: dict[str, str] = {}):
|
|
||||||
293 + def single_line_func_wrong(value: dict[str, str] = None):
|
|
||||||
294 | """Docstring"""; ...
|
|
||||||
295 |
|
295 |
|
||||||
296 |
|
- def single_line_func_wrong(value: dict[str, str] = {}):
|
||||||
|
296 + def single_line_func_wrong(value: dict[str, str] = None):
|
||||||
|
297 | """Docstring"""; ...
|
||||||
|
298 |
|
||||||
|
299 |
|
||||||
note: This is an unsafe fix and may change runtime behavior
|
note: This is an unsafe fix and may change runtime behavior
|
||||||
|
|
||||||
B006 [*] Do not use mutable data structures for argument defaults
|
B006 [*] Do not use mutable data structures for argument defaults
|
||||||
--> B006_B008.py:297:52
|
--> B006_B008.py:300:52
|
||||||
|
|
|
|
||||||
297 | def single_line_func_wrong(value: dict[str, str] = {}):
|
300 | def single_line_func_wrong(value: dict[str, str] = {}):
|
||||||
| ^^
|
| ^^
|
||||||
298 | """Docstring"""; \
|
301 | """Docstring"""; \
|
||||||
299 | ...
|
302 | ...
|
||||||
|
|
|
|
||||||
help: Replace with `None`; initialize within function
|
help: Replace with `None`; initialize within function
|
||||||
294 | """Docstring"""; ...
|
297 | """Docstring"""; ...
|
||||||
295 |
|
298 |
|
||||||
296 |
|
299 |
|
||||||
- def single_line_func_wrong(value: dict[str, str] = {}):
|
- def single_line_func_wrong(value: dict[str, str] = {}):
|
||||||
297 + def single_line_func_wrong(value: dict[str, str] = None):
|
300 + def single_line_func_wrong(value: dict[str, str] = None):
|
||||||
298 | """Docstring"""; \
|
301 | """Docstring"""; \
|
||||||
299 | ...
|
302 | ...
|
||||||
300 |
|
303 |
|
||||||
note: This is an unsafe fix and may change runtime behavior
|
note: This is an unsafe fix and may change runtime behavior
|
||||||
|
|
||||||
B006 [*] Do not use mutable data structures for argument defaults
|
B006 [*] Do not use mutable data structures for argument defaults
|
||||||
--> B006_B008.py:302:52
|
--> B006_B008.py:305:52
|
||||||
|
|
|
|
||||||
302 | def single_line_func_wrong(value: dict[str, str] = {
|
305 | def single_line_func_wrong(value: dict[str, str] = {
|
||||||
| ____________________________________________________^
|
| ____________________________________________________^
|
||||||
303 | | # This is a comment
|
306 | | # This is a comment
|
||||||
304 | | }):
|
307 | | }):
|
||||||
| |_^
|
| |_^
|
||||||
305 | """Docstring"""
|
308 | """Docstring"""
|
||||||
|
|
|
|
||||||
help: Replace with `None`; initialize within function
|
help: Replace with `None`; initialize within function
|
||||||
299 | ...
|
302 | ...
|
||||||
300 |
|
303 |
|
||||||
301 |
|
304 |
|
||||||
- def single_line_func_wrong(value: dict[str, str] = {
|
- def single_line_func_wrong(value: dict[str, str] = {
|
||||||
- # This is a comment
|
- # This is a comment
|
||||||
- }):
|
- }):
|
||||||
302 + def single_line_func_wrong(value: dict[str, str] = None):
|
305 + def single_line_func_wrong(value: dict[str, str] = None):
|
||||||
303 | """Docstring"""
|
306 | """Docstring"""
|
||||||
304 |
|
307 |
|
||||||
305 |
|
308 |
|
||||||
note: This is an unsafe fix and may change runtime behavior
|
note: This is an unsafe fix and may change runtime behavior
|
||||||
|
|
||||||
B006 Do not use mutable data structures for argument defaults
|
B006 Do not use mutable data structures for argument defaults
|
||||||
--> B006_B008.py:308:52
|
--> B006_B008.py:311:52
|
||||||
|
|
|
|
||||||
308 | def single_line_func_wrong(value: dict[str, str] = {}) \
|
311 | def single_line_func_wrong(value: dict[str, str] = {}) \
|
||||||
| ^^
|
| ^^
|
||||||
309 | : \
|
312 | : \
|
||||||
310 | """Docstring"""
|
313 | """Docstring"""
|
||||||
|
|
|
|
||||||
help: Replace with `None`; initialize within function
|
help: Replace with `None`; initialize within function
|
||||||
|
|
||||||
B006 [*] Do not use mutable data structures for argument defaults
|
B006 [*] Do not use mutable data structures for argument defaults
|
||||||
--> B006_B008.py:313:52
|
--> B006_B008.py:316:52
|
||||||
|
|
|
|
||||||
313 | def single_line_func_wrong(value: dict[str, str] = {}):
|
316 | def single_line_func_wrong(value: dict[str, str] = {}):
|
||||||
| ^^
|
| ^^
|
||||||
314 | """Docstring without newline"""
|
317 | """Docstring without newline"""
|
||||||
|
|
|
|
||||||
help: Replace with `None`; initialize within function
|
help: Replace with `None`; initialize within function
|
||||||
310 | """Docstring"""
|
313 | """Docstring"""
|
||||||
311 |
|
314 |
|
||||||
312 |
|
315 |
|
||||||
- def single_line_func_wrong(value: dict[str, str] = {}):
|
- def single_line_func_wrong(value: dict[str, str] = {}):
|
||||||
313 + def single_line_func_wrong(value: dict[str, str] = None):
|
316 + def single_line_func_wrong(value: dict[str, str] = None):
|
||||||
314 | """Docstring without newline"""
|
317 | """Docstring without newline"""
|
||||||
note: This is an unsafe fix and may change runtime behavior
|
note: This is an unsafe fix and may change runtime behavior
|
||||||
|
|
|
||||||
|
|
@ -53,39 +53,39 @@ B008 Do not perform function call in argument defaults; instead, perform the cal
|
||||||
|
|
|
|
||||||
|
|
||||||
B008 Do not perform function call `dt.datetime.now` in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable
|
B008 Do not perform function call `dt.datetime.now` in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable
|
||||||
--> B006_B008.py:239:31
|
--> B006_B008.py:242:31
|
||||||
|
|
|
|
||||||
237 | # B006 and B008
|
240 | # B006 and B008
|
||||||
238 | # We should handle arbitrary nesting of these B008.
|
241 | # We should handle arbitrary nesting of these B008.
|
||||||
239 | def nested_combo(a=[float(3), dt.datetime.now()]):
|
242 | def nested_combo(a=[float(3), dt.datetime.now()]):
|
||||||
| ^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^
|
||||||
240 | pass
|
243 | pass
|
||||||
|
|
|
|
||||||
|
|
||||||
B008 Do not perform function call `map` in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable
|
B008 Do not perform function call `map` in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable
|
||||||
--> B006_B008.py:245:22
|
--> B006_B008.py:248:22
|
||||||
|
|
|
|
||||||
243 | # Don't flag nested B006 since we can't guarantee that
|
246 | # Don't flag nested B006 since we can't guarantee that
|
||||||
244 | # it isn't made mutable by the outer operation.
|
247 | # it isn't made mutable by the outer operation.
|
||||||
245 | def no_nested_b006(a=map(lambda s: s.upper(), ["a", "b", "c"])):
|
248 | def no_nested_b006(a=map(lambda s: s.upper(), ["a", "b", "c"])):
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
246 | pass
|
249 | pass
|
||||||
|
|
|
|
||||||
|
|
||||||
B008 Do not perform function call `random.randint` in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable
|
B008 Do not perform function call `random.randint` in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable
|
||||||
--> B006_B008.py:250:19
|
--> B006_B008.py:253:19
|
||||||
|
|
|
|
||||||
249 | # B008-ception.
|
252 | # B008-ception.
|
||||||
250 | def nested_b008(a=random.randint(0, dt.datetime.now().year)):
|
253 | def nested_b008(a=random.randint(0, dt.datetime.now().year)):
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
251 | pass
|
254 | pass
|
||||||
|
|
|
|
||||||
|
|
||||||
B008 Do not perform function call `dt.datetime.now` in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable
|
B008 Do not perform function call `dt.datetime.now` in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable
|
||||||
--> B006_B008.py:250:37
|
--> B006_B008.py:253:37
|
||||||
|
|
|
|
||||||
249 | # B008-ception.
|
252 | # B008-ception.
|
||||||
250 | def nested_b008(a=random.randint(0, dt.datetime.now().year)):
|
253 | def nested_b008(a=random.randint(0, dt.datetime.now().year)):
|
||||||
| ^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^
|
||||||
251 | pass
|
254 | pass
|
||||||
|
|
|
|
||||||
|
|
|
||||||
|
|
@ -236,227 +236,227 @@ help: Replace with `None`; initialize within function
|
||||||
note: This is an unsafe fix and may change runtime behavior
|
note: This is an unsafe fix and may change runtime behavior
|
||||||
|
|
||||||
B006 [*] Do not use mutable data structures for argument defaults
|
B006 [*] Do not use mutable data structures for argument defaults
|
||||||
--> B006_B008.py:239:20
|
--> B006_B008.py:242:20
|
||||||
|
|
|
|
||||||
237 | # B006 and B008
|
240 | # B006 and B008
|
||||||
238 | # We should handle arbitrary nesting of these B008.
|
241 | # We should handle arbitrary nesting of these B008.
|
||||||
239 | def nested_combo(a=[float(3), dt.datetime.now()]):
|
242 | def nested_combo(a=[float(3), dt.datetime.now()]):
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
240 | pass
|
243 | pass
|
||||||
|
|
|
|
||||||
help: Replace with `None`; initialize within function
|
help: Replace with `None`; initialize within function
|
||||||
236 |
|
239 |
|
||||||
237 | # B006 and B008
|
240 | # B006 and B008
|
||||||
238 | # We should handle arbitrary nesting of these B008.
|
241 | # We should handle arbitrary nesting of these B008.
|
||||||
- def nested_combo(a=[float(3), dt.datetime.now()]):
|
- def nested_combo(a=[float(3), dt.datetime.now()]):
|
||||||
239 + def nested_combo(a=None):
|
242 + def nested_combo(a=None):
|
||||||
240 | pass
|
243 | pass
|
||||||
241 |
|
244 |
|
||||||
242 |
|
245 |
|
||||||
note: This is an unsafe fix and may change runtime behavior
|
note: This is an unsafe fix and may change runtime behavior
|
||||||
|
|
||||||
B006 [*] Do not use mutable data structures for argument defaults
|
B006 [*] Do not use mutable data structures for argument defaults
|
||||||
--> B006_B008.py:276:27
|
--> B006_B008.py:279:27
|
||||||
|
|
|
|
||||||
275 | def mutable_annotations(
|
278 | def mutable_annotations(
|
||||||
276 | a: list[int] | None = [],
|
279 | a: list[int] | None = [],
|
||||||
| ^^
|
| ^^
|
||||||
277 | b: Optional[Dict[int, int]] = {},
|
280 | b: Optional[Dict[int, int]] = {},
|
||||||
278 | c: Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
281 | c: Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
||||||
|
|
|
|
||||||
help: Replace with `None`; initialize within function
|
help: Replace with `None`; initialize within function
|
||||||
273 |
|
276 |
|
||||||
274 |
|
277 |
|
||||||
275 | def mutable_annotations(
|
278 | def mutable_annotations(
|
||||||
- a: list[int] | None = [],
|
- a: list[int] | None = [],
|
||||||
276 + a: list[int] | None = None,
|
279 + a: list[int] | None = None,
|
||||||
277 | b: Optional[Dict[int, int]] = {},
|
280 | b: Optional[Dict[int, int]] = {},
|
||||||
278 | c: Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
281 | c: Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
||||||
279 | d: typing_extensions.Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
282 | d: typing_extensions.Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
||||||
note: This is an unsafe fix and may change runtime behavior
|
note: This is an unsafe fix and may change runtime behavior
|
||||||
|
|
||||||
B006 [*] Do not use mutable data structures for argument defaults
|
B006 [*] Do not use mutable data structures for argument defaults
|
||||||
--> B006_B008.py:277:35
|
--> B006_B008.py:280:35
|
||||||
|
|
|
|
||||||
275 | def mutable_annotations(
|
278 | def mutable_annotations(
|
||||||
276 | a: list[int] | None = [],
|
279 | a: list[int] | None = [],
|
||||||
277 | b: Optional[Dict[int, int]] = {},
|
280 | b: Optional[Dict[int, int]] = {},
|
||||||
| ^^
|
| ^^
|
||||||
278 | c: Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
281 | c: Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
||||||
279 | d: typing_extensions.Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
282 | d: typing_extensions.Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
||||||
|
|
|
|
||||||
help: Replace with `None`; initialize within function
|
help: Replace with `None`; initialize within function
|
||||||
274 |
|
277 |
|
||||||
275 | def mutable_annotations(
|
278 | def mutable_annotations(
|
||||||
276 | a: list[int] | None = [],
|
279 | a: list[int] | None = [],
|
||||||
- b: Optional[Dict[int, int]] = {},
|
- b: Optional[Dict[int, int]] = {},
|
||||||
277 + b: Optional[Dict[int, int]] = None,
|
280 + b: Optional[Dict[int, int]] = None,
|
||||||
278 | c: Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
281 | c: Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
||||||
279 | d: typing_extensions.Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
282 | d: typing_extensions.Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
||||||
280 | ):
|
283 | ):
|
||||||
note: This is an unsafe fix and may change runtime behavior
|
note: This is an unsafe fix and may change runtime behavior
|
||||||
|
|
||||||
B006 [*] Do not use mutable data structures for argument defaults
|
B006 [*] Do not use mutable data structures for argument defaults
|
||||||
--> B006_B008.py:278:62
|
--> B006_B008.py:281:62
|
||||||
|
|
|
|
||||||
276 | a: list[int] | None = [],
|
279 | a: list[int] | None = [],
|
||||||
277 | b: Optional[Dict[int, int]] = {},
|
280 | b: Optional[Dict[int, int]] = {},
|
||||||
278 | c: Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
281 | c: Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
279 | d: typing_extensions.Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
282 | d: typing_extensions.Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
||||||
280 | ):
|
283 | ):
|
||||||
|
|
|
|
||||||
help: Replace with `None`; initialize within function
|
help: Replace with `None`; initialize within function
|
||||||
275 | def mutable_annotations(
|
278 | def mutable_annotations(
|
||||||
276 | a: list[int] | None = [],
|
279 | a: list[int] | None = [],
|
||||||
277 | b: Optional[Dict[int, int]] = {},
|
280 | b: Optional[Dict[int, int]] = {},
|
||||||
- c: Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
- c: Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
||||||
278 + c: Annotated[Union[Set[str], abc.Sized], "annotation"] = None,
|
281 + c: Annotated[Union[Set[str], abc.Sized], "annotation"] = None,
|
||||||
279 | d: typing_extensions.Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
282 | d: typing_extensions.Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
||||||
280 | ):
|
283 | ):
|
||||||
281 | pass
|
284 | pass
|
||||||
note: This is an unsafe fix and may change runtime behavior
|
note: This is an unsafe fix and may change runtime behavior
|
||||||
|
|
||||||
B006 [*] Do not use mutable data structures for argument defaults
|
B006 [*] Do not use mutable data structures for argument defaults
|
||||||
--> B006_B008.py:279:80
|
--> B006_B008.py:282:80
|
||||||
|
|
|
|
||||||
277 | b: Optional[Dict[int, int]] = {},
|
280 | b: Optional[Dict[int, int]] = {},
|
||||||
278 | c: Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
281 | c: Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
||||||
279 | d: typing_extensions.Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
282 | d: typing_extensions.Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
280 | ):
|
283 | ):
|
||||||
281 | pass
|
284 | pass
|
||||||
|
|
|
|
||||||
help: Replace with `None`; initialize within function
|
help: Replace with `None`; initialize within function
|
||||||
276 | a: list[int] | None = [],
|
279 | a: list[int] | None = [],
|
||||||
277 | b: Optional[Dict[int, int]] = {},
|
280 | b: Optional[Dict[int, int]] = {},
|
||||||
278 | c: Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
281 | c: Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
||||||
- d: typing_extensions.Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
- d: typing_extensions.Annotated[Union[Set[str], abc.Sized], "annotation"] = set(),
|
||||||
279 + d: typing_extensions.Annotated[Union[Set[str], abc.Sized], "annotation"] = None,
|
282 + d: typing_extensions.Annotated[Union[Set[str], abc.Sized], "annotation"] = None,
|
||||||
280 | ):
|
283 | ):
|
||||||
281 | pass
|
284 | pass
|
||||||
282 |
|
285 |
|
||||||
note: This is an unsafe fix and may change runtime behavior
|
note: This is an unsafe fix and may change runtime behavior
|
||||||
|
|
||||||
B006 [*] Do not use mutable data structures for argument defaults
|
B006 [*] Do not use mutable data structures for argument defaults
|
||||||
--> B006_B008.py:284:52
|
--> B006_B008.py:287:52
|
||||||
|
|
|
|
||||||
284 | def single_line_func_wrong(value: dict[str, str] = {}):
|
287 | def single_line_func_wrong(value: dict[str, str] = {}):
|
||||||
| ^^
|
| ^^
|
||||||
285 | """Docstring"""
|
288 | """Docstring"""
|
||||||
|
|
|
|
||||||
help: Replace with `None`; initialize within function
|
help: Replace with `None`; initialize within function
|
||||||
281 | pass
|
284 | pass
|
||||||
282 |
|
285 |
|
||||||
283 |
|
|
||||||
- def single_line_func_wrong(value: dict[str, str] = {}):
|
|
||||||
284 + def single_line_func_wrong(value: dict[str, str] = None):
|
|
||||||
285 | """Docstring"""
|
|
||||||
286 |
|
286 |
|
||||||
287 |
|
- def single_line_func_wrong(value: dict[str, str] = {}):
|
||||||
|
287 + def single_line_func_wrong(value: dict[str, str] = None):
|
||||||
|
288 | """Docstring"""
|
||||||
|
289 |
|
||||||
|
290 |
|
||||||
note: This is an unsafe fix and may change runtime behavior
|
note: This is an unsafe fix and may change runtime behavior
|
||||||
|
|
||||||
B006 [*] Do not use mutable data structures for argument defaults
|
B006 [*] Do not use mutable data structures for argument defaults
|
||||||
--> B006_B008.py:288:52
|
--> B006_B008.py:291:52
|
||||||
|
|
|
|
||||||
288 | def single_line_func_wrong(value: dict[str, str] = {}):
|
291 | def single_line_func_wrong(value: dict[str, str] = {}):
|
||||||
| ^^
|
| ^^
|
||||||
289 | """Docstring"""
|
292 | """Docstring"""
|
||||||
290 | ...
|
293 | ...
|
||||||
|
|
|
|
||||||
help: Replace with `None`; initialize within function
|
help: Replace with `None`; initialize within function
|
||||||
285 | """Docstring"""
|
288 | """Docstring"""
|
||||||
286 |
|
289 |
|
||||||
287 |
|
290 |
|
||||||
- def single_line_func_wrong(value: dict[str, str] = {}):
|
- def single_line_func_wrong(value: dict[str, str] = {}):
|
||||||
288 + def single_line_func_wrong(value: dict[str, str] = None):
|
291 + def single_line_func_wrong(value: dict[str, str] = None):
|
||||||
289 | """Docstring"""
|
292 | """Docstring"""
|
||||||
290 | ...
|
293 | ...
|
||||||
291 |
|
294 |
|
||||||
note: This is an unsafe fix and may change runtime behavior
|
note: This is an unsafe fix and may change runtime behavior
|
||||||
|
|
||||||
B006 [*] Do not use mutable data structures for argument defaults
|
B006 [*] Do not use mutable data structures for argument defaults
|
||||||
--> B006_B008.py:293:52
|
--> B006_B008.py:296:52
|
||||||
|
|
|
|
||||||
293 | def single_line_func_wrong(value: dict[str, str] = {}):
|
296 | def single_line_func_wrong(value: dict[str, str] = {}):
|
||||||
| ^^
|
| ^^
|
||||||
294 | """Docstring"""; ...
|
297 | """Docstring"""; ...
|
||||||
|
|
|
|
||||||
help: Replace with `None`; initialize within function
|
help: Replace with `None`; initialize within function
|
||||||
290 | ...
|
293 | ...
|
||||||
291 |
|
294 |
|
||||||
292 |
|
|
||||||
- def single_line_func_wrong(value: dict[str, str] = {}):
|
|
||||||
293 + def single_line_func_wrong(value: dict[str, str] = None):
|
|
||||||
294 | """Docstring"""; ...
|
|
||||||
295 |
|
295 |
|
||||||
296 |
|
- def single_line_func_wrong(value: dict[str, str] = {}):
|
||||||
|
296 + def single_line_func_wrong(value: dict[str, str] = None):
|
||||||
|
297 | """Docstring"""; ...
|
||||||
|
298 |
|
||||||
|
299 |
|
||||||
note: This is an unsafe fix and may change runtime behavior
|
note: This is an unsafe fix and may change runtime behavior
|
||||||
|
|
||||||
B006 [*] Do not use mutable data structures for argument defaults
|
B006 [*] Do not use mutable data structures for argument defaults
|
||||||
--> B006_B008.py:297:52
|
--> B006_B008.py:300:52
|
||||||
|
|
|
|
||||||
297 | def single_line_func_wrong(value: dict[str, str] = {}):
|
300 | def single_line_func_wrong(value: dict[str, str] = {}):
|
||||||
| ^^
|
| ^^
|
||||||
298 | """Docstring"""; \
|
301 | """Docstring"""; \
|
||||||
299 | ...
|
302 | ...
|
||||||
|
|
|
|
||||||
help: Replace with `None`; initialize within function
|
help: Replace with `None`; initialize within function
|
||||||
294 | """Docstring"""; ...
|
297 | """Docstring"""; ...
|
||||||
295 |
|
298 |
|
||||||
296 |
|
299 |
|
||||||
- def single_line_func_wrong(value: dict[str, str] = {}):
|
- def single_line_func_wrong(value: dict[str, str] = {}):
|
||||||
297 + def single_line_func_wrong(value: dict[str, str] = None):
|
300 + def single_line_func_wrong(value: dict[str, str] = None):
|
||||||
298 | """Docstring"""; \
|
301 | """Docstring"""; \
|
||||||
299 | ...
|
302 | ...
|
||||||
300 |
|
303 |
|
||||||
note: This is an unsafe fix and may change runtime behavior
|
note: This is an unsafe fix and may change runtime behavior
|
||||||
|
|
||||||
B006 [*] Do not use mutable data structures for argument defaults
|
B006 [*] Do not use mutable data structures for argument defaults
|
||||||
--> B006_B008.py:302:52
|
--> B006_B008.py:305:52
|
||||||
|
|
|
|
||||||
302 | def single_line_func_wrong(value: dict[str, str] = {
|
305 | def single_line_func_wrong(value: dict[str, str] = {
|
||||||
| ____________________________________________________^
|
| ____________________________________________________^
|
||||||
303 | | # This is a comment
|
306 | | # This is a comment
|
||||||
304 | | }):
|
307 | | }):
|
||||||
| |_^
|
| |_^
|
||||||
305 | """Docstring"""
|
308 | """Docstring"""
|
||||||
|
|
|
|
||||||
help: Replace with `None`; initialize within function
|
help: Replace with `None`; initialize within function
|
||||||
299 | ...
|
302 | ...
|
||||||
300 |
|
303 |
|
||||||
301 |
|
304 |
|
||||||
- def single_line_func_wrong(value: dict[str, str] = {
|
- def single_line_func_wrong(value: dict[str, str] = {
|
||||||
- # This is a comment
|
- # This is a comment
|
||||||
- }):
|
- }):
|
||||||
302 + def single_line_func_wrong(value: dict[str, str] = None):
|
305 + def single_line_func_wrong(value: dict[str, str] = None):
|
||||||
303 | """Docstring"""
|
306 | """Docstring"""
|
||||||
304 |
|
307 |
|
||||||
305 |
|
308 |
|
||||||
note: This is an unsafe fix and may change runtime behavior
|
note: This is an unsafe fix and may change runtime behavior
|
||||||
|
|
||||||
B006 Do not use mutable data structures for argument defaults
|
B006 Do not use mutable data structures for argument defaults
|
||||||
--> B006_B008.py:308:52
|
--> B006_B008.py:311:52
|
||||||
|
|
|
|
||||||
308 | def single_line_func_wrong(value: dict[str, str] = {}) \
|
311 | def single_line_func_wrong(value: dict[str, str] = {}) \
|
||||||
| ^^
|
| ^^
|
||||||
309 | : \
|
312 | : \
|
||||||
310 | """Docstring"""
|
313 | """Docstring"""
|
||||||
|
|
|
|
||||||
help: Replace with `None`; initialize within function
|
help: Replace with `None`; initialize within function
|
||||||
|
|
||||||
B006 [*] Do not use mutable data structures for argument defaults
|
B006 [*] Do not use mutable data structures for argument defaults
|
||||||
--> B006_B008.py:313:52
|
--> B006_B008.py:316:52
|
||||||
|
|
|
|
||||||
313 | def single_line_func_wrong(value: dict[str, str] = {}):
|
316 | def single_line_func_wrong(value: dict[str, str] = {}):
|
||||||
| ^^
|
| ^^
|
||||||
314 | """Docstring without newline"""
|
317 | """Docstring without newline"""
|
||||||
|
|
|
|
||||||
help: Replace with `None`; initialize within function
|
help: Replace with `None`; initialize within function
|
||||||
310 | """Docstring"""
|
313 | """Docstring"""
|
||||||
311 |
|
314 |
|
||||||
312 |
|
315 |
|
||||||
- def single_line_func_wrong(value: dict[str, str] = {}):
|
- def single_line_func_wrong(value: dict[str, str] = {}):
|
||||||
313 + def single_line_func_wrong(value: dict[str, str] = None):
|
316 + def single_line_func_wrong(value: dict[str, str] = None):
|
||||||
314 | """Docstring without newline"""
|
317 | """Docstring without newline"""
|
||||||
note: This is an unsafe fix and may change runtime behavior
|
note: This is an unsafe fix and may change runtime behavior
|
||||||
|
|
|
||||||
|
|
@ -326,7 +326,15 @@ pub fn is_immutable_return_type(qualified_name: &[&str]) -> bool {
|
||||||
| ["re", "compile"]
|
| ["re", "compile"]
|
||||||
| [
|
| [
|
||||||
"",
|
"",
|
||||||
"bool" | "bytes" | "complex" | "float" | "frozenset" | "int" | "str" | "tuple"
|
"bool"
|
||||||
|
| "bytes"
|
||||||
|
| "complex"
|
||||||
|
| "float"
|
||||||
|
| "frozenset"
|
||||||
|
| "int"
|
||||||
|
| "str"
|
||||||
|
| "tuple"
|
||||||
|
| "slice"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue