← board

A collecting lambda

f = lambda *a: len(a)
print(f(1, 2))        # CPython 2
                      # pxx  TypeError: <lambda>() takes 1 positional argument
                      #      but 2 were given

Measured 2026-08-15, the sibling of [[bug-nilpy-a-star-args-def-taken-as-a-value-is-called-with-loose-arguments]] and found by the same sweep. Same concept, the OTHER callable representation: a lambda lifts through pyboundfn_* (pyeval's word-based bridge), not through the pybound_new pair.

Root cause

The lifter's header loop matched only tkIdent; a tkStar fell through to the Next at the bottom, so *a was indistinguishable from a. The lifted proc then declared ONE Variant parameter, pyboundfn_setdefaults published that as the legal arity, and the arity check — correctly, given what it had been told — refused every call with more than one argument. Loud rather than silent, which is the one thing this shape had going for it.

The fix

pyboundfn_setstar(obj, si), chained after pyboundfn_setown exactly as the other setters are. It records the own-parameter index that COLLECTS, and that one field carries both halves of the semantics:

Frontend side: the star parameter is typed TPyList (the same type the def header gives *args), ProcPyStarIdx is recorded on the lifted proc, and pyboundfn_setstar joins the three callable-CONSTRUCTOR name lists. Missing that last step is worth remembering: the chain's final node is what gets boxed, so an unlisted setter made the whole lambda box as a plain integer and the call died with "object is not callable" — a symptom nowhere near the change.

What is still open

Gate

make compiler/pascal26 + tools/gate.sh quick GREEN; pinned v333. test/test_nilpy_lambda_star_args.npy, byte-identical to CPython: arity 0..3, the tuple the body sees, fixed parameters before the star, a lambda passed as an argument, and one with a capture as well as a star. Re-checked the nine existing star/callable .npy tests against their oracles.