[`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:
Loïc Riegel 2025-12-08 20:00:43 +01:00 committed by GitHub
parent 45fb3732a4
commit 2d3466eccf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 288 additions and 277 deletions

View File

@ -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)):

View File

@ -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

View File

@ -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
| |

View File

@ -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

View File

@ -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"
] ]
) )
} }