← board

abs() of a complex raises TypeError

Found 2026-08-16 while resolving [[bug-n-pow-expected-predates-the-complex-type-and-pxx-differs-from-cpython]]. abs(z) was the natural way to assert a complex result without pinning the last bits of its repr; it does not work.

Measured

z = (-8.0) ** 0.5
print(type(z).__name__)                        # complex        — matches
print(round(z.real, 12), round(z.imag, 12))    # 0.0 2.828427124746 — matches
print(abs(z))                                  # CPython: 2.8284271247461903
result
CPython 2.8284271247461903
pxx Unhandled exception: TypeError: expected a number, got object

Every other accessor in that set is already right, so this is one missing arm rather than a gap in complex support: abs reaches a numeric coercion that does not know the complex object and rejects it as a bare object.

abs(complex) is ordinary CPython — it is the documented way to get a magnitude and appears in any numeric code that ports across. By the standing rule that a program CPython accepts and runs must work under NilPy, this is a plain defect rather than a divergence.

Likely shape of the fix

abs needs the same complex arm the other accessors have: return hypot(z.real, z.imag). Note pycomplex_pow already computes exactly that expression inline (PyCxSqrt(a.FRe*a.FRe + a.FIm*a.FIm)), so the helper exists and wants lifting to a named function rather than a second copy.

Gate

abs((-8.0) ** 0.5) matching CPython, plus abs(3+4j) = 5.0 as the exact control; make test-nilpy; self-host fixedpoint.