diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/rules/function_call_in_argument_default.rs b/crates/ruff_linter/src/rules/flake8_bugbear/rules/function_call_in_argument_default.rs index 964026d5f09e0..9da675d797b71 100644 --- a/crates/ruff_linter/src/rules/flake8_bugbear/rules/function_call_in_argument_default.rs +++ b/crates/ruff_linter/src/rules/flake8_bugbear/rules/function_call_in_argument_default.rs @@ -50,6 +50,16 @@ use crate::checkers::ast::Checker; /// return arg /// ``` /// +/// If the use of a singleton is intentional, assign the result call to a +/// module-level variable, and use that variable in the default argument: +/// ```python +/// ERROR = ValueError("Hosts weren't successfully added") +/// +/// +/// def add_host(error: Exception = ERROR) -> None: +/// ... +/// ``` +/// /// ## Options /// - `flake8-bugbear.extend-immutable-calls` #[violation] @@ -62,9 +72,9 @@ impl Violation for FunctionCallInDefaultArgument { fn message(&self) -> String { let FunctionCallInDefaultArgument { name } = self; if let Some(name) = name { - format!("Do not perform function call `{name}` in argument defaults") + format!("Do not perform function call `{name}` in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable") } else { - format!("Do not perform function call in argument defaults") + format!("Do not perform function call in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable") } } } diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B008_B006_B008.py.snap b/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B008_B006_B008.py.snap index c45d87aa5ae77..9e967b877262c 100644 --- a/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B008_B006_B008.py.snap +++ b/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B008_B006_B008.py.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/rules/flake8_bugbear/mod.rs --- -B006_B008.py:102:61: B008 Do not perform function call `range` in argument defaults +B006_B008.py:102:61: B008 Do not perform function call `range` in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable | 101 | # N.B. we're also flagging the function call in the comprehension 102 | def list_comprehension_also_not_okay(default=[i**2 for i in range(3)]): @@ -9,21 +9,21 @@ B006_B008.py:102:61: B008 Do not perform function call `range` in argument defau 103 | pass | -B006_B008.py:106:64: B008 Do not perform function call `range` in argument defaults +B006_B008.py:106:64: B008 Do not perform function call `range` in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable | 106 | def dict_comprehension_also_not_okay(default={i: i**2 for i in range(3)}): | ^^^^^^^^ B008 107 | pass | -B006_B008.py:110:60: B008 Do not perform function call `range` in argument defaults +B006_B008.py:110:60: B008 Do not perform function call `range` in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable | 110 | def set_comprehension_also_not_okay(default={i**2 for i in range(3)}): | ^^^^^^^^ B008 111 | pass | -B006_B008.py:126:39: B008 Do not perform function call `time.time` in argument defaults +B006_B008.py:126:39: B008 Do not perform function call `time.time` in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable | 124 | # B008 125 | # Flag function calls as default args (including if they are part of a sub-expression) @@ -32,21 +32,21 @@ B006_B008.py:126:39: B008 Do not perform function call `time.time` in argument d 127 | ... | -B006_B008.py:130:12: B008 Do not perform function call `dt.datetime.now` in argument defaults +B006_B008.py:130:12: 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 | 130 | def f(when=dt.datetime.now() + dt.timedelta(days=7)): | ^^^^^^^^^^^^^^^^^ B008 131 | pass | -B006_B008.py:134:30: B008 Do not perform function call in argument defaults +B006_B008.py:134:30: B008 Do not perform function call in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable | 134 | def can_even_catch_lambdas(a=(lambda x: x)()): | ^^^^^^^^^^^^^^^ B008 135 | ... | -B006_B008.py:239:31: B008 Do not perform function call `dt.datetime.now` in argument defaults +B006_B008.py:239:31: 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 | 237 | # B006 and B008 238 | # We should handle arbitrary nesting of these B008. @@ -55,7 +55,7 @@ B006_B008.py:239:31: B008 Do not perform function call `dt.datetime.now` in argu 240 | pass | -B006_B008.py:245:22: B008 Do not perform function call `map` in argument defaults +B006_B008.py:245:22: 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 | 243 | # Don't flag nested B006 since we can't guarantee that 244 | # it isn't made mutable by the outer operation. @@ -64,7 +64,7 @@ B006_B008.py:245:22: B008 Do not perform function call `map` in argument default 246 | pass | -B006_B008.py:250:19: B008 Do not perform function call `random.randint` in argument defaults +B006_B008.py:250:19: 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 | 249 | # B008-ception. 250 | def nested_b008(a=random.randint(0, dt.datetime.now().year)): @@ -72,7 +72,7 @@ B006_B008.py:250:19: B008 Do not perform function call `random.randint` in argum 251 | pass | -B006_B008.py:250:37: B008 Do not perform function call `dt.datetime.now` in argument defaults +B006_B008.py:250:37: 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 | 249 | # B008-ception. 250 | def nested_b008(a=random.randint(0, dt.datetime.now().year)): diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__extend_immutable_calls_arg_default.snap b/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__extend_immutable_calls_arg_default.snap index 56b5a1db75f39..064b5f1e0cfc5 100644 --- a/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__extend_immutable_calls_arg_default.snap +++ b/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__extend_immutable_calls_arg_default.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/rules/flake8_bugbear/mod.rs --- -B008_extended.py:24:51: B008 Do not perform function call `Depends` in argument defaults +B008_extended.py:24:51: B008 Do not perform function call `Depends` in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable | 24 | def error_due_to_missing_import(data: List[str] = Depends(None)): | ^^^^^^^^^^^^^ B008