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
6 changes: 6 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,11 @@ This is meant to be enabled by developers writing visitors using the ``ast`` mod

The ``strict=`` argument was added in Python 3.13, so don't enable this flag for code that should work on <3.13.

.. _B912:

**B912**: ``map()`` without an explicit `strict=` parameter set. ``strict=True`` causes the resulting iterator
to raise a ``ValueError`` if the arguments are exhausted at differing lengths.

.. _B950:

**B950**: Line too long. This is a pragmatic equivalent of
Expand Down Expand Up @@ -480,6 +485,7 @@ UNRELEASED
* B042: New check for reminding to call super().__init__ in custom exceptions
* flake8-bugbear now requires at least Python 3.9, like flake8>=7.2.0
* B028: Skip if skip_file_prefixes is used (#503)
* Add B912: `map()` without an explicit `strict=` parameter. (#516)

24.12.12
~~~~~~~~
Expand Down
13 changes: 13 additions & 0 deletions bugbear.py
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,7 @@ def visit_Call(self, node) -> None:
self.check_for_b905(node)
self.check_for_b910(node)
self.check_for_b911(node)
self.check_for_b912(node)

# no need for copying, if used in nested calls it will be set to None
current_b040_caught_exception = self.b040_caught_exception
Expand Down Expand Up @@ -1536,6 +1537,16 @@ def check_for_b905(self, node) -> None:
if not any(kw.arg == "strict" for kw in node.keywords):
self.add_error("B905", node)

def check_for_b912(self, node) -> None:
if not (
isinstance(node.func, ast.Name)
and node.func.id == "map"
and len(node.args) > 2
):
return
if not any(kw.arg == "strict" for kw in node.keywords):
self.add_error("B912", node)

def check_for_b906(self, node: ast.FunctionDef) -> None:
if not node.name.startswith("visit_"):
return
Expand Down Expand Up @@ -2465,6 +2476,7 @@ def __call__(self, lineno: int, col: int, vars: tuple[object, ...] = ()) -> erro
"B911": Error(
message="B911 `itertools.batched()` without an explicit `strict=` parameter."
),
"B912": Error(message="B912 `map()` without an explicit `strict=` parameter."),
"B950": Error(message="B950 line too long ({} > {} characters)"),
}

Expand All @@ -2480,5 +2492,6 @@ def __call__(self, lineno: int, col: int, vars: tuple[object, ...] = ()) -> erro
"B909",
"B910",
"B911",
"B912",
"B950",
]
8 changes: 8 additions & 0 deletions tests/eval_files/b912_py314.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
map(lambda x: x, "a", "b") # B912: 0
map(lambda x: x, "a", "b", *map("c")) # B912: 0
map(lambda x: x, "a", map(lambda x: x, "a"), strict=True) # B912: 22

map()
map(lambda x: x, "a")
map(lambda x: x, "a", "b", strict=False)
map(lambda x: x, "a", "b", "c", strict=True)