The library that couldn't
read its own output.

SymPy generated domain strings it refused to parse back. The bug sat open for 2,094 days. Kodah closed it in 351 seconds, it even covered edge cases nobody reported.

Repositorysympy/sympy · issue #2709
First openedDecember 24, 2013
MergedSeptember 17, 2019
Real TTR~2,094 days
Official TTR (second report → merge)561 days
Kodah runtime351.3 seconds
Participants · Comments6 participants · 9 comments

The bug

SymPy is one of the most widely used mathematical computing libraries in the Python ecosystem. In late 2013, its maintainer filed a bug with a single, clear symptom: the library was producing output it refused to accept as input.

Ask SymPy to infer the structure of an expression and it would return a domain string. Hand that exact string back in the very next call and it would crash with an error, claiming the value was invalid. The system was generating notation it couldn't parse: a contradiction hiding in plain sight inside one of the most downloaded scientific packages in Python.

The system was generating notation it couldn't parse: a contradiction hiding in plain sight.

The issue sat open, labeled and acknowledged, for years. It was re-reported in 2018 by a different user who hit the same wall, restarting the clock: 561 days this time before the fix was finally merged. The merge was made by the same person who had filed the original report back in 2013.

What Kodah did

Kodah located the gap in the domain parser: it recognized real and complex fields as standalone values, but had no logic for when those same fields appeared as the base of a polynomial ring. The input fell through every check and hit the error handler: not because it was malformed, but because that case had simply never been implemented.

Before generating the patch, Kodah mapped the full family of affected cases: the short aliases, the precision-suffixed variants, and their complex field equivalents. A fix scoped only to the reported input would have left those variants silently broken.


Kodah's patch

sympy/polys/domains/polynomialring.py
+ # allow polynomial rings over RR/CC, e.g. 'RR[y,z]' or 'CC_53[x]' + r = re.match(r'^(R|RR|C|CC)(?:_(\d+))?\[(.+)\]$', domain) + if r is not None: + ground, prec, gens = r.groups() + gens = list(map(sympify, gens.split(','))) + if ground in ['R', 'RR']: + if prec is None: + base = sympy.polys.domains.RR + else: + base = sympy.polys.domains.RealField(int(prec)) + else: + if prec is None: + base = sympy.polys.domains.CC + else: + base = sympy.polys.domains.ComplexField(int(prec)) + return base.poly_ring(*gens)

The human patch — PR #14396

sympy/polys/domains/polynomialring.py
- _re_polynomial = re.compile(r"^(Z|ZZ|Q|QQ)\[(.+)\]$") + _re_polynomial = re.compile(r"^(Z|ZZ|Q|QQ|R|RR|C|CC)\[(.+)\]$") - else: + elif ground in ['Q', 'QQ']: return sympy.polys.domains.QQ.poly_ring(*gens) + elif ground in ['R', 'RR']: + return sympy.polys.domains.RR.poly_ring(*gens) + else: + return sympy.polys.domains.CC.poly_ring(*gens)

How they compare

Both patches fix the reported bug. The human patch touches the minimum amount of code to close the issue as filed. Kodah, however, went further: beyond fixing the original case, it independently identified and handled precision-qualified variants like RR_53[x] and CC_80[x], edge cases that were never reported, already covered.

Dimension Kodah Human (PR #14396)
Bug fixed Yes Yes
Precision variants
RR_53[x], CC_80[x]
Covered Not covered
Approach Full regex + branching over all variants Minimal: extend existing regex + add two branches
Time to patch 351 seconds 561 days (second report → merge)
351s Kodah runtime
2,094 Days open
Dec 2013 First report
Sep 2019 Fix merged

The bug was open for 2,094 days. Kodah closed it in 351 seconds and didn't go into anyone's queue. Kodah — $0.50 per fix.


← Back to Blog