← board

A str into a by-name pylib list parameter segfaults

Found 2026-08-16, sweeping the population named in [[project_nilpy_byname_findproc_lowerings_are_the_unchecked_population]] immediately after [[bug-nilpy-dict-fromkeys-of-a-str-segfaults]] — the note says to grep the by-name lowerings against pylib's TPyList-taking routines and enumerate the crashes, and that is what this is.

Measured

random.choice("abc")   # CPython 'a'                   pxx SIGSEGV
math.fsum("ab")        # CPython TypeError             pxx SIGSEGV
math.prod("ab")        # CPython TypeError             pxx SIGSEGV
random.shuffle("abc")  # CPython TypeError             pxx silent no-op

random.choice over a str is the sharp one: it is a working CPython program, not an error case, and picking a random character from a string is what the function is for.

Cause

PyParseStdlibCall builds these calls by name and re-targets only by ARITY. A TPyList parameter therefore accepted a str and dereferenced it as an object.

Fix — in the callee, and not uniformly

pymath_prod, pymath_fsum and pyrandom_choice take a Variant and go through pylist_v, the one bridge that turns any Python iterable into a list and raises a named TypeError for anything else. A call-site check would have to be repeated per site, which is the whole point of the population note.

random.shuffle is deliberately NOT that, and it is why this needed a sweep rather than a sed: pylist_v COPIES, so shuffling its result would shuffle nothing the caller can see — a silent no-op, strictly worse than the crash. It takes the real TPyList out of the variant and refuses everything else by name, which is also CPython's answer (TypeError: 'str' object does not support item assignment).

Gate

test/test_nilpy_by_name_list_params_take_a_str.npy — str, list and tuple receivers for choice, in-place shuffle plus its str refusal, and fsum / prod over both a list and a tuple. Output identical to CPython's on every row; the random VALUES are not asserted (the generator is not CPython's), so the rows assert membership and length instead. gate.sh quick green.