@@ -100,54 +100,17 @@ typedef struct {
100100
101101#define PyIsoCalendarDate_CAST (op ) ((PyDateTime_IsoCalendarDate *)(op))
102102
103- static inline PyObject *
104- get_const_us_per_ms (datetime_state * st ) {
105- return st ? st -> us_per_ms : PyLong_FromLong (1000 );
106- }
107-
108- static inline PyObject *
109- get_const_us_per_second (datetime_state * st ) {
110- return st ? st -> us_per_second : PyLong_FromLong (1000000 );
111- }
112-
113- static inline PyObject *
114- get_const_us_per_minute (datetime_state * st ) {
115- return st ? st -> us_per_minute : PyLong_FromLong (60000000 );
116- }
117-
118- static inline PyObject *
119- get_const_us_per_hour (datetime_state * st ) {
120- return st ? st -> us_per_hour : PyLong_FromDouble (3600000000.0 );
121- }
122-
123- static inline PyObject *
124- get_const_us_per_day (datetime_state * st ) {
125- return st ? st -> us_per_day : PyLong_FromDouble (86400000000.0 );
126- }
127-
128- static inline PyObject *
129- get_const_us_per_week (datetime_state * st ) {
130- return st ? st -> us_per_week : PyLong_FromDouble (604800000000.0 );
131- }
132-
133- static inline PyObject *
134- get_const_sec_per_day (datetime_state * st ) {
135- return st ? st -> seconds_per_day : PyLong_FromLong (24 * 3600 );
136- }
137-
138- #define CONST_US_PER_MS (st ) get_const_us_per_ms(st)
139- #define CONST_US_PER_SECOND (st ) get_const_us_per_second(st)
140- #define CONST_US_PER_MINUTE (st ) get_const_us_per_minute(st)
141- #define CONST_US_PER_HOUR (st ) get_const_us_per_hour(st)
142- #define CONST_US_PER_DAY (st ) get_const_us_per_day(st)
143- #define CONST_US_PER_WEEK (st ) get_const_us_per_week(st)
144- #define CONST_SEC_PER_DAY (st ) get_const_sec_per_day(st)
145103#define CONST_UTC (st ) ((PyObject *)&utc_timezone)
146- #define CONST_EPOCH (st ) \
147- (st ? ((datetime_state *)st)->epoch \
148- : new_datetime(1970, 1, 1, 0, 0, 0, 0, (PyObject *)&utc_timezone, 0))
149-
150- static datetime_state *
104+ static inline PyObject * get_const_us_per_ms (datetime_state * st );
105+ static inline PyObject * get_const_us_per_second (datetime_state * st );
106+ static inline PyObject * get_const_us_per_minute (datetime_state * st );
107+ static inline PyObject * get_const_us_per_hour (datetime_state * st );
108+ static inline PyObject * get_const_us_per_day (datetime_state * st );
109+ static inline PyObject * get_const_us_per_week (datetime_state * st );
110+ static inline PyObject * get_const_sec_per_day (datetime_state * st );
111+ static inline PyObject * get_const_epoch (datetime_state * st );
112+
113+ static inline datetime_state *
151114get_module_state (PyObject * module )
152115{
153116 void * state = _PyModule_GetState (module );
@@ -2149,7 +2112,12 @@ delta_to_microseconds(PyDateTime_Delta *self)
21492112 x1 = PyLong_FromLong (GET_TD_DAYS (self ));
21502113 if (x1 == NULL )
21512114 goto Done ;
2152- x2 = PyNumber_Multiply (x1 , CONST_SEC_PER_DAY (st )); /* days in seconds */
2115+ PyObject * sec_per_day = get_const_sec_per_day (st );
2116+ if (sec_per_day == NULL ) {
2117+ goto Done ;
2118+ }
2119+ x2 = PyNumber_Multiply (x1 , sec_per_day ); /* days in seconds */
2120+ Py_DECREF (sec_per_day );
21532121 if (x2 == NULL )
21542122 goto Done ;
21552123 Py_SETREF (x1 , NULL );
@@ -2166,7 +2134,12 @@ delta_to_microseconds(PyDateTime_Delta *self)
21662134 /* x1 = */ x2 = NULL ;
21672135
21682136 /* x3 has days+seconds in seconds */
2169- x1 = PyNumber_Multiply (x3 , CONST_US_PER_SECOND (st )); /* us */
2137+ PyObject * us_per_sec = get_const_us_per_second (st );
2138+ if (us_per_sec == NULL ) {
2139+ goto Done ;
2140+ }
2141+ x1 = PyNumber_Multiply (x3 , us_per_sec ); /* us */
2142+ Py_DECREF (us_per_sec );
21702143 if (x1 == NULL )
21712144 goto Done ;
21722145 Py_SETREF (x3 , NULL );
@@ -2225,7 +2198,12 @@ microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
22252198 PyObject * current_mod = NULL ;
22262199 datetime_state * st = GET_CURRENT_STATE (current_mod );
22272200
2228- tuple = checked_divmod (pyus , CONST_US_PER_SECOND (st ));
2201+ PyObject * us_per_sec = get_const_us_per_second (st );
2202+ if (us_per_sec == NULL ) {
2203+ goto Done ;
2204+ }
2205+ tuple = checked_divmod (pyus , us_per_sec );
2206+ Py_DECREF (us_per_sec );
22292207 if (tuple == NULL ) {
22302208 goto Done ;
22312209 }
@@ -2243,7 +2221,12 @@ microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
22432221 num = Py_NewRef (PyTuple_GET_ITEM (tuple , 0 )); /* leftover seconds */
22442222 Py_DECREF (tuple );
22452223
2246- tuple = checked_divmod (num , CONST_SEC_PER_DAY (st ));
2224+ PyObject * sec_per_day = get_const_sec_per_day (st );
2225+ if (sec_per_day == NULL ) {
2226+ goto Done ;
2227+ }
2228+ tuple = checked_divmod (num , sec_per_day );
2229+ Py_DECREF (sec_per_day );
22472230 if (tuple == NULL )
22482231 goto Done ;
22492232 Py_DECREF (num );
@@ -2849,27 +2832,57 @@ delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
28492832 CLEANUP ;
28502833 }
28512834 if (ms ) {
2852- y = accum ("milliseconds" , x , ms , CONST_US_PER_MS (st ), & leftover_us );
2835+ PyObject * us_per_ms = get_const_us_per_ms (st );
2836+ if (us_per_ms == NULL ) {
2837+ goto Done ;
2838+ }
2839+ y = accum ("milliseconds" , x , ms , us_per_ms , & leftover_us );
2840+ Py_DECREF (us_per_ms );
28532841 CLEANUP ;
28542842 }
28552843 if (second ) {
2856- y = accum ("seconds" , x , second , CONST_US_PER_SECOND (st ), & leftover_us );
2844+ PyObject * us_per_sec = get_const_us_per_second (st );
2845+ if (us_per_sec == NULL ) {
2846+ goto Done ;
2847+ }
2848+ y = accum ("seconds" , x , second , us_per_sec , & leftover_us );
2849+ Py_DECREF (us_per_sec );
28572850 CLEANUP ;
28582851 }
28592852 if (minute ) {
2860- y = accum ("minutes" , x , minute , CONST_US_PER_MINUTE (st ), & leftover_us );
2853+ PyObject * us_per_min = get_const_us_per_minute (st );
2854+ if (us_per_min == NULL ) {
2855+ goto Done ;
2856+ }
2857+ y = accum ("minutes" , x , minute , us_per_min , & leftover_us );
2858+ Py_DECREF (us_per_min );
28612859 CLEANUP ;
28622860 }
28632861 if (hour ) {
2864- y = accum ("hours" , x , hour , CONST_US_PER_HOUR (st ), & leftover_us );
2862+ PyObject * us_per_hour = get_const_us_per_hour (st );
2863+ if (us_per_hour == NULL ) {
2864+ goto Done ;
2865+ }
2866+ y = accum ("hours" , x , hour , us_per_hour , & leftover_us );
2867+ Py_DECREF (us_per_hour );
28652868 CLEANUP ;
28662869 }
28672870 if (day ) {
2868- y = accum ("days" , x , day , CONST_US_PER_DAY (st ), & leftover_us );
2871+ PyObject * us_per_day = get_const_us_per_day (st );
2872+ if (us_per_day == NULL ) {
2873+ goto Done ;
2874+ }
2875+ y = accum ("days" , x , day , us_per_day , & leftover_us );
2876+ Py_DECREF (us_per_day );
28692877 CLEANUP ;
28702878 }
28712879 if (week ) {
2872- y = accum ("weeks" , x , week , CONST_US_PER_WEEK (st ), & leftover_us );
2880+ PyObject * us_per_week = get_const_us_per_week (st );
2881+ if (us_per_week == NULL ) {
2882+ goto Done ;
2883+ }
2884+ y = accum ("weeks" , x , week , us_per_week , & leftover_us );
2885+ Py_DECREF (us_per_week );
28732886 CLEANUP ;
28742887 }
28752888 if (leftover_us ) {
@@ -3019,7 +3032,7 @@ delta_getstate(PyDateTime_Delta *self)
30193032static PyObject *
30203033delta_total_seconds (PyObject * op , PyObject * Py_UNUSED (dummy ))
30213034{
3022- PyObject * total_seconds ;
3035+ PyObject * total_seconds = NULL ;
30233036 PyObject * total_microseconds ;
30243037
30253038 total_microseconds = delta_to_microseconds (PyDelta_CAST (op ));
@@ -3029,8 +3042,13 @@ delta_total_seconds(PyObject *op, PyObject *Py_UNUSED(dummy))
30293042 PyObject * current_mod = NULL ;
30303043 datetime_state * st = GET_CURRENT_STATE (current_mod );
30313044
3032- total_seconds = PyNumber_TrueDivide (total_microseconds , CONST_US_PER_SECOND (st ));
3033-
3045+ PyObject * us_per_sec = get_const_us_per_second (st );
3046+ if (us_per_sec == NULL ) {
3047+ goto finally ;
3048+ }
3049+ total_seconds = PyNumber_TrueDivide (total_microseconds , us_per_sec );
3050+ Py_DECREF (us_per_sec );
3051+ finally :
30343052 RELEASE_CURRENT_STATE (st , current_mod );
30353053 Py_DECREF (total_microseconds );
30363054 return total_seconds ;
@@ -6612,7 +6630,12 @@ local_timezone(PyDateTime_DateTime *utc_time)
66126630 PyObject * current_mod = NULL ;
66136631 datetime_state * st = GET_CURRENT_STATE (current_mod );
66146632
6615- delta = datetime_subtract ((PyObject * )utc_time , CONST_EPOCH (st ));
6633+ PyObject * epoch = get_const_epoch (st );
6634+ if (epoch == NULL ) {
6635+ return NULL ;
6636+ }
6637+ delta = datetime_subtract ((PyObject * )utc_time , epoch );
6638+ Py_DECREF (epoch );
66166639 RELEASE_CURRENT_STATE (st , current_mod );
66176640 if (delta == NULL )
66186641 return NULL ;
@@ -6856,8 +6879,12 @@ datetime_timestamp(PyObject *op, PyObject *Py_UNUSED(dummy))
68566879 PyObject * current_mod = NULL ;
68576880 datetime_state * st = GET_CURRENT_STATE (current_mod );
68586881
6859- PyObject * delta ;
6860- delta = datetime_subtract (op , CONST_EPOCH (st ));
6882+ PyObject * epoch = get_const_epoch (st );
6883+ if (epoch == NULL ) {
6884+ return NULL ;
6885+ }
6886+ PyObject * delta = datetime_subtract (op , epoch );
6887+ Py_DECREF (epoch );
68616888 RELEASE_CURRENT_STATE (st , current_mod );
68626889 if (delta == NULL )
68636890 return NULL ;
@@ -7224,6 +7251,56 @@ create_timezone_from_delta(int days, int sec, int ms, int normalize)
72247251 * Module state lifecycle.
72257252 */
72267253
7254+ static inline PyObject *
7255+ get_const_us_per_ms (datetime_state * st ) {
7256+ return st && st -> us_per_ms ? Py_NewRef (st -> us_per_ms )
7257+ : PyLong_FromLong (1000 );
7258+ }
7259+
7260+ static inline PyObject *
7261+ get_const_us_per_second (datetime_state * st ) {
7262+ return st && st -> us_per_second ? Py_NewRef (st -> us_per_second )
7263+ : PyLong_FromLong (1000000 );
7264+ }
7265+
7266+ static inline PyObject *
7267+ get_const_us_per_minute (datetime_state * st ) {
7268+ return st && st -> us_per_minute ? Py_NewRef (st -> us_per_minute )
7269+ : PyLong_FromLong (60000000 );
7270+ }
7271+
7272+ static inline PyObject *
7273+ get_const_us_per_hour (datetime_state * st ) {
7274+ return st && st -> us_per_hour ? Py_NewRef (st -> us_per_hour )
7275+ : PyLong_FromDouble (3600000000.0 );
7276+ }
7277+
7278+ static inline PyObject *
7279+ get_const_us_per_day (datetime_state * st ) {
7280+ return st && st -> us_per_day ? Py_NewRef (st -> us_per_day )
7281+ : PyLong_FromDouble (86400000000.0 );
7282+ }
7283+
7284+ static inline PyObject *
7285+ get_const_us_per_week (datetime_state * st ) {
7286+ return st && st -> us_per_week ? Py_NewRef (st -> us_per_week )
7287+ : PyLong_FromDouble (604800000000.0 );
7288+ }
7289+
7290+ static inline PyObject *
7291+ get_const_sec_per_day (datetime_state * st ) {
7292+ return st && st -> seconds_per_day ? Py_NewRef (st -> seconds_per_day )
7293+ : PyLong_FromLong (24 * 3600 );
7294+ }
7295+
7296+ static inline PyObject *
7297+ get_const_epoch (datetime_state * st ) {
7298+ return st && st -> epoch ? Py_NewRef (st -> epoch )
7299+ : new_datetime (1970 , 1 , 1 , 0 , 0 , 0 , 0 ,
7300+ (PyObject * )& utc_timezone , 0 );
7301+ }
7302+
7303+
72277304static int
72287305init_state (datetime_state * st , PyObject * module , PyObject * old_module )
72297306{
@@ -7243,41 +7320,41 @@ init_state(datetime_state *st, PyObject *module, PyObject *old_module)
72437320 return 0 ;
72447321 }
72457322
7246- st -> us_per_ms = CONST_US_PER_MS (NULL );
7323+ st -> us_per_ms = get_const_us_per_ms (NULL );
72477324 if (st -> us_per_ms == NULL ) {
72487325 return -1 ;
72497326 }
7250- st -> us_per_second = CONST_US_PER_SECOND (NULL );
7327+ st -> us_per_second = get_const_us_per_second (NULL );
72517328 if (st -> us_per_second == NULL ) {
72527329 return -1 ;
72537330 }
7254- st -> us_per_minute = CONST_US_PER_MINUTE (NULL );
7331+ st -> us_per_minute = get_const_us_per_minute (NULL );
72557332 if (st -> us_per_minute == NULL ) {
72567333 return -1 ;
72577334 }
7258- st -> seconds_per_day = CONST_SEC_PER_DAY (NULL );
7335+ st -> seconds_per_day = get_const_sec_per_day (NULL );
72597336 if (st -> seconds_per_day == NULL ) {
72607337 return -1 ;
72617338 }
72627339
72637340 /* The rest are too big for 32-bit ints, but even
72647341 * us_per_week fits in 40 bits, so doubles should be exact.
72657342 */
7266- st -> us_per_hour = CONST_US_PER_HOUR (NULL );
7343+ st -> us_per_hour = get_const_us_per_hour (NULL );
72677344 if (st -> us_per_hour == NULL ) {
72687345 return -1 ;
72697346 }
7270- st -> us_per_day = CONST_US_PER_DAY (NULL );
7347+ st -> us_per_day = get_const_us_per_day (NULL );
72717348 if (st -> us_per_day == NULL ) {
72727349 return -1 ;
72737350 }
7274- st -> us_per_week = CONST_US_PER_WEEK (NULL );
7351+ st -> us_per_week = get_const_us_per_week (NULL );
72757352 if (st -> us_per_week == NULL ) {
72767353 return -1 ;
72777354 }
72787355
72797356 /* Init Unix epoch */
7280- st -> epoch = CONST_EPOCH (NULL );
7357+ st -> epoch = get_const_epoch (NULL );
72817358 if (st -> epoch == NULL ) {
72827359 return -1 ;
72837360 }
0 commit comments