python / python/cpython

Maximum Recursions on Windows but not Linux on Python 3.12.10, 3.13.12

Abierto
#145,518 7 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

OS-windows pending type-bug
Lenguaje dominante
Python
Estrellas
77.2k
Forks
35.9k
Métricas de merge de PR
Métricas de PR pendientes

Descripción

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

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

Empieza ejecutando el reproductor proporcionado de FQ.pow en Windows y Linux con Python 3.12 y 3.13, y después compáralo con la versión de sillypow. Revisa los issues 133 y 134 relacionados de py_ecc para obtener contexto. Se considera terminado cuando se explique la diferencia entre plataformas y se establezca un comportamiento corregido o una resolución apropiada para CPython.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
python
Área
operating-systems
Tipo de issue
Error
Dificultad
4/5
Tiempo estimado
3-5 días
Estado de actividad
Tranquilo
Claridad
Bastante claro
Aptitud para principiantes
45/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.