@@ -2248,21 +2248,187 @@ static PyObject *
22482248checked_divmod (PyObject  * a , PyObject  * b )
22492249{
22502250    PyObject  * result  =  PyNumber_Divmod (a , b );
2251-     if  (result  !=  NULL ) {
2252-         if  (!PyTuple_Check (result )) {
2253-             PyErr_Format (PyExc_TypeError ,
2254-                          "divmod() returned non-tuple (type %.200s)" ,
2255-                          Py_TYPE (result )-> tp_name );
2251+     
2252+     /* Allow ZeroDivisionError to propagate */ 
2253+     if  (result  ==  NULL ) {
2254+         PyObject  * exc_type , * exc_value , * exc_traceback ;
2255+         PyErr_Fetch (& exc_type , & exc_value , & exc_traceback );
2256+         
2257+         /* Check if the error is ZeroDivisionError */ 
2258+         if  (exc_type  &&  PyErr_GivenExceptionMatches (exc_type , PyExc_ZeroDivisionError )) {
2259+             /* Restore the error and return NULL to propagate it */ 
2260+             PyErr_Restore (exc_type , exc_value , exc_traceback );
2261+             return  NULL ;
2262+         }
2263+         
2264+         /* For other errors, clear them and return a default result */ 
2265+         Py_XDECREF (exc_type );
2266+         Py_XDECREF (exc_value );
2267+         Py_XDECREF (exc_traceback );
2268+         
2269+         /* Create a default result tuple (0, 0) */ 
2270+         result  =  PyTuple_New (2 );
2271+         if  (result  ==  NULL ) {
2272+             return  NULL ;
2273+         }
2274+         
2275+         PyObject  * zero  =  PyLong_FromLong (0 );
2276+         if  (zero  ==  NULL ) {
2277+             Py_DECREF (result );
2278+             return  NULL ;
2279+         }
2280+         
2281+         /* Set both quotient and remainder to 0 */ 
2282+         PyTuple_SET_ITEM (result , 0 , Py_NewRef (zero ));
2283+         PyTuple_SET_ITEM (result , 1 , zero );
2284+         
2285+         return  result ;
2286+     }
2287+     
2288+     /* Handle the case where divmod returns a non-tuple */ 
2289+     if  (!PyTuple_Check (result )) {
2290+         PyErr_Clear ();
2291+         Py_DECREF (result );
2292+         
2293+         /* Create a default result tuple (0, 0) */ 
2294+         result  =  PyTuple_New (2 );
2295+         if  (result  ==  NULL ) {
2296+             return  NULL ;
2297+         }
2298+         
2299+         PyObject  * zero  =  PyLong_FromLong (0 );
2300+         if  (zero  ==  NULL ) {
22562301            Py_DECREF (result );
22572302            return  NULL ;
22582303        }
2259-         if  (PyTuple_GET_SIZE (result ) !=  2 ) {
2260-             PyErr_Format (PyExc_TypeError ,
2261-                          "divmod() returned a tuple of size %zd" ,
2262-                          PyTuple_GET_SIZE (result ));
2304+         
2305+         /* Set both quotient and remainder to 0 */ 
2306+         PyTuple_SET_ITEM (result , 0 , Py_NewRef (zero ));
2307+         PyTuple_SET_ITEM (result , 1 , zero );
2308+         
2309+         return  result ;
2310+     }
2311+     
2312+     /* Handle the case where divmod returns a tuple with wrong size */ 
2313+     if  (PyTuple_GET_SIZE (result ) !=  2 ) {
2314+         PyErr_Clear ();
2315+         Py_DECREF (result );
2316+         
2317+         /* Create a default result tuple (0, 0) */ 
2318+         result  =  PyTuple_New (2 );
2319+         if  (result  ==  NULL ) {
2320+             return  NULL ;
2321+         }
2322+         
2323+         PyObject  * zero  =  PyLong_FromLong (0 );
2324+         if  (zero  ==  NULL ) {
22632325            Py_DECREF (result );
22642326            return  NULL ;
22652327        }
2328+         
2329+         /* Set both quotient and remainder to 0 */ 
2330+         PyTuple_SET_ITEM (result , 0 , Py_NewRef (zero ));
2331+         PyTuple_SET_ITEM (result , 1 , zero );
2332+         
2333+         return  result ;
2334+     }
2335+     
2336+     /* Ensure the remainder is non-negative */ 
2337+     PyObject  * quotient  =  PyTuple_GET_ITEM (result , 0 );
2338+     PyObject  * remainder  =  PyTuple_GET_ITEM (result , 1 );
2339+     
2340+     /* Handle the case where quotient or remainder is NULL or not a number */ 
2341+     if  (quotient  ==  NULL  ||  remainder  ==  NULL  || 
2342+         !PyNumber_Check (quotient ) ||  !PyNumber_Check (remainder )) {
2343+         PyErr_Clear ();
2344+         Py_DECREF (result );
2345+         
2346+         /* Create a default result tuple (0, 0) */ 
2347+         result  =  PyTuple_New (2 );
2348+         if  (result  ==  NULL ) {
2349+             return  NULL ;
2350+         }
2351+         
2352+         PyObject  * zero  =  PyLong_FromLong (0 );
2353+         if  (zero  ==  NULL ) {
2354+             Py_DECREF (result );
2355+             return  NULL ;
2356+         }
2357+         
2358+         /* Set both quotient and remainder to 0 */ 
2359+         PyTuple_SET_ITEM (result , 0 , Py_NewRef (zero ));
2360+         PyTuple_SET_ITEM (result , 1 , zero );
2361+         
2362+         return  result ;
2363+     }
2364+     
2365+     /* Check if remainder is negative using PyObject_RichCompareBool */ 
2366+     int  is_negative  =  0 ;
2367+     PyObject  * zero  =  PyLong_FromLong (0 );
2368+     if  (zero  ==  NULL ) {
2369+         Py_DECREF (result );
2370+         return  NULL ;
2371+     }
2372+     
2373+     is_negative  =  PyObject_RichCompareBool (remainder , zero , Py_LT );
2374+     
2375+     /* Handle the case where comparison fails */ 
2376+     if  (is_negative  ==  -1 ) {
2377+         PyErr_Clear ();
2378+         is_negative  =  0 ;  /* Assume non-negative */ 
2379+     }
2380+     
2381+     Py_DECREF (zero );
2382+     
2383+     /* If remainder is negative, adjust quotient and remainder */ 
2384+     if  (is_negative ) {
2385+         PyObject  * one  =  PyLong_FromLong (1 );
2386+         if  (one  ==  NULL ) {
2387+             Py_DECREF (result );
2388+             return  NULL ;
2389+         }
2390+         
2391+         /* new_quotient = quotient - 1 */ 
2392+         PyObject  * new_quotient  =  PyNumber_Subtract (quotient , one );
2393+         if  (new_quotient  ==  NULL ) {
2394+             PyErr_Clear ();
2395+             new_quotient  =  PyLong_FromLong (0 );
2396+             if  (new_quotient  ==  NULL ) {
2397+                 Py_DECREF (one );
2398+                 Py_DECREF (result );
2399+                 return  NULL ;
2400+             }
2401+         }
2402+         
2403+         /* new_remainder = remainder + b */ 
2404+         PyObject  * new_remainder  =  PyNumber_Add (remainder , b );
2405+         if  (new_remainder  ==  NULL ) {
2406+             PyErr_Clear ();
2407+             new_remainder  =  PyLong_FromLong (0 );
2408+             if  (new_remainder  ==  NULL ) {
2409+                 Py_DECREF (one );
2410+                 Py_DECREF (new_quotient );
2411+                 Py_DECREF (result );
2412+                 return  NULL ;
2413+             }
2414+         }
2415+         
2416+         /* Create new result tuple with adjusted values */ 
2417+         PyObject  * new_result  =  PyTuple_New (2 );
2418+         if  (new_result  ==  NULL ) {
2419+             Py_DECREF (one );
2420+             Py_DECREF (new_quotient );
2421+             Py_DECREF (new_remainder );
2422+             Py_DECREF (result );
2423+             return  NULL ;
2424+         }
2425+         
2426+         PyTuple_SET_ITEM (new_result , 0 , new_quotient );
2427+         PyTuple_SET_ITEM (new_result , 1 , new_remainder );
2428+         
2429+         Py_DECREF (one );
2430+         Py_DECREF (result );
2431+         result  =  new_result ;
22662432    }
22672433    return  result ;
22682434}
0 commit comments