← board

PyFixIterableArgs is inert: its own test passes with it disabled

The measurement

compiler/pyparser.inc:21717, the function's first lines, with a control inserted:

begin
  Result := False;
  if True then Exit;   { POSITIVE CONTROL }
  if not PyExprMode then Exit;
  ...

Rebuilt (13ff03adbf6d -> 1498ac818774, so the artifact demonstrably changed), then run against the test written for this exact mechanism:

test/test_nilpy_user_iterable_in_builtins.npy
  baseline vs control : IDENTICAL   (37 lines)
  baseline vs CPython : IDENTICAL
  emitted binaries    : identical

Byte-identical emitted binaries, not merely equal output — so the function did not merely fail to change the answer, it did not change the AST at all on the one input written to make it act.

Also unchanged with it disabled: quick_canary_nilpy.npy, and four scratch probes covering sum(bag), len(list(Bag())), sorted(..., key=int) over a class implementing __iter__/__next__, in both statement and expression position.

Why this is not the same finding as the ticket that produced it

That ticket deleted arms which could not run (wrong guard, unreachable population). This is the opposite and worse shape: a call site that does run, in the right frontend, on the right input, and removing it changes nothing. A dead guard is visible to anyone who reads the condition; this is invisible to reading and only a control finds it.

What it does NOT establish

The corpus here is one suite file plus five hand-written probes. It shows the mechanism is uncovered by the test that names it; it does not show no input reaches it. Before deleting, find an input that makes the control fire — if none exists, that is the answer.

The function's own header documents two halves (procIdx >= 0 fixing a wrong overload match, procIdx < 0 draining so the match can be retried). If one half was superseded and the other was not, the fix is narrowing, not deletion.

Candidate explanation, unverified

PyNodeIsUserIterable gates every mutation in the body. If that predicate stopped recognising the __iter__/__next__ shape — a plausible casualty of the RTTI or class-representation work — the function would go silently inert exactly like this, and the test would keep passing because some later path now handles the same programs correctly. Check the predicate before the function.