@@ -3386,13 +3386,35 @@ count_nextlong(countobject *lz)
33863386 return long_cnt ;
33873387}
33883388
3389+ static inline int
3390+ count_switch_to_slow_mode (countobject * lz )
3391+ {
3392+ assert (lz -> cnt == PY_SSIZE_T_MAX );
3393+ assert (lz -> long_cnt == NULL );
3394+ /* Switch to slow_mode */
3395+ PyObject * long_cnt = PyLong_FromSsize_t (PY_SSIZE_T_MAX );
3396+ if (long_cnt == NULL ) {
3397+ return -1 ;
3398+ }
3399+ lz -> long_cnt = long_cnt ;
3400+ return 0 ;
3401+ }
3402+
33893403static PyObject *
33903404count_next (countobject * lz )
33913405{
33923406#ifndef Py_GIL_DISABLED
33933407 if (lz -> cnt == PY_SSIZE_T_MAX )
33943408 return count_nextlong (lz );
3395- return PyLong_FromSsize_t (lz -> cnt ++ );
3409+ PyObject * res = PyLong_FromSsize_t (lz -> cnt ++ );
3410+ if (lz -> cnt == PY_SSIZE_T_MAX && lz -> long_cnt == NULL ) {
3411+ /* populate lz->long_cnt since it could be used by repr() */
3412+ if (count_switch_to_slow_mode (lz ) < 0 ) {
3413+ Py_DECREF (res );
3414+ return NULL ;
3415+ }
3416+ }
3417+ return res ;
33963418#else
33973419 // free-threading version
33983420 // fast mode uses compare-exchange loop
@@ -3409,7 +3431,19 @@ count_next(countobject *lz)
34093431 return returned ;
34103432 }
34113433 if (_Py_atomic_compare_exchange_ssize (& lz -> cnt , & cnt , cnt + 1 )) {
3412- return PyLong_FromSsize_t (cnt );
3434+ /* populate lz->long_cnt now since it could be used by repr() */
3435+ returned = PyLong_FromSsize_t (cnt );
3436+ if (lz -> cnt == PY_SSIZE_T_MAX && lz -> long_cnt == NULL ) {
3437+ int rc ;
3438+ Py_BEGIN_CRITICAL_SECTION (lz );
3439+ rc = count_switch_to_slow_mode (lz );
3440+ Py_END_CRITICAL_SECTION ();
3441+ if (rc < 0 ) {
3442+ Py_DECREF (returned );
3443+ return NULL ;
3444+ }
3445+ }
3446+ return returned ;
34133447 }
34143448 }
34153449#endif
0 commit comments