← board

A NilPy callable can only be handed ZERO or ONE argument from library code

The limit

pylib.pas exports exactly two bridges for calling a NilPy callable from library code:

function pycallback_call0(const cb: Variant): Int64;
function pycallback_call1(const cb: Variant; const a0: Variant): Int64;

and the bound-function path underneath is the same shape — pyboundfn_call_ptr(objptr, const a0: Variant) passes exactly ONE argument (pyeval.pas:1870).

So a library can hand a Python callable nothing, or one value, and that is all.

What needs it

Tk calls several options with its OWN argument lists, not with a single event:

option Tk calls it with
-yscrollcommand / -xscrollcommand first last — two fractions
a scrollbar's -command moveto <frac> or scroll <n> units|pages
-validatecommand, -postcommand, trace handlers their own argument sets

The façade cannot express any of those as a Python callable today, and says so loudly rather than wiring something wrong. Note the scroll pair specifically does NOT need this — CPython's tkinter does not call back into Python for it either, it wires Tcl straight to the other widget's subcommand, and the façade now does the same. This is about the general shape.

Nothing outside tkinter is blocked on it today, which is why it is ranked below the frontend bugs.

Shape

  1. pycallback_call2 / pycallback_call3 beside the existing pair.
  2. A bound-fn / closure invoke path that accepts more than one own parameter — the single-argument assumption in pyboundfn_call_ptr is the actual constraint, and the two pycallback_call* entry points are its surface.
  3. Keep the existing zero/one entry points; this widens, it does not replace.

Gate

make test-nilpy green + self-host byte-identical, plus a .npy that hands a def, a lambda and a bound method to a library routine which calls each with two and with three arguments, diffed against CPython.