fixhunt

ruff B912

labelled unknown
Runs / 2026-10-17T20-15-52-421Z-usjh-ruff-B912ruff 0.17.12026-10-17 20:15 UTC8 programs × 2 round(s)16 programs, 0 fired, 0 fixed, 0 findings, 1 rejectedmodel cost $0.0036

Analysis Nemotron 3 Super

Flags map() calls lacking an explicit 'strict' keyword argument when invoked with multiple iterables or starred arguments.

Fix: Adds ', strict=True' as the final keyword argument to the map call, preserving all existing arguments and their order.

12 hazards
  • If the original call already contains a '**kwargs' unpacking that might include 'strict', adding another 'strict' argument creates a duplicate keyword error.
  • If the map call is part of a larger expression where trailing commas affect parsing (e.g., inside a tuple literal), inserting ', strict=True' could alter grouping or create invalid syntax.
  • When the map call appears in a context where the argument list ends with a bare '*args' (no following comma), inserting ', strict=True' after it may be misinterpreted as part of the starred expression rather than a keyword argument.
  • If the function being mapped relies on side effects that occur during iteration, changing from implicit truncation to strict length checking could cause early termination via ValueError where previously the loop would have completed silently.
  • In code targeting Python versions <3.14, the added 'strict' argument will raise a TypeError at runtime since older map implementations do not accept this parameter.
  • If the map call is embedded within a lambda or comprehension where the argument list is constructed dynamically, the static insertion of 'strict=True' may not reflect the intended runtime behavior.
  • Comments placed between the last positional argument and the closing parenthesis (e.g., 'map(f, a, b # comment)') risk being displaced or rendered invalid when the fix inserts ', strict=True' before the closing parenthesis.
  • When the map call uses positional-only parameters or appears in a stub file (.pyi), inserting 'strict=True' may violate type checker expectations or overload definitions.
  • If the iterables passed to map are actually the same object (e.g., map(f, x, x)), the strict check passes trivially, but the fix still adds noise without benefit.
  • In code that intentionally relies on zip-like truncation behavior (e.g., processing paired data where excess elements are ignorable), enforcing strict=True introduces unnecessary failures.
  • If the map call is written across multiple lines with inconsistent indentation, the autofix may insert ', strict=True' at an incorrect indentation level, breaking formatting rules.
  • When the map call is immediately followed by a method chain (e.g., map(f, a, b).filter(...)), inserting ', strict=True' before the closing parenthesis does not affect the chain, but if the chain starts on the same line, whitespace handling could become ambiguous.

Programs

idresulttitlehazard
r1-p001silent prediction offbytes vs str encodingAdding strict=True changes behavior when mapping over mismatched-length byte/str sequences due to encoding assumptions.
r1-p002silent prediction offstar-imports and __all__map with *args triggers rule; if imported module has side effects in __all__, evaluation order matters.
r1-p003silent prediction offsame object twicemap(f, x, x) passes strict trivially, but fix adds noisy strict=True; no behavior change, but violates minimality.
r1-p004silent prediction offdescriptor side effectsFunction mapped uses descriptor whose __get__ has side effects; strict=True may cause early exit before all accesses.
r1-p005silent prediction offside effects in functionmapped function has side effects; strict=True causes ValueError on length mismatch, skipping remaining side effects.
r1-p006silent prediction offkeyword-only and defaultsmap with function using keyword-only args; rule triggers on *args, but fix may interfere if defaults are mutable.
r1-p007invalidexceptions and finallystrict=True raises ValueError in map; alters control flow, skipping finally or else blocks in caller.
r1-p008silent prediction offdict ordering and duplicate keysmap over dict items with duplicate keys via __eq__ override; strict=True may fail before all duplicates seen.
r2-p001silent prediction offFile Modes and Truncationfile modes and truncation, partial writes, non-str data passed to write
r2-p002silent prediction off**kwargs Unpacking ConflictIf the original call already contains a '**kwargs' unpacking that might include 'strict', adding another 'strict' argument creates a duplicate keyword error.
r2-p003silent prediction offKeyword-Only and Defaultskeyword-only, positional-only, *args/**kwargs forwarding, defaults evaluated once
r2-p004silent prediction offTruthiness and Identitytruthiness of custom __bool__/__len__, None vs falsy, 'is' vs '=='
r2-p005silent prediction offSide Effects in Mapped FunctionIf the function being mapped relies on side effects that occur during iteration, changing from implicit truncation to strict length checking could cause early termination via ValueError where previous
r2-p006silent prediction offDescriptor Side Effectsclass attributes vs instance attributes, descriptors, properties with side effects
r2-p007silent prediction offLambda/Comprehension EmbeddingIf the map call is embedded within a lambda or comprehension where the argument list is constructed dynamically, the static insertion of 'strict=True' may not reflect the intended runtime behavior.
r2-p008silent prediction offIntentional Truncation RelianceIn code that intentionally relies on zip-like truncation behavior (e.g., processing paired data where excess elements are ignorable), enforcing strict=True introduces unnecessary failures.

Sources

r1-p001 · bytes vs str encoding
1def f(a, b): return a + b.decode()
2s1 = b'hello'
3s2 = ['world', '!']
4try:
5 res = list(map(f, s1, s2))
6except Exception as e:
7 print('error:', type(e).__name__, str(e))
8else:
9 print('result:', ''.join(res))
error: AttributeError 'str' object has no attribute 'decode'
r1-p002 · star-imports and __all__
1import sys
2sys.modules[__name__].__all__ = ['x', 'y'] # side effect
3x = [1, 2]
4y = [3]
5def g(a, b): return a + b
6try:
7 res = list(map(g, * [x, y]))
8except Exception as e:
9 print('error:', type(e).__name__, str(e))
10else:
11 print('sum:', sum(res))
sum: 4
r1-p003 · same object twice
1x = [1, 2, 3]
2def h(a, b): return a if a == b else 0
3res = list(map(h, x, x))
4print('all equal?', all(v == 1 for v in res))
all equal? False
r1-p004 · descriptor side effects
1class Desc:
2 def __get__(self, obj, owner):
3 print('access')
4 return 42
5class C:
6 attr = Desc()
7c = C()
8def get_attr(_): return c.attr
9try:
10 res = list(map(get_attr, [0, 0])) # two accesses
11 print('results:', res)
12except Exception as e:
13 print('error:', type(e).__name__, str(e))
access
access
results: [42, 42]
r1-p005 · side effects in function
1effects = []
2def side(x):
3 effects.append(x)
4 return x * 2
5try:
6 list(map(side, [1, 2, 3], [4, 5])) # mismatched lengths
7 print('effects:', effects)
8except ValueError as e:
9 print('ValueError:', str(e))
10 print('effects so far:', effects)
r1-p006 · keyword-only and defaults
1def f(a, *, b=[]):
2 b.append(a)
3 return b[:]
4try:
5 res = list(map(f, [1, 2], * [[], []]))
6except Exception as e:
7 print('error:', type(e).__name__, str(e))
8else:
9 print('lists:', res)
lists: []
r1-p007 · exceptions and finally (generated program does not parse: Traceback (most recent call last):)
1def g(): try: return 1/0
2except ZeroDivisionError: return 'inf'
3finally: print('finally ran')
4def h(x): return g() + x
5try:
6 list(map(h, [1, 2], [3])) # triggers strict
7 print('completed')
8except ValueError as e:
9 print('ValueError:', str(e))
r1-p008 · dict ordering and duplicate keys
1class K:
2 def __init__(self, v): self.v = v
3 def __eq__(self, other): return isinstance(other, K) and self.v == other.v
4 def __hash__(self): return hash(self.v)
5d1 = {K(1): 'a', K(1): 'b'} # deduped to one
6d2 = {'x': 1, 'y': 2}
7try:
8 res = list(map(lambda kv: kv[0].v + kv[1], zip(d1.items(), d2.items())))
9 print('result:', res)
10except Exception as e:
11 print('error:', type(e).__name__, str(e))
error: AttributeError 'tuple' object has no attribute 'v'
r2-p001 · File Modes and Truncation
1def f(x):
2 return open('temp.txt', 'a').write(x)
3files = ['data1\n', 'data2\n']
4sources = [b'hello', b'world']
5try:
6 list(map(f, sources))
7except Exception as e:
8 print(type(e).__name__, str(e))
9finally:
10 with open('temp.txt', 'r') as fp:
11 print(fp.read(), end='')
TypeError write() argument must be str, not bytes
r2-p002 · **kwargs Unpacking Conflict
1def func(a, b, **kwargs):
2 return a + b
3args = [(1, 2)]
4kwargss = [{}]
5try:
6 result = list(map(func, *args, *zip(*[(1,2)], **{'strict': False})))
7 print(result)
8except TypeError as e:
9 print(type(e).__name__, str(e))
TypeError func() takes 2 positional arguments but 3 were given
r2-p003 · Keyword-Only and Defaults
1defaults = []
2def kwonly_func(a, *, b=defaults.append(len(defaults)) or 10):
3 return a + b
4args = [[1], [2]]
5try:
6 res = list(map(kwonly_func, *args))
7 print('result:', res)
8 print('defaults:', defaults)
9except Exception as e:
10 print(type(e).__name__, str(e))
TypeError kwonly_func() takes 1 positional argument but 2 were given
r2-p004 · Truthiness and Identity
1class Obj:
2 def __init__(self, val):
3 self.val = val
4 def __bool__(self):
5 return self.val is not None
6 def __len__(self):
7 return 0 if self.val is None else 1
8objs = [Obj(1), Obj(None)]
9vals = [1, None]
10results = list(map(lambda o, v: (o is None) == (v is None), objs, vals))
11print(results)
[True, False]
r2-p005 · Side Effects in Mapped Function
1state = []
2def side_effect_func(x):
3 state.append(x)
4 if len(state) > 2:
5 raise RuntimeError('too many')
6 return x * 2
7try:
8 list(map(side_effect_func, [1, 2, 3], [10, 20]))
9except ValueError as e:
10 print('ValueError:', e)
11except RuntimeError as e:
12 print('RuntimeError:', e)
13print('state:', state)
r2-p006 · Descriptor Side Effects
1class Desc:
2 def __get__(self, obj, objtype=None):
3 Desc.counter += 1
4 return 99
5Desc.counter = 0
6class Container:
7 x = Desc()
8containers = [Container(), Container()]
9vals = [1, 2, 3] # longer
10try:
11 results = list(map(lambda c, v: c.x + v, containers, vals))
12 print('results:', results)
13except ValueError as e:
14 print('ValueError:', e)
15print('Desc.counter:', Desc.counter)
results: [100, 101]
Desc.counter: 2
r2-p007 · Lambda/Comprehension Embedding
1def make_map(args_list):
2 return lambda f, *iters: list(map(f, *iters, *args_list))
3args_provider = [[]] # empty
4mapper = make_map(args_provider)
5try:
6 result = mapper(pow, [2, 3], [3, 2])
7 print('result:', result)
8except ValueError as e:
9 print('ValueError:', e)
result: []
r2-p008 · Intentional Truncation Reliance
1pairs = [('a', 1), ('b', 2), ('c', 3)]
2extra = [10, 20, 30, 40] # ignore 40
3try:
4 results = list(map(lambda p, e: (p[0], p[1] + e), pairs, extra))
5 print('results:', results)
6except ValueError as e:
7 print('ValueError:', e)
results: [('a', 11), ('b', 22), ('c', 33)]