Maximum Recursions on Windows but not Linux on Python 3.12.10, 3.13.12
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 77.2k
- Forks
- 35.9k
- PR merge metrics
- PR metrics pending
Description
Bug report
Bug description:
Running the following simplified exponentiation code from https://github.com/ethereum/py_ecc produces maximum recursion errors on Windows but not Linux, and does not seem to be helped by increasing the recursion limit. Note the (maybe too generous) recursion limit of 1 million.
class FQ:
n: int
field_modulus = 21888242871839275222246405745257275088696311157297823662689037894645226208583
def __init__(self , val) -> None:
if isinstance(val, FQ):
self.n = val.n
elif isinstance(val, int):
self.n = val % self.field_modulus
else:
raise TypeError(f"Expected an int or FQ object, but got object of type {type(val)}")
def __mul__(self, other):
if not isinstance(other, FQ):
raise TypeError(f"Expected FQ object, but got object of type {type(other)}")
return FQ((self.n * other.n) % self.field_modulus)
def __pow__(self, other: int):
if other == 0:
return FQ(1)
elif other == 1:
return FQ(self.n)
elif other % 2 == 0:
return (self * self) ** (other // 2)
else:
return ((self * self) ** (other // 2)) * self
import sys
sys.setrecursionlimit(1000000)
bigexponent = 5524842336132240963126171267831731470973821037629576541888827343141969108399075412139745027615406298170096085486546803436277011538294467478109073732568415510062016396777261399460291999684125988048823917022730190836532720475663165843655597764930274954582383739028759376599435048732205541615505259263023033317474635156447118766531771295783031910959009091916248178265666882418044080818927857259679317140977167095260922612780719525601711114440720492291235650574837501614600243533462841672824527562176623355288135191398082911705390721253812308157290715448616027509369648293136081373254263837351221752295411553763464360939302874020895174269731789175697133847480818272554725769374714961957527271882614356332712387101317360962997981688529255405493423307752798770067843548014222497225737835616851796188164800376950055154261623624310722456383247444
x = FQ(3)
y = x ** bigexponent
print(y)
When running it on 64-bit Windows 10, one runs into:
(lots of printouts)
return FQ((self.n * other.n) % self.field_modulus)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
RecursionError: maximum recursion depth exceeded
However, this runs fine on Ubuntu Linux.
For comparison, here's a non-class, but still highly recursive version that runs fine on both operating systems and reports the right answer, even with a much more reasonable recursion limit of 10,000.
p = 21888242871839275222246405745257275088696311157297823662689037894645226208583
bigexponent = 5524842336132240963126171267831731470973821037629576541888827343141969108399075412139745027615406298170096085486546803436277011538294467478109073732568415510062016396777261399460291999684125988048823917022730190836532720475663165843655597764930274954582383739028759376599435048732205541615505259263023033317474635156447118766531771295783031910959009091916248178265666882418044080818927857259679317140977167095260922612780719525601711114440720492291235650574837501614600243533462841672824527562176623355288135191398082911705390721253812308157290715448616027509369648293136081373254263837351221752295411553763464360939302874020895174269731789175697133847480818272554725769374714961957527271882614356332712387101317360962997981688529255405493423307752798770067843548014222497225737835616851796188164800376950055154261623624310722456383247444
def sillymul(x, y):
return (x * y) % p
def sillypow(x, other):
if other == 0:
return 1
elif other == 1:
return x
elif other % 2 == 0:
return sillypow(sillymul(x, x), (other // 2)) % p
else:
return sillymul(sillypow(sillymul(x, x), (other // 2)), x)
import sys
sys.setrecursionlimit(10000)
x = 3
y = sillypow(x, bigexponent)
print(y)
print(pow(3, bigexponent, p))
Some more context might be found at https://github.com/ethereum/py_ecc/issues/134 and https://github.com/ethereum/py_ecc/issues/133
CPython versions tested on:
3.12, 3.13
Operating systems tested on:
Linux, Windows
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by running the supplied FQ.pow reproducer on Windows and Linux with Python 3.12 and 3.13, then compare it with the sillypow version. Review the related py_ecc issues 133 and 134 for context. Done means explaining the platform difference and establishing corrected behavior or an appropriate CPython resolution.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- operating-systems
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100