Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
from itertools import count, cycle, repeat

# Errors
zip()
zip(range(3))
zip("a", "b")
zip("a", "b", *zip("c"))
zip(zip("a"), strict=False)
zip(zip("a", strict=True))
zip(zip("a", "b"), strict=False)
zip(zip("a", strict=True),"b")

# OK
zip(range(3), strict=True)
Expand All @@ -27,3 +25,10 @@
import builtins
# Still an error even though it uses the qualified name
builtins.zip([1, 2, 3])

# Regression https://github.com/astral-sh/ruff/issues/20997
# Ok
zip()
zip(range(3))
# Error
zip(*lot_of_iterators)
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,6 @@
map(lambda x, y: x + y, [1, 2, 3], repeat(1))
map(lambda x, y: x + y, [1, 2, 3], repeat(1, times=None))
map(lambda x, y: x + y, [1, 2, 3], count())

# Regression https://github.com/astral-sh/ruff/issues/20997
map(f, *lots_of_iterators)
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::rules::flake8_bugbear::helpers::any_infinite_iterables;
use crate::{AlwaysFixableViolation, Applicability, Fix};

/// ## What it does
/// Checks for `map` calls without an explicit `strict` parameter when called with two or more iterables.
/// Checks for `map` calls without an explicit `strict` parameter when called with two or more iterables, or any starred argument.
///
/// This rule applies to Python 3.14 and later, where `map` accepts a `strict` keyword
/// argument. For details, see: [What’s New in Python 3.14](https://docs.python.org/dev/whatsnew/3.14.html).
Expand Down Expand Up @@ -62,7 +62,12 @@ pub(crate) fn map_without_explicit_strict(checker: &Checker, call: &ast::ExprCal

if semantic.match_builtin_expr(&call.func, "map")
&& call.arguments.find_keyword("strict").is_none()
&& call.arguments.args.len() >= 3 // function + at least 2 iterables
&& (
// at least 2 iterables (+ 1 function)
call.arguments.args.len() >= 3
// or a starred argument
|| call.arguments.args.iter().any(ast::Expr::is_starred_expr)
)
&& !any_infinite_iterables(call.arguments.args.iter().skip(1), semantic)
{
checker
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::rules::flake8_bugbear::helpers::any_infinite_iterables;
use crate::{AlwaysFixableViolation, Applicability, Fix};

/// ## What it does
/// Checks for `zip` calls without an explicit `strict` parameter.
/// Checks for `zip` calls without an explicit `strict` parameter when called with two or more iterables, or any starred argument.
///
/// ## Why is this bad?
/// By default, if the iterables passed to `zip` are of different lengths, the
Expand Down Expand Up @@ -58,6 +58,12 @@ pub(crate) fn zip_without_explicit_strict(checker: &Checker, call: &ast::ExprCal

if semantic.match_builtin_expr(&call.func, "zip")
&& call.arguments.find_keyword("strict").is_none()
&& (
// at least 2 iterables
call.arguments.args.len() >= 2
// or a starred argument
|| call.arguments.args.iter().any(ast::Expr::is_starred_expr)
)
&& !any_infinite_iterables(call.arguments.args.iter(), semantic)
{
checker
Expand Down
Original file line number Diff line number Diff line change
@@ -1,204 +1,140 @@
---
source: crates/ruff_linter/src/rules/flake8_bugbear/mod.rs
assertion_line: 156
---
B905 [*] `zip()` without an explicit `strict=` parameter
--> B905.py:4:1
|
3 | # Errors
4 | zip()
| ^^^^^
5 | zip(range(3))
6 | zip("a", "b")
4 | zip("a", "b")
| ^^^^^^^^^^^^^
5 | zip("a", "b", *zip("c"))
6 | zip(zip("a", "b"), strict=False)
|
help: Add explicit value for parameter `strict=`
1 | from itertools import count, cycle, repeat
2 |
3 | # Errors
- zip()
4 + zip(strict=False)
5 | zip(range(3))
6 | zip("a", "b")
7 | zip("a", "b", *zip("c"))
- zip("a", "b")
4 + zip("a", "b", strict=False)
5 | zip("a", "b", *zip("c"))
6 | zip(zip("a", "b"), strict=False)
7 | zip(zip("a", strict=True),"b")
note: This is an unsafe fix and may change runtime behavior

B905 [*] `zip()` without an explicit `strict=` parameter
--> B905.py:5:1
|
3 | # Errors
4 | zip()
5 | zip(range(3))
| ^^^^^^^^^^^^^
6 | zip("a", "b")
7 | zip("a", "b", *zip("c"))
4 | zip("a", "b")
5 | zip("a", "b", *zip("c"))
| ^^^^^^^^^^^^^^^^^^^^^^^^
6 | zip(zip("a", "b"), strict=False)
7 | zip(zip("a", strict=True),"b")
|
help: Add explicit value for parameter `strict=`
2 |
3 | # Errors
4 | zip()
- zip(range(3))
5 + zip(range(3), strict=False)
6 | zip("a", "b")
7 | zip("a", "b", *zip("c"))
8 | zip(zip("a"), strict=False)
4 | zip("a", "b")
- zip("a", "b", *zip("c"))
5 + zip("a", "b", *zip("c"), strict=False)
6 | zip(zip("a", "b"), strict=False)
7 | zip(zip("a", strict=True),"b")
8 |
note: This is an unsafe fix and may change runtime behavior

B905 [*] `zip()` without an explicit `strict=` parameter
--> B905.py:6:1
--> B905.py:6:5
|
4 | zip()
5 | zip(range(3))
6 | zip("a", "b")
| ^^^^^^^^^^^^^
7 | zip("a", "b", *zip("c"))
8 | zip(zip("a"), strict=False)
4 | zip("a", "b")
5 | zip("a", "b", *zip("c"))
6 | zip(zip("a", "b"), strict=False)
| ^^^^^^^^^^^^^
7 | zip(zip("a", strict=True),"b")
|
help: Add explicit value for parameter `strict=`
3 | # Errors
4 | zip()
5 | zip(range(3))
- zip("a", "b")
6 + zip("a", "b", strict=False)
7 | zip("a", "b", *zip("c"))
8 | zip(zip("a"), strict=False)
9 | zip(zip("a", strict=True))
4 | zip("a", "b")
5 | zip("a", "b", *zip("c"))
- zip(zip("a", "b"), strict=False)
6 + zip(zip("a", "b", strict=False), strict=False)
7 | zip(zip("a", strict=True),"b")
8 |
9 | # OK
note: This is an unsafe fix and may change runtime behavior

B905 [*] `zip()` without an explicit `strict=` parameter
--> B905.py:7:1
|
5 | zip(range(3))
6 | zip("a", "b")
7 | zip("a", "b", *zip("c"))
| ^^^^^^^^^^^^^^^^^^^^^^^^
8 | zip(zip("a"), strict=False)
9 | zip(zip("a", strict=True))
|
help: Add explicit value for parameter `strict=`
4 | zip()
5 | zip(range(3))
6 | zip("a", "b")
- zip("a", "b", *zip("c"))
7 + zip("a", "b", *zip("c"), strict=False)
8 | zip(zip("a"), strict=False)
9 | zip(zip("a", strict=True))
10 |
note: This is an unsafe fix and may change runtime behavior

B905 [*] `zip()` without an explicit `strict=` parameter
--> B905.py:7:16
|
5 | zip(range(3))
6 | zip("a", "b")
7 | zip("a", "b", *zip("c"))
| ^^^^^^^^
8 | zip(zip("a"), strict=False)
9 | zip(zip("a", strict=True))
5 | zip("a", "b", *zip("c"))
6 | zip(zip("a", "b"), strict=False)
7 | zip(zip("a", strict=True),"b")
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
8 |
9 | # OK
|
help: Add explicit value for parameter `strict=`
4 | zip()
5 | zip(range(3))
6 | zip("a", "b")
- zip("a", "b", *zip("c"))
7 + zip("a", "b", *zip("c", strict=False))
8 | zip(zip("a"), strict=False)
9 | zip(zip("a", strict=True))
10 |
note: This is an unsafe fix and may change runtime behavior

B905 [*] `zip()` without an explicit `strict=` parameter
--> B905.py:8:5
|
6 | zip("a", "b")
7 | zip("a", "b", *zip("c"))
8 | zip(zip("a"), strict=False)
| ^^^^^^^^
9 | zip(zip("a", strict=True))
|
help: Add explicit value for parameter `strict=`
5 | zip(range(3))
6 | zip("a", "b")
7 | zip("a", "b", *zip("c"))
- zip(zip("a"), strict=False)
8 + zip(zip("a", strict=False), strict=False)
9 | zip(zip("a", strict=True))
10 |
11 | # OK
note: This is an unsafe fix and may change runtime behavior

B905 [*] `zip()` without an explicit `strict=` parameter
--> B905.py:9:1
|
7 | zip("a", "b", *zip("c"))
8 | zip(zip("a"), strict=False)
9 | zip(zip("a", strict=True))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
10 |
11 | # OK
|
help: Add explicit value for parameter `strict=`
6 | zip("a", "b")
7 | zip("a", "b", *zip("c"))
8 | zip(zip("a"), strict=False)
- zip(zip("a", strict=True))
9 + zip(zip("a", strict=True), strict=False)
10 |
11 | # OK
12 | zip(range(3), strict=True)
4 | zip("a", "b")
5 | zip("a", "b", *zip("c"))
6 | zip(zip("a", "b"), strict=False)
- zip(zip("a", strict=True),"b")
7 + zip(zip("a", strict=True),"b", strict=False)
8 |
9 | # OK
10 | zip(range(3), strict=True)
note: This is an unsafe fix and may change runtime behavior

B905 [*] `zip()` without an explicit `strict=` parameter
--> B905.py:24:1
--> B905.py:22:1
|
23 | # Errors (limited iterators).
24 | zip([1, 2, 3], repeat(1, 1))
21 | # Errors (limited iterators).
22 | zip([1, 2, 3], repeat(1, 1))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
25 | zip([1, 2, 3], repeat(1, times=4))
23 | zip([1, 2, 3], repeat(1, times=4))
|
help: Add explicit value for parameter `strict=`
21 | zip([1, 2, 3], repeat(1, times=None))
22 |
23 | # Errors (limited iterators).
19 | zip([1, 2, 3], repeat(1, times=None))
20 |
21 | # Errors (limited iterators).
- zip([1, 2, 3], repeat(1, 1))
24 + zip([1, 2, 3], repeat(1, 1), strict=False)
25 | zip([1, 2, 3], repeat(1, times=4))
26 |
27 | import builtins
22 + zip([1, 2, 3], repeat(1, 1), strict=False)
23 | zip([1, 2, 3], repeat(1, times=4))
24 |
25 | import builtins
note: This is an unsafe fix and may change runtime behavior

B905 [*] `zip()` without an explicit `strict=` parameter
--> B905.py:25:1
--> B905.py:23:1
|
23 | # Errors (limited iterators).
24 | zip([1, 2, 3], repeat(1, 1))
25 | zip([1, 2, 3], repeat(1, times=4))
21 | # Errors (limited iterators).
22 | zip([1, 2, 3], repeat(1, 1))
23 | zip([1, 2, 3], repeat(1, times=4))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
26 |
27 | import builtins
24 |
25 | import builtins
|
help: Add explicit value for parameter `strict=`
22 |
23 | # Errors (limited iterators).
24 | zip([1, 2, 3], repeat(1, 1))
20 |
21 | # Errors (limited iterators).
22 | zip([1, 2, 3], repeat(1, 1))
- zip([1, 2, 3], repeat(1, times=4))
25 + zip([1, 2, 3], repeat(1, times=4), strict=False)
26 |
27 | import builtins
28 | # Still an error even though it uses the qualified name
23 + zip([1, 2, 3], repeat(1, times=4), strict=False)
24 |
25 | import builtins
26 | # Still an error even though it uses the qualified name
note: This is an unsafe fix and may change runtime behavior

B905 [*] `zip()` without an explicit `strict=` parameter
--> B905.py:29:1
--> B905.py:34:1
|
27 | import builtins
28 | # Still an error even though it uses the qualified name
29 | builtins.zip([1, 2, 3])
| ^^^^^^^^^^^^^^^^^^^^^^^
32 | zip(range(3))
33 | # Error
34 | zip(*lot_of_iterators)
| ^^^^^^^^^^^^^^^^^^^^^^
|
help: Add explicit value for parameter `strict=`
26 |
27 | import builtins
28 | # Still an error even though it uses the qualified name
- builtins.zip([1, 2, 3])
29 + builtins.zip([1, 2, 3], strict=False)
31 | zip()
32 | zip(range(3))
33 | # Error
- zip(*lot_of_iterators)
34 + zip(*lot_of_iterators, strict=False)
note: This is an unsafe fix and may change runtime behavior
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
---
source: crates/ruff_linter/src/rules/flake8_bugbear/mod.rs
assertion_line: 112
---
B912 [*] `map()` without an explicit `strict=` parameter
--> B912.py:5:1
Expand Down Expand Up @@ -147,3 +146,18 @@ help: Add explicit value for parameter `strict=`
19 | # OK
20 | map(lambda x: x, [1, 2, 3], strict=True)
note: This is an unsafe fix and may change runtime behavior

B912 [*] `map()` without an explicit `strict=` parameter
--> B912.py:36:1
|
35 | # Regression https://github.com/astral-sh/ruff/issues/20997
36 | map(f, *lots_of_iterators)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: Add explicit value for parameter `strict=`
33 | map(lambda x, y: x + y, [1, 2, 3], count())
34 |
35 | # Regression https://github.com/astral-sh/ruff/issues/20997
- map(f, *lots_of_iterators)
36 + map(f, *lots_of_iterators, strict=False)
note: This is an unsafe fix and may change runtime behavior