1 /*  C implementation for the date/time type documented at
2  *  https://www.zope.dev/Members/fdrake/DateTimeWiki/FrontPage
3  */
4 
5 /* bpo-35081: Defining this prevents including the C API capsule;
6  * internal versions of the  Py*_Check macros which do not require
7  * the capsule are defined below */
8 #define _PY_DATETIME_IMPL
9 
10 #ifndef Py_BUILD_CORE_BUILTIN
11 #  define Py_BUILD_CORE_MODULE 1
12 #endif
13 #define NEEDS_PY_IDENTIFIER
14 
15 #include "Python.h"
16 #include "pycore_long.h"          // _PyLong_GetOne()
17 #include "pycore_object.h"        // _PyObject_Init()
18 #include "datetime.h"
19 #include "structmember.h"         // PyMemberDef
20 
21 #include <time.h>
22 
23 #ifdef MS_WINDOWS
24 #  include <winsock2.h>         /* struct timeval */
25 #endif
26 
27 #define PyDate_Check(op) PyObject_TypeCheck(op, &PyDateTime_DateType)
28 #define PyDate_CheckExact(op) Py_IS_TYPE(op, &PyDateTime_DateType)
29 
30 #define PyDateTime_Check(op) PyObject_TypeCheck(op, &PyDateTime_DateTimeType)
31 #define PyDateTime_CheckExact(op) Py_IS_TYPE(op, &PyDateTime_DateTimeType)
32 
33 #define PyTime_Check(op) PyObject_TypeCheck(op, &PyDateTime_TimeType)
34 #define PyTime_CheckExact(op) Py_IS_TYPE(op, &PyDateTime_TimeType)
35 
36 #define PyDelta_Check(op) PyObject_TypeCheck(op, &PyDateTime_DeltaType)
37 #define PyDelta_CheckExact(op) Py_IS_TYPE(op, &PyDateTime_DeltaType)
38 
39 #define PyTZInfo_Check(op) PyObject_TypeCheck(op, &PyDateTime_TZInfoType)
40 #define PyTZInfo_CheckExact(op) Py_IS_TYPE(op, &PyDateTime_TZInfoType)
41 
42 #define PyTimezone_Check(op) PyObject_TypeCheck(op, &PyDateTime_TimeZoneType)
43 
44 /*[clinic input]
45 module datetime
46 class datetime.datetime "PyDateTime_DateTime *" "&PyDateTime_DateTimeType"
47 class datetime.date "PyDateTime_Date *" "&PyDateTime_DateType"
48 class datetime.IsoCalendarDate "PyDateTime_IsoCalendarDate *" "&PyDateTime_IsoCalendarDateType"
49 [clinic start generated code]*/
50 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=81bec0fa19837f63]*/
51 
52 #include "clinic/_datetimemodule.c.h"
53 
54 /* We require that C int be at least 32 bits, and use int virtually
55  * everywhere.  In just a few cases we use a temp long, where a Python
56  * API returns a C long.  In such cases, we have to ensure that the
57  * final result fits in a C int (this can be an issue on 64-bit boxes).
58  */
59 #if SIZEOF_INT < 4
60 #       error "_datetime.c requires that C int have at least 32 bits"
61 #endif
62 
63 #define MINYEAR 1
64 #define MAXYEAR 9999
65 #define MAXORDINAL 3652059 /* date(9999,12,31).toordinal() */
66 
67 /* Nine decimal digits is easy to communicate, and leaves enough room
68  * so that two delta days can be added w/o fear of overflowing a signed
69  * 32-bit int, and with plenty of room left over to absorb any possible
70  * carries from adding seconds.
71  */
72 #define MAX_DELTA_DAYS 999999999
73 
74 /* Rename the long macros in datetime.h to more reasonable short names. */
75 #define GET_YEAR                PyDateTime_GET_YEAR
76 #define GET_MONTH               PyDateTime_GET_MONTH
77 #define GET_DAY                 PyDateTime_GET_DAY
78 #define DATE_GET_HOUR           PyDateTime_DATE_GET_HOUR
79 #define DATE_GET_MINUTE         PyDateTime_DATE_GET_MINUTE
80 #define DATE_GET_SECOND         PyDateTime_DATE_GET_SECOND
81 #define DATE_GET_MICROSECOND    PyDateTime_DATE_GET_MICROSECOND
82 #define DATE_GET_FOLD           PyDateTime_DATE_GET_FOLD
83 
84 /* Date accessors for date and datetime. */
85 #define SET_YEAR(o, v)          (((o)->data[0] = ((v) & 0xff00) >> 8), \
86                  ((o)->data[1] = ((v) & 0x00ff)))
87 #define SET_MONTH(o, v)         (PyDateTime_GET_MONTH(o) = (v))
88 #define SET_DAY(o, v)           (PyDateTime_GET_DAY(o) = (v))
89 
90 /* Date/Time accessors for datetime. */
91 #define DATE_SET_HOUR(o, v)     (PyDateTime_DATE_GET_HOUR(o) = (v))
92 #define DATE_SET_MINUTE(o, v)   (PyDateTime_DATE_GET_MINUTE(o) = (v))
93 #define DATE_SET_SECOND(o, v)   (PyDateTime_DATE_GET_SECOND(o) = (v))
94 #define DATE_SET_MICROSECOND(o, v)      \
95     (((o)->data[7] = ((v) & 0xff0000) >> 16), \
96      ((o)->data[8] = ((v) & 0x00ff00) >> 8), \
97      ((o)->data[9] = ((v) & 0x0000ff)))
98 #define DATE_SET_FOLD(o, v)   (PyDateTime_DATE_GET_FOLD(o) = (v))
99 
100 /* Time accessors for time. */
101 #define TIME_GET_HOUR           PyDateTime_TIME_GET_HOUR
102 #define TIME_GET_MINUTE         PyDateTime_TIME_GET_MINUTE
103 #define TIME_GET_SECOND         PyDateTime_TIME_GET_SECOND
104 #define TIME_GET_MICROSECOND    PyDateTime_TIME_GET_MICROSECOND
105 #define TIME_GET_FOLD           PyDateTime_TIME_GET_FOLD
106 #define TIME_SET_HOUR(o, v)     (PyDateTime_TIME_GET_HOUR(o) = (v))
107 #define TIME_SET_MINUTE(o, v)   (PyDateTime_TIME_GET_MINUTE(o) = (v))
108 #define TIME_SET_SECOND(o, v)   (PyDateTime_TIME_GET_SECOND(o) = (v))
109 #define TIME_SET_MICROSECOND(o, v)      \
110     (((o)->data[3] = ((v) & 0xff0000) >> 16), \
111      ((o)->data[4] = ((v) & 0x00ff00) >> 8), \
112      ((o)->data[5] = ((v) & 0x0000ff)))
113 #define TIME_SET_FOLD(o, v)   (PyDateTime_TIME_GET_FOLD(o) = (v))
114 
115 /* Delta accessors for timedelta. */
116 #define GET_TD_DAYS(o)          (((PyDateTime_Delta *)(o))->days)
117 #define GET_TD_SECONDS(o)       (((PyDateTime_Delta *)(o))->seconds)
118 #define GET_TD_MICROSECONDS(o)  (((PyDateTime_Delta *)(o))->microseconds)
119 
120 #define SET_TD_DAYS(o, v)       ((o)->days = (v))
121 #define SET_TD_SECONDS(o, v)    ((o)->seconds = (v))
122 #define SET_TD_MICROSECONDS(o, v) ((o)->microseconds = (v))
123 
124 #define HASTZINFO               _PyDateTime_HAS_TZINFO
125 #define GET_TIME_TZINFO         PyDateTime_TIME_GET_TZINFO
126 #define GET_DT_TZINFO           PyDateTime_DATE_GET_TZINFO
127 /* M is a char or int claiming to be a valid month.  The macro is equivalent
128  * to the two-sided Python test
129  *      1 <= M <= 12
130  */
131 #define MONTH_IS_SANE(M) ((unsigned int)(M) - 1 < 12)
132 
133 /* Forward declarations. */
134 static PyTypeObject PyDateTime_DateType;
135 static PyTypeObject PyDateTime_DateTimeType;
136 static PyTypeObject PyDateTime_DeltaType;
137 static PyTypeObject PyDateTime_IsoCalendarDateType;
138 static PyTypeObject PyDateTime_TimeType;
139 static PyTypeObject PyDateTime_TZInfoType;
140 static PyTypeObject PyDateTime_TimeZoneType;
141 
142 static int check_tzinfo_subclass(PyObject *p);
143 
144 _Py_IDENTIFIER(as_integer_ratio);
145 _Py_IDENTIFIER(fromutc);
146 _Py_IDENTIFIER(isoformat);
147 _Py_IDENTIFIER(strftime);
148 
149 /* ---------------------------------------------------------------------------
150  * Math utilities.
151  */
152 
153 /* k = i+j overflows iff k differs in sign from both inputs,
154  * iff k^i has sign bit set and k^j has sign bit set,
155  * iff (k^i)&(k^j) has sign bit set.
156  */
157 #define SIGNED_ADD_OVERFLOWED(RESULT, I, J) \
158     ((((RESULT) ^ (I)) & ((RESULT) ^ (J))) < 0)
159 
160 /* Compute Python divmod(x, y), returning the quotient and storing the
161  * remainder into *r.  The quotient is the floor of x/y, and that's
162  * the real point of this.  C will probably truncate instead (C99
163  * requires truncation; C89 left it implementation-defined).
164  * Simplification:  we *require* that y > 0 here.  That's appropriate
165  * for all the uses made of it.  This simplifies the code and makes
166  * the overflow case impossible (divmod(LONG_MIN, -1) is the only
167  * overflow case).
168  */
169 static int
divmod(int x,int y,int * r)170 divmod(int x, int y, int *r)
171 {
172     int quo;
173 
174     assert(y > 0);
175     quo = x / y;
176     *r = x - quo * y;
177     if (*r < 0) {
178         --quo;
179         *r += y;
180     }
181     assert(0 <= *r && *r < y);
182     return quo;
183 }
184 
185 /* Nearest integer to m / n for integers m and n. Half-integer results
186  * are rounded to even.
187  */
188 static PyObject *
divide_nearest(PyObject * m,PyObject * n)189 divide_nearest(PyObject *m, PyObject *n)
190 {
191     PyObject *result;
192     PyObject *temp;
193 
194     temp = _PyLong_DivmodNear(m, n);
195     if (temp == NULL)
196         return NULL;
197     result = PyTuple_GET_ITEM(temp, 0);
198     Py_INCREF(result);
199     Py_DECREF(temp);
200 
201     return result;
202 }
203 
204 /* ---------------------------------------------------------------------------
205  * General calendrical helper functions
206  */
207 
208 /* For each month ordinal in 1..12, the number of days in that month,
209  * and the number of days before that month in the same year.  These
210  * are correct for non-leap years only.
211  */
212 static const int _days_in_month[] = {
213     0, /* unused; this vector uses 1-based indexing */
214     31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
215 };
216 
217 static const int _days_before_month[] = {
218     0, /* unused; this vector uses 1-based indexing */
219     0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
220 };
221 
222 /* year -> 1 if leap year, else 0. */
223 static int
is_leap(int year)224 is_leap(int year)
225 {
226     /* Cast year to unsigned.  The result is the same either way, but
227      * C can generate faster code for unsigned mod than for signed
228      * mod (especially for % 4 -- a good compiler should just grab
229      * the last 2 bits when the LHS is unsigned).
230      */
231     const unsigned int ayear = (unsigned int)year;
232     return ayear % 4 == 0 && (ayear % 100 != 0 || ayear % 400 == 0);
233 }
234 
235 /* year, month -> number of days in that month in that year */
236 static int
days_in_month(int year,int month)237 days_in_month(int year, int month)
238 {
239     assert(month >= 1);
240     assert(month <= 12);
241     if (month == 2 && is_leap(year))
242         return 29;
243     else
244         return _days_in_month[month];
245 }
246 
247 /* year, month -> number of days in year preceding first day of month */
248 static int
days_before_month(int year,int month)249 days_before_month(int year, int month)
250 {
251     int days;
252 
253     assert(month >= 1);
254     assert(month <= 12);
255     days = _days_before_month[month];
256     if (month > 2 && is_leap(year))
257         ++days;
258     return days;
259 }
260 
261 /* year -> number of days before January 1st of year.  Remember that we
262  * start with year 1, so days_before_year(1) == 0.
263  */
264 static int
days_before_year(int year)265 days_before_year(int year)
266 {
267     int y = year - 1;
268     /* This is incorrect if year <= 0; we really want the floor
269      * here.  But so long as MINYEAR is 1, the smallest year this
270      * can see is 1.
271      */
272     assert (year >= 1);
273     return y*365 + y/4 - y/100 + y/400;
274 }
275 
276 /* Number of days in 4, 100, and 400 year cycles.  That these have
277  * the correct values is asserted in the module init function.
278  */
279 #define DI4Y    1461    /* days_before_year(5); days in 4 years */
280 #define DI100Y  36524   /* days_before_year(101); days in 100 years */
281 #define DI400Y  146097  /* days_before_year(401); days in 400 years  */
282 
283 /* ordinal -> year, month, day, considering 01-Jan-0001 as day 1. */
284 static void
ord_to_ymd(int ordinal,int * year,int * month,int * day)285 ord_to_ymd(int ordinal, int *year, int *month, int *day)
286 {
287     int n, n1, n4, n100, n400, leapyear, preceding;
288 
289     /* ordinal is a 1-based index, starting at 1-Jan-1.  The pattern of
290      * leap years repeats exactly every 400 years.  The basic strategy is
291      * to find the closest 400-year boundary at or before ordinal, then
292      * work with the offset from that boundary to ordinal.  Life is much
293      * clearer if we subtract 1 from ordinal first -- then the values
294      * of ordinal at 400-year boundaries are exactly those divisible
295      * by DI400Y:
296      *
297      *    D  M   Y            n              n-1
298      *    -- --- ----        ----------     ----------------
299      *    31 Dec -400        -DI400Y       -DI400Y -1
300      *     1 Jan -399         -DI400Y +1   -DI400Y      400-year boundary
301      *    ...
302      *    30 Dec  000        -1             -2
303      *    31 Dec  000         0             -1
304      *     1 Jan  001         1              0          400-year boundary
305      *     2 Jan  001         2              1
306      *     3 Jan  001         3              2
307      *    ...
308      *    31 Dec  400         DI400Y        DI400Y -1
309      *     1 Jan  401         DI400Y +1     DI400Y      400-year boundary
310      */
311     assert(ordinal >= 1);
312     --ordinal;
313     n400 = ordinal / DI400Y;
314     n = ordinal % DI400Y;
315     *year = n400 * 400 + 1;
316 
317     /* Now n is the (non-negative) offset, in days, from January 1 of
318      * year, to the desired date.  Now compute how many 100-year cycles
319      * precede n.
320      * Note that it's possible for n100 to equal 4!  In that case 4 full
321      * 100-year cycles precede the desired day, which implies the
322      * desired day is December 31 at the end of a 400-year cycle.
323      */
324     n100 = n / DI100Y;
325     n = n % DI100Y;
326 
327     /* Now compute how many 4-year cycles precede it. */
328     n4 = n / DI4Y;
329     n = n % DI4Y;
330 
331     /* And now how many single years.  Again n1 can be 4, and again
332      * meaning that the desired day is December 31 at the end of the
333      * 4-year cycle.
334      */
335     n1 = n / 365;
336     n = n % 365;
337 
338     *year += n100 * 100 + n4 * 4 + n1;
339     if (n1 == 4 || n100 == 4) {
340         assert(n == 0);
341         *year -= 1;
342         *month = 12;
343         *day = 31;
344         return;
345     }
346 
347     /* Now the year is correct, and n is the offset from January 1.  We
348      * find the month via an estimate that's either exact or one too
349      * large.
350      */
351     leapyear = n1 == 3 && (n4 != 24 || n100 == 3);
352     assert(leapyear == is_leap(*year));
353     *month = (n + 50) >> 5;
354     preceding = (_days_before_month[*month] + (*month > 2 && leapyear));
355     if (preceding > n) {
356         /* estimate is too large */
357         *month -= 1;
358         preceding -= days_in_month(*year, *month);
359     }
360     n -= preceding;
361     assert(0 <= n);
362     assert(n < days_in_month(*year, *month));
363 
364     *day = n + 1;
365 }
366 
367 /* year, month, day -> ordinal, considering 01-Jan-0001 as day 1. */
368 static int
ymd_to_ord(int year,int month,int day)369 ymd_to_ord(int year, int month, int day)
370 {
371     return days_before_year(year) + days_before_month(year, month) + day;
372 }
373 
374 /* Day of week, where Monday==0, ..., Sunday==6.  1/1/1 was a Monday. */
375 static int
weekday(int year,int month,int day)376 weekday(int year, int month, int day)
377 {
378     return (ymd_to_ord(year, month, day) + 6) % 7;
379 }
380 
381 /* Ordinal of the Monday starting week 1 of the ISO year.  Week 1 is the
382  * first calendar week containing a Thursday.
383  */
384 static int
iso_week1_monday(int year)385 iso_week1_monday(int year)
386 {
387     int first_day = ymd_to_ord(year, 1, 1);     /* ord of 1/1 */
388     /* 0 if 1/1 is a Monday, 1 if a Tue, etc. */
389     int first_weekday = (first_day + 6) % 7;
390     /* ordinal of closest Monday at or before 1/1 */
391     int week1_monday  = first_day - first_weekday;
392 
393     if (first_weekday > 3)      /* if 1/1 was Fri, Sat, Sun */
394         week1_monday += 7;
395     return week1_monday;
396 }
397 
398 static int
iso_to_ymd(const int iso_year,const int iso_week,const int iso_day,int * year,int * month,int * day)399 iso_to_ymd(const int iso_year, const int iso_week, const int iso_day,
400            int *year, int *month, int *day) {
401     if (iso_week <= 0 || iso_week >= 53) {
402         int out_of_range = 1;
403         if (iso_week == 53) {
404             // ISO years have 53 weeks in it on years starting with a Thursday
405             // and on leap years starting on Wednesday
406             int first_weekday = weekday(iso_year, 1, 1);
407             if (first_weekday == 3 || (first_weekday == 2 && is_leap(iso_year))) {
408                 out_of_range = 0;
409             }
410         }
411 
412         if (out_of_range) {
413             return -2;
414         }
415     }
416 
417     if (iso_day <= 0 || iso_day >= 8) {
418         return -3;
419     }
420 
421     // Convert (Y, W, D) to (Y, M, D) in-place
422     int day_1 = iso_week1_monday(iso_year);
423 
424     int day_offset = (iso_week - 1)*7 + iso_day - 1;
425 
426     ord_to_ymd(day_1 + day_offset, year, month, day);
427     return 0;
428 }
429 
430 
431 /* ---------------------------------------------------------------------------
432  * Range checkers.
433  */
434 
435 /* Check that -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS.  If so, return 0.
436  * If not, raise OverflowError and return -1.
437  */
438 static int
check_delta_day_range(int days)439 check_delta_day_range(int days)
440 {
441     if (-MAX_DELTA_DAYS <= days && days <= MAX_DELTA_DAYS)
442         return 0;
443     PyErr_Format(PyExc_OverflowError,
444                  "days=%d; must have magnitude <= %d",
445                  days, MAX_DELTA_DAYS);
446     return -1;
447 }
448 
449 /* Check that date arguments are in range.  Return 0 if they are.  If they
450  * aren't, raise ValueError and return -1.
451  */
452 static int
check_date_args(int year,int month,int day)453 check_date_args(int year, int month, int day)
454 {
455 
456     if (year < MINYEAR || year > MAXYEAR) {
457         PyErr_Format(PyExc_ValueError, "year %i is out of range", year);
458         return -1;
459     }
460     if (month < 1 || month > 12) {
461         PyErr_SetString(PyExc_ValueError,
462                         "month must be in 1..12");
463         return -1;
464     }
465     if (day < 1 || day > days_in_month(year, month)) {
466         PyErr_SetString(PyExc_ValueError,
467                         "day is out of range for month");
468         return -1;
469     }
470     return 0;
471 }
472 
473 /* Check that time arguments are in range.  Return 0 if they are.  If they
474  * aren't, raise ValueError and return -1.
475  */
476 static int
check_time_args(int h,int m,int s,int us,int fold)477 check_time_args(int h, int m, int s, int us, int fold)
478 {
479     if (h < 0 || h > 23) {
480         PyErr_SetString(PyExc_ValueError,
481                         "hour must be in 0..23");
482         return -1;
483     }
484     if (m < 0 || m > 59) {
485         PyErr_SetString(PyExc_ValueError,
486                         "minute must be in 0..59");
487         return -1;
488     }
489     if (s < 0 || s > 59) {
490         PyErr_SetString(PyExc_ValueError,
491                         "second must be in 0..59");
492         return -1;
493     }
494     if (us < 0 || us > 999999) {
495         PyErr_SetString(PyExc_ValueError,
496                         "microsecond must be in 0..999999");
497         return -1;
498     }
499     if (fold != 0 && fold != 1) {
500         PyErr_SetString(PyExc_ValueError,
501                         "fold must be either 0 or 1");
502         return -1;
503     }
504     return 0;
505 }
506 
507 /* ---------------------------------------------------------------------------
508  * Normalization utilities.
509  */
510 
511 /* One step of a mixed-radix conversion.  A "hi" unit is equivalent to
512  * factor "lo" units.  factor must be > 0.  If *lo is less than 0, or
513  * at least factor, enough of *lo is converted into "hi" units so that
514  * 0 <= *lo < factor.  The input values must be such that int overflow
515  * is impossible.
516  */
517 static void
normalize_pair(int * hi,int * lo,int factor)518 normalize_pair(int *hi, int *lo, int factor)
519 {
520     assert(factor > 0);
521     assert(lo != hi);
522     if (*lo < 0 || *lo >= factor) {
523         const int num_hi = divmod(*lo, factor, lo);
524         const int new_hi = *hi + num_hi;
525         assert(! SIGNED_ADD_OVERFLOWED(new_hi, *hi, num_hi));
526         *hi = new_hi;
527     }
528     assert(0 <= *lo && *lo < factor);
529 }
530 
531 /* Fiddle days (d), seconds (s), and microseconds (us) so that
532  *      0 <= *s < 24*3600
533  *      0 <= *us < 1000000
534  * The input values must be such that the internals don't overflow.
535  * The way this routine is used, we don't get close.
536  */
537 static void
normalize_d_s_us(int * d,int * s,int * us)538 normalize_d_s_us(int *d, int *s, int *us)
539 {
540     if (*us < 0 || *us >= 1000000) {
541         normalize_pair(s, us, 1000000);
542         /* |s| can't be bigger than about
543          * |original s| + |original us|/1000000 now.
544          */
545 
546     }
547     if (*s < 0 || *s >= 24*3600) {
548         normalize_pair(d, s, 24*3600);
549         /* |d| can't be bigger than about
550          * |original d| +
551          * (|original s| + |original us|/1000000) / (24*3600) now.
552          */
553     }
554     assert(0 <= *s && *s < 24*3600);
555     assert(0 <= *us && *us < 1000000);
556 }
557 
558 /* Fiddle years (y), months (m), and days (d) so that
559  *      1 <= *m <= 12
560  *      1 <= *d <= days_in_month(*y, *m)
561  * The input values must be such that the internals don't overflow.
562  * The way this routine is used, we don't get close.
563  */
564 static int
normalize_y_m_d(int * y,int * m,int * d)565 normalize_y_m_d(int *y, int *m, int *d)
566 {
567     int dim;            /* # of days in month */
568 
569     /* In actual use, m is always the month component extracted from a
570      * date/datetime object.  Therefore it is always in [1, 12] range.
571      */
572 
573     assert(1 <= *m && *m <= 12);
574 
575     /* Now only day can be out of bounds (year may also be out of bounds
576      * for a datetime object, but we don't care about that here).
577      * If day is out of bounds, what to do is arguable, but at least the
578      * method here is principled and explainable.
579      */
580     dim = days_in_month(*y, *m);
581     if (*d < 1 || *d > dim) {
582         /* Move day-1 days from the first of the month.  First try to
583          * get off cheap if we're only one day out of range
584          * (adjustments for timezone alone can't be worse than that).
585          */
586         if (*d == 0) {
587             --*m;
588             if (*m > 0)
589                 *d = days_in_month(*y, *m);
590             else {
591                 --*y;
592                 *m = 12;
593                 *d = 31;
594             }
595         }
596         else if (*d == dim + 1) {
597             /* move forward a day */
598             ++*m;
599             *d = 1;
600             if (*m > 12) {
601                 *m = 1;
602                 ++*y;
603             }
604         }
605         else {
606             int ordinal = ymd_to_ord(*y, *m, 1) +
607                                       *d - 1;
608             if (ordinal < 1 || ordinal > MAXORDINAL) {
609                 goto error;
610             } else {
611                 ord_to_ymd(ordinal, y, m, d);
612                 return 0;
613             }
614         }
615     }
616     assert(*m > 0);
617     assert(*d > 0);
618     if (MINYEAR <= *y && *y <= MAXYEAR)
619         return 0;
620  error:
621     PyErr_SetString(PyExc_OverflowError,
622             "date value out of range");
623     return -1;
624 
625 }
626 
627 /* Fiddle out-of-bounds months and days so that the result makes some kind
628  * of sense.  The parameters are both inputs and outputs.  Returns < 0 on
629  * failure, where failure means the adjusted year is out of bounds.
630  */
631 static int
normalize_date(int * year,int * month,int * day)632 normalize_date(int *year, int *month, int *day)
633 {
634     return normalize_y_m_d(year, month, day);
635 }
636 
637 /* Force all the datetime fields into range.  The parameters are both
638  * inputs and outputs.  Returns < 0 on error.
639  */
640 static int
normalize_datetime(int * year,int * month,int * day,int * hour,int * minute,int * second,int * microsecond)641 normalize_datetime(int *year, int *month, int *day,
642                    int *hour, int *minute, int *second,
643                    int *microsecond)
644 {
645     normalize_pair(second, microsecond, 1000000);
646     normalize_pair(minute, second, 60);
647     normalize_pair(hour, minute, 60);
648     normalize_pair(day, hour, 24);
649     return normalize_date(year, month, day);
650 }
651 
652 /* ---------------------------------------------------------------------------
653  * Basic object allocation:  tp_alloc implementations.  These allocate
654  * Python objects of the right size and type, and do the Python object-
655  * initialization bit.  If there's not enough memory, they return NULL after
656  * setting MemoryError.  All data members remain uninitialized trash.
657  *
658  * We abuse the tp_alloc "nitems" argument to communicate whether a tzinfo
659  * member is needed.  This is ugly, imprecise, and possibly insecure.
660  * tp_basicsize for the time and datetime types is set to the size of the
661  * struct that has room for the tzinfo member, so subclasses in Python will
662  * allocate enough space for a tzinfo member whether or not one is actually
663  * needed.  That's the "ugly and imprecise" parts.  The "possibly insecure"
664  * part is that PyType_GenericAlloc() (which subclasses in Python end up
665  * using) just happens today to effectively ignore the nitems argument
666  * when tp_itemsize is 0, which it is for these type objects.  If that
667  * changes, perhaps the callers of tp_alloc slots in this file should
668  * be changed to force a 0 nitems argument unless the type being allocated
669  * is a base type implemented in this file (so that tp_alloc is time_alloc
670  * or datetime_alloc below, which know about the nitems abuse).
671  */
672 
673 static PyObject *
time_alloc(PyTypeObject * type,Py_ssize_t aware)674 time_alloc(PyTypeObject *type, Py_ssize_t aware)
675 {
676     size_t size = aware ? sizeof(PyDateTime_Time) : sizeof(_PyDateTime_BaseTime);
677     PyObject *self = (PyObject *)PyObject_Malloc(size);
678     if (self == NULL) {
679         return PyErr_NoMemory();
680     }
681     _PyObject_Init(self, type);
682     return self;
683 }
684 
685 static PyObject *
datetime_alloc(PyTypeObject * type,Py_ssize_t aware)686 datetime_alloc(PyTypeObject *type, Py_ssize_t aware)
687 {
688     size_t size = aware ? sizeof(PyDateTime_DateTime) : sizeof(_PyDateTime_BaseDateTime);
689     PyObject *self = (PyObject *)PyObject_Malloc(size);
690     if (self == NULL) {
691         return PyErr_NoMemory();
692     }
693     _PyObject_Init(self, type);
694     return self;
695 }
696 
697 /* ---------------------------------------------------------------------------
698  * Helpers for setting object fields.  These work on pointers to the
699  * appropriate base class.
700  */
701 
702 /* For date and datetime. */
703 static void
set_date_fields(PyDateTime_Date * self,int y,int m,int d)704 set_date_fields(PyDateTime_Date *self, int y, int m, int d)
705 {
706     self->hashcode = -1;
707     SET_YEAR(self, y);
708     SET_MONTH(self, m);
709     SET_DAY(self, d);
710 }
711 
712 /* ---------------------------------------------------------------------------
713  * String parsing utilities and helper functions
714  */
715 
716 static unsigned char
is_digit(const char c)717 is_digit(const char c) {
718     return ((unsigned int)(c - '0')) < 10;
719 }
720 
721 static const char *
parse_digits(const char * ptr,int * var,size_t num_digits)722 parse_digits(const char *ptr, int *var, size_t num_digits)
723 {
724     for (size_t i = 0; i < num_digits; ++i) {
725         unsigned int tmp = (unsigned int)(*(ptr++) - '0');
726         if (tmp > 9) {
727             return NULL;
728         }
729         *var *= 10;
730         *var += (signed int)tmp;
731     }
732 
733     return ptr;
734 }
735 
736 static int
parse_isoformat_date(const char * dtstr,const size_t len,int * year,int * month,int * day)737 parse_isoformat_date(const char *dtstr, const size_t len, int *year, int *month, int *day)
738 {
739     /* Parse the date components of the result of date.isoformat()
740      *
741      *  Return codes:
742      *       0:  Success
743      *      -1:  Failed to parse date component
744      *      -2:  Inconsistent date separator usage
745      *      -3:  Failed to parse ISO week.
746      *      -4:  Failed to parse ISO day.
747      *      -5, -6: Failure in iso_to_ymd
748      */
749     const char *p = dtstr;
750     p = parse_digits(p, year, 4);
751     if (NULL == p) {
752         return -1;
753     }
754 
755     const unsigned char uses_separator = (*p == '-');
756     if (uses_separator) {
757         ++p;
758     }
759 
760     if(*p == 'W') {
761         // This is an isocalendar-style date string
762         p++;
763         int iso_week = 0;
764         int iso_day = 0;
765 
766         p = parse_digits(p, &iso_week, 2);
767         if (NULL == p) {
768             return -3;
769         }
770 
771         assert(p > dtstr);
772         if ((size_t)(p - dtstr) < len) {
773             if (uses_separator && *(p++) != '-') {
774                 return -2;
775             }
776 
777             p = parse_digits(p, &iso_day, 1);
778             if (NULL == p) {
779                 return -4;
780             }
781         } else {
782             iso_day = 1;
783         }
784 
785         int rv = iso_to_ymd(*year, iso_week, iso_day, year, month, day);
786         if (rv) {
787             return -3 + rv;
788         } else {
789             return 0;
790         }
791     }
792 
793     p = parse_digits(p, month, 2);
794     if (NULL == p) {
795         return -1;
796     }
797 
798     if (uses_separator && *(p++) != '-') {
799         return -2;
800     }
801     p = parse_digits(p, day, 2);
802     if (p == NULL) {
803         return -1;
804     }
805     return 0;
806 }
807 
808 static int
parse_hh_mm_ss_ff(const char * tstr,const char * tstr_end,int * hour,int * minute,int * second,int * microsecond)809 parse_hh_mm_ss_ff(const char *tstr, const char *tstr_end, int *hour,
810                   int *minute, int *second, int *microsecond)
811 {
812     *hour = *minute = *second = *microsecond = 0;
813     const char *p = tstr;
814     const char *p_end = tstr_end;
815     int *vals[3] = {hour, minute, second};
816     // This is initialized to satisfy an erroneous compiler warning.
817     unsigned char has_separator = 1;
818 
819     // Parse [HH[:?MM[:?SS]]]
820     for (size_t i = 0; i < 3; ++i) {
821         p = parse_digits(p, vals[i], 2);
822         if (NULL == p) {
823             return -3;
824         }
825 
826         char c = *(p++);
827         if (i == 0) {
828             has_separator = (c == ':');
829         }
830 
831         if (p >= p_end) {
832             return c != '\0';
833         }
834         else if (has_separator && (c == ':')) {
835             continue;
836         }
837         else if (c == '.' || c == ',') {
838             break;
839         } else if (!has_separator) {
840             --p;
841         } else {
842             return -4;  // Malformed time separator
843         }
844     }
845 
846     // Parse fractional components
847     size_t len_remains = p_end - p;
848     size_t to_parse = len_remains;
849     if (len_remains >= 6) {
850         to_parse = 6;
851     }
852 
853     p = parse_digits(p, microsecond, to_parse);
854     if (NULL == p) {
855         return -3;
856     }
857 
858     static int correction[] = {
859         100000, 10000, 1000, 100, 10
860     };
861 
862     if (to_parse < 6) {
863         *microsecond *= correction[to_parse-1];
864     }
865 
866     while (is_digit(*p)){
867         ++p; // skip truncated digits
868     }
869 
870     // Return 1 if it's not the end of the string
871     return *p != '\0';
872 }
873 
874 static int
parse_isoformat_time(const char * dtstr,size_t dtlen,int * hour,int * minute,int * second,int * microsecond,int * tzoffset,int * tzmicrosecond)875 parse_isoformat_time(const char *dtstr, size_t dtlen, int *hour, int *minute,
876                      int *second, int *microsecond, int *tzoffset,
877                      int *tzmicrosecond)
878 {
879     // Parse the time portion of a datetime.isoformat() string
880     //
881     // Return codes:
882     //      0:  Success (no tzoffset)
883     //      1:  Success (with tzoffset)
884     //     -3:  Failed to parse time component
885     //     -4:  Failed to parse time separator
886     //     -5:  Malformed timezone string
887 
888     const char *p = dtstr;
889     const char *p_end = dtstr + dtlen;
890 
891     const char *tzinfo_pos = p;
892     do {
893         if (*tzinfo_pos == 'Z' || *tzinfo_pos == '+' || *tzinfo_pos == '-') {
894             break;
895         }
896     } while (++tzinfo_pos < p_end);
897 
898     int rv = parse_hh_mm_ss_ff(dtstr, tzinfo_pos, hour, minute, second,
899                                microsecond);
900 
901     if (rv < 0) {
902         return rv;
903     }
904     else if (tzinfo_pos == p_end) {
905         // We know that there's no time zone, so if there's stuff at the
906         // end of the string it's an error.
907         if (rv == 1) {
908             return -5;
909         }
910         else {
911             return 0;
912         }
913     }
914 
915     // Special case UTC / Zulu time.
916     if (*tzinfo_pos == 'Z') {
917         *tzoffset = 0;
918         *tzmicrosecond = 0;
919 
920         if (*(tzinfo_pos + 1) != '\0') {
921             return -5;
922         } else {
923             return 1;
924         }
925     }
926 
927     int tzsign = (*tzinfo_pos == '-') ? -1 : 1;
928     tzinfo_pos++;
929     int tzhour = 0, tzminute = 0, tzsecond = 0;
930     rv = parse_hh_mm_ss_ff(tzinfo_pos, p_end, &tzhour, &tzminute, &tzsecond,
931                            tzmicrosecond);
932 
933     *tzoffset = tzsign * ((tzhour * 3600) + (tzminute * 60) + tzsecond);
934     *tzmicrosecond *= tzsign;
935 
936     return rv ? -5 : 1;
937 }
938 
939 /* ---------------------------------------------------------------------------
940  * Create various objects, mostly without range checking.
941  */
942 
943 /* Create a date instance with no range checking. */
944 static PyObject *
new_date_ex(int year,int month,int day,PyTypeObject * type)945 new_date_ex(int year, int month, int day, PyTypeObject *type)
946 {
947     PyDateTime_Date *self;
948 
949     if (check_date_args(year, month, day) < 0) {
950         return NULL;
951     }
952 
953     self = (PyDateTime_Date *)(type->tp_alloc(type, 0));
954     if (self != NULL)
955         set_date_fields(self, year, month, day);
956     return (PyObject *)self;
957 }
958 
959 #define new_date(year, month, day) \
960     new_date_ex(year, month, day, &PyDateTime_DateType)
961 
962 // Forward declaration
963 static PyObject *
964 new_datetime_ex(int, int, int, int, int, int, int, PyObject *, PyTypeObject *);
965 
966 /* Create date instance with no range checking, or call subclass constructor */
967 static PyObject *
new_date_subclass_ex(int year,int month,int day,PyObject * cls)968 new_date_subclass_ex(int year, int month, int day, PyObject *cls)
969 {
970     PyObject *result;
971     // We have "fast path" constructors for two subclasses: date and datetime
972     if ((PyTypeObject *)cls == &PyDateTime_DateType) {
973         result = new_date_ex(year, month, day, (PyTypeObject *)cls);
974     }
975     else if ((PyTypeObject *)cls == &PyDateTime_DateTimeType) {
976         result = new_datetime_ex(year, month, day, 0, 0, 0, 0, Py_None,
977                                  (PyTypeObject *)cls);
978     }
979     else {
980         result = PyObject_CallFunction(cls, "iii", year, month, day);
981     }
982 
983     return result;
984 }
985 
986 /* Create a datetime instance with no range checking. */
987 static PyObject *
new_datetime_ex2(int year,int month,int day,int hour,int minute,int second,int usecond,PyObject * tzinfo,int fold,PyTypeObject * type)988 new_datetime_ex2(int year, int month, int day, int hour, int minute,
989                  int second, int usecond, PyObject *tzinfo, int fold, PyTypeObject *type)
990 {
991     PyDateTime_DateTime *self;
992     char aware = tzinfo != Py_None;
993 
994     if (check_date_args(year, month, day) < 0) {
995         return NULL;
996     }
997     if (check_time_args(hour, minute, second, usecond, fold) < 0) {
998         return NULL;
999     }
1000     if (check_tzinfo_subclass(tzinfo) < 0) {
1001         return NULL;
1002     }
1003 
1004     self = (PyDateTime_DateTime *) (type->tp_alloc(type, aware));
1005     if (self != NULL) {
1006         self->hastzinfo = aware;
1007         set_date_fields((PyDateTime_Date *)self, year, month, day);
1008         DATE_SET_HOUR(self, hour);
1009         DATE_SET_MINUTE(self, minute);
1010         DATE_SET_SECOND(self, second);
1011         DATE_SET_MICROSECOND(self, usecond);
1012         if (aware) {
1013             Py_INCREF(tzinfo);
1014             self->tzinfo = tzinfo;
1015         }
1016         DATE_SET_FOLD(self, fold);
1017     }
1018     return (PyObject *)self;
1019 }
1020 
1021 static PyObject *
new_datetime_ex(int year,int month,int day,int hour,int minute,int second,int usecond,PyObject * tzinfo,PyTypeObject * type)1022 new_datetime_ex(int year, int month, int day, int hour, int minute,
1023                 int second, int usecond, PyObject *tzinfo, PyTypeObject *type)
1024 {
1025     return new_datetime_ex2(year, month, day, hour, minute, second, usecond,
1026                             tzinfo, 0, type);
1027 }
1028 
1029 #define new_datetime(y, m, d, hh, mm, ss, us, tzinfo, fold) \
1030     new_datetime_ex2(y, m, d, hh, mm, ss, us, tzinfo, fold, \
1031                     &PyDateTime_DateTimeType)
1032 
1033 static PyObject *
new_datetime_subclass_fold_ex(int year,int month,int day,int hour,int minute,int second,int usecond,PyObject * tzinfo,int fold,PyObject * cls)1034 new_datetime_subclass_fold_ex(int year, int month, int day, int hour, int minute,
1035                               int second, int usecond, PyObject *tzinfo,
1036                               int fold, PyObject *cls) {
1037     PyObject* dt;
1038     if ((PyTypeObject*)cls == &PyDateTime_DateTimeType) {
1039         // Use the fast path constructor
1040         dt = new_datetime(year, month, day, hour, minute, second, usecond,
1041                           tzinfo, fold);
1042     } else {
1043         // Subclass
1044         dt = PyObject_CallFunction(cls, "iiiiiiiO",
1045                                    year,
1046                                    month,
1047                                    day,
1048                                    hour,
1049                                    minute,
1050                                    second,
1051                                    usecond,
1052                                    tzinfo);
1053     }
1054 
1055     return dt;
1056 }
1057 
1058 static PyObject *
new_datetime_subclass_ex(int year,int month,int day,int hour,int minute,int second,int usecond,PyObject * tzinfo,PyObject * cls)1059 new_datetime_subclass_ex(int year, int month, int day, int hour, int minute,
1060                               int second, int usecond, PyObject *tzinfo,
1061                               PyObject *cls) {
1062     return new_datetime_subclass_fold_ex(year, month, day, hour, minute,
1063                                          second, usecond, tzinfo, 0,
1064                                          cls);
1065 }
1066 
1067 /* Create a time instance with no range checking. */
1068 static PyObject *
new_time_ex2(int hour,int minute,int second,int usecond,PyObject * tzinfo,int fold,PyTypeObject * type)1069 new_time_ex2(int hour, int minute, int second, int usecond,
1070              PyObject *tzinfo, int fold, PyTypeObject *type)
1071 {
1072     PyDateTime_Time *self;
1073     char aware = tzinfo != Py_None;
1074 
1075     if (check_time_args(hour, minute, second, usecond, fold) < 0) {
1076         return NULL;
1077     }
1078     if (check_tzinfo_subclass(tzinfo) < 0) {
1079         return NULL;
1080     }
1081 
1082     self = (PyDateTime_Time *) (type->tp_alloc(type, aware));
1083     if (self != NULL) {
1084         self->hastzinfo = aware;
1085         self->hashcode = -1;
1086         TIME_SET_HOUR(self, hour);
1087         TIME_SET_MINUTE(self, minute);
1088         TIME_SET_SECOND(self, second);
1089         TIME_SET_MICROSECOND(self, usecond);
1090         if (aware) {
1091             Py_INCREF(tzinfo);
1092             self->tzinfo = tzinfo;
1093         }
1094         TIME_SET_FOLD(self, fold);
1095     }
1096     return (PyObject *)self;
1097 }
1098 
1099 static PyObject *
new_time_ex(int hour,int minute,int second,int usecond,PyObject * tzinfo,PyTypeObject * type)1100 new_time_ex(int hour, int minute, int second, int usecond,
1101             PyObject *tzinfo, PyTypeObject *type)
1102 {
1103     return new_time_ex2(hour, minute, second, usecond, tzinfo, 0, type);
1104 }
1105 
1106 #define new_time(hh, mm, ss, us, tzinfo, fold)                       \
1107     new_time_ex2(hh, mm, ss, us, tzinfo, fold, &PyDateTime_TimeType)
1108 
1109 /* Create a timedelta instance.  Normalize the members iff normalize is
1110  * true.  Passing false is a speed optimization, if you know for sure
1111  * that seconds and microseconds are already in their proper ranges.  In any
1112  * case, raises OverflowError and returns NULL if the normalized days is out
1113  * of range.
1114  */
1115 static PyObject *
new_delta_ex(int days,int seconds,int microseconds,int normalize,PyTypeObject * type)1116 new_delta_ex(int days, int seconds, int microseconds, int normalize,
1117              PyTypeObject *type)
1118 {
1119     PyDateTime_Delta *self;
1120 
1121     if (normalize)
1122         normalize_d_s_us(&days, &seconds, &microseconds);
1123     assert(0 <= seconds && seconds < 24*3600);
1124     assert(0 <= microseconds && microseconds < 1000000);
1125 
1126     if (check_delta_day_range(days) < 0)
1127         return NULL;
1128 
1129     self = (PyDateTime_Delta *) (type->tp_alloc(type, 0));
1130     if (self != NULL) {
1131         self->hashcode = -1;
1132         SET_TD_DAYS(self, days);
1133         SET_TD_SECONDS(self, seconds);
1134         SET_TD_MICROSECONDS(self, microseconds);
1135     }
1136     return (PyObject *) self;
1137 }
1138 
1139 #define new_delta(d, s, us, normalize)  \
1140     new_delta_ex(d, s, us, normalize, &PyDateTime_DeltaType)
1141 
1142 
1143 typedef struct
1144 {
1145     PyObject_HEAD
1146     PyObject *offset;
1147     PyObject *name;
1148 } PyDateTime_TimeZone;
1149 
1150 /* The interned UTC timezone instance */
1151 static PyObject *PyDateTime_TimeZone_UTC;
1152 /* The interned Epoch datetime instance */
1153 static PyObject *PyDateTime_Epoch;
1154 
1155 /* Create new timezone instance checking offset range.  This
1156    function does not check the name argument.  Caller must assure
1157    that offset is a timedelta instance and name is either NULL
1158    or a unicode object. */
1159 static PyObject *
create_timezone(PyObject * offset,PyObject * name)1160 create_timezone(PyObject *offset, PyObject *name)
1161 {
1162     PyDateTime_TimeZone *self;
1163     PyTypeObject *type = &PyDateTime_TimeZoneType;
1164 
1165     assert(offset != NULL);
1166     assert(PyDelta_Check(offset));
1167     assert(name == NULL || PyUnicode_Check(name));
1168 
1169     self = (PyDateTime_TimeZone *)(type->tp_alloc(type, 0));
1170     if (self == NULL) {
1171         return NULL;
1172     }
1173     Py_INCREF(offset);
1174     self->offset = offset;
1175     Py_XINCREF(name);
1176     self->name = name;
1177     return (PyObject *)self;
1178 }
1179 
1180 static int delta_bool(PyDateTime_Delta *self);
1181 
1182 static PyObject *
new_timezone(PyObject * offset,PyObject * name)1183 new_timezone(PyObject *offset, PyObject *name)
1184 {
1185     assert(offset != NULL);
1186     assert(PyDelta_Check(offset));
1187     assert(name == NULL || PyUnicode_Check(name));
1188 
1189     if (name == NULL && delta_bool((PyDateTime_Delta *)offset) == 0) {
1190         Py_INCREF(PyDateTime_TimeZone_UTC);
1191         return PyDateTime_TimeZone_UTC;
1192     }
1193     if ((GET_TD_DAYS(offset) == -1 &&
1194             GET_TD_SECONDS(offset) == 0 &&
1195             GET_TD_MICROSECONDS(offset) < 1) ||
1196         GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) {
1197         PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
1198                      " strictly between -timedelta(hours=24) and"
1199                      " timedelta(hours=24),"
1200                      " not %R.", offset);
1201         return NULL;
1202     }
1203 
1204     return create_timezone(offset, name);
1205 }
1206 
1207 /* ---------------------------------------------------------------------------
1208  * tzinfo helpers.
1209  */
1210 
1211 /* Ensure that p is None or of a tzinfo subclass.  Return 0 if OK; if not
1212  * raise TypeError and return -1.
1213  */
1214 static int
check_tzinfo_subclass(PyObject * p)1215 check_tzinfo_subclass(PyObject *p)
1216 {
1217     if (p == Py_None || PyTZInfo_Check(p))
1218         return 0;
1219     PyErr_Format(PyExc_TypeError,
1220                  "tzinfo argument must be None or of a tzinfo subclass, "
1221                  "not type '%s'",
1222                  Py_TYPE(p)->tp_name);
1223     return -1;
1224 }
1225 
1226 /* If self has a tzinfo member, return a BORROWED reference to it.  Else
1227  * return NULL, which is NOT AN ERROR.  There are no error returns here,
1228  * and the caller must not decref the result.
1229  */
1230 static PyObject *
get_tzinfo_member(PyObject * self)1231 get_tzinfo_member(PyObject *self)
1232 {
1233     PyObject *tzinfo = NULL;
1234 
1235     if (PyDateTime_Check(self) && HASTZINFO(self))
1236         tzinfo = ((PyDateTime_DateTime *)self)->tzinfo;
1237     else if (PyTime_Check(self) && HASTZINFO(self))
1238         tzinfo = ((PyDateTime_Time *)self)->tzinfo;
1239 
1240     return tzinfo;
1241 }
1242 
1243 /* Call getattr(tzinfo, name)(tzinfoarg), and check the result.  tzinfo must
1244  * be an instance of the tzinfo class.  If the method returns None, this
1245  * returns None.  If the method doesn't return None or timedelta, TypeError is
1246  * raised and this returns NULL.  If it returns a timedelta and the value is
1247  * out of range or isn't a whole number of minutes, ValueError is raised and
1248  * this returns NULL.  Else result is returned.
1249  */
1250 static PyObject *
call_tzinfo_method(PyObject * tzinfo,const char * name,PyObject * tzinfoarg)1251 call_tzinfo_method(PyObject *tzinfo, const char *name, PyObject *tzinfoarg)
1252 {
1253     PyObject *offset;
1254 
1255     assert(tzinfo != NULL);
1256     assert(PyTZInfo_Check(tzinfo) || tzinfo == Py_None);
1257     assert(tzinfoarg != NULL);
1258 
1259     if (tzinfo == Py_None)
1260         Py_RETURN_NONE;
1261     offset = PyObject_CallMethod(tzinfo, name, "O", tzinfoarg);
1262     if (offset == Py_None || offset == NULL)
1263         return offset;
1264     if (PyDelta_Check(offset)) {
1265         if ((GET_TD_DAYS(offset) == -1 &&
1266                 GET_TD_SECONDS(offset) == 0 &&
1267                 GET_TD_MICROSECONDS(offset) < 1) ||
1268             GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) {
1269             Py_DECREF(offset);
1270             PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
1271                          " strictly between -timedelta(hours=24) and"
1272                          " timedelta(hours=24).");
1273             return NULL;
1274         }
1275     }
1276     else {
1277         PyErr_Format(PyExc_TypeError,
1278                      "tzinfo.%s() must return None or "
1279                      "timedelta, not '%.200s'",
1280                      name, Py_TYPE(offset)->tp_name);
1281         Py_DECREF(offset);
1282         return NULL;
1283     }
1284 
1285     return offset;
1286 }
1287 
1288 /* Call tzinfo.utcoffset(tzinfoarg), and extract an integer from the
1289  * result.  tzinfo must be an instance of the tzinfo class.  If utcoffset()
1290  * returns None, call_utcoffset returns 0 and sets *none to 1.  If uctoffset()
1291  * doesn't return None or timedelta, TypeError is raised and this returns -1.
1292  * If utcoffset() returns an out of range timedelta,
1293  * ValueError is raised and this returns -1.  Else *none is
1294  * set to 0 and the offset is returned (as timedelta, positive east of UTC).
1295  */
1296 static PyObject *
call_utcoffset(PyObject * tzinfo,PyObject * tzinfoarg)1297 call_utcoffset(PyObject *tzinfo, PyObject *tzinfoarg)
1298 {
1299     return call_tzinfo_method(tzinfo, "utcoffset", tzinfoarg);
1300 }
1301 
1302 /* Call tzinfo.dst(tzinfoarg), and extract an integer from the
1303  * result.  tzinfo must be an instance of the tzinfo class.  If dst()
1304  * returns None, call_dst returns 0 and sets *none to 1.  If dst()
1305  * doesn't return None or timedelta, TypeError is raised and this
1306  * returns -1.  If dst() returns an invalid timedelta for a UTC offset,
1307  * ValueError is raised and this returns -1.  Else *none is set to 0 and
1308  * the offset is returned (as timedelta, positive east of UTC).
1309  */
1310 static PyObject *
call_dst(PyObject * tzinfo,PyObject * tzinfoarg)1311 call_dst(PyObject *tzinfo, PyObject *tzinfoarg)
1312 {
1313     return call_tzinfo_method(tzinfo, "dst", tzinfoarg);
1314 }
1315 
1316 /* Call tzinfo.tzname(tzinfoarg), and return the result.  tzinfo must be
1317  * an instance of the tzinfo class or None.  If tzinfo isn't None, and
1318  * tzname() doesn't return None or a string, TypeError is raised and this
1319  * returns NULL.  If the result is a string, we ensure it is a Unicode
1320  * string.
1321  */
1322 static PyObject *
call_tzname(PyObject * tzinfo,PyObject * tzinfoarg)1323 call_tzname(PyObject *tzinfo, PyObject *tzinfoarg)
1324 {
1325     PyObject *result;
1326     _Py_IDENTIFIER(tzname);
1327 
1328     assert(tzinfo != NULL);
1329     assert(check_tzinfo_subclass(tzinfo) >= 0);
1330     assert(tzinfoarg != NULL);
1331 
1332     if (tzinfo == Py_None)
1333         Py_RETURN_NONE;
1334 
1335     result = _PyObject_CallMethodIdOneArg(tzinfo, &PyId_tzname, tzinfoarg);
1336 
1337     if (result == NULL || result == Py_None)
1338         return result;
1339 
1340     if (!PyUnicode_Check(result)) {
1341         PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must "
1342                      "return None or a string, not '%s'",
1343                      Py_TYPE(result)->tp_name);
1344         Py_DECREF(result);
1345         result = NULL;
1346     }
1347 
1348     return result;
1349 }
1350 
1351 /* repr is like "someclass(arg1, arg2)".  If tzinfo isn't None,
1352  * stuff
1353  *     ", tzinfo=" + repr(tzinfo)
1354  * before the closing ")".
1355  */
1356 static PyObject *
append_keyword_tzinfo(PyObject * repr,PyObject * tzinfo)1357 append_keyword_tzinfo(PyObject *repr, PyObject *tzinfo)
1358 {
1359     PyObject *temp;
1360 
1361     assert(PyUnicode_Check(repr));
1362     assert(tzinfo);
1363     if (tzinfo == Py_None)
1364         return repr;
1365     /* Get rid of the trailing ')'. */
1366     assert(PyUnicode_READ_CHAR(repr, PyUnicode_GET_LENGTH(repr)-1) == ')');
1367     temp = PyUnicode_Substring(repr, 0, PyUnicode_GET_LENGTH(repr) - 1);
1368     Py_DECREF(repr);
1369     if (temp == NULL)
1370         return NULL;
1371     repr = PyUnicode_FromFormat("%U, tzinfo=%R)", temp, tzinfo);
1372     Py_DECREF(temp);
1373     return repr;
1374 }
1375 
1376 /* repr is like "someclass(arg1, arg2)".  If fold isn't 0,
1377  * stuff
1378  *     ", fold=" + repr(tzinfo)
1379  * before the closing ")".
1380  */
1381 static PyObject *
append_keyword_fold(PyObject * repr,int fold)1382 append_keyword_fold(PyObject *repr, int fold)
1383 {
1384     PyObject *temp;
1385 
1386     assert(PyUnicode_Check(repr));
1387     if (fold == 0)
1388         return repr;
1389     /* Get rid of the trailing ')'. */
1390     assert(PyUnicode_READ_CHAR(repr, PyUnicode_GET_LENGTH(repr)-1) == ')');
1391     temp = PyUnicode_Substring(repr, 0, PyUnicode_GET_LENGTH(repr) - 1);
1392     Py_DECREF(repr);
1393     if (temp == NULL)
1394         return NULL;
1395     repr = PyUnicode_FromFormat("%U, fold=%d)", temp, fold);
1396     Py_DECREF(temp);
1397     return repr;
1398 }
1399 
1400 static inline PyObject *
tzinfo_from_isoformat_results(int rv,int tzoffset,int tz_useconds)1401 tzinfo_from_isoformat_results(int rv, int tzoffset, int tz_useconds)
1402 {
1403     PyObject *tzinfo;
1404     if (rv == 1) {
1405         // Create a timezone from offset in seconds (0 returns UTC)
1406         if (tzoffset == 0) {
1407             Py_INCREF(PyDateTime_TimeZone_UTC);
1408             return PyDateTime_TimeZone_UTC;
1409         }
1410 
1411         PyObject *delta = new_delta(0, tzoffset, tz_useconds, 1);
1412         if (delta == NULL) {
1413             return NULL;
1414         }
1415         tzinfo = new_timezone(delta, NULL);
1416         Py_DECREF(delta);
1417     }
1418     else {
1419         tzinfo = Py_None;
1420         Py_INCREF(Py_None);
1421     }
1422 
1423     return tzinfo;
1424 }
1425 
1426 /* ---------------------------------------------------------------------------
1427  * String format helpers.
1428  */
1429 
1430 static PyObject *
format_ctime(PyDateTime_Date * date,int hours,int minutes,int seconds)1431 format_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds)
1432 {
1433     static const char * const DayNames[] = {
1434         "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
1435     };
1436     static const char * const MonthNames[] = {
1437         "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1438         "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
1439     };
1440 
1441     int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date));
1442 
1443     return PyUnicode_FromFormat("%s %s %2d %02d:%02d:%02d %04d",
1444                                 DayNames[wday], MonthNames[GET_MONTH(date)-1],
1445                                 GET_DAY(date), hours, minutes, seconds,
1446                                 GET_YEAR(date));
1447 }
1448 
1449 static PyObject *delta_negative(PyDateTime_Delta *self);
1450 
1451 /* Add formatted UTC offset string to buf.  buf has no more than
1452  * buflen bytes remaining.  The UTC offset is gotten by calling
1453  * tzinfo.uctoffset(tzinfoarg).  If that returns None, \0 is stored into
1454  * *buf, and that's all.  Else the returned value is checked for sanity (an
1455  * integer in range), and if that's OK it's converted to an hours & minutes
1456  * string of the form
1457  *   sign HH sep MM [sep SS [. UUUUUU]]
1458  * Returns 0 if everything is OK.  If the return value from utcoffset() is
1459  * bogus, an appropriate exception is set and -1 is returned.
1460  */
1461 static int
format_utcoffset(char * buf,size_t buflen,const char * sep,PyObject * tzinfo,PyObject * tzinfoarg)1462 format_utcoffset(char *buf, size_t buflen, const char *sep,
1463                 PyObject *tzinfo, PyObject *tzinfoarg)
1464 {
1465     PyObject *offset;
1466     int hours, minutes, seconds, microseconds;
1467     char sign;
1468 
1469     assert(buflen >= 1);
1470 
1471     offset = call_utcoffset(tzinfo, tzinfoarg);
1472     if (offset == NULL)
1473         return -1;
1474     if (offset == Py_None) {
1475         Py_DECREF(offset);
1476         *buf = '\0';
1477         return 0;
1478     }
1479     /* Offset is normalized, so it is negative if days < 0 */
1480     if (GET_TD_DAYS(offset) < 0) {
1481         sign = '-';
1482         Py_SETREF(offset, delta_negative((PyDateTime_Delta *)offset));
1483         if (offset == NULL)
1484             return -1;
1485     }
1486     else {
1487         sign = '+';
1488     }
1489     /* Offset is not negative here. */
1490     microseconds = GET_TD_MICROSECONDS(offset);
1491     seconds = GET_TD_SECONDS(offset);
1492     Py_DECREF(offset);
1493     minutes = divmod(seconds, 60, &seconds);
1494     hours = divmod(minutes, 60, &minutes);
1495     if (microseconds) {
1496         PyOS_snprintf(buf, buflen, "%c%02d%s%02d%s%02d.%06d", sign,
1497                       hours, sep, minutes, sep, seconds, microseconds);
1498         return 0;
1499     }
1500     if (seconds) {
1501         PyOS_snprintf(buf, buflen, "%c%02d%s%02d%s%02d", sign, hours,
1502                       sep, minutes, sep, seconds);
1503         return 0;
1504     }
1505     PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
1506     return 0;
1507 }
1508 
1509 static PyObject *
make_Zreplacement(PyObject * object,PyObject * tzinfoarg)1510 make_Zreplacement(PyObject *object, PyObject *tzinfoarg)
1511 {
1512     PyObject *temp;
1513     PyObject *tzinfo = get_tzinfo_member(object);
1514     PyObject *Zreplacement = PyUnicode_FromStringAndSize(NULL, 0);
1515     _Py_IDENTIFIER(replace);
1516 
1517     if (Zreplacement == NULL)
1518         return NULL;
1519     if (tzinfo == Py_None || tzinfo == NULL)
1520         return Zreplacement;
1521 
1522     assert(tzinfoarg != NULL);
1523     temp = call_tzname(tzinfo, tzinfoarg);
1524     if (temp == NULL)
1525         goto Error;
1526     if (temp == Py_None) {
1527         Py_DECREF(temp);
1528         return Zreplacement;
1529     }
1530 
1531     assert(PyUnicode_Check(temp));
1532     /* Since the tzname is getting stuffed into the
1533      * format, we have to double any % signs so that
1534      * strftime doesn't treat them as format codes.
1535      */
1536     Py_DECREF(Zreplacement);
1537     Zreplacement = _PyObject_CallMethodId(temp, &PyId_replace, "ss", "%", "%%");
1538     Py_DECREF(temp);
1539     if (Zreplacement == NULL)
1540         return NULL;
1541     if (!PyUnicode_Check(Zreplacement)) {
1542         PyErr_SetString(PyExc_TypeError,
1543                         "tzname.replace() did not return a string");
1544         goto Error;
1545     }
1546     return Zreplacement;
1547 
1548   Error:
1549     Py_DECREF(Zreplacement);
1550     return NULL;
1551 }
1552 
1553 static PyObject *
make_freplacement(PyObject * object)1554 make_freplacement(PyObject *object)
1555 {
1556     char freplacement[64];
1557     if (PyTime_Check(object))
1558         sprintf(freplacement, "%06d", TIME_GET_MICROSECOND(object));
1559     else if (PyDateTime_Check(object))
1560         sprintf(freplacement, "%06d", DATE_GET_MICROSECOND(object));
1561     else
1562         sprintf(freplacement, "%06d", 0);
1563 
1564     return PyBytes_FromStringAndSize(freplacement, strlen(freplacement));
1565 }
1566 
1567 /* I sure don't want to reproduce the strftime code from the time module,
1568  * so this imports the module and calls it.  All the hair is due to
1569  * giving special meanings to the %z, %Z and %f format codes via a
1570  * preprocessing step on the format string.
1571  * tzinfoarg is the argument to pass to the object's tzinfo method, if
1572  * needed.
1573  */
1574 static PyObject *
wrap_strftime(PyObject * object,PyObject * format,PyObject * timetuple,PyObject * tzinfoarg)1575 wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
1576               PyObject *tzinfoarg)
1577 {
1578     PyObject *result = NULL;            /* guilty until proved innocent */
1579 
1580     PyObject *zreplacement = NULL;      /* py string, replacement for %z */
1581     PyObject *Zreplacement = NULL;      /* py string, replacement for %Z */
1582     PyObject *freplacement = NULL;      /* py string, replacement for %f */
1583 
1584     const char *pin;            /* pointer to next char in input format */
1585     Py_ssize_t flen;            /* length of input format */
1586     char ch;                    /* next char in input format */
1587 
1588     PyObject *newfmt = NULL;            /* py string, the output format */
1589     char *pnew;         /* pointer to available byte in output format */
1590     size_t totalnew;            /* number bytes total in output format buffer,
1591                                exclusive of trailing \0 */
1592     size_t usednew;     /* number bytes used so far in output format buffer */
1593 
1594     const char *ptoappend;      /* ptr to string to append to output buffer */
1595     Py_ssize_t ntoappend;       /* # of bytes to append to output buffer */
1596 
1597     assert(object && format && timetuple);
1598     assert(PyUnicode_Check(format));
1599     /* Convert the input format to a C string and size */
1600     pin = PyUnicode_AsUTF8AndSize(format, &flen);
1601     if (!pin)
1602         return NULL;
1603 
1604     /* Scan the input format, looking for %z/%Z/%f escapes, building
1605      * a new format.  Since computing the replacements for those codes
1606      * is expensive, don't unless they're actually used.
1607      */
1608     if (flen > INT_MAX - 1) {
1609         PyErr_NoMemory();
1610         goto Done;
1611     }
1612 
1613     totalnew = flen + 1;        /* realistic if no %z/%Z */
1614     newfmt = PyBytes_FromStringAndSize(NULL, totalnew);
1615     if (newfmt == NULL) goto Done;
1616     pnew = PyBytes_AsString(newfmt);
1617     usednew = 0;
1618 
1619     while ((ch = *pin++) != '\0') {
1620         if (ch != '%') {
1621             ptoappend = pin - 1;
1622             ntoappend = 1;
1623         }
1624         else if ((ch = *pin++) == '\0') {
1625         /* Null byte follows %, copy only '%'.
1626          *
1627          * Back the pin up one char so that we catch the null check
1628          * the next time through the loop.*/
1629             pin--;
1630             ptoappend = pin - 1;
1631             ntoappend = 1;
1632         }
1633         /* A % has been seen and ch is the character after it. */
1634         else if (ch == 'z') {
1635             if (zreplacement == NULL) {
1636                 /* format utcoffset */
1637                 char buf[100];
1638                 PyObject *tzinfo = get_tzinfo_member(object);
1639                 zreplacement = PyBytes_FromStringAndSize("", 0);
1640                 if (zreplacement == NULL) goto Done;
1641                 if (tzinfo != Py_None && tzinfo != NULL) {
1642                     assert(tzinfoarg != NULL);
1643                     if (format_utcoffset(buf,
1644                                          sizeof(buf),
1645                                          "",
1646                                          tzinfo,
1647                                          tzinfoarg) < 0)
1648                         goto Done;
1649                     Py_DECREF(zreplacement);
1650                     zreplacement =
1651                       PyBytes_FromStringAndSize(buf,
1652                                                strlen(buf));
1653                     if (zreplacement == NULL)
1654                         goto Done;
1655                 }
1656             }
1657             assert(zreplacement != NULL);
1658             ptoappend = PyBytes_AS_STRING(zreplacement);
1659             ntoappend = PyBytes_GET_SIZE(zreplacement);
1660         }
1661         else if (ch == 'Z') {
1662             /* format tzname */
1663             if (Zreplacement == NULL) {
1664                 Zreplacement = make_Zreplacement(object,
1665                                                  tzinfoarg);
1666                 if (Zreplacement == NULL)
1667                     goto Done;
1668             }
1669             assert(Zreplacement != NULL);
1670             assert(PyUnicode_Check(Zreplacement));
1671             ptoappend = PyUnicode_AsUTF8AndSize(Zreplacement,
1672                                                   &ntoappend);
1673             if (ptoappend == NULL)
1674                 goto Done;
1675         }
1676         else if (ch == 'f') {
1677             /* format microseconds */
1678             if (freplacement == NULL) {
1679                 freplacement = make_freplacement(object);
1680                 if (freplacement == NULL)
1681                     goto Done;
1682             }
1683             assert(freplacement != NULL);
1684             assert(PyBytes_Check(freplacement));
1685             ptoappend = PyBytes_AS_STRING(freplacement);
1686             ntoappend = PyBytes_GET_SIZE(freplacement);
1687         }
1688         else {
1689             /* percent followed by neither z nor Z */
1690             ptoappend = pin - 2;
1691             ntoappend = 2;
1692         }
1693 
1694         /* Append the ntoappend chars starting at ptoappend to
1695          * the new format.
1696          */
1697         if (ntoappend == 0)
1698             continue;
1699         assert(ptoappend != NULL);
1700         assert(ntoappend > 0);
1701         while (usednew + ntoappend > totalnew) {
1702             if (totalnew > (PY_SSIZE_T_MAX >> 1)) { /* overflow */
1703                 PyErr_NoMemory();
1704                 goto Done;
1705             }
1706             totalnew <<= 1;
1707             if (_PyBytes_Resize(&newfmt, totalnew) < 0)
1708                 goto Done;
1709             pnew = PyBytes_AsString(newfmt) + usednew;
1710         }
1711         memcpy(pnew, ptoappend, ntoappend);
1712         pnew += ntoappend;
1713         usednew += ntoappend;
1714         assert(usednew <= totalnew);
1715     }  /* end while() */
1716 
1717     if (_PyBytes_Resize(&newfmt, usednew) < 0)
1718         goto Done;
1719     {
1720         PyObject *format;
1721         PyObject *time = PyImport_ImportModule("time");
1722 
1723         if (time == NULL)
1724             goto Done;
1725         format = PyUnicode_FromString(PyBytes_AS_STRING(newfmt));
1726         if (format != NULL) {
1727             result = _PyObject_CallMethodIdObjArgs(time, &PyId_strftime,
1728                                                    format, timetuple, NULL);
1729             Py_DECREF(format);
1730         }
1731         Py_DECREF(time);
1732     }
1733  Done:
1734     Py_XDECREF(freplacement);
1735     Py_XDECREF(zreplacement);
1736     Py_XDECREF(Zreplacement);
1737     Py_XDECREF(newfmt);
1738     return result;
1739 }
1740 
1741 /* ---------------------------------------------------------------------------
1742  * Wrap functions from the time module.  These aren't directly available
1743  * from C.  Perhaps they should be.
1744  */
1745 
1746 /* Call time.time() and return its result (a Python float). */
1747 static PyObject *
time_time(void)1748 time_time(void)
1749 {
1750     PyObject *result = NULL;
1751     PyObject *time = PyImport_ImportModule("time");
1752 
1753     if (time != NULL) {
1754         _Py_IDENTIFIER(time);
1755 
1756         result = _PyObject_CallMethodIdNoArgs(time, &PyId_time);
1757         Py_DECREF(time);
1758     }
1759     return result;
1760 }
1761 
1762 /* Build a time.struct_time.  The weekday and day number are automatically
1763  * computed from the y,m,d args.
1764  */
1765 static PyObject *
build_struct_time(int y,int m,int d,int hh,int mm,int ss,int dstflag)1766 build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1767 {
1768     PyObject *time;
1769     PyObject *result;
1770     _Py_IDENTIFIER(struct_time);
1771     PyObject *args;
1772 
1773 
1774     time = PyImport_ImportModule("time");
1775     if (time == NULL) {
1776         return NULL;
1777     }
1778 
1779     args = Py_BuildValue("iiiiiiiii",
1780                          y, m, d,
1781                          hh, mm, ss,
1782                          weekday(y, m, d),
1783                          days_before_month(y, m) + d,
1784                          dstflag);
1785     if (args == NULL) {
1786         Py_DECREF(time);
1787         return NULL;
1788     }
1789 
1790     result = _PyObject_CallMethodIdOneArg(time, &PyId_struct_time, args);
1791     Py_DECREF(time);
1792     Py_DECREF(args);
1793     return result;
1794 }
1795 
1796 /* ---------------------------------------------------------------------------
1797  * Miscellaneous helpers.
1798  */
1799 
1800 /* The comparisons here all most naturally compute a cmp()-like result.
1801  * This little helper turns that into a bool result for rich comparisons.
1802  */
1803 static PyObject *
diff_to_bool(int diff,int op)1804 diff_to_bool(int diff, int op)
1805 {
1806     Py_RETURN_RICHCOMPARE(diff, 0, op);
1807 }
1808 
1809 /* Raises a "can't compare" TypeError and returns NULL. */
1810 static PyObject *
cmperror(PyObject * a,PyObject * b)1811 cmperror(PyObject *a, PyObject *b)
1812 {
1813     PyErr_Format(PyExc_TypeError,
1814                  "can't compare %s to %s",
1815                  Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
1816     return NULL;
1817 }
1818 
1819 /* ---------------------------------------------------------------------------
1820  * Cached Python objects; these are set by the module init function.
1821  */
1822 
1823 /* Conversion factors. */
1824 static PyObject *us_per_ms = NULL;      /* 1000 */
1825 static PyObject *us_per_second = NULL;  /* 1000000 */
1826 static PyObject *us_per_minute = NULL;  /* 1e6 * 60 as Python int */
1827 static PyObject *us_per_hour = NULL;    /* 1e6 * 3600 as Python int */
1828 static PyObject *us_per_day = NULL;     /* 1e6 * 3600 * 24 as Python int */
1829 static PyObject *us_per_week = NULL;    /* 1e6*3600*24*7 as Python int */
1830 static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1831 
1832 /* ---------------------------------------------------------------------------
1833  * Class implementations.
1834  */
1835 
1836 /*
1837  * PyDateTime_Delta implementation.
1838  */
1839 
1840 /* Convert a timedelta to a number of us,
1841  *      (24*3600*self.days + self.seconds)*1000000 + self.microseconds
1842  * as a Python int.
1843  * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1844  * due to ubiquitous overflow possibilities.
1845  */
1846 static PyObject *
delta_to_microseconds(PyDateTime_Delta * self)1847 delta_to_microseconds(PyDateTime_Delta *self)
1848 {
1849     PyObject *x1 = NULL;
1850     PyObject *x2 = NULL;
1851     PyObject *x3 = NULL;
1852     PyObject *result = NULL;
1853 
1854     x1 = PyLong_FromLong(GET_TD_DAYS(self));
1855     if (x1 == NULL)
1856         goto Done;
1857     x2 = PyNumber_Multiply(x1, seconds_per_day);        /* days in seconds */
1858     if (x2 == NULL)
1859         goto Done;
1860     Py_DECREF(x1);
1861     x1 = NULL;
1862 
1863     /* x2 has days in seconds */
1864     x1 = PyLong_FromLong(GET_TD_SECONDS(self));         /* seconds */
1865     if (x1 == NULL)
1866         goto Done;
1867     x3 = PyNumber_Add(x1, x2);          /* days and seconds in seconds */
1868     if (x3 == NULL)
1869         goto Done;
1870     Py_DECREF(x1);
1871     Py_DECREF(x2);
1872     /* x1 = */ x2 = NULL;
1873 
1874     /* x3 has days+seconds in seconds */
1875     x1 = PyNumber_Multiply(x3, us_per_second);          /* us */
1876     if (x1 == NULL)
1877         goto Done;
1878     Py_DECREF(x3);
1879     x3 = NULL;
1880 
1881     /* x1 has days+seconds in us */
1882     x2 = PyLong_FromLong(GET_TD_MICROSECONDS(self));
1883     if (x2 == NULL)
1884         goto Done;
1885     result = PyNumber_Add(x1, x2);
1886     assert(result == NULL || PyLong_CheckExact(result));
1887 
1888 Done:
1889     Py_XDECREF(x1);
1890     Py_XDECREF(x2);
1891     Py_XDECREF(x3);
1892     return result;
1893 }
1894 
1895 static PyObject *
checked_divmod(PyObject * a,PyObject * b)1896 checked_divmod(PyObject *a, PyObject *b)
1897 {
1898     PyObject *result = PyNumber_Divmod(a, b);
1899     if (result != NULL) {
1900         if (!PyTuple_Check(result)) {
1901             PyErr_Format(PyExc_TypeError,
1902                          "divmod() returned non-tuple (type %.200s)",
1903                          Py_TYPE(result)->tp_name);
1904             Py_DECREF(result);
1905             return NULL;
1906         }
1907         if (PyTuple_GET_SIZE(result) != 2) {
1908             PyErr_Format(PyExc_TypeError,
1909                          "divmod() returned a tuple of size %zd",
1910                          PyTuple_GET_SIZE(result));
1911             Py_DECREF(result);
1912             return NULL;
1913         }
1914     }
1915     return result;
1916 }
1917 
1918 /* Convert a number of us (as a Python int) to a timedelta.
1919  */
1920 static PyObject *
microseconds_to_delta_ex(PyObject * pyus,PyTypeObject * type)1921 microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
1922 {
1923     int us;
1924     int s;
1925     int d;
1926 
1927     PyObject *tuple = NULL;
1928     PyObject *num = NULL;
1929     PyObject *result = NULL;
1930 
1931     tuple = checked_divmod(pyus, us_per_second);
1932     if (tuple == NULL) {
1933         goto Done;
1934     }
1935 
1936     num = PyTuple_GET_ITEM(tuple, 1);           /* us */
1937     us = _PyLong_AsInt(num);
1938     num = NULL;
1939     if (us == -1 && PyErr_Occurred()) {
1940         goto Done;
1941     }
1942     if (!(0 <= us && us < 1000000)) {
1943         goto BadDivmod;
1944     }
1945 
1946     num = PyTuple_GET_ITEM(tuple, 0);           /* leftover seconds */
1947     Py_INCREF(num);
1948     Py_DECREF(tuple);
1949 
1950     tuple = checked_divmod(num, seconds_per_day);
1951     if (tuple == NULL)
1952         goto Done;
1953     Py_DECREF(num);
1954 
1955     num = PyTuple_GET_ITEM(tuple, 1);           /* seconds */
1956     s = _PyLong_AsInt(num);
1957     num = NULL;
1958     if (s == -1 && PyErr_Occurred()) {
1959         goto Done;
1960     }
1961     if (!(0 <= s && s < 24*3600)) {
1962         goto BadDivmod;
1963     }
1964 
1965     num = PyTuple_GET_ITEM(tuple, 0);           /* leftover days */
1966     Py_INCREF(num);
1967     d = _PyLong_AsInt(num);
1968     if (d == -1 && PyErr_Occurred()) {
1969         goto Done;
1970     }
1971     result = new_delta_ex(d, s, us, 0, type);
1972 
1973 Done:
1974     Py_XDECREF(tuple);
1975     Py_XDECREF(num);
1976     return result;
1977 
1978 BadDivmod:
1979     PyErr_SetString(PyExc_TypeError,
1980                     "divmod() returned a value out of range");
1981     goto Done;
1982 }
1983 
1984 #define microseconds_to_delta(pymicros) \
1985     microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
1986 
1987 static PyObject *
multiply_int_timedelta(PyObject * intobj,PyDateTime_Delta * delta)1988 multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1989 {
1990     PyObject *pyus_in;
1991     PyObject *pyus_out;
1992     PyObject *result;
1993 
1994     pyus_in = delta_to_microseconds(delta);
1995     if (pyus_in == NULL)
1996         return NULL;
1997 
1998     pyus_out = PyNumber_Multiply(intobj, pyus_in);
1999     Py_DECREF(pyus_in);
2000     if (pyus_out == NULL)
2001         return NULL;
2002 
2003     result = microseconds_to_delta(pyus_out);
2004     Py_DECREF(pyus_out);
2005     return result;
2006 }
2007 
2008 static PyObject *
get_float_as_integer_ratio(PyObject * floatobj)2009 get_float_as_integer_ratio(PyObject *floatobj)
2010 {
2011     PyObject *ratio;
2012 
2013     assert(floatobj && PyFloat_Check(floatobj));
2014     ratio = _PyObject_CallMethodIdNoArgs(floatobj, &PyId_as_integer_ratio);
2015     if (ratio == NULL) {
2016         return NULL;
2017     }
2018     if (!PyTuple_Check(ratio)) {
2019         PyErr_Format(PyExc_TypeError,
2020                      "unexpected return type from as_integer_ratio(): "
2021                      "expected tuple, got '%.200s'",
2022                      Py_TYPE(ratio)->tp_name);
2023         Py_DECREF(ratio);
2024         return NULL;
2025     }
2026     if (PyTuple_Size(ratio) != 2) {
2027         PyErr_SetString(PyExc_ValueError,
2028                         "as_integer_ratio() must return a 2-tuple");
2029         Py_DECREF(ratio);
2030         return NULL;
2031     }
2032     return ratio;
2033 }
2034 
2035 /* op is 0 for multiplication, 1 for division */
2036 static PyObject *
multiply_truedivide_timedelta_float(PyDateTime_Delta * delta,PyObject * floatobj,int op)2037 multiply_truedivide_timedelta_float(PyDateTime_Delta *delta, PyObject *floatobj, int op)
2038 {
2039     PyObject *result = NULL;
2040     PyObject *pyus_in = NULL, *temp, *pyus_out;
2041     PyObject *ratio = NULL;
2042 
2043     pyus_in = delta_to_microseconds(delta);
2044     if (pyus_in == NULL)
2045         return NULL;
2046     ratio = get_float_as_integer_ratio(floatobj);
2047     if (ratio == NULL) {
2048         goto error;
2049     }
2050     temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, op));
2051     Py_DECREF(pyus_in);
2052     pyus_in = NULL;
2053     if (temp == NULL)
2054         goto error;
2055     pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, !op));
2056     Py_DECREF(temp);
2057     if (pyus_out == NULL)
2058         goto error;
2059     result = microseconds_to_delta(pyus_out);
2060     Py_DECREF(pyus_out);
2061  error:
2062     Py_XDECREF(pyus_in);
2063     Py_XDECREF(ratio);
2064 
2065     return result;
2066 }
2067 
2068 static PyObject *
divide_timedelta_int(PyDateTime_Delta * delta,PyObject * intobj)2069 divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
2070 {
2071     PyObject *pyus_in;
2072     PyObject *pyus_out;
2073     PyObject *result;
2074 
2075     pyus_in = delta_to_microseconds(delta);
2076     if (pyus_in == NULL)
2077         return NULL;
2078 
2079     pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
2080     Py_DECREF(pyus_in);
2081     if (pyus_out == NULL)
2082         return NULL;
2083 
2084     result = microseconds_to_delta(pyus_out);
2085     Py_DECREF(pyus_out);
2086     return result;
2087 }
2088 
2089 static PyObject *
divide_timedelta_timedelta(PyDateTime_Delta * left,PyDateTime_Delta * right)2090 divide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
2091 {
2092     PyObject *pyus_left;
2093     PyObject *pyus_right;
2094     PyObject *result;
2095 
2096     pyus_left = delta_to_microseconds(left);
2097     if (pyus_left == NULL)
2098         return NULL;
2099 
2100     pyus_right = delta_to_microseconds(right);
2101     if (pyus_right == NULL)     {
2102         Py_DECREF(pyus_left);
2103         return NULL;
2104     }
2105 
2106     result = PyNumber_FloorDivide(pyus_left, pyus_right);
2107     Py_DECREF(pyus_left);
2108     Py_DECREF(pyus_right);
2109     return result;
2110 }
2111 
2112 static PyObject *
truedivide_timedelta_timedelta(PyDateTime_Delta * left,PyDateTime_Delta * right)2113 truedivide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
2114 {
2115     PyObject *pyus_left;
2116     PyObject *pyus_right;
2117     PyObject *result;
2118 
2119     pyus_left = delta_to_microseconds(left);
2120     if (pyus_left == NULL)
2121         return NULL;
2122 
2123     pyus_right = delta_to_microseconds(right);
2124     if (pyus_right == NULL)     {
2125         Py_DECREF(pyus_left);
2126         return NULL;
2127     }
2128 
2129     result = PyNumber_TrueDivide(pyus_left, pyus_right);
2130     Py_DECREF(pyus_left);
2131     Py_DECREF(pyus_right);
2132     return result;
2133 }
2134 
2135 static PyObject *
truedivide_timedelta_int(PyDateTime_Delta * delta,PyObject * i)2136 truedivide_timedelta_int(PyDateTime_Delta *delta, PyObject *i)
2137 {
2138     PyObject *result;
2139     PyObject *pyus_in, *pyus_out;
2140     pyus_in = delta_to_microseconds(delta);
2141     if (pyus_in == NULL)
2142         return NULL;
2143     pyus_out = divide_nearest(pyus_in, i);
2144     Py_DECREF(pyus_in);
2145     if (pyus_out == NULL)
2146         return NULL;
2147     result = microseconds_to_delta(pyus_out);
2148     Py_DECREF(pyus_out);
2149 
2150     return result;
2151 }
2152 
2153 static PyObject *
delta_add(PyObject * left,PyObject * right)2154 delta_add(PyObject *left, PyObject *right)
2155 {
2156     PyObject *result = Py_NotImplemented;
2157 
2158     if (PyDelta_Check(left) && PyDelta_Check(right)) {
2159         /* delta + delta */
2160         /* The C-level additions can't overflow because of the
2161          * invariant bounds.
2162          */
2163         int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
2164         int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
2165         int microseconds = GET_TD_MICROSECONDS(left) +
2166                            GET_TD_MICROSECONDS(right);
2167         result = new_delta(days, seconds, microseconds, 1);
2168     }
2169 
2170     if (result == Py_NotImplemented)
2171         Py_INCREF(result);
2172     return result;
2173 }
2174 
2175 static PyObject *
delta_negative(PyDateTime_Delta * self)2176 delta_negative(PyDateTime_Delta *self)
2177 {
2178     return new_delta(-GET_TD_DAYS(self),
2179                      -GET_TD_SECONDS(self),
2180                      -GET_TD_MICROSECONDS(self),
2181                      1);
2182 }
2183 
2184 static PyObject *
delta_positive(PyDateTime_Delta * self)2185 delta_positive(PyDateTime_Delta *self)
2186 {
2187     /* Could optimize this (by returning self) if this isn't a
2188      * subclass -- but who uses unary + ?  Approximately nobody.
2189      */
2190     return new_delta(GET_TD_DAYS(self),
2191                      GET_TD_SECONDS(self),
2192                      GET_TD_MICROSECONDS(self),
2193                      0);
2194 }
2195 
2196 static PyObject *
delta_abs(PyDateTime_Delta * self)2197 delta_abs(PyDateTime_Delta *self)
2198 {
2199     PyObject *result;
2200 
2201     assert(GET_TD_MICROSECONDS(self) >= 0);
2202     assert(GET_TD_SECONDS(self) >= 0);
2203 
2204     if (GET_TD_DAYS(self) < 0)
2205         result = delta_negative(self);
2206     else
2207         result = delta_positive(self);
2208 
2209     return result;
2210 }
2211 
2212 static PyObject *
delta_subtract(PyObject * left,PyObject * right)2213 delta_subtract(PyObject *left, PyObject *right)
2214 {
2215     PyObject *result = Py_NotImplemented;
2216 
2217     if (PyDelta_Check(left) && PyDelta_Check(right)) {
2218         /* delta - delta */
2219         /* The C-level additions can't overflow because of the
2220          * invariant bounds.
2221          */
2222         int days = GET_TD_DAYS(left) - GET_TD_DAYS(right);
2223         int seconds = GET_TD_SECONDS(left) - GET_TD_SECONDS(right);
2224         int microseconds = GET_TD_MICROSECONDS(left) -
2225                            GET_TD_MICROSECONDS(right);
2226         result = new_delta(days, seconds, microseconds, 1);
2227     }
2228 
2229     if (result == Py_NotImplemented)
2230         Py_INCREF(result);
2231     return result;
2232 }
2233 
2234 static int
delta_cmp(PyObject * self,PyObject * other)2235 delta_cmp(PyObject *self, PyObject *other)
2236 {
2237     int diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
2238     if (diff == 0) {
2239         diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
2240         if (diff == 0)
2241             diff = GET_TD_MICROSECONDS(self) -
2242                 GET_TD_MICROSECONDS(other);
2243     }
2244     return diff;
2245 }
2246 
2247 static PyObject *
delta_richcompare(PyObject * self,PyObject * other,int op)2248 delta_richcompare(PyObject *self, PyObject *other, int op)
2249 {
2250     if (PyDelta_Check(other)) {
2251         int diff = delta_cmp(self, other);
2252         return diff_to_bool(diff, op);
2253     }
2254     else {
2255         Py_RETURN_NOTIMPLEMENTED;
2256     }
2257 }
2258 
2259 static PyObject *delta_getstate(PyDateTime_Delta *self);
2260 
2261 static Py_hash_t
delta_hash(PyDateTime_Delta * self)2262 delta_hash(PyDateTime_Delta *self)
2263 {
2264     if (self->hashcode == -1) {
2265         PyObject *temp = delta_getstate(self);
2266         if (temp != NULL) {
2267             self->hashcode = PyObject_Hash(temp);
2268             Py_DECREF(temp);
2269         }
2270     }
2271     return self->hashcode;
2272 }
2273 
2274 static PyObject *
delta_multiply(PyObject * left,PyObject * right)2275 delta_multiply(PyObject *left, PyObject *right)
2276 {
2277     PyObject *result = Py_NotImplemented;
2278 
2279     if (PyDelta_Check(left)) {
2280         /* delta * ??? */
2281         if (PyLong_Check(right))
2282             result = multiply_int_timedelta(right,
2283                             (PyDateTime_Delta *) left);
2284         else if (PyFloat_Check(right))
2285             result = multiply_truedivide_timedelta_float(
2286                             (PyDateTime_Delta *) left, right, 0);
2287     }
2288     else if (PyLong_Check(left))
2289         result = multiply_int_timedelta(left,
2290                         (PyDateTime_Delta *) right);
2291     else if (PyFloat_Check(left))
2292         result = multiply_truedivide_timedelta_float(
2293                         (PyDateTime_Delta *) right, left, 0);
2294 
2295     if (result == Py_NotImplemented)
2296         Py_INCREF(result);
2297     return result;
2298 }
2299 
2300 static PyObject *
delta_divide(PyObject * left,PyObject * right)2301 delta_divide(PyObject *left, PyObject *right)
2302 {
2303     PyObject *result = Py_NotImplemented;
2304 
2305     if (PyDelta_Check(left)) {
2306         /* delta * ??? */
2307         if (PyLong_Check(right))
2308             result = divide_timedelta_int(
2309                             (PyDateTime_Delta *)left,
2310                             right);
2311         else if (PyDelta_Check(right))
2312             result = divide_timedelta_timedelta(
2313                             (PyDateTime_Delta *)left,
2314                             (PyDateTime_Delta *)right);
2315     }
2316 
2317     if (result == Py_NotImplemented)
2318         Py_INCREF(result);
2319     return result;
2320 }
2321 
2322 static PyObject *
delta_truedivide(PyObject * left,PyObject * right)2323 delta_truedivide(PyObject *left, PyObject *right)
2324 {
2325     PyObject *result = Py_NotImplemented;
2326 
2327     if (PyDelta_Check(left)) {
2328         if (PyDelta_Check(right))
2329             result = truedivide_timedelta_timedelta(
2330                             (PyDateTime_Delta *)left,
2331                             (PyDateTime_Delta *)right);
2332         else if (PyFloat_Check(right))
2333             result = multiply_truedivide_timedelta_float(
2334                             (PyDateTime_Delta *)left, right, 1);
2335         else if (PyLong_Check(right))
2336             result = truedivide_timedelta_int(
2337                             (PyDateTime_Delta *)left, right);
2338     }
2339 
2340     if (result == Py_NotImplemented)
2341         Py_INCREF(result);
2342     return result;
2343 }
2344 
2345 static PyObject *
delta_remainder(PyObject * left,PyObject * right)2346 delta_remainder(PyObject *left, PyObject *right)
2347 {
2348     PyObject *pyus_left;
2349     PyObject *pyus_right;
2350     PyObject *pyus_remainder;
2351     PyObject *remainder;
2352 
2353     if (!PyDelta_Check(left) || !PyDelta_Check(right))
2354         Py_RETURN_NOTIMPLEMENTED;
2355 
2356     pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
2357     if (pyus_left == NULL)
2358         return NULL;
2359 
2360     pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
2361     if (pyus_right == NULL) {
2362         Py_DECREF(pyus_left);
2363         return NULL;
2364     }
2365 
2366     pyus_remainder = PyNumber_Remainder(pyus_left, pyus_right);
2367     Py_DECREF(pyus_left);
2368     Py_DECREF(pyus_right);
2369     if (pyus_remainder == NULL)
2370         return NULL;
2371 
2372     remainder = microseconds_to_delta(pyus_remainder);
2373     Py_DECREF(pyus_remainder);
2374     if (remainder == NULL)
2375         return NULL;
2376 
2377     return remainder;
2378 }
2379 
2380 static PyObject *
delta_divmod(PyObject * left,PyObject * right)2381 delta_divmod(PyObject *left, PyObject *right)
2382 {
2383     PyObject *pyus_left;
2384     PyObject *pyus_right;
2385     PyObject *divmod;
2386     PyObject *delta;
2387     PyObject *result;
2388 
2389     if (!PyDelta_Check(left) || !PyDelta_Check(right))
2390         Py_RETURN_NOTIMPLEMENTED;
2391 
2392     pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
2393     if (pyus_left == NULL)
2394         return NULL;
2395 
2396     pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
2397     if (pyus_right == NULL) {
2398         Py_DECREF(pyus_left);
2399         return NULL;
2400     }
2401 
2402     divmod = checked_divmod(pyus_left, pyus_right);
2403     Py_DECREF(pyus_left);
2404     Py_DECREF(pyus_right);
2405     if (divmod == NULL)
2406         return NULL;
2407 
2408     delta = microseconds_to_delta(PyTuple_GET_ITEM(divmod, 1));
2409     if (delta == NULL) {
2410         Py_DECREF(divmod);
2411         return NULL;
2412     }
2413     result = PyTuple_Pack(2, PyTuple_GET_ITEM(divmod, 0), delta);
2414     Py_DECREF(delta);
2415     Py_DECREF(divmod);
2416     return result;
2417 }
2418 
2419 /* Fold in the value of the tag ("seconds", "weeks", etc) component of a
2420  * timedelta constructor.  sofar is the # of microseconds accounted for
2421  * so far, and there are factor microseconds per current unit, the number
2422  * of which is given by num.  num * factor is added to sofar in a
2423  * numerically careful way, and that's the result.  Any fractional
2424  * microseconds left over (this can happen if num is a float type) are
2425  * added into *leftover.
2426  * Note that there are many ways this can give an error (NULL) return.
2427  */
2428 static PyObject *
accum(const char * tag,PyObject * sofar,PyObject * num,PyObject * factor,double * leftover)2429 accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
2430       double *leftover)
2431 {
2432     PyObject *prod;
2433     PyObject *sum;
2434 
2435     assert(num != NULL);
2436 
2437     if (PyLong_Check(num)) {
2438         prod = PyNumber_Multiply(num, factor);
2439         if (prod == NULL)
2440             return NULL;
2441         sum = PyNumber_Add(sofar, prod);
2442         Py_DECREF(prod);
2443         return sum;
2444     }
2445 
2446     if (PyFloat_Check(num)) {
2447         double dnum;
2448         double fracpart;
2449         double intpart;
2450         PyObject *x;
2451         PyObject *y;
2452 
2453         /* The Plan:  decompose num into an integer part and a
2454          * fractional part, num = intpart + fracpart.
2455          * Then num * factor ==
2456          *      intpart * factor + fracpart * factor
2457          * and the LHS can be computed exactly in long arithmetic.
2458          * The RHS is again broken into an int part and frac part.
2459          * and the frac part is added into *leftover.
2460          */
2461         dnum = PyFloat_AsDouble(num);
2462         if (dnum == -1.0 && PyErr_Occurred())
2463             return NULL;
2464         fracpart = modf(dnum, &intpart);
2465         x = PyLong_FromDouble(intpart);
2466         if (x == NULL)
2467             return NULL;
2468 
2469         prod = PyNumber_Multiply(x, factor);
2470         Py_DECREF(x);
2471         if (prod == NULL)
2472             return NULL;
2473 
2474         sum = PyNumber_Add(sofar, prod);
2475         Py_DECREF(prod);
2476         if (sum == NULL)
2477             return NULL;
2478 
2479         if (fracpart == 0.0)
2480             return sum;
2481         /* So far we've lost no information.  Dealing with the
2482          * fractional part requires float arithmetic, and may
2483          * lose a little info.
2484          */
2485         assert(PyLong_CheckExact(factor));
2486         dnum = PyLong_AsDouble(factor);
2487 
2488         dnum *= fracpart;
2489         fracpart = modf(dnum, &intpart);
2490         x = PyLong_FromDouble(intpart);
2491         if (x == NULL) {
2492             Py_DECREF(sum);
2493             return NULL;
2494         }
2495 
2496         y = PyNumber_Add(sum, x);
2497         Py_DECREF(sum);
2498         Py_DECREF(x);
2499         *leftover += fracpart;
2500         return y;
2501     }
2502 
2503     PyErr_Format(PyExc_TypeError,
2504                  "unsupported type for timedelta %s component: %s",
2505                  tag, Py_TYPE(num)->tp_name);
2506     return NULL;
2507 }
2508 
2509 static PyObject *
delta_new(PyTypeObject * type,PyObject * args,PyObject * kw)2510 delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2511 {
2512     PyObject *self = NULL;
2513 
2514     /* Argument objects. */
2515     PyObject *day = NULL;
2516     PyObject *second = NULL;
2517     PyObject *us = NULL;
2518     PyObject *ms = NULL;
2519     PyObject *minute = NULL;
2520     PyObject *hour = NULL;
2521     PyObject *week = NULL;
2522 
2523     PyObject *x = NULL;         /* running sum of microseconds */
2524     PyObject *y = NULL;         /* temp sum of microseconds */
2525     double leftover_us = 0.0;
2526 
2527     static char *keywords[] = {
2528         "days", "seconds", "microseconds", "milliseconds",
2529         "minutes", "hours", "weeks", NULL
2530     };
2531 
2532     if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
2533                                     keywords,
2534                                     &day, &second, &us,
2535                                     &ms, &minute, &hour, &week) == 0)
2536         goto Done;
2537 
2538     x = PyLong_FromLong(0);
2539     if (x == NULL)
2540         goto Done;
2541 
2542 #define CLEANUP         \
2543     Py_DECREF(x);       \
2544     x = y;              \
2545     if (x == NULL)      \
2546         goto Done
2547 
2548     if (us) {
2549         y = accum("microseconds", x, us, _PyLong_GetOne(), &leftover_us);
2550         CLEANUP;
2551     }
2552     if (ms) {
2553         y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
2554         CLEANUP;
2555     }
2556     if (second) {
2557         y = accum("seconds", x, second, us_per_second, &leftover_us);
2558         CLEANUP;
2559     }
2560     if (minute) {
2561         y = accum("minutes", x, minute, us_per_minute, &leftover_us);
2562         CLEANUP;
2563     }
2564     if (hour) {
2565         y = accum("hours", x, hour, us_per_hour, &leftover_us);
2566         CLEANUP;
2567     }
2568     if (day) {
2569         y = accum("days", x, day, us_per_day, &leftover_us);
2570         CLEANUP;
2571     }
2572     if (week) {
2573         y = accum("weeks", x, week, us_per_week, &leftover_us);
2574         CLEANUP;
2575     }
2576     if (leftover_us) {
2577         /* Round to nearest whole # of us, and add into x. */
2578         double whole_us = round(leftover_us);
2579         int x_is_odd;
2580         PyObject *temp;
2581 
2582         if (fabs(whole_us - leftover_us) == 0.5) {
2583             /* We're exactly halfway between two integers.  In order
2584              * to do round-half-to-even, we must determine whether x
2585              * is odd. Note that x is odd when it's last bit is 1. The
2586              * code below uses bitwise and operation to check the last
2587              * bit. */
2588             temp = PyNumber_And(x, _PyLong_GetOne());  /* temp <- x & 1 */
2589             if (temp == NULL) {
2590                 Py_DECREF(x);
2591                 goto Done;
2592             }
2593             x_is_odd = PyObject_IsTrue(temp);
2594             Py_DECREF(temp);
2595             if (x_is_odd == -1) {
2596                 Py_DECREF(x);
2597                 goto Done;
2598             }
2599             whole_us = 2.0 * round((leftover_us + x_is_odd) * 0.5) - x_is_odd;
2600         }
2601 
2602         temp = PyLong_FromLong((long)whole_us);
2603 
2604         if (temp == NULL) {
2605             Py_DECREF(x);
2606             goto Done;
2607         }
2608         y = PyNumber_Add(x, temp);
2609         Py_DECREF(temp);
2610         CLEANUP;
2611     }
2612 
2613     self = microseconds_to_delta_ex(x, type);
2614     Py_DECREF(x);
2615 Done:
2616     return self;
2617 
2618 #undef CLEANUP
2619 }
2620 
2621 static int
delta_bool(PyDateTime_Delta * self)2622 delta_bool(PyDateTime_Delta *self)
2623 {
2624     return (GET_TD_DAYS(self) != 0
2625         || GET_TD_SECONDS(self) != 0
2626         || GET_TD_MICROSECONDS(self) != 0);
2627 }
2628 
2629 static PyObject *
delta_repr(PyDateTime_Delta * self)2630 delta_repr(PyDateTime_Delta *self)
2631 {
2632     PyObject *args = PyUnicode_FromString("");
2633 
2634     if (args == NULL) {
2635         return NULL;
2636     }
2637 
2638     const char *sep = "";
2639 
2640     if (GET_TD_DAYS(self) != 0) {
2641         Py_SETREF(args, PyUnicode_FromFormat("days=%d", GET_TD_DAYS(self)));
2642         if (args == NULL) {
2643             return NULL;
2644         }
2645         sep = ", ";
2646     }
2647 
2648     if (GET_TD_SECONDS(self) != 0) {
2649         Py_SETREF(args, PyUnicode_FromFormat("%U%sseconds=%d", args, sep,
2650                                              GET_TD_SECONDS(self)));
2651         if (args == NULL) {
2652             return NULL;
2653         }
2654         sep = ", ";
2655     }
2656 
2657     if (GET_TD_MICROSECONDS(self) != 0) {
2658         Py_SETREF(args, PyUnicode_FromFormat("%U%smicroseconds=%d", args, sep,
2659                                              GET_TD_MICROSECONDS(self)));
2660         if (args == NULL) {
2661             return NULL;
2662         }
2663     }
2664 
2665     if (PyUnicode_GET_LENGTH(args) == 0) {
2666         Py_SETREF(args, PyUnicode_FromString("0"));
2667         if (args == NULL) {
2668             return NULL;
2669         }
2670     }
2671 
2672     PyObject *repr = PyUnicode_FromFormat("%s(%S)", Py_TYPE(self)->tp_name,
2673                                           args);
2674     Py_DECREF(args);
2675     return repr;
2676 }
2677 
2678 static PyObject *
delta_str(PyDateTime_Delta * self)2679 delta_str(PyDateTime_Delta *self)
2680 {
2681     int us = GET_TD_MICROSECONDS(self);
2682     int seconds = GET_TD_SECONDS(self);
2683     int minutes = divmod(seconds, 60, &seconds);
2684     int hours = divmod(minutes, 60, &minutes);
2685     int days = GET_TD_DAYS(self);
2686 
2687     if (days) {
2688         if (us)
2689             return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d.%06d",
2690                                         days, (days == 1 || days == -1) ? "" : "s",
2691                                         hours, minutes, seconds, us);
2692         else
2693             return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d",
2694                                         days, (days == 1 || days == -1) ? "" : "s",
2695                                         hours, minutes, seconds);
2696     } else {
2697         if (us)
2698             return PyUnicode_FromFormat("%d:%02d:%02d.%06d",
2699                                         hours, minutes, seconds, us);
2700         else
2701             return PyUnicode_FromFormat("%d:%02d:%02d",
2702                                         hours, minutes, seconds);
2703     }
2704 
2705 }
2706 
2707 /* Pickle support, a simple use of __reduce__. */
2708 
2709 /* __getstate__ isn't exposed */
2710 static PyObject *
delta_getstate(PyDateTime_Delta * self)2711 delta_getstate(PyDateTime_Delta *self)
2712 {
2713     return Py_BuildValue("iii", GET_TD_DAYS(self),
2714                                 GET_TD_SECONDS(self),
2715                                 GET_TD_MICROSECONDS(self));
2716 }
2717 
2718 static PyObject *
delta_total_seconds(PyObject * self,PyObject * Py_UNUSED (ignored))2719 delta_total_seconds(PyObject *self, PyObject *Py_UNUSED(ignored))
2720 {
2721     PyObject *total_seconds;
2722     PyObject *total_microseconds;
2723 
2724     total_microseconds = delta_to_microseconds((PyDateTime_Delta *)self);
2725     if (total_microseconds == NULL)
2726         return NULL;
2727 
2728     total_seconds = PyNumber_TrueDivide(total_microseconds, us_per_second);
2729 
2730     Py_DECREF(total_microseconds);
2731     return total_seconds;
2732 }
2733 
2734 static PyObject *
delta_reduce(PyDateTime_Delta * self,PyObject * Py_UNUSED (ignored))2735 delta_reduce(PyDateTime_Delta* self, PyObject *Py_UNUSED(ignored))
2736 {
2737     return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
2738 }
2739 
2740 #define OFFSET(field)  offsetof(PyDateTime_Delta, field)
2741 
2742 static PyMemberDef delta_members[] = {
2743 
2744     {"days",         T_INT, OFFSET(days),         READONLY,
2745      PyDoc_STR("Number of days.")},
2746 
2747     {"seconds",      T_INT, OFFSET(seconds),      READONLY,
2748      PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
2749 
2750     {"microseconds", T_INT, OFFSET(microseconds), READONLY,
2751      PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2752     {NULL}
2753 };
2754 
2755 static PyMethodDef delta_methods[] = {
2756     {"total_seconds", delta_total_seconds, METH_NOARGS,
2757      PyDoc_STR("Total seconds in the duration.")},
2758 
2759     {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2760      PyDoc_STR("__reduce__() -> (cls, state)")},
2761 
2762     {NULL,      NULL},
2763 };
2764 
2765 static const char delta_doc[] =
2766 PyDoc_STR("Difference between two datetime values.\n\n"
2767           "timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, "
2768           "minutes=0, hours=0, weeks=0)\n\n"
2769           "All arguments are optional and default to 0.\n"
2770           "Arguments may be integers or floats, and may be positive or negative.");
2771 
2772 static PyNumberMethods delta_as_number = {
2773     delta_add,                                  /* nb_add */
2774     delta_subtract,                             /* nb_subtract */
2775     delta_multiply,                             /* nb_multiply */
2776     delta_remainder,                            /* nb_remainder */
2777     delta_divmod,                               /* nb_divmod */
2778     0,                                          /* nb_power */
2779     (unaryfunc)delta_negative,                  /* nb_negative */
2780     (unaryfunc)delta_positive,                  /* nb_positive */
2781     (unaryfunc)delta_abs,                       /* nb_absolute */
2782     (inquiry)delta_bool,                        /* nb_bool */
2783     0,                                          /*nb_invert*/
2784     0,                                          /*nb_lshift*/
2785     0,                                          /*nb_rshift*/
2786     0,                                          /*nb_and*/
2787     0,                                          /*nb_xor*/
2788     0,                                          /*nb_or*/
2789     0,                                          /*nb_int*/
2790     0,                                          /*nb_reserved*/
2791     0,                                          /*nb_float*/
2792     0,                                          /*nb_inplace_add*/
2793     0,                                          /*nb_inplace_subtract*/
2794     0,                                          /*nb_inplace_multiply*/
2795     0,                                          /*nb_inplace_remainder*/
2796     0,                                          /*nb_inplace_power*/
2797     0,                                          /*nb_inplace_lshift*/
2798     0,                                          /*nb_inplace_rshift*/
2799     0,                                          /*nb_inplace_and*/
2800     0,                                          /*nb_inplace_xor*/
2801     0,                                          /*nb_inplace_or*/
2802     delta_divide,                               /* nb_floor_divide */
2803     delta_truedivide,                           /* nb_true_divide */
2804     0,                                          /* nb_inplace_floor_divide */
2805     0,                                          /* nb_inplace_true_divide */
2806 };
2807 
2808 static PyTypeObject PyDateTime_DeltaType = {
2809     PyVarObject_HEAD_INIT(NULL, 0)
2810     "datetime.timedelta",                               /* tp_name */
2811     sizeof(PyDateTime_Delta),                           /* tp_basicsize */
2812     0,                                                  /* tp_itemsize */
2813     0,                                                  /* tp_dealloc */
2814     0,                                                  /* tp_vectorcall_offset */
2815     0,                                                  /* tp_getattr */
2816     0,                                                  /* tp_setattr */
2817     0,                                                  /* tp_as_async */
2818     (reprfunc)delta_repr,                               /* tp_repr */
2819     &delta_as_number,                                   /* tp_as_number */
2820     0,                                                  /* tp_as_sequence */
2821     0,                                                  /* tp_as_mapping */
2822     (hashfunc)delta_hash,                               /* tp_hash */
2823     0,                                                  /* tp_call */
2824     (reprfunc)delta_str,                                /* tp_str */
2825     PyObject_GenericGetAttr,                            /* tp_getattro */
2826     0,                                                  /* tp_setattro */
2827     0,                                                  /* tp_as_buffer */
2828     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,           /* tp_flags */
2829     delta_doc,                                          /* tp_doc */
2830     0,                                                  /* tp_traverse */
2831     0,                                                  /* tp_clear */
2832     delta_richcompare,                                  /* tp_richcompare */
2833     0,                                                  /* tp_weaklistoffset */
2834     0,                                                  /* tp_iter */
2835     0,                                                  /* tp_iternext */
2836     delta_methods,                                      /* tp_methods */
2837     delta_members,                                      /* tp_members */
2838     0,                                                  /* tp_getset */
2839     0,                                                  /* tp_base */
2840     0,                                                  /* tp_dict */
2841     0,                                                  /* tp_descr_get */
2842     0,                                                  /* tp_descr_set */
2843     0,                                                  /* tp_dictoffset */
2844     0,                                                  /* tp_init */
2845     0,                                                  /* tp_alloc */
2846     delta_new,                                          /* tp_new */
2847     0,                                                  /* tp_free */
2848 };
2849 
2850 /*
2851  * PyDateTime_Date implementation.
2852  */
2853 
2854 /* Accessor properties. */
2855 
2856 static PyObject *
date_year(PyDateTime_Date * self,void * unused)2857 date_year(PyDateTime_Date *self, void *unused)
2858 {
2859     return PyLong_FromLong(GET_YEAR(self));
2860 }
2861 
2862 static PyObject *
date_month(PyDateTime_Date * self,void * unused)2863 date_month(PyDateTime_Date *self, void *unused)
2864 {
2865     return PyLong_FromLong(GET_MONTH(self));
2866 }
2867 
2868 static PyObject *
date_day(PyDateTime_Date * self,void * unused)2869 date_day(PyDateTime_Date *self, void *unused)
2870 {
2871     return PyLong_FromLong(GET_DAY(self));
2872 }
2873 
2874 static PyGetSetDef date_getset[] = {
2875     {"year",        (getter)date_year},
2876     {"month",       (getter)date_month},
2877     {"day",         (getter)date_day},
2878     {NULL}
2879 };
2880 
2881 /* Constructors. */
2882 
2883 static char *date_kws[] = {"year", "month", "day", NULL};
2884 
2885 static PyObject *
date_from_pickle(PyTypeObject * type,PyObject * state)2886 date_from_pickle(PyTypeObject *type, PyObject *state)
2887 {
2888     PyDateTime_Date *me;
2889 
2890     me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
2891     if (me != NULL) {
2892         const char *pdata = PyBytes_AS_STRING(state);
2893         memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2894         me->hashcode = -1;
2895     }
2896     return (PyObject *)me;
2897 }
2898 
2899 static PyObject *
date_new(PyTypeObject * type,PyObject * args,PyObject * kw)2900 date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2901 {
2902     PyObject *self = NULL;
2903     int year;
2904     int month;
2905     int day;
2906 
2907     /* Check for invocation from pickle with __getstate__ state */
2908     if (PyTuple_GET_SIZE(args) == 1) {
2909         PyObject *state = PyTuple_GET_ITEM(args, 0);
2910         if (PyBytes_Check(state)) {
2911             if (PyBytes_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2912                 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
2913             {
2914                 return date_from_pickle(type, state);
2915             }
2916         }
2917         else if (PyUnicode_Check(state)) {
2918             if (PyUnicode_READY(state)) {
2919                 return NULL;
2920             }
2921             if (PyUnicode_GET_LENGTH(state) == _PyDateTime_DATE_DATASIZE &&
2922                 MONTH_IS_SANE(PyUnicode_READ_CHAR(state, 2)))
2923             {
2924                 state = PyUnicode_AsLatin1String(state);
2925                 if (state == NULL) {
2926                     if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) {
2927                         /* More informative error message. */
2928                         PyErr_SetString(PyExc_ValueError,
2929                             "Failed to encode latin1 string when unpickling "
2930                             "a date object. "
2931                             "pickle.load(data, encoding='latin1') is assumed.");
2932                     }
2933                     return NULL;
2934                 }
2935                 self = date_from_pickle(type, state);
2936                 Py_DECREF(state);
2937                 return self;
2938             }
2939         }
2940     }
2941 
2942     if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
2943                                     &year, &month, &day)) {
2944         self = new_date_ex(year, month, day, type);
2945     }
2946     return self;
2947 }
2948 
2949 static PyObject *
date_fromtimestamp(PyObject * cls,PyObject * obj)2950 date_fromtimestamp(PyObject *cls, PyObject *obj)
2951 {
2952     struct tm tm;
2953     time_t t;
2954 
2955     if (_PyTime_ObjectToTime_t(obj, &t, _PyTime_ROUND_FLOOR) == -1)
2956         return NULL;
2957 
2958     if (_PyTime_localtime(t, &tm) != 0)
2959         return NULL;
2960 
2961     return new_date_subclass_ex(tm.tm_year + 1900,
2962                                 tm.tm_mon + 1,
2963                                 tm.tm_mday,
2964                                 cls);
2965 }
2966 
2967 /* Return new date from current time.
2968  * We say this is equivalent to fromtimestamp(time.time()), and the
2969  * only way to be sure of that is to *call* time.time().  That's not
2970  * generally the same as calling C's time.
2971  */
2972 static PyObject *
date_today(PyObject * cls,PyObject * dummy)2973 date_today(PyObject *cls, PyObject *dummy)
2974 {
2975     PyObject *time;
2976     PyObject *result;
2977     _Py_IDENTIFIER(fromtimestamp);
2978 
2979     time = time_time();
2980     if (time == NULL)
2981         return NULL;
2982 
2983     /* Note well:  today() is a class method, so this may not call
2984      * date.fromtimestamp.  For example, it may call
2985      * datetime.fromtimestamp.  That's why we need all the accuracy
2986      * time.time() delivers; if someone were gonzo about optimization,
2987      * date.today() could get away with plain C time().
2988      */
2989     result = _PyObject_CallMethodIdOneArg(cls, &PyId_fromtimestamp, time);
2990     Py_DECREF(time);
2991     return result;
2992 }
2993 
2994 /*[clinic input]
2995 @classmethod
2996 datetime.date.fromtimestamp
2997 
2998     timestamp: object
2999     /
3000 
3001 Create a date from a POSIX timestamp.
3002 
3003 The timestamp is a number, e.g. created via time.time(), that is interpreted
3004 as local time.
3005 [clinic start generated code]*/
3006 
3007 static PyObject *
datetime_date_fromtimestamp(PyTypeObject * type,PyObject * timestamp)3008 datetime_date_fromtimestamp(PyTypeObject *type, PyObject *timestamp)
3009 /*[clinic end generated code: output=fd045fda58168869 input=eabb3fe7f40491fe]*/
3010 {
3011     return date_fromtimestamp((PyObject *) type, timestamp);
3012 }
3013 
3014 /* bpo-36025: This is a wrapper for API compatibility with the public C API,
3015  * which expects a function that takes an *args tuple, whereas the argument
3016  * clinic generates code that takes METH_O.
3017  */
3018 static PyObject *
datetime_date_fromtimestamp_capi(PyObject * cls,PyObject * args)3019 datetime_date_fromtimestamp_capi(PyObject *cls, PyObject *args)
3020 {
3021     PyObject *timestamp;
3022     PyObject *result = NULL;
3023 
3024     if (PyArg_UnpackTuple(args, "fromtimestamp", 1, 1, &timestamp)) {
3025         result = date_fromtimestamp(cls, timestamp);
3026     }
3027 
3028     return result;
3029 }
3030 
3031 /* Return new date from proleptic Gregorian ordinal.  Raises ValueError if
3032  * the ordinal is out of range.
3033  */
3034 static PyObject *
date_fromordinal(PyObject * cls,PyObject * args)3035 date_fromordinal(PyObject *cls, PyObject *args)
3036 {
3037     PyObject *result = NULL;
3038     int ordinal;
3039 
3040     if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
3041         int year;
3042         int month;
3043         int day;
3044 
3045         if (ordinal < 1)
3046             PyErr_SetString(PyExc_ValueError, "ordinal must be "
3047                                               ">= 1");
3048         else {
3049             ord_to_ymd(ordinal, &year, &month, &day);
3050             result = new_date_subclass_ex(year, month, day, cls);
3051         }
3052     }
3053     return result;
3054 }
3055 
3056 /* Return the new date from a string as generated by date.isoformat() */
3057 static PyObject *
date_fromisoformat(PyObject * cls,PyObject * dtstr)3058 date_fromisoformat(PyObject *cls, PyObject *dtstr)
3059 {
3060     assert(dtstr != NULL);
3061 
3062     if (!PyUnicode_Check(dtstr)) {
3063         PyErr_SetString(PyExc_TypeError,
3064                         "fromisoformat: argument must be str");
3065         return NULL;
3066     }
3067 
3068     Py_ssize_t len;
3069 
3070     const char *dt_ptr = PyUnicode_AsUTF8AndSize(dtstr, &len);
3071     if (dt_ptr == NULL) {
3072         goto invalid_string_error;
3073     }
3074 
3075     int year = 0, month = 0, day = 0;
3076 
3077     int rv;
3078     if (len == 7 || len == 8 || len == 10) {
3079         rv = parse_isoformat_date(dt_ptr, len, &year, &month, &day);
3080     }
3081     else {
3082         rv = -1;
3083     }
3084 
3085     if (rv < 0) {
3086         goto invalid_string_error;
3087     }
3088 
3089     return new_date_subclass_ex(year, month, day, cls);
3090 
3091 invalid_string_error:
3092     PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", dtstr);
3093     return NULL;
3094 }
3095 
3096 
3097 static PyObject *
date_fromisocalendar(PyObject * cls,PyObject * args,PyObject * kw)3098 date_fromisocalendar(PyObject *cls, PyObject *args, PyObject *kw)
3099 {
3100     static char *keywords[] = {
3101         "year", "week", "day", NULL
3102     };
3103 
3104     int year, week, day;
3105     if (PyArg_ParseTupleAndKeywords(args, kw, "iii:fromisocalendar",
3106                 keywords,
3107                 &year, &week, &day) == 0) {
3108         if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
3109             PyErr_Format(PyExc_ValueError,
3110                     "ISO calendar component out of range");
3111 
3112         }
3113         return NULL;
3114     }
3115 
3116     // Year is bounded to 0 < year < 10000 because 9999-12-31 is (9999, 52, 5)
3117     if (year < MINYEAR || year > MAXYEAR) {
3118         PyErr_Format(PyExc_ValueError, "Year is out of range: %d", year);
3119         return NULL;
3120     }
3121 
3122     int month;
3123     int rv = iso_to_ymd(year, week, day, &year, &month, &day);
3124 
3125 
3126     if (rv == -2) {
3127         PyErr_Format(PyExc_ValueError, "Invalid week: %d", week);
3128         return NULL;
3129     }
3130 
3131     if (rv == -3) {
3132         PyErr_Format(PyExc_ValueError, "Invalid day: %d (range is [1, 7])",
3133                      day);
3134         return NULL;
3135     }
3136 
3137     return new_date_subclass_ex(year, month, day, cls);
3138 }
3139 
3140 
3141 /*
3142  * Date arithmetic.
3143  */
3144 
3145 /* date + timedelta -> date.  If arg negate is true, subtract the timedelta
3146  * instead.
3147  */
3148 static PyObject *
add_date_timedelta(PyDateTime_Date * date,PyDateTime_Delta * delta,int negate)3149 add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
3150 {
3151     PyObject *result = NULL;
3152     int year = GET_YEAR(date);
3153     int month = GET_MONTH(date);
3154     int deltadays = GET_TD_DAYS(delta);
3155     /* C-level overflow is impossible because |deltadays| < 1e9. */
3156     int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
3157 
3158     if (normalize_date(&year, &month, &day) >= 0)
3159         result = new_date_subclass_ex(year, month, day,
3160                                       (PyObject* )Py_TYPE(date));
3161     return result;
3162 }
3163 
3164 static PyObject *
date_add(PyObject * left,PyObject * right)3165 date_add(PyObject *left, PyObject *right)
3166 {
3167     if (PyDateTime_Check(left) || PyDateTime_Check(right))
3168         Py_RETURN_NOTIMPLEMENTED;
3169 
3170     if (PyDate_Check(left)) {
3171         /* date + ??? */
3172         if (PyDelta_Check(right))
3173             /* date + delta */
3174             return add_date_timedelta((PyDateTime_Date *) left,
3175                                       (PyDateTime_Delta *) right,
3176                                       0);
3177     }
3178     else {
3179         /* ??? + date
3180          * 'right' must be one of us, or we wouldn't have been called
3181          */
3182         if (PyDelta_Check(left))
3183             /* delta + date */
3184             return add_date_timedelta((PyDateTime_Date *) right,
3185                                       (PyDateTime_Delta *) left,
3186                                       0);
3187     }
3188     Py_RETURN_NOTIMPLEMENTED;
3189 }
3190 
3191 static PyObject *
date_subtract(PyObject * left,PyObject * right)3192 date_subtract(PyObject *left, PyObject *right)
3193 {
3194     if (PyDateTime_Check(left) || PyDateTime_Check(right))
3195         Py_RETURN_NOTIMPLEMENTED;
3196 
3197     if (PyDate_Check(left)) {
3198         if (PyDate_Check(right)) {
3199             /* date - date */
3200             int left_ord = ymd_to_ord(GET_YEAR(left),
3201                                       GET_MONTH(left),
3202                                       GET_DAY(left));
3203             int right_ord = ymd_to_ord(GET_YEAR(right),
3204                                        GET_MONTH(right),
3205                                        GET_DAY(right));
3206             return new_delta(left_ord - right_ord, 0, 0, 0);
3207         }
3208         if (PyDelta_Check(right)) {
3209             /* date - delta */
3210             return add_date_timedelta((PyDateTime_Date *) left,
3211                                       (PyDateTime_Delta *) right,
3212                                       1);
3213         }
3214     }
3215     Py_RETURN_NOTIMPLEMENTED;
3216 }
3217 
3218 
3219 /* Various ways to turn a date into a string. */
3220 
3221 static PyObject *
date_repr(PyDateTime_Date * self)3222 date_repr(PyDateTime_Date *self)
3223 {
3224     return PyUnicode_FromFormat("%s(%d, %d, %d)",
3225                                 Py_TYPE(self)->tp_name,
3226                                 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
3227 }
3228 
3229 static PyObject *
date_isoformat(PyDateTime_Date * self,PyObject * Py_UNUSED (ignored))3230 date_isoformat(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
3231 {
3232     return PyUnicode_FromFormat("%04d-%02d-%02d",
3233                                 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
3234 }
3235 
3236 /* str() calls the appropriate isoformat() method. */
3237 static PyObject *
date_str(PyDateTime_Date * self)3238 date_str(PyDateTime_Date *self)
3239 {
3240     return _PyObject_CallMethodIdNoArgs((PyObject *)self, &PyId_isoformat);
3241 }
3242 
3243 
3244 static PyObject *
date_ctime(PyDateTime_Date * self,PyObject * Py_UNUSED (ignored))3245 date_ctime(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
3246 {
3247     return format_ctime(self, 0, 0, 0);
3248 }
3249 
3250 static PyObject *
date_strftime(PyDateTime_Date * self,PyObject * args,PyObject * kw)3251 date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
3252 {
3253     /* This method can be inherited, and needs to call the
3254      * timetuple() method appropriate to self's class.
3255      */
3256     PyObject *result;
3257     PyObject *tuple;
3258     PyObject *format;
3259     _Py_IDENTIFIER(timetuple);
3260     static char *keywords[] = {"format", NULL};
3261 
3262     if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
3263                                       &format))
3264         return NULL;
3265 
3266     tuple = _PyObject_CallMethodIdNoArgs((PyObject *)self, &PyId_timetuple);
3267     if (tuple == NULL)
3268         return NULL;
3269     result = wrap_strftime((PyObject *)self, format, tuple,
3270                            (PyObject *)self);
3271     Py_DECREF(tuple);
3272     return result;
3273 }
3274 
3275 static PyObject *
date_format(PyDateTime_Date * self,PyObject * args)3276 date_format(PyDateTime_Date *self, PyObject *args)
3277 {
3278     PyObject *format;
3279 
3280     if (!PyArg_ParseTuple(args, "U:__format__", &format))
3281         return NULL;
3282 
3283     /* if the format is zero length, return str(self) */
3284     if (PyUnicode_GetLength(format) == 0)
3285         return PyObject_Str((PyObject *)self);
3286 
3287     return _PyObject_CallMethodIdOneArg((PyObject *)self, &PyId_strftime,
3288                                         format);
3289 }
3290 
3291 /* ISO methods. */
3292 
3293 static PyObject *
date_isoweekday(PyDateTime_Date * self,PyObject * Py_UNUSED (ignored))3294 date_isoweekday(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
3295 {
3296     int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
3297 
3298     return PyLong_FromLong(dow + 1);
3299 }
3300 
3301 PyDoc_STRVAR(iso_calendar_date__doc__,
3302 "The result of date.isocalendar() or datetime.isocalendar()\n\n\
3303 This object may be accessed either as a tuple of\n\
3304   ((year, week, weekday)\n\
3305 or via the object attributes as named in the above tuple.");
3306 
3307 typedef struct {
3308     PyTupleObject tuple;
3309 } PyDateTime_IsoCalendarDate;
3310 
3311 static PyObject *
iso_calendar_date_repr(PyDateTime_IsoCalendarDate * self)3312 iso_calendar_date_repr(PyDateTime_IsoCalendarDate *self)
3313 {
3314     PyObject* year = PyTuple_GetItem((PyObject *)self, 0);
3315     if (year == NULL) {
3316         return NULL;
3317     }
3318     PyObject* week = PyTuple_GetItem((PyObject *)self, 1);
3319     if (week == NULL) {
3320         return NULL;
3321     }
3322     PyObject* weekday = PyTuple_GetItem((PyObject *)self, 2);
3323     if (weekday == NULL) {
3324         return NULL;
3325     }
3326 
3327     return PyUnicode_FromFormat("%.200s(year=%S, week=%S, weekday=%S)",
3328                                Py_TYPE(self)->tp_name, year, week, weekday);
3329 }
3330 
3331 static PyObject *
iso_calendar_date_reduce(PyObject * self,PyObject * Py_UNUSED (ignored))3332 iso_calendar_date_reduce(PyObject *self, PyObject *Py_UNUSED(ignored))
3333 {
3334     // Construct the tuple that this reduces to
3335     PyObject * reduce_tuple = Py_BuildValue(
3336         "O((OOO))", &PyTuple_Type,
3337         PyTuple_GET_ITEM(self, 0),
3338         PyTuple_GET_ITEM(self, 1),
3339         PyTuple_GET_ITEM(self, 2)
3340     );
3341 
3342     return reduce_tuple;
3343 }
3344 
3345 static PyObject *
iso_calendar_date_year(PyDateTime_IsoCalendarDate * self,void * unused)3346 iso_calendar_date_year(PyDateTime_IsoCalendarDate *self, void *unused)
3347 {
3348     PyObject *year = PyTuple_GetItem((PyObject *)self, 0);
3349     if (year == NULL) {
3350         return NULL;
3351     }
3352     Py_INCREF(year);
3353     return year;
3354 }
3355 
3356 static PyObject *
iso_calendar_date_week(PyDateTime_IsoCalendarDate * self,void * unused)3357 iso_calendar_date_week(PyDateTime_IsoCalendarDate *self, void *unused)
3358 {
3359     PyObject *week = PyTuple_GetItem((PyObject *)self, 1);
3360     if (week == NULL) {
3361         return NULL;
3362     }
3363     Py_INCREF(week);
3364     return week;
3365 }
3366 
3367 static PyObject *
iso_calendar_date_weekday(PyDateTime_IsoCalendarDate * self,void * unused)3368 iso_calendar_date_weekday(PyDateTime_IsoCalendarDate *self, void *unused)
3369 {
3370     PyObject *weekday = PyTuple_GetItem((PyObject *)self, 2);
3371     if (weekday == NULL) {
3372         return NULL;
3373     }
3374     Py_INCREF(weekday);
3375     return weekday;
3376 }
3377 
3378 static PyGetSetDef iso_calendar_date_getset[] = {
3379     {"year",        (getter)iso_calendar_date_year},
3380     {"week",      (getter)iso_calendar_date_week},
3381     {"weekday",      (getter)iso_calendar_date_weekday},
3382     {NULL}
3383 };
3384 
3385 static PyMethodDef iso_calendar_date_methods[] = {
3386     {"__reduce__", (PyCFunction)iso_calendar_date_reduce, METH_NOARGS,
3387      PyDoc_STR("__reduce__() -> (cls, state)")},
3388     {NULL, NULL},
3389 };
3390 
3391 static PyTypeObject PyDateTime_IsoCalendarDateType = {
3392     PyVarObject_HEAD_INIT(NULL, 0)
3393     .tp_name = "datetime.IsoCalendarDate",
3394     .tp_basicsize = sizeof(PyDateTime_IsoCalendarDate),
3395     .tp_repr = (reprfunc) iso_calendar_date_repr,
3396     .tp_flags = Py_TPFLAGS_DEFAULT,
3397     .tp_doc = iso_calendar_date__doc__,
3398     .tp_methods = iso_calendar_date_methods,
3399     .tp_getset = iso_calendar_date_getset,
3400     // .tp_base = &PyTuple_Type,  // filled in PyInit__datetime
3401     .tp_new = iso_calendar_date_new,
3402 };
3403 
3404 /*[clinic input]
3405 @classmethod
3406 datetime.IsoCalendarDate.__new__ as iso_calendar_date_new
3407     year: int
3408     week: int
3409     weekday: int
3410 [clinic start generated code]*/
3411 
3412 static PyObject *
iso_calendar_date_new_impl(PyTypeObject * type,int year,int week,int weekday)3413 iso_calendar_date_new_impl(PyTypeObject *type, int year, int week,
3414                            int weekday)
3415 /*[clinic end generated code: output=383d33d8dc7183a2 input=4f2c663c9d19c4ee]*/
3416 
3417 {
3418     PyDateTime_IsoCalendarDate *self;
3419     self = (PyDateTime_IsoCalendarDate *) type->tp_alloc(type, 3);
3420     if (self == NULL) {
3421         return NULL;
3422     }
3423 
3424     PyTuple_SET_ITEM(self, 0, PyLong_FromLong(year));
3425     PyTuple_SET_ITEM(self, 1, PyLong_FromLong(week));
3426     PyTuple_SET_ITEM(self, 2, PyLong_FromLong(weekday));
3427 
3428     return (PyObject *)self;
3429 }
3430 
3431 static PyObject *
date_isocalendar(PyDateTime_Date * self,PyObject * Py_UNUSED (ignored))3432 date_isocalendar(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
3433 {
3434     int  year         = GET_YEAR(self);
3435     int  week1_monday = iso_week1_monday(year);
3436     int today         = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
3437     int  week;
3438     int  day;
3439 
3440     week = divmod(today - week1_monday, 7, &day);
3441     if (week < 0) {
3442         --year;
3443         week1_monday = iso_week1_monday(year);
3444         week = divmod(today - week1_monday, 7, &day);
3445     }
3446     else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
3447         ++year;
3448         week = 0;
3449     }
3450 
3451     PyObject* v = iso_calendar_date_new_impl(&PyDateTime_IsoCalendarDateType,
3452                     year, week + 1, day + 1);
3453     if (v == NULL) {
3454         return NULL;
3455     }
3456     return v;
3457 }
3458 
3459 /* Miscellaneous methods. */
3460 
3461 static PyObject *
date_richcompare(PyObject * self,PyObject * other,int op)3462 date_richcompare(PyObject *self, PyObject *other, int op)
3463 {
3464     if (PyDate_Check(other)) {
3465         int diff = memcmp(((PyDateTime_Date *)self)->data,
3466                           ((PyDateTime_Date *)other)->data,
3467                           _PyDateTime_DATE_DATASIZE);
3468         return diff_to_bool(diff, op);
3469     }
3470     else
3471         Py_RETURN_NOTIMPLEMENTED;
3472 }
3473 
3474 static PyObject *
date_timetuple(PyDateTime_Date * self,PyObject * Py_UNUSED (ignored))3475 date_timetuple(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
3476 {
3477     return build_struct_time(GET_YEAR(self),
3478                              GET_MONTH(self),
3479                              GET_DAY(self),
3480                              0, 0, 0, -1);
3481 }
3482 
3483 static PyObject *
date_replace(PyDateTime_Date * self,PyObject * args,PyObject * kw)3484 date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
3485 {
3486     PyObject *clone;
3487     PyObject *tuple;
3488     int year = GET_YEAR(self);
3489     int month = GET_MONTH(self);
3490     int day = GET_DAY(self);
3491 
3492     if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
3493                                       &year, &month, &day))
3494         return NULL;
3495     tuple = Py_BuildValue("iii", year, month, day);
3496     if (tuple == NULL)
3497         return NULL;
3498     clone = date_new(Py_TYPE(self), tuple, NULL);
3499     Py_DECREF(tuple);
3500     return clone;
3501 }
3502 
3503 static Py_hash_t
generic_hash(unsigned char * data,int len)3504 generic_hash(unsigned char *data, int len)
3505 {
3506     return _Py_HashBytes(data, len);
3507 }
3508 
3509 
3510 static PyObject *date_getstate(PyDateTime_Date *self);
3511 
3512 static Py_hash_t
date_hash(PyDateTime_Date * self)3513 date_hash(PyDateTime_Date *self)
3514 {
3515     if (self->hashcode == -1) {
3516         self->hashcode = generic_hash(
3517             (unsigned char *)self->data, _PyDateTime_DATE_DATASIZE);
3518     }
3519 
3520     return self->hashcode;
3521 }
3522 
3523 static PyObject *
date_toordinal(PyDateTime_Date * self,PyObject * Py_UNUSED (ignored))3524 date_toordinal(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
3525 {
3526     return PyLong_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
3527                                      GET_DAY(self)));
3528 }
3529 
3530 static PyObject *
date_weekday(PyDateTime_Date * self,PyObject * Py_UNUSED (ignored))3531 date_weekday(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
3532 {
3533     int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
3534 
3535     return PyLong_FromLong(dow);
3536 }
3537 
3538 /* Pickle support, a simple use of __reduce__. */
3539 
3540 /* __getstate__ isn't exposed */
3541 static PyObject *
date_getstate(PyDateTime_Date * self)3542 date_getstate(PyDateTime_Date *self)
3543 {
3544     PyObject* field;
3545     field = PyBytes_FromStringAndSize((char*)self->data,
3546                                        _PyDateTime_DATE_DATASIZE);
3547     return Py_BuildValue("(N)", field);
3548 }
3549 
3550 static PyObject *
date_reduce(PyDateTime_Date * self,PyObject * arg)3551 date_reduce(PyDateTime_Date *self, PyObject *arg)
3552 {
3553     return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
3554 }
3555 
3556 static PyMethodDef date_methods[] = {
3557 
3558     /* Class methods: */
3559     DATETIME_DATE_FROMTIMESTAMP_METHODDEF
3560 
3561     {"fromordinal", (PyCFunction)date_fromordinal,      METH_VARARGS |
3562                                                     METH_CLASS,
3563      PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
3564                "ordinal.")},
3565 
3566      {"fromisoformat", (PyCFunction)date_fromisoformat,  METH_O |
3567                                                          METH_CLASS,
3568       PyDoc_STR("str -> Construct a date from a string in ISO 8601 format.")},
3569 
3570      {"fromisocalendar", _PyCFunction_CAST(date_fromisocalendar),
3571       METH_VARARGS | METH_KEYWORDS | METH_CLASS,
3572       PyDoc_STR("int, int, int -> Construct a date from the ISO year, week "
3573                 "number and weekday.\n\n"
3574                 "This is the inverse of the date.isocalendar() function")},
3575 
3576     {"today",         (PyCFunction)date_today,   METH_NOARGS | METH_CLASS,
3577      PyDoc_STR("Current date or datetime:  same as "
3578                "self.__class__.fromtimestamp(time.time()).")},
3579 
3580     /* Instance methods: */
3581 
3582     {"ctime",       (PyCFunction)date_ctime,        METH_NOARGS,
3583      PyDoc_STR("Return ctime() style string.")},
3584 
3585     {"strftime",        _PyCFunction_CAST(date_strftime),     METH_VARARGS | METH_KEYWORDS,
3586      PyDoc_STR("format -> strftime() style string.")},
3587 
3588     {"__format__",      (PyCFunction)date_format,       METH_VARARGS,
3589      PyDoc_STR("Formats self with strftime.")},
3590 
3591     {"timetuple",   (PyCFunction)date_timetuple,    METH_NOARGS,
3592      PyDoc_STR("Return time tuple, compatible with time.localtime().")},
3593 
3594     {"isocalendar", (PyCFunction)date_isocalendar,  METH_NOARGS,
3595      PyDoc_STR("Return a named tuple containing ISO year, week number, and "
3596                "weekday.")},
3597 
3598     {"isoformat",   (PyCFunction)date_isoformat,        METH_NOARGS,
3599      PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
3600 
3601     {"isoweekday",  (PyCFunction)date_isoweekday,   METH_NOARGS,
3602      PyDoc_STR("Return the day of the week represented by the date.\n"
3603                "Monday == 1 ... Sunday == 7")},
3604 
3605     {"toordinal",   (PyCFunction)date_toordinal,    METH_NOARGS,
3606      PyDoc_STR("Return proleptic Gregorian ordinal.  January 1 of year "
3607                "1 is day 1.")},
3608 
3609     {"weekday",     (PyCFunction)date_weekday,      METH_NOARGS,
3610      PyDoc_STR("Return the day of the week represented by the date.\n"
3611                "Monday == 0 ... Sunday == 6")},
3612 
3613     {"replace",     _PyCFunction_CAST(date_replace),      METH_VARARGS | METH_KEYWORDS,
3614      PyDoc_STR("Return date with new specified fields.")},
3615 
3616     {"__reduce__", (PyCFunction)date_reduce,        METH_NOARGS,
3617      PyDoc_STR("__reduce__() -> (cls, state)")},
3618 
3619     {NULL,      NULL}
3620 };
3621 
3622 static const char date_doc[] =
3623 PyDoc_STR("date(year, month, day) --> date object");
3624 
3625 static PyNumberMethods date_as_number = {
3626     date_add,                                           /* nb_add */
3627     date_subtract,                                      /* nb_subtract */
3628     0,                                                  /* nb_multiply */
3629     0,                                                  /* nb_remainder */
3630     0,                                                  /* nb_divmod */
3631     0,                                                  /* nb_power */
3632     0,                                                  /* nb_negative */
3633     0,                                                  /* nb_positive */
3634     0,                                                  /* nb_absolute */
3635     0,                                                  /* nb_bool */
3636 };
3637 
3638 static PyTypeObject PyDateTime_DateType = {
3639     PyVarObject_HEAD_INIT(NULL, 0)
3640     "datetime.date",                                    /* tp_name */
3641     sizeof(PyDateTime_Date),                            /* tp_basicsize */
3642     0,                                                  /* tp_itemsize */
3643     0,                                                  /* tp_dealloc */
3644     0,                                                  /* tp_vectorcall_offset */
3645     0,                                                  /* tp_getattr */
3646     0,                                                  /* tp_setattr */
3647     0,                                                  /* tp_as_async */
3648     (reprfunc)date_repr,                                /* tp_repr */
3649     &date_as_number,                                    /* tp_as_number */
3650     0,                                                  /* tp_as_sequence */
3651     0,                                                  /* tp_as_mapping */
3652     (hashfunc)date_hash,                                /* tp_hash */
3653     0,                                                  /* tp_call */
3654     (reprfunc)date_str,                                 /* tp_str */
3655     PyObject_GenericGetAttr,                            /* tp_getattro */
3656     0,                                                  /* tp_setattro */
3657     0,                                                  /* tp_as_buffer */
3658     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,           /* tp_flags */
3659     date_doc,                                           /* tp_doc */
3660     0,                                                  /* tp_traverse */
3661     0,                                                  /* tp_clear */
3662     date_richcompare,                                   /* tp_richcompare */
3663     0,                                                  /* tp_weaklistoffset */
3664     0,                                                  /* tp_iter */
3665     0,                                                  /* tp_iternext */
3666     date_methods,                                       /* tp_methods */
3667     0,                                                  /* tp_members */
3668     date_getset,                                        /* tp_getset */
3669     0,                                                  /* tp_base */
3670     0,                                                  /* tp_dict */
3671     0,                                                  /* tp_descr_get */
3672     0,                                                  /* tp_descr_set */
3673     0,                                                  /* tp_dictoffset */
3674     0,                                                  /* tp_init */
3675     0,                                                  /* tp_alloc */
3676     date_new,                                           /* tp_new */
3677     0,                                                  /* tp_free */
3678 };
3679 
3680 /*
3681  * PyDateTime_TZInfo implementation.
3682  */
3683 
3684 /* This is a pure abstract base class, so doesn't do anything beyond
3685  * raising NotImplemented exceptions.  Real tzinfo classes need
3686  * to derive from this.  This is mostly for clarity, and for efficiency in
3687  * datetime and time constructors (their tzinfo arguments need to
3688  * be subclasses of this tzinfo class, which is easy and quick to check).
3689  *
3690  * Note:  For reasons having to do with pickling of subclasses, we have
3691  * to allow tzinfo objects to be instantiated.  This wasn't an issue
3692  * in the Python implementation (__init__() could raise NotImplementedError
3693  * there without ill effect), but doing so in the C implementation hit a
3694  * brick wall.
3695  */
3696 
3697 static PyObject *
tzinfo_nogo(const char * methodname)3698 tzinfo_nogo(const char* methodname)
3699 {
3700     PyErr_Format(PyExc_NotImplementedError,
3701                  "a tzinfo subclass must implement %s()",
3702                  methodname);
3703     return NULL;
3704 }
3705 
3706 /* Methods.  A subclass must implement these. */
3707 
3708 static PyObject *
tzinfo_tzname(PyDateTime_TZInfo * self,PyObject * dt)3709 tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
3710 {
3711     return tzinfo_nogo("tzname");
3712 }
3713 
3714 static PyObject *
tzinfo_utcoffset(PyDateTime_TZInfo * self,PyObject * dt)3715 tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
3716 {
3717     return tzinfo_nogo("utcoffset");
3718 }
3719 
3720 static PyObject *
tzinfo_dst(PyDateTime_TZInfo * self,PyObject * dt)3721 tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
3722 {
3723     return tzinfo_nogo("dst");
3724 }
3725 
3726 
3727 static PyObject *add_datetime_timedelta(PyDateTime_DateTime *date,
3728                                         PyDateTime_Delta *delta,
3729                                         int factor);
3730 static PyObject *datetime_utcoffset(PyObject *self, PyObject *);
3731 static PyObject *datetime_dst(PyObject *self, PyObject *);
3732 
3733 static PyObject *
tzinfo_fromutc(PyDateTime_TZInfo * self,PyObject * dt)3734 tzinfo_fromutc(PyDateTime_TZInfo *self, PyObject *dt)
3735 {
3736     PyObject *result = NULL;
3737     PyObject *off = NULL, *dst = NULL;
3738     PyDateTime_Delta *delta = NULL;
3739 
3740     if (!PyDateTime_Check(dt)) {
3741         PyErr_SetString(PyExc_TypeError,
3742                         "fromutc: argument must be a datetime");
3743         return NULL;
3744     }
3745     if (GET_DT_TZINFO(dt) != (PyObject *)self) {
3746         PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3747                         "is not self");
3748         return NULL;
3749     }
3750 
3751     off = datetime_utcoffset(dt, NULL);
3752     if (off == NULL)
3753         return NULL;
3754     if (off == Py_None) {
3755         PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3756                         "utcoffset() result required");
3757         goto Fail;
3758     }
3759 
3760     dst = datetime_dst(dt, NULL);
3761     if (dst == NULL)
3762         goto Fail;
3763     if (dst == Py_None) {
3764         PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3765                         "dst() result required");
3766         goto Fail;
3767     }
3768 
3769     delta = (PyDateTime_Delta *)delta_subtract(off, dst);
3770     if (delta == NULL)
3771         goto Fail;
3772     result = add_datetime_timedelta((PyDateTime_DateTime *)dt, delta, 1);
3773     if (result == NULL)
3774         goto Fail;
3775 
3776     Py_DECREF(dst);
3777     dst = call_dst(GET_DT_TZINFO(dt), result);
3778     if (dst == NULL)
3779         goto Fail;
3780     if (dst == Py_None)
3781         goto Inconsistent;
3782     if (delta_bool((PyDateTime_Delta *)dst) != 0) {
3783         Py_SETREF(result, add_datetime_timedelta((PyDateTime_DateTime *)result,
3784                                                  (PyDateTime_Delta *)dst, 1));
3785         if (result == NULL)
3786             goto Fail;
3787     }
3788     Py_DECREF(delta);
3789     Py_DECREF(dst);
3790     Py_DECREF(off);
3791     return result;
3792 
3793 Inconsistent:
3794     PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave "
3795                     "inconsistent results; cannot convert");
3796 
3797     /* fall through to failure */
3798 Fail:
3799     Py_XDECREF(off);
3800     Py_XDECREF(dst);
3801     Py_XDECREF(delta);
3802     Py_XDECREF(result);
3803     return NULL;
3804 }
3805 
3806 /*
3807  * Pickle support.  This is solely so that tzinfo subclasses can use
3808  * pickling -- tzinfo itself is supposed to be uninstantiable.
3809  */
3810 
3811 static PyObject *
tzinfo_reduce(PyObject * self,PyObject * Py_UNUSED (ignored))3812 tzinfo_reduce(PyObject *self, PyObject *Py_UNUSED(ignored))
3813 {
3814     PyObject *args, *state;
3815     PyObject *getinitargs;
3816     _Py_IDENTIFIER(__getinitargs__);
3817 
3818     if (_PyObject_LookupAttrId(self, &PyId___getinitargs__, &getinitargs) < 0) {
3819         return NULL;
3820     }
3821     if (getinitargs != NULL) {
3822         args = PyObject_CallNoArgs(getinitargs);
3823         Py_DECREF(getinitargs);
3824     }
3825     else {
3826         args = PyTuple_New(0);
3827     }
3828     if (args == NULL) {
3829         return NULL;
3830     }
3831 
3832     state = _PyObject_GetState(self);
3833     if (state == NULL) {
3834         Py_DECREF(args);
3835         return NULL;
3836     }
3837 
3838     return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
3839 }
3840 
3841 static PyMethodDef tzinfo_methods[] = {
3842 
3843     {"tzname",          (PyCFunction)tzinfo_tzname,             METH_O,
3844      PyDoc_STR("datetime -> string name of time zone.")},
3845 
3846     {"utcoffset",       (PyCFunction)tzinfo_utcoffset,          METH_O,
3847      PyDoc_STR("datetime -> timedelta showing offset from UTC, negative "
3848            "values indicating West of UTC")},
3849 
3850     {"dst",             (PyCFunction)tzinfo_dst,                METH_O,
3851      PyDoc_STR("datetime -> DST offset as timedelta positive east of UTC.")},
3852 
3853     {"fromutc",         (PyCFunction)tzinfo_fromutc,            METH_O,
3854      PyDoc_STR("datetime in UTC -> datetime in local time.")},
3855 
3856     {"__reduce__",  tzinfo_reduce,             METH_NOARGS,
3857      PyDoc_STR("-> (cls, state)")},
3858 
3859     {NULL, NULL}
3860 };
3861 
3862 static const char tzinfo_doc[] =
3863 PyDoc_STR("Abstract base class for time zone info objects.");
3864 
3865 static PyTypeObject PyDateTime_TZInfoType = {
3866     PyVarObject_HEAD_INIT(NULL, 0)
3867     "datetime.tzinfo",                          /* tp_name */
3868     sizeof(PyDateTime_TZInfo),                  /* tp_basicsize */
3869     0,                                          /* tp_itemsize */
3870     0,                                          /* tp_dealloc */
3871     0,                                          /* tp_vectorcall_offset */
3872     0,                                          /* tp_getattr */
3873     0,                                          /* tp_setattr */
3874     0,                                          /* tp_as_async */
3875     0,                                          /* tp_repr */
3876     0,                                          /* tp_as_number */
3877     0,                                          /* tp_as_sequence */
3878     0,                                          /* tp_as_mapping */
3879     0,                                          /* tp_hash */
3880     0,                                          /* tp_call */
3881     0,                                          /* tp_str */
3882     PyObject_GenericGetAttr,                    /* tp_getattro */
3883     0,                                          /* tp_setattro */
3884     0,                                          /* tp_as_buffer */
3885     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,   /* tp_flags */
3886     tzinfo_doc,                                 /* tp_doc */
3887     0,                                          /* tp_traverse */
3888     0,                                          /* tp_clear */
3889     0,                                          /* tp_richcompare */
3890     0,                                          /* tp_weaklistoffset */
3891     0,                                          /* tp_iter */
3892     0,                                          /* tp_iternext */
3893     tzinfo_methods,                             /* tp_methods */
3894     0,                                          /* tp_members */
3895     0,                                          /* tp_getset */
3896     0,                                          /* tp_base */
3897     0,                                          /* tp_dict */
3898     0,                                          /* tp_descr_get */
3899     0,                                          /* tp_descr_set */
3900     0,                                          /* tp_dictoffset */
3901     0,                                          /* tp_init */
3902     0,                                          /* tp_alloc */
3903     PyType_GenericNew,                          /* tp_new */
3904     0,                                          /* tp_free */
3905 };
3906 
3907 static char *timezone_kws[] = {"offset", "name", NULL};
3908 
3909 static PyObject *
timezone_new(PyTypeObject * type,PyObject * args,PyObject * kw)3910 timezone_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3911 {
3912     PyObject *offset;
3913     PyObject *name = NULL;
3914     if (PyArg_ParseTupleAndKeywords(args, kw, "O!|U:timezone", timezone_kws,
3915                                     &PyDateTime_DeltaType, &offset, &name))
3916         return new_timezone(offset, name);
3917 
3918     return NULL;
3919 }
3920 
3921 static void
timezone_dealloc(PyDateTime_TimeZone * self)3922 timezone_dealloc(PyDateTime_TimeZone *self)
3923 {
3924     Py_CLEAR(self->offset);
3925     Py_CLEAR(self->name);
3926     Py_TYPE(self)->tp_free((PyObject *)self);
3927 }
3928 
3929 static PyObject *
timezone_richcompare(PyDateTime_TimeZone * self,PyDateTime_TimeZone * other,int op)3930 timezone_richcompare(PyDateTime_TimeZone *self,
3931                      PyDateTime_TimeZone *other, int op)
3932 {
3933     if (op != Py_EQ && op != Py_NE)
3934         Py_RETURN_NOTIMPLEMENTED;
3935     if (!PyTimezone_Check(other)) {
3936         Py_RETURN_NOTIMPLEMENTED;
3937     }
3938     return delta_richcompare(self->offset, other->offset, op);
3939 }
3940 
3941 static Py_hash_t
timezone_hash(PyDateTime_TimeZone * self)3942 timezone_hash(PyDateTime_TimeZone *self)
3943 {
3944     return delta_hash((PyDateTime_Delta *)self->offset);
3945 }
3946 
3947 /* Check argument type passed to tzname, utcoffset, or dst methods.
3948    Returns 0 for good argument.  Returns -1 and sets exception info
3949    otherwise.
3950  */
3951 static int
_timezone_check_argument(PyObject * dt,const char * meth)3952 _timezone_check_argument(PyObject *dt, const char *meth)
3953 {
3954     if (dt == Py_None || PyDateTime_Check(dt))
3955         return 0;
3956     PyErr_Format(PyExc_TypeError, "%s(dt) argument must be a datetime instance"
3957                  " or None, not %.200s", meth, Py_TYPE(dt)->tp_name);
3958     return -1;
3959 }
3960 
3961 static PyObject *
timezone_repr(PyDateTime_TimeZone * self)3962 timezone_repr(PyDateTime_TimeZone *self)
3963 {
3964     /* Note that although timezone is not subclassable, it is convenient
3965        to use Py_TYPE(self)->tp_name here. */
3966     const char *type_name = Py_TYPE(self)->tp_name;
3967 
3968     if (((PyObject *)self) == PyDateTime_TimeZone_UTC)
3969         return PyUnicode_FromFormat("%s.utc", type_name);
3970 
3971     if (self->name == NULL)
3972         return PyUnicode_FromFormat("%s(%R)", type_name, self->offset);
3973 
3974     return PyUnicode_FromFormat("%s(%R, %R)", type_name, self->offset,
3975                                 self->name);
3976 }
3977 
3978 
3979 static PyObject *
timezone_str(PyDateTime_TimeZone * self)3980 timezone_str(PyDateTime_TimeZone *self)
3981 {
3982     int hours, minutes, seconds, microseconds;
3983     PyObject *offset;
3984     char sign;
3985 
3986     if (self->name != NULL) {
3987         Py_INCREF(self->name);
3988         return self->name;
3989     }
3990     if ((PyObject *)self == PyDateTime_TimeZone_UTC ||
3991            (GET_TD_DAYS(self->offset) == 0 &&
3992             GET_TD_SECONDS(self->offset) == 0 &&
3993             GET_TD_MICROSECONDS(self->offset) == 0))
3994         return PyUnicode_FromString("UTC");
3995     /* Offset is normalized, so it is negative if days < 0 */
3996     if (GET_TD_DAYS(self->offset) < 0) {
3997         sign = '-';
3998         offset = delta_negative((PyDateTime_Delta *)self->offset);
3999         if (offset == NULL)
4000             return NULL;
4001     }
4002     else {
4003         sign = '+';
4004         offset = self->offset;
4005         Py_INCREF(offset);
4006     }
4007     /* Offset is not negative here. */
4008     microseconds = GET_TD_MICROSECONDS(offset);
4009     seconds = GET_TD_SECONDS(offset);
4010     Py_DECREF(offset);
4011     minutes = divmod(seconds, 60, &seconds);
4012     hours = divmod(minutes, 60, &minutes);
4013     if (microseconds != 0) {
4014         return PyUnicode_FromFormat("UTC%c%02d:%02d:%02d.%06d",
4015                                     sign, hours, minutes,
4016                                     seconds, microseconds);
4017     }
4018     if (seconds != 0) {
4019         return PyUnicode_FromFormat("UTC%c%02d:%02d:%02d",
4020                                     sign, hours, minutes, seconds);
4021     }
4022     return PyUnicode_FromFormat("UTC%c%02d:%02d", sign, hours, minutes);
4023 }
4024 
4025 static PyObject *
timezone_tzname(PyDateTime_TimeZone * self,PyObject * dt)4026 timezone_tzname(PyDateTime_TimeZone *self, PyObject *dt)
4027 {
4028     if (_timezone_check_argument(dt, "tzname") == -1)
4029         return NULL;
4030 
4031     return timezone_str(self);
4032 }
4033 
4034 static PyObject *
timezone_utcoffset(PyDateTime_TimeZone * self,PyObject * dt)4035 timezone_utcoffset(PyDateTime_TimeZone *self, PyObject *dt)
4036 {
4037     if (_timezone_check_argument(dt, "utcoffset") == -1)
4038         return NULL;
4039 
4040     Py_INCREF(self->offset);
4041     return self->offset;
4042 }
4043 
4044 static PyObject *
timezone_dst(PyObject * self,PyObject * dt)4045 timezone_dst(PyObject *self, PyObject *dt)
4046 {
4047     if (_timezone_check_argument(dt, "dst") == -1)
4048         return NULL;
4049 
4050     Py_RETURN_NONE;
4051 }
4052 
4053 static PyObject *
timezone_fromutc(PyDateTime_TimeZone * self,PyDateTime_DateTime * dt)4054 timezone_fromutc(PyDateTime_TimeZone *self, PyDateTime_DateTime *dt)
4055 {
4056     if (!PyDateTime_Check(dt)) {
4057         PyErr_SetString(PyExc_TypeError,
4058                         "fromutc: argument must be a datetime");
4059         return NULL;
4060     }
4061     if (!HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
4062         PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
4063                         "is not self");
4064         return NULL;
4065     }
4066 
4067     return add_datetime_timedelta(dt, (PyDateTime_Delta *)self->offset, 1);
4068 }
4069 
4070 static PyObject *
timezone_getinitargs(PyDateTime_TimeZone * self,PyObject * Py_UNUSED (ignored))4071 timezone_getinitargs(PyDateTime_TimeZone *self, PyObject *Py_UNUSED(ignored))
4072 {
4073     if (self->name == NULL)
4074         return Py_BuildValue("(O)", self->offset);
4075     return Py_BuildValue("(OO)", self->offset, self->name);
4076 }
4077 
4078 static PyMethodDef timezone_methods[] = {
4079     {"tzname", (PyCFunction)timezone_tzname, METH_O,
4080      PyDoc_STR("If name is specified when timezone is created, returns the name."
4081                "  Otherwise returns offset as 'UTC(+|-)HH:MM'.")},
4082 
4083     {"utcoffset", (PyCFunction)timezone_utcoffset, METH_O,
4084      PyDoc_STR("Return fixed offset.")},
4085 
4086     {"dst", (PyCFunction)timezone_dst, METH_O,
4087      PyDoc_STR("Return None.")},
4088 
4089     {"fromutc", (PyCFunction)timezone_fromutc, METH_O,
4090      PyDoc_STR("datetime in UTC -> datetime in local time.")},
4091 
4092     {"__getinitargs__", (PyCFunction)timezone_getinitargs, METH_NOARGS,
4093      PyDoc_STR("pickle support")},
4094 
4095     {NULL, NULL}
4096 };
4097 
4098 static const char timezone_doc[] =
4099 PyDoc_STR("Fixed offset from UTC implementation of tzinfo.");
4100 
4101 static PyTypeObject PyDateTime_TimeZoneType = {
4102     PyVarObject_HEAD_INIT(NULL, 0)
4103     "datetime.timezone",              /* tp_name */
4104     sizeof(PyDateTime_TimeZone),      /* tp_basicsize */
4105     0,                                /* tp_itemsize */
4106     (destructor)timezone_dealloc,     /* tp_dealloc */
4107     0,                                /* tp_vectorcall_offset */
4108     0,                                /* tp_getattr */
4109     0,                                /* tp_setattr */
4110     0,                                /* tp_as_async */
4111     (reprfunc)timezone_repr,          /* tp_repr */
4112     0,                                /* tp_as_number */
4113     0,                                /* tp_as_sequence */
4114     0,                                /* tp_as_mapping */
4115     (hashfunc)timezone_hash,          /* tp_hash */
4116     0,                                /* tp_call */
4117     (reprfunc)timezone_str,           /* tp_str */
4118     0,                                /* tp_getattro */
4119     0,                                /* tp_setattro */
4120     0,                                /* tp_as_buffer */
4121     Py_TPFLAGS_DEFAULT,               /* tp_flags */
4122     timezone_doc,                     /* tp_doc */
4123     0,                                /* tp_traverse */
4124     0,                                /* tp_clear */
4125     (richcmpfunc)timezone_richcompare,/* tp_richcompare */
4126     0,                                /* tp_weaklistoffset */
4127     0,                                /* tp_iter */
4128     0,                                /* tp_iternext */
4129     timezone_methods,                 /* tp_methods */
4130     0,                                /* tp_members */
4131     0,                                /* tp_getset */
4132     0,                                /* tp_base; filled in PyInit__datetime */
4133     0,                                /* tp_dict */
4134     0,                                /* tp_descr_get */
4135     0,                                /* tp_descr_set */
4136     0,                                /* tp_dictoffset */
4137     0,                                /* tp_init */
4138     0,                                /* tp_alloc */
4139     timezone_new,                     /* tp_new */
4140 };
4141 
4142 /*
4143  * PyDateTime_Time implementation.
4144  */
4145 
4146 /* Accessor properties.
4147  */
4148 
4149 static PyObject *
time_hour(PyDateTime_Time * self,void * unused)4150 time_hour(PyDateTime_Time *self, void *unused)
4151 {
4152     return PyLong_FromLong(TIME_GET_HOUR(self));
4153 }
4154 
4155 static PyObject *
time_minute(PyDateTime_Time * self,void * unused)4156 time_minute(PyDateTime_Time *self, void *unused)
4157 {
4158     return PyLong_FromLong(TIME_GET_MINUTE(self));
4159 }
4160 
4161 /* The name time_second conflicted with some platform header file. */
4162 static PyObject *
py_time_second(PyDateTime_Time * self,void * unused)4163 py_time_second(PyDateTime_Time *self, void *unused)
4164 {
4165     return PyLong_FromLong(TIME_GET_SECOND(self));
4166 }
4167 
4168 static PyObject *
time_microsecond(PyDateTime_Time * self,void * unused)4169 time_microsecond(PyDateTime_Time *self, void *unused)
4170 {
4171     return PyLong_FromLong(TIME_GET_MICROSECOND(self));
4172 }
4173 
4174 static PyObject *
time_tzinfo(PyDateTime_Time * self,void * unused)4175 time_tzinfo(PyDateTime_Time *self, void *unused)
4176 {
4177     PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
4178     Py_INCREF(result);
4179     return result;
4180 }
4181 
4182 static PyObject *
time_fold(PyDateTime_Time * self,void * unused)4183 time_fold(PyDateTime_Time *self, void *unused)
4184 {
4185     return PyLong_FromLong(TIME_GET_FOLD(self));
4186 }
4187 
4188 static PyGetSetDef time_getset[] = {
4189     {"hour",        (getter)time_hour},
4190     {"minute",      (getter)time_minute},
4191     {"second",      (getter)py_time_second},
4192     {"microsecond", (getter)time_microsecond},
4193     {"tzinfo",      (getter)time_tzinfo},
4194     {"fold",        (getter)time_fold},
4195     {NULL}
4196 };
4197 
4198 /*
4199  * Constructors.
4200  */
4201 
4202 static char *time_kws[] = {"hour", "minute", "second", "microsecond",
4203                            "tzinfo", "fold", NULL};
4204 
4205 static PyObject *
time_from_pickle(PyTypeObject * type,PyObject * state,PyObject * tzinfo)4206 time_from_pickle(PyTypeObject *type, PyObject *state, PyObject *tzinfo)
4207 {
4208     PyDateTime_Time *me;
4209     char aware = (char)(tzinfo != Py_None);
4210 
4211     if (aware && check_tzinfo_subclass(tzinfo) < 0) {
4212         PyErr_SetString(PyExc_TypeError, "bad tzinfo state arg");
4213         return NULL;
4214     }
4215 
4216     me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
4217     if (me != NULL) {
4218         const char *pdata = PyBytes_AS_STRING(state);
4219 
4220         memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
4221         me->hashcode = -1;
4222         me->hastzinfo = aware;
4223         if (aware) {
4224             Py_INCREF(tzinfo);
4225             me->tzinfo = tzinfo;
4226         }
4227         if (pdata[0] & (1 << 7)) {
4228             me->data[0] -= 128;
4229             me->fold = 1;
4230         }
4231         else {
4232             me->fold = 0;
4233         }
4234     }
4235     return (PyObject *)me;
4236 }
4237 
4238 static PyObject *
time_new(PyTypeObject * type,PyObject * args,PyObject * kw)4239 time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
4240 {
4241     PyObject *self = NULL;
4242     int hour = 0;
4243     int minute = 0;
4244     int second = 0;
4245     int usecond = 0;
4246     PyObject *tzinfo = Py_None;
4247     int fold = 0;
4248 
4249     /* Check for invocation from pickle with __getstate__ state */
4250     if (PyTuple_GET_SIZE(args) >= 1 && PyTuple_GET_SIZE(args) <= 2) {
4251         PyObject *state = PyTuple_GET_ITEM(args, 0);
4252         if (PyTuple_GET_SIZE(args) == 2) {
4253             tzinfo = PyTuple_GET_ITEM(args, 1);
4254         }
4255         if (PyBytes_Check(state)) {
4256             if (PyBytes_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
4257                 (0x7F & ((unsigned char) (PyBytes_AS_STRING(state)[0]))) < 24)
4258             {
4259                 return time_from_pickle(type, state, tzinfo);
4260             }
4261         }
4262         else if (PyUnicode_Check(state)) {
4263             if (PyUnicode_READY(state)) {
4264                 return NULL;
4265             }
4266             if (PyUnicode_GET_LENGTH(state) == _PyDateTime_TIME_DATASIZE &&
4267                 (0x7F & PyUnicode_READ_CHAR(state, 0)) < 24)
4268             {
4269                 state = PyUnicode_AsLatin1String(state);
4270                 if (state == NULL) {
4271                     if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) {
4272                         /* More informative error message. */
4273                         PyErr_SetString(PyExc_ValueError,
4274                             "Failed to encode latin1 string when unpickling "
4275                             "a time object. "
4276                             "pickle.load(data, encoding='latin1') is assumed.");
4277                     }
4278                     return NULL;
4279                 }
4280                 self = time_from_pickle(type, state, tzinfo);
4281                 Py_DECREF(state);
4282                 return self;
4283             }
4284         }
4285         tzinfo = Py_None;
4286     }
4287 
4288     if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i", time_kws,
4289                                     &hour, &minute, &second, &usecond,
4290                                     &tzinfo, &fold)) {
4291         self = new_time_ex2(hour, minute, second, usecond, tzinfo, fold,
4292                             type);
4293     }
4294     return self;
4295 }
4296 
4297 /*
4298  * Destructor.
4299  */
4300 
4301 static void
time_dealloc(PyDateTime_Time * self)4302 time_dealloc(PyDateTime_Time *self)
4303 {
4304     if (HASTZINFO(self)) {
4305         Py_XDECREF(self->tzinfo);
4306     }
4307     Py_TYPE(self)->tp_free((PyObject *)self);
4308 }
4309 
4310 /*
4311  * Indirect access to tzinfo methods.
4312  */
4313 
4314 /* These are all METH_NOARGS, so don't need to check the arglist. */
4315 static PyObject *
time_utcoffset(PyObject * self,PyObject * unused)4316 time_utcoffset(PyObject *self, PyObject *unused) {
4317     return call_utcoffset(GET_TIME_TZINFO(self), Py_None);
4318 }
4319 
4320 static PyObject *
time_dst(PyObject * self,PyObject * unused)4321 time_dst(PyObject *self, PyObject *unused) {
4322     return call_dst(GET_TIME_TZINFO(self), Py_None);
4323 }
4324 
4325 static PyObject *
time_tzname(PyDateTime_Time * self,PyObject * unused)4326 time_tzname(PyDateTime_Time *self, PyObject *unused) {
4327     return call_tzname(GET_TIME_TZINFO(self), Py_None);
4328 }
4329 
4330 /*
4331  * Various ways to turn a time into a string.
4332  */
4333 
4334 static PyObject *
time_repr(PyDateTime_Time * self)4335 time_repr(PyDateTime_Time *self)
4336 {
4337     const char *type_name = Py_TYPE(self)->tp_name;
4338     int h = TIME_GET_HOUR(self);
4339     int m = TIME_GET_MINUTE(self);
4340     int s = TIME_GET_SECOND(self);
4341     int us = TIME_GET_MICROSECOND(self);
4342     int fold = TIME_GET_FOLD(self);
4343     PyObject *result = NULL;
4344 
4345     if (us)
4346         result = PyUnicode_FromFormat("%s(%d, %d, %d, %d)",
4347                                       type_name, h, m, s, us);
4348     else if (s)
4349         result = PyUnicode_FromFormat("%s(%d, %d, %d)",
4350                                       type_name, h, m, s);
4351     else
4352         result = PyUnicode_FromFormat("%s(%d, %d)", type_name, h, m);
4353     if (result != NULL && HASTZINFO(self))
4354         result = append_keyword_tzinfo(result, self->tzinfo);
4355     if (result != NULL && fold)
4356         result = append_keyword_fold(result, fold);
4357     return result;
4358 }
4359 
4360 static PyObject *
time_str(PyDateTime_Time * self)4361 time_str(PyDateTime_Time *self)
4362 {
4363     return _PyObject_CallMethodIdNoArgs((PyObject *)self, &PyId_isoformat);
4364 }
4365 
4366 static PyObject *
time_isoformat(PyDateTime_Time * self,PyObject * args,PyObject * kw)4367 time_isoformat(PyDateTime_Time *self, PyObject *args, PyObject *kw)
4368 {
4369     char buf[100];
4370     const char *timespec = NULL;
4371     static char *keywords[] = {"timespec", NULL};
4372     PyObject *result;
4373     int us = TIME_GET_MICROSECOND(self);
4374     static const char *specs[][2] = {
4375         {"hours", "%02d"},
4376         {"minutes", "%02d:%02d"},
4377         {"seconds", "%02d:%02d:%02d"},
4378         {"milliseconds", "%02d:%02d:%02d.%03d"},
4379         {"microseconds", "%02d:%02d:%02d.%06d"},
4380     };
4381     size_t given_spec;
4382 
4383     if (!PyArg_ParseTupleAndKeywords(args, kw, "|s:isoformat", keywords, &timespec))
4384         return NULL;
4385 
4386     if (timespec == NULL || strcmp(timespec, "auto") == 0) {
4387         if (us == 0) {
4388             /* seconds */
4389             given_spec = 2;
4390         }
4391         else {
4392             /* microseconds */
4393             given_spec = 4;
4394         }
4395     }
4396     else {
4397         for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) {
4398             if (strcmp(timespec, specs[given_spec][0]) == 0) {
4399                 if (given_spec == 3) {
4400                     /* milliseconds */
4401                     us = us / 1000;
4402                 }
4403                 break;
4404             }
4405         }
4406     }
4407 
4408     if (given_spec == Py_ARRAY_LENGTH(specs)) {
4409         PyErr_Format(PyExc_ValueError, "Unknown timespec value");
4410         return NULL;
4411     }
4412     else {
4413         result = PyUnicode_FromFormat(specs[given_spec][1],
4414                                       TIME_GET_HOUR(self), TIME_GET_MINUTE(self),
4415                                       TIME_GET_SECOND(self), us);
4416     }
4417 
4418     if (result == NULL || !HASTZINFO(self) || self->tzinfo == Py_None)
4419         return result;
4420 
4421     /* We need to append the UTC offset. */
4422     if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
4423                          Py_None) < 0) {
4424         Py_DECREF(result);
4425         return NULL;
4426     }
4427     PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buf));
4428     return result;
4429 }
4430 
4431 static PyObject *
time_strftime(PyDateTime_Time * self,PyObject * args,PyObject * kw)4432 time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
4433 {
4434     PyObject *result;
4435     PyObject *tuple;
4436     PyObject *format;
4437     static char *keywords[] = {"format", NULL};
4438 
4439     if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
4440                                       &format))
4441         return NULL;
4442 
4443     /* Python's strftime does insane things with the year part of the
4444      * timetuple.  The year is forced to (the otherwise nonsensical)
4445      * 1900 to work around that.
4446      */
4447     tuple = Py_BuildValue("iiiiiiiii",
4448                           1900, 1, 1, /* year, month, day */
4449                   TIME_GET_HOUR(self),
4450                   TIME_GET_MINUTE(self),
4451                   TIME_GET_SECOND(self),
4452                   0, 1, -1); /* weekday, daynum, dst */
4453     if (tuple == NULL)
4454         return NULL;
4455     assert(PyTuple_Size(tuple) == 9);
4456     result = wrap_strftime((PyObject *)self, format, tuple,
4457                            Py_None);
4458     Py_DECREF(tuple);
4459     return result;
4460 }
4461 
4462 /*
4463  * Miscellaneous methods.
4464  */
4465 
4466 static PyObject *
time_richcompare(PyObject * self,PyObject * other,int op)4467 time_richcompare(PyObject *self, PyObject *other, int op)
4468 {
4469     PyObject *result = NULL;
4470     PyObject *offset1, *offset2;
4471     int diff;
4472 
4473     if (! PyTime_Check(other))
4474         Py_RETURN_NOTIMPLEMENTED;
4475 
4476     if (GET_TIME_TZINFO(self) == GET_TIME_TZINFO(other)) {
4477         diff = memcmp(((PyDateTime_Time *)self)->data,
4478                       ((PyDateTime_Time *)other)->data,
4479                       _PyDateTime_TIME_DATASIZE);
4480         return diff_to_bool(diff, op);
4481     }
4482     offset1 = time_utcoffset(self, NULL);
4483     if (offset1 == NULL)
4484         return NULL;
4485     offset2 = time_utcoffset(other, NULL);
4486     if (offset2 == NULL)
4487         goto done;
4488     /* If they're both naive, or both aware and have the same offsets,
4489      * we get off cheap.  Note that if they're both naive, offset1 ==
4490      * offset2 == Py_None at this point.
4491      */
4492     if ((offset1 == offset2) ||
4493         (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
4494          delta_cmp(offset1, offset2) == 0)) {
4495         diff = memcmp(((PyDateTime_Time *)self)->data,
4496                       ((PyDateTime_Time *)other)->data,
4497                       _PyDateTime_TIME_DATASIZE);
4498         result = diff_to_bool(diff, op);
4499     }
4500     /* The hard case: both aware with different UTC offsets */
4501     else if (offset1 != Py_None && offset2 != Py_None) {
4502         int offsecs1, offsecs2;
4503         assert(offset1 != offset2); /* else last "if" handled it */
4504         offsecs1 = TIME_GET_HOUR(self) * 3600 +
4505                    TIME_GET_MINUTE(self) * 60 +
4506                    TIME_GET_SECOND(self) -
4507                    GET_TD_DAYS(offset1) * 86400 -
4508                    GET_TD_SECONDS(offset1);
4509         offsecs2 = TIME_GET_HOUR(other) * 3600 +
4510                    TIME_GET_MINUTE(other) * 60 +
4511                    TIME_GET_SECOND(other) -
4512                    GET_TD_DAYS(offset2) * 86400 -
4513                    GET_TD_SECONDS(offset2);
4514         diff = offsecs1 - offsecs2;
4515         if (diff == 0)
4516             diff = TIME_GET_MICROSECOND(self) -
4517                    TIME_GET_MICROSECOND(other);
4518         result = diff_to_bool(diff, op);
4519     }
4520     else if (op == Py_EQ) {
4521         result = Py_False;
4522         Py_INCREF(result);
4523     }
4524     else if (op == Py_NE) {
4525         result = Py_True;
4526         Py_INCREF(result);
4527     }
4528     else {
4529         PyErr_SetString(PyExc_TypeError,
4530                         "can't compare offset-naive and "
4531                         "offset-aware times");
4532     }
4533  done:
4534     Py_DECREF(offset1);
4535     Py_XDECREF(offset2);
4536     return result;
4537 }
4538 
4539 static Py_hash_t
time_hash(PyDateTime_Time * self)4540 time_hash(PyDateTime_Time *self)
4541 {
4542     if (self->hashcode == -1) {
4543         PyObject *offset, *self0;
4544         if (TIME_GET_FOLD(self)) {
4545             self0 = new_time_ex2(TIME_GET_HOUR(self),
4546                                  TIME_GET_MINUTE(self),
4547                                  TIME_GET_SECOND(self),
4548                                  TIME_GET_MICROSECOND(self),
4549                                  HASTZINFO(self) ? self->tzinfo : Py_None,
4550                                  0, Py_TYPE(self));
4551             if (self0 == NULL)
4552                 return -1;
4553         }
4554         else {
4555             self0 = (PyObject *)self;
4556             Py_INCREF(self0);
4557         }
4558         offset = time_utcoffset(self0, NULL);
4559         Py_DECREF(self0);
4560 
4561         if (offset == NULL)
4562             return -1;
4563 
4564         /* Reduce this to a hash of another object. */
4565         if (offset == Py_None)
4566             self->hashcode = generic_hash(
4567                 (unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
4568         else {
4569             PyObject *temp1, *temp2;
4570             int seconds, microseconds;
4571             assert(HASTZINFO(self));
4572             seconds = TIME_GET_HOUR(self) * 3600 +
4573                       TIME_GET_MINUTE(self) * 60 +
4574                       TIME_GET_SECOND(self);
4575             microseconds = TIME_GET_MICROSECOND(self);
4576             temp1 = new_delta(0, seconds, microseconds, 1);
4577             if (temp1 == NULL) {
4578                 Py_DECREF(offset);
4579                 return -1;
4580             }
4581             temp2 = delta_subtract(temp1, offset);
4582             Py_DECREF(temp1);
4583             if (temp2 == NULL) {
4584                 Py_DECREF(offset);
4585                 return -1;
4586             }
4587             self->hashcode = PyObject_Hash(temp2);
4588             Py_DECREF(temp2);
4589         }
4590         Py_DECREF(offset);
4591     }
4592     return self->hashcode;
4593 }
4594 
4595 static PyObject *
time_replace(PyDateTime_Time * self,PyObject * args,PyObject * kw)4596 time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
4597 {
4598     PyObject *clone;
4599     PyObject *tuple;
4600     int hh = TIME_GET_HOUR(self);
4601     int mm = TIME_GET_MINUTE(self);
4602     int ss = TIME_GET_SECOND(self);
4603     int us = TIME_GET_MICROSECOND(self);
4604     PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
4605     int fold = TIME_GET_FOLD(self);
4606 
4607     if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i:replace",
4608                                       time_kws,
4609                                       &hh, &mm, &ss, &us, &tzinfo, &fold))
4610         return NULL;
4611     if (fold != 0 && fold != 1) {
4612         PyErr_SetString(PyExc_ValueError,
4613                         "fold must be either 0 or 1");
4614         return NULL;
4615     }
4616     tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
4617     if (tuple == NULL)
4618         return NULL;
4619     clone = time_new(Py_TYPE(self), tuple, NULL);
4620     if (clone != NULL) {
4621         TIME_SET_FOLD(clone, fold);
4622     }
4623     Py_DECREF(tuple);
4624     return clone;
4625 }
4626 
4627 static PyObject *
time_fromisoformat(PyObject * cls,PyObject * tstr)4628 time_fromisoformat(PyObject *cls, PyObject *tstr) {
4629     assert(tstr != NULL);
4630 
4631     if (!PyUnicode_Check(tstr)) {
4632         PyErr_SetString(PyExc_TypeError, "fromisoformat: argument must be str");
4633         return NULL;
4634     }
4635 
4636     Py_ssize_t len;
4637     const char *p = PyUnicode_AsUTF8AndSize(tstr, &len);
4638 
4639     if (p == NULL) {
4640         goto invalid_string_error;
4641     }
4642 
4643     // The spec actually requires that time-only ISO 8601 strings start with
4644     // T, but the extended format allows this to be omitted as long as there
4645     // is no ambiguity with date strings.
4646     if (*p == 'T') {
4647         ++p;
4648         len -= 1;
4649     }
4650 
4651     int hour = 0, minute = 0, second = 0, microsecond = 0;
4652     int tzoffset, tzimicrosecond = 0;
4653     int rv = parse_isoformat_time(p, len,
4654                                   &hour, &minute, &second, &microsecond,
4655                                   &tzoffset, &tzimicrosecond);
4656 
4657     if (rv < 0) {
4658         goto invalid_string_error;
4659     }
4660 
4661     PyObject *tzinfo = tzinfo_from_isoformat_results(rv, tzoffset,
4662                                                      tzimicrosecond);
4663 
4664     if (tzinfo == NULL) {
4665         return NULL;
4666     }
4667 
4668     PyObject *t;
4669     if ( (PyTypeObject *)cls == &PyDateTime_TimeType ) {
4670         t = new_time(hour, minute, second, microsecond, tzinfo, 0);
4671     } else {
4672         t = PyObject_CallFunction(cls, "iiiiO",
4673                                   hour, minute, second, microsecond, tzinfo);
4674     }
4675 
4676     Py_DECREF(tzinfo);
4677     return t;
4678 
4679 invalid_string_error:
4680     PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", tstr);
4681     return NULL;
4682 }
4683 
4684 
4685 /* Pickle support, a simple use of __reduce__. */
4686 
4687 /* Let basestate be the non-tzinfo data string.
4688  * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4689  * So it's a tuple in any (non-error) case.
4690  * __getstate__ isn't exposed.
4691  */
4692 static PyObject *
time_getstate(PyDateTime_Time * self,int proto)4693 time_getstate(PyDateTime_Time *self, int proto)
4694 {
4695     PyObject *basestate;
4696     PyObject *result = NULL;
4697 
4698     basestate =  PyBytes_FromStringAndSize((char *)self->data,
4699                                             _PyDateTime_TIME_DATASIZE);
4700     if (basestate != NULL) {
4701         if (proto > 3 && TIME_GET_FOLD(self))
4702             /* Set the first bit of the first byte */
4703             PyBytes_AS_STRING(basestate)[0] |= (1 << 7);
4704         if (! HASTZINFO(self) || self->tzinfo == Py_None)
4705             result = PyTuple_Pack(1, basestate);
4706         else
4707             result = PyTuple_Pack(2, basestate, self->tzinfo);
4708         Py_DECREF(basestate);
4709     }
4710     return result;
4711 }
4712 
4713 static PyObject *
time_reduce_ex(PyDateTime_Time * self,PyObject * args)4714 time_reduce_ex(PyDateTime_Time *self, PyObject *args)
4715 {
4716     int proto;
4717     if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto))
4718         return NULL;
4719 
4720     return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, proto));
4721 }
4722 
4723 static PyObject *
time_reduce(PyDateTime_Time * self,PyObject * arg)4724 time_reduce(PyDateTime_Time *self, PyObject *arg)
4725 {
4726     return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, 2));
4727 }
4728 
4729 static PyMethodDef time_methods[] = {
4730 
4731     {"isoformat",   _PyCFunction_CAST(time_isoformat),        METH_VARARGS | METH_KEYWORDS,
4732      PyDoc_STR("Return string in ISO 8601 format, [HH[:MM[:SS[.mmm[uuu]]]]]"
4733                "[+HH:MM].\n\n"
4734                "The optional argument timespec specifies the number "
4735                "of additional terms\nof the time to include. Valid "
4736                "options are 'auto', 'hours', 'minutes',\n'seconds', "
4737                "'milliseconds' and 'microseconds'.\n")},
4738 
4739     {"strftime",        _PyCFunction_CAST(time_strftime),     METH_VARARGS | METH_KEYWORDS,
4740      PyDoc_STR("format -> strftime() style string.")},
4741 
4742     {"__format__",      (PyCFunction)date_format,       METH_VARARGS,
4743      PyDoc_STR("Formats self with strftime.")},
4744 
4745     {"utcoffset",       (PyCFunction)time_utcoffset,    METH_NOARGS,
4746      PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
4747 
4748     {"tzname",          (PyCFunction)time_tzname,       METH_NOARGS,
4749      PyDoc_STR("Return self.tzinfo.tzname(self).")},
4750 
4751     {"dst",             (PyCFunction)time_dst,          METH_NOARGS,
4752      PyDoc_STR("Return self.tzinfo.dst(self).")},
4753 
4754     {"replace",     _PyCFunction_CAST(time_replace),          METH_VARARGS | METH_KEYWORDS,
4755      PyDoc_STR("Return time with new specified fields.")},
4756 
4757      {"fromisoformat", (PyCFunction)time_fromisoformat, METH_O | METH_CLASS,
4758      PyDoc_STR("string -> time from a string in ISO 8601 format")},
4759 
4760     {"__reduce_ex__", (PyCFunction)time_reduce_ex,        METH_VARARGS,
4761      PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")},
4762 
4763     {"__reduce__", (PyCFunction)time_reduce,        METH_NOARGS,
4764      PyDoc_STR("__reduce__() -> (cls, state)")},
4765 
4766     {NULL,      NULL}
4767 };
4768 
4769 static const char time_doc[] =
4770 PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
4771 \n\
4772 All arguments are optional. tzinfo may be None, or an instance of\n\
4773 a tzinfo subclass. The remaining arguments may be ints.\n");
4774 
4775 static PyTypeObject PyDateTime_TimeType = {
4776     PyVarObject_HEAD_INIT(NULL, 0)
4777     "datetime.time",                            /* tp_name */
4778     sizeof(PyDateTime_Time),                    /* tp_basicsize */
4779     0,                                          /* tp_itemsize */
4780     (destructor)time_dealloc,                   /* tp_dealloc */
4781     0,                                          /* tp_vectorcall_offset */
4782     0,                                          /* tp_getattr */
4783     0,                                          /* tp_setattr */
4784     0,                                          /* tp_as_async */
4785     (reprfunc)time_repr,                        /* tp_repr */
4786     0,                                          /* tp_as_number */
4787     0,                                          /* tp_as_sequence */
4788     0,                                          /* tp_as_mapping */
4789     (hashfunc)time_hash,                        /* tp_hash */
4790     0,                                          /* tp_call */
4791     (reprfunc)time_str,                         /* tp_str */
4792     PyObject_GenericGetAttr,                    /* tp_getattro */
4793     0,                                          /* tp_setattro */
4794     0,                                          /* tp_as_buffer */
4795     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4796     time_doc,                                   /* tp_doc */
4797     0,                                          /* tp_traverse */
4798     0,                                          /* tp_clear */
4799     time_richcompare,                           /* tp_richcompare */
4800     0,                                          /* tp_weaklistoffset */
4801     0,                                          /* tp_iter */
4802     0,                                          /* tp_iternext */
4803     time_methods,                               /* tp_methods */
4804     0,                                          /* tp_members */
4805     time_getset,                                /* tp_getset */
4806     0,                                          /* tp_base */
4807     0,                                          /* tp_dict */
4808     0,                                          /* tp_descr_get */
4809     0,                                          /* tp_descr_set */
4810     0,                                          /* tp_dictoffset */
4811     0,                                          /* tp_init */
4812     time_alloc,                                 /* tp_alloc */
4813     time_new,                                   /* tp_new */
4814     0,                                          /* tp_free */
4815 };
4816 
4817 /*
4818  * PyDateTime_DateTime implementation.
4819  */
4820 
4821 /* Accessor properties.  Properties for day, month, and year are inherited
4822  * from date.
4823  */
4824 
4825 static PyObject *
datetime_hour(PyDateTime_DateTime * self,void * unused)4826 datetime_hour(PyDateTime_DateTime *self, void *unused)
4827 {
4828     return PyLong_FromLong(DATE_GET_HOUR(self));
4829 }
4830 
4831 static PyObject *
datetime_minute(PyDateTime_DateTime * self,void * unused)4832 datetime_minute(PyDateTime_DateTime *self, void *unused)
4833 {
4834     return PyLong_FromLong(DATE_GET_MINUTE(self));
4835 }
4836 
4837 static PyObject *
datetime_second(PyDateTime_DateTime * self,void * unused)4838 datetime_second(PyDateTime_DateTime *self, void *unused)
4839 {
4840     return PyLong_FromLong(DATE_GET_SECOND(self));
4841 }
4842 
4843 static PyObject *
datetime_microsecond(PyDateTime_DateTime * self,void * unused)4844 datetime_microsecond(PyDateTime_DateTime *self, void *unused)
4845 {
4846     return PyLong_FromLong(DATE_GET_MICROSECOND(self));
4847 }
4848 
4849 static PyObject *
datetime_tzinfo(PyDateTime_DateTime * self,void * unused)4850 datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
4851 {
4852     PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
4853     Py_INCREF(result);
4854     return result;
4855 }
4856 
4857 static PyObject *
datetime_fold(PyDateTime_DateTime * self,void * unused)4858 datetime_fold(PyDateTime_DateTime *self, void *unused)
4859 {
4860     return PyLong_FromLong(DATE_GET_FOLD(self));
4861 }
4862 
4863 static PyGetSetDef datetime_getset[] = {
4864     {"hour",        (getter)datetime_hour},
4865     {"minute",      (getter)datetime_minute},
4866     {"second",      (getter)datetime_second},
4867     {"microsecond", (getter)datetime_microsecond},
4868     {"tzinfo",      (getter)datetime_tzinfo},
4869     {"fold",        (getter)datetime_fold},
4870     {NULL}
4871 };
4872 
4873 /*
4874  * Constructors.
4875  */
4876 
4877 static char *datetime_kws[] = {
4878     "year", "month", "day", "hour", "minute", "second",
4879     "microsecond", "tzinfo", "fold", NULL
4880 };
4881 
4882 static PyObject *
datetime_from_pickle(PyTypeObject * type,PyObject * state,PyObject * tzinfo)4883 datetime_from_pickle(PyTypeObject *type, PyObject *state, PyObject *tzinfo)
4884 {
4885     PyDateTime_DateTime *me;
4886     char aware = (char)(tzinfo != Py_None);
4887 
4888     if (aware && check_tzinfo_subclass(tzinfo) < 0) {
4889         PyErr_SetString(PyExc_TypeError, "bad tzinfo state arg");
4890         return NULL;
4891     }
4892 
4893     me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
4894     if (me != NULL) {
4895         const char *pdata = PyBytes_AS_STRING(state);
4896 
4897         memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
4898         me->hashcode = -1;
4899         me->hastzinfo = aware;
4900         if (aware) {
4901             Py_INCREF(tzinfo);
4902             me->tzinfo = tzinfo;
4903         }
4904         if (pdata[2] & (1 << 7)) {
4905             me->data[2] -= 128;
4906             me->fold = 1;
4907         }
4908         else {
4909             me->fold = 0;
4910         }
4911     }
4912     return (PyObject *)me;
4913 }
4914 
4915 static PyObject *
datetime_new(PyTypeObject * type,PyObject * args,PyObject * kw)4916 datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
4917 {
4918     PyObject *self = NULL;
4919     int year;
4920     int month;
4921     int day;
4922     int hour = 0;
4923     int minute = 0;
4924     int second = 0;
4925     int usecond = 0;
4926     int fold = 0;
4927     PyObject *tzinfo = Py_None;
4928 
4929     /* Check for invocation from pickle with __getstate__ state */
4930     if (PyTuple_GET_SIZE(args) >= 1 && PyTuple_GET_SIZE(args) <= 2) {
4931         PyObject *state = PyTuple_GET_ITEM(args, 0);
4932         if (PyTuple_GET_SIZE(args) == 2) {
4933             tzinfo = PyTuple_GET_ITEM(args, 1);
4934         }
4935         if (PyBytes_Check(state)) {
4936             if (PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
4937                 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2] & 0x7F))
4938             {
4939                 return datetime_from_pickle(type, state, tzinfo);
4940             }
4941         }
4942         else if (PyUnicode_Check(state)) {
4943             if (PyUnicode_READY(state)) {
4944                 return NULL;
4945             }
4946             if (PyUnicode_GET_LENGTH(state) == _PyDateTime_DATETIME_DATASIZE &&
4947                 MONTH_IS_SANE(PyUnicode_READ_CHAR(state, 2) & 0x7F))
4948             {
4949                 state = PyUnicode_AsLatin1String(state);
4950                 if (state == NULL) {
4951                     if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) {
4952                         /* More informative error message. */
4953                         PyErr_SetString(PyExc_ValueError,
4954                             "Failed to encode latin1 string when unpickling "
4955                             "a datetime object. "
4956                             "pickle.load(data, encoding='latin1') is assumed.");
4957                     }
4958                     return NULL;
4959                 }
4960                 self = datetime_from_pickle(type, state, tzinfo);
4961                 Py_DECREF(state);
4962                 return self;
4963             }
4964         }
4965         tzinfo = Py_None;
4966     }
4967 
4968     if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO$i", datetime_kws,
4969                                     &year, &month, &day, &hour, &minute,
4970                                     &second, &usecond, &tzinfo, &fold)) {
4971         self = new_datetime_ex2(year, month, day,
4972                                 hour, minute, second, usecond,
4973                                 tzinfo, fold, type);
4974     }
4975     return self;
4976 }
4977 
4978 /* TM_FUNC is the shared type of _PyTime_localtime() and
4979  * _PyTime_gmtime(). */
4980 typedef int (*TM_FUNC)(time_t timer, struct tm*);
4981 
4982 /* As of version 2015f max fold in IANA database is
4983  * 23 hours at 1969-09-30 13:00:00 in Kwajalein. */
4984 static long long max_fold_seconds = 24 * 3600;
4985 /* NB: date(1970,1,1).toordinal() == 719163 */
4986 static long long epoch = 719163LL * 24 * 60 * 60;
4987 
4988 static long long
utc_to_seconds(int year,int month,int day,int hour,int minute,int second)4989 utc_to_seconds(int year, int month, int day,
4990                int hour, int minute, int second)
4991 {
4992     long long ordinal;
4993 
4994     /* ymd_to_ord() doesn't support year <= 0 */
4995     if (year < MINYEAR || year > MAXYEAR) {
4996         PyErr_Format(PyExc_ValueError, "year %i is out of range", year);
4997         return -1;
4998     }
4999 
5000     ordinal = ymd_to_ord(year, month, day);
5001     return ((ordinal * 24 + hour) * 60 + minute) * 60 + second;
5002 }
5003 
5004 static long long
local(long long u)5005 local(long long u)
5006 {
5007     struct tm local_time;
5008     time_t t;
5009     u -= epoch;
5010     t = u;
5011     if (t != u) {
5012         PyErr_SetString(PyExc_OverflowError,
5013         "timestamp out of range for platform time_t");
5014         return -1;
5015     }
5016     if (_PyTime_localtime(t, &local_time) != 0)
5017         return -1;
5018     return utc_to_seconds(local_time.tm_year + 1900,
5019                           local_time.tm_mon + 1,
5020                           local_time.tm_mday,
5021                           local_time.tm_hour,
5022                           local_time.tm_min,
5023                           local_time.tm_sec);
5024 }
5025 
5026 /* Internal helper.
5027  * Build datetime from a time_t and a distinct count of microseconds.
5028  * Pass localtime or gmtime for f, to control the interpretation of timet.
5029  */
5030 static PyObject *
datetime_from_timet_and_us(PyObject * cls,TM_FUNC f,time_t timet,int us,PyObject * tzinfo)5031 datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
5032                            PyObject *tzinfo)
5033 {
5034     struct tm tm;
5035     int year, month, day, hour, minute, second, fold = 0;
5036 
5037     if (f(timet, &tm) != 0)
5038         return NULL;
5039 
5040     year = tm.tm_year + 1900;
5041     month = tm.tm_mon + 1;
5042     day = tm.tm_mday;
5043     hour = tm.tm_hour;
5044     minute = tm.tm_min;
5045     /* The platform localtime/gmtime may insert leap seconds,
5046      * indicated by tm.tm_sec > 59.  We don't care about them,
5047      * except to the extent that passing them on to the datetime
5048      * constructor would raise ValueError for a reason that
5049      * made no sense to the user.
5050      */
5051     second = Py_MIN(59, tm.tm_sec);
5052 
5053     /* local timezone requires to compute fold */
5054     if (tzinfo == Py_None && f == _PyTime_localtime
5055     /* On Windows, passing a negative value to local results
5056      * in an OSError because localtime_s on Windows does
5057      * not support negative timestamps. Unfortunately this
5058      * means that fold detection for time values between
5059      * 0 and max_fold_seconds will result in an identical
5060      * error since we subtract max_fold_seconds to detect a
5061      * fold. However, since we know there haven't been any
5062      * folds in the interval [0, max_fold_seconds) in any
5063      * timezone, we can hackily just forego fold detection
5064      * for this time range.
5065      */
5066 #ifdef MS_WINDOWS
5067         && (timet - max_fold_seconds > 0)
5068 #endif
5069         ) {
5070         long long probe_seconds, result_seconds, transition;
5071 
5072         result_seconds = utc_to_seconds(year, month, day,
5073                                         hour, minute, second);
5074         if (result_seconds == -1 && PyErr_Occurred()) {
5075             return NULL;
5076         }
5077 
5078         /* Probe max_fold_seconds to detect a fold. */
5079         probe_seconds = local(epoch + timet - max_fold_seconds);
5080         if (probe_seconds == -1)
5081             return NULL;
5082         transition = result_seconds - probe_seconds - max_fold_seconds;
5083         if (transition < 0) {
5084             probe_seconds = local(epoch + timet + transition);
5085             if (probe_seconds == -1)
5086                 return NULL;
5087             if (probe_seconds == result_seconds)
5088                 fold = 1;
5089         }
5090     }
5091     return new_datetime_subclass_fold_ex(year, month, day, hour, minute,
5092                                          second, us, tzinfo, fold, cls);
5093 }
5094 
5095 /* Internal helper.
5096  * Build datetime from a Python timestamp.  Pass localtime or gmtime for f,
5097  * to control the interpretation of the timestamp.  Since a double doesn't
5098  * have enough bits to cover a datetime's full range of precision, it's
5099  * better to call datetime_from_timet_and_us provided you have a way
5100  * to get that much precision (e.g., C time() isn't good enough).
5101  */
5102 static PyObject *
datetime_from_timestamp(PyObject * cls,TM_FUNC f,PyObject * timestamp,PyObject * tzinfo)5103 datetime_from_timestamp(PyObject *cls, TM_FUNC f, PyObject *timestamp,
5104                         PyObject *tzinfo)
5105 {
5106     time_t timet;
5107     long us;
5108 
5109     if (_PyTime_ObjectToTimeval(timestamp,
5110                                 &timet, &us, _PyTime_ROUND_HALF_EVEN) == -1)
5111         return NULL;
5112 
5113     return datetime_from_timet_and_us(cls, f, timet, (int)us, tzinfo);
5114 }
5115 
5116 /* Internal helper.
5117  * Build most accurate possible datetime for current time.  Pass localtime or
5118  * gmtime for f as appropriate.
5119  */
5120 static PyObject *
datetime_best_possible(PyObject * cls,TM_FUNC f,PyObject * tzinfo)5121 datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
5122 {
5123     _PyTime_t ts = _PyTime_GetSystemClock();
5124     time_t secs;
5125     int us;
5126 
5127     if (_PyTime_AsTimevalTime_t(ts, &secs, &us, _PyTime_ROUND_FLOOR) < 0)
5128         return NULL;
5129     assert(0 <= us && us <= 999999);
5130 
5131     return datetime_from_timet_and_us(cls, f, secs, us, tzinfo);
5132 }
5133 
5134 /*[clinic input]
5135 
5136 @classmethod
5137 datetime.datetime.now
5138 
5139     tz: object = None
5140         Timezone object.
5141 
5142 Returns new datetime object representing current time local to tz.
5143 
5144 If no tz is specified, uses local timezone.
5145 [clinic start generated code]*/
5146 
5147 static PyObject *
datetime_datetime_now_impl(PyTypeObject * type,PyObject * tz)5148 datetime_datetime_now_impl(PyTypeObject *type, PyObject *tz)
5149 /*[clinic end generated code: output=b3386e5345e2b47a input=80d09869c5267d00]*/
5150 {
5151     PyObject *self;
5152 
5153     /* Return best possible local time -- this isn't constrained by the
5154      * precision of a timestamp.
5155      */
5156     if (check_tzinfo_subclass(tz) < 0)
5157         return NULL;
5158 
5159     self = datetime_best_possible((PyObject *)type,
5160                                   tz == Py_None ? _PyTime_localtime :
5161                                   _PyTime_gmtime,
5162                                   tz);
5163     if (self != NULL && tz != Py_None) {
5164         /* Convert UTC to tzinfo's zone. */
5165         self = _PyObject_CallMethodId(tz, &PyId_fromutc, "N", self);
5166     }
5167     return self;
5168 }
5169 
5170 /* Return best possible UTC time -- this isn't constrained by the
5171  * precision of a timestamp.
5172  */
5173 static PyObject *
datetime_utcnow(PyObject * cls,PyObject * dummy)5174 datetime_utcnow(PyObject *cls, PyObject *dummy)
5175 {
5176     return datetime_best_possible(cls, _PyTime_gmtime, Py_None);
5177 }
5178 
5179 /* Return new local datetime from timestamp (Python timestamp -- a double). */
5180 static PyObject *
datetime_fromtimestamp(PyObject * cls,PyObject * args,PyObject * kw)5181 datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
5182 {
5183     PyObject *self;
5184     PyObject *timestamp;
5185     PyObject *tzinfo = Py_None;
5186     static char *keywords[] = {"timestamp", "tz", NULL};
5187 
5188     if (! PyArg_ParseTupleAndKeywords(args, kw, "O|O:fromtimestamp",
5189                                       keywords, &timestamp, &tzinfo))
5190         return NULL;
5191     if (check_tzinfo_subclass(tzinfo) < 0)
5192         return NULL;
5193 
5194     self = datetime_from_timestamp(cls,
5195                                    tzinfo == Py_None ? _PyTime_localtime :
5196                                    _PyTime_gmtime,
5197                                    timestamp,
5198                                    tzinfo);
5199     if (self != NULL && tzinfo != Py_None) {
5200         /* Convert UTC to tzinfo's zone. */
5201         self = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "N", self);
5202     }
5203     return self;
5204 }
5205 
5206 /* Return new UTC datetime from timestamp (Python timestamp -- a double). */
5207 static PyObject *
datetime_utcfromtimestamp(PyObject * cls,PyObject * args)5208 datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
5209 {
5210     PyObject *timestamp;
5211     PyObject *result = NULL;
5212 
5213     if (PyArg_ParseTuple(args, "O:utcfromtimestamp", &timestamp))
5214         result = datetime_from_timestamp(cls, _PyTime_gmtime, timestamp,
5215                                          Py_None);
5216     return result;
5217 }
5218 
5219 /* Return new datetime from _strptime.strptime_datetime(). */
5220 static PyObject *
datetime_strptime(PyObject * cls,PyObject * args)5221 datetime_strptime(PyObject *cls, PyObject *args)
5222 {
5223     static PyObject *module = NULL;
5224     PyObject *string, *format;
5225     _Py_IDENTIFIER(_strptime_datetime);
5226 
5227     if (!PyArg_ParseTuple(args, "UU:strptime", &string, &format))
5228         return NULL;
5229 
5230     if (module == NULL) {
5231         module = PyImport_ImportModule("_strptime");
5232         if (module == NULL)
5233             return NULL;
5234     }
5235     return _PyObject_CallMethodIdObjArgs(module, &PyId__strptime_datetime,
5236                                          cls, string, format, NULL);
5237 }
5238 
5239 /* Return new datetime from date/datetime and time arguments. */
5240 static PyObject *
datetime_combine(PyObject * cls,PyObject * args,PyObject * kw)5241 datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
5242 {
5243     static char *keywords[] = {"date", "time", "tzinfo", NULL};
5244     PyObject *date;
5245     PyObject *time;
5246     PyObject *tzinfo = NULL;
5247     PyObject *result = NULL;
5248 
5249     if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!|O:combine", keywords,
5250                                     &PyDateTime_DateType, &date,
5251                                     &PyDateTime_TimeType, &time, &tzinfo)) {
5252         if (tzinfo == NULL) {
5253             if (HASTZINFO(time))
5254                 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
5255             else
5256                 tzinfo = Py_None;
5257         }
5258         result = new_datetime_subclass_fold_ex(GET_YEAR(date),
5259                                                GET_MONTH(date),
5260                                                GET_DAY(date),
5261                                                TIME_GET_HOUR(time),
5262                                                TIME_GET_MINUTE(time),
5263                                                TIME_GET_SECOND(time),
5264                                                TIME_GET_MICROSECOND(time),
5265                                                tzinfo,
5266                                                TIME_GET_FOLD(time),
5267                                                cls);
5268     }
5269     return result;
5270 }
5271 
5272 static PyObject *
_sanitize_isoformat_str(PyObject * dtstr)5273 _sanitize_isoformat_str(PyObject *dtstr)
5274 {
5275     Py_ssize_t len = PyUnicode_GetLength(dtstr);
5276     if (len < 7) {  // All valid ISO 8601 strings are at least 7 characters long
5277         return NULL;
5278     }
5279 
5280     // `fromisoformat` allows surrogate characters in exactly one position,
5281     // the separator; to allow datetime_fromisoformat to make the simplifying
5282     // assumption that all valid strings can be encoded in UTF-8, this function
5283     // replaces any surrogate character separators with `T`.
5284     //
5285     // The result of this, if not NULL, returns a new reference
5286     const void* const unicode_data = PyUnicode_DATA(dtstr);
5287     const unsigned int kind = PyUnicode_KIND(dtstr);
5288 
5289     // Depending on the format of the string, the separator can only ever be
5290     // in positions 7, 8 or 10. We'll check each of these for a surrogate and
5291     // if we find one, replace it with `T`. If there is more than one surrogate,
5292     // we don't have to bother sanitizing it, because the function will later
5293     // fail when we try to encode the string as ASCII.
5294     static const size_t potential_separators[3] = {7, 8, 10};
5295     size_t surrogate_separator = 0;
5296     for(size_t idx = 0;
5297          idx < sizeof(potential_separators) / sizeof(*potential_separators);
5298          ++idx) {
5299         size_t pos = potential_separators[idx];
5300         if (pos > (size_t)len) {
5301             break;
5302         }
5303 
5304         if(Py_UNICODE_IS_SURROGATE(PyUnicode_READ(kind, unicode_data, pos))) {
5305             surrogate_separator = pos;
5306             break;
5307         }
5308     }
5309 
5310     if (surrogate_separator == 0) {
5311         Py_INCREF(dtstr);
5312         return dtstr;
5313     }
5314 
5315     PyObject *str_out = _PyUnicode_Copy(dtstr);
5316     if (str_out == NULL) {
5317         return NULL;
5318     }
5319 
5320     if (PyUnicode_WriteChar(str_out, surrogate_separator, (Py_UCS4)'T')) {
5321         Py_DECREF(str_out);
5322         return NULL;
5323     }
5324 
5325     return str_out;
5326 }
5327 
5328 
5329 static Py_ssize_t
_find_isoformat_datetime_separator(const char * dtstr,Py_ssize_t len)5330 _find_isoformat_datetime_separator(const char *dtstr, Py_ssize_t len) {
5331     // The valid date formats can all be distinguished by characters 4 and 5
5332     // and further narrowed down by character
5333     // which tells us where to look for the separator character.
5334     // Format    |  As-rendered |   Position
5335     // ---------------------------------------
5336     // %Y-%m-%d  |  YYYY-MM-DD  |    10
5337     // %Y%m%d    |  YYYYMMDD    |     8
5338     // %Y-W%V    |  YYYY-Www    |     8
5339     // %YW%V     |  YYYYWww     |     7
5340     // %Y-W%V-%u |  YYYY-Www-d  |    10
5341     // %YW%V%u   |  YYYYWwwd    |     8
5342     // %Y-%j     |  YYYY-DDD    |     8
5343     // %Y%j      |  YYYYDDD     |     7
5344     //
5345     // Note that because we allow *any* character for the separator, in the
5346     // case where character 4 is W, it's not straightforward to determine where
5347     // the separator is — in the case of YYYY-Www-d, you have actual ambiguity,
5348     // e.g. 2020-W01-0000 could be YYYY-Www-D0HH or YYYY-Www-HHMM, when the
5349     // separator character is a number in the former case or a hyphen in the
5350     // latter case.
5351     //
5352     // The case of YYYYWww can be distinguished from YYYYWwwd by tracking ahead
5353     // to either the end of the string or the first non-numeric character —
5354     // since the time components all come in pairs YYYYWww#HH can be
5355     // distinguished from YYYYWwwd#HH by the fact that there will always be an
5356     // odd number of digits before the first non-digit character in the former
5357     // case.
5358     static const char date_separator = '-';
5359     static const char week_indicator = 'W';
5360 
5361     if (len == 7) {
5362         return 7;
5363     }
5364 
5365     if (dtstr[4] == date_separator) {
5366         // YYYY-???
5367 
5368         if (dtstr[5] == week_indicator) {
5369             // YYYY-W??
5370 
5371             if (len < 8) {
5372                 return -1;
5373             }
5374 
5375             if (len > 8 && dtstr[8] == date_separator) {
5376                 // YYYY-Www-D (10) or YYYY-Www-HH (8)
5377                 if (len == 9) { return -1; }
5378                 if (len > 10 && is_digit(dtstr[10])) {
5379                     // This is as far as we'll try to go to resolve the
5380                     // ambiguity for the moment — if we have YYYY-Www-##, the
5381                     // separator is either a hyphen at 8 or a number at 10.
5382                     //
5383                     // We'll assume it's a hyphen at 8 because it's way more
5384                     // likely that someone will use a hyphen as a separator
5385                     // than a number, but at this point it's really best effort
5386                     // because this is an extension of the spec anyway.
5387                     return 8;
5388                 }
5389 
5390                 return 10;
5391             } else {
5392                 // YYYY-Www (8)
5393                 return 8;
5394             }
5395         } else {
5396             // YYYY-MM-DD (10)
5397             return 10;
5398         }
5399     } else {
5400         // YYYY???
5401         if (dtstr[4] == week_indicator) {
5402             // YYYYWww (7) or YYYYWwwd (8)
5403             size_t idx = 7;
5404             for (; idx < (size_t)len; ++idx) {
5405                 // Keep going until we run out of digits.
5406                 if (!is_digit(dtstr[idx])) {
5407                     break;
5408                 }
5409             }
5410 
5411             if (idx < 9) {
5412                 return idx;
5413             }
5414 
5415             if (idx % 2 == 0) {
5416                 // If the index of the last number is even, it's YYYYWww
5417                 return 7;
5418             } else {
5419                 return 8;
5420             }
5421         } else {
5422             // YYYYMMDD (8)
5423             return 8;
5424         }
5425     }
5426 }
5427 
5428 static PyObject *
datetime_fromisoformat(PyObject * cls,PyObject * dtstr)5429 datetime_fromisoformat(PyObject *cls, PyObject *dtstr)
5430 {
5431     assert(dtstr != NULL);
5432 
5433     if (!PyUnicode_Check(dtstr)) {
5434         PyErr_SetString(PyExc_TypeError,
5435                         "fromisoformat: argument must be str");
5436         return NULL;
5437     }
5438 
5439     // We only need to sanitize this string if the separator is a surrogate
5440     // character. In the situation where the separator location is ambiguous,
5441     // we don't have to sanitize it anything because that can only happen when
5442     // the separator is either '-' or a number. This should mostly be a noop
5443     // but it makes the reference counting easier if we still sanitize.
5444     PyObject *dtstr_clean = _sanitize_isoformat_str(dtstr);
5445     if (dtstr_clean == NULL) {
5446         goto invalid_string_error;
5447     }
5448 
5449     Py_ssize_t len;
5450     const char *dt_ptr = PyUnicode_AsUTF8AndSize(dtstr_clean, &len);
5451 
5452     if (dt_ptr == NULL) {
5453         if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) {
5454             // Encoding errors are invalid string errors at this point
5455             goto invalid_string_error;
5456         }
5457         else {
5458             goto error;
5459         }
5460     }
5461 
5462     const Py_ssize_t separator_location = _find_isoformat_datetime_separator(
5463             dt_ptr, len);
5464 
5465 
5466     const char *p = dt_ptr;
5467 
5468     int year = 0, month = 0, day = 0;
5469     int hour = 0, minute = 0, second = 0, microsecond = 0;
5470     int tzoffset = 0, tzusec = 0;
5471 
5472     // date runs up to separator_location
5473     int rv = parse_isoformat_date(p, separator_location, &year, &month, &day);
5474 
5475     if (!rv && len > separator_location) {
5476         // In UTF-8, the length of multi-byte characters is encoded in the MSB
5477         p += separator_location;
5478         if ((p[0] & 0x80) == 0) {
5479             p += 1;
5480         }
5481         else {
5482             switch (p[0] & 0xf0) {
5483                 case 0xe0:
5484                     p += 3;
5485                     break;
5486                 case 0xf0:
5487                     p += 4;
5488                     break;
5489                 default:
5490                     p += 2;
5491                     break;
5492             }
5493         }
5494 
5495         len -= (p - dt_ptr);
5496         rv = parse_isoformat_time(p, len, &hour, &minute, &second,
5497                                   &microsecond, &tzoffset, &tzusec);
5498     }
5499     if (rv < 0) {
5500         goto invalid_string_error;
5501     }
5502 
5503     PyObject *tzinfo = tzinfo_from_isoformat_results(rv, tzoffset, tzusec);
5504     if (tzinfo == NULL) {
5505         goto error;
5506     }
5507 
5508     PyObject *dt = new_datetime_subclass_ex(year, month, day, hour, minute,
5509                                             second, microsecond, tzinfo, cls);
5510 
5511     Py_DECREF(tzinfo);
5512     Py_DECREF(dtstr_clean);
5513     return dt;
5514 
5515 invalid_string_error:
5516     PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", dtstr);
5517 
5518 error:
5519     Py_XDECREF(dtstr_clean);
5520 
5521     return NULL;
5522 }
5523 
5524 /*
5525  * Destructor.
5526  */
5527 
5528 static void
datetime_dealloc(PyDateTime_DateTime * self)5529 datetime_dealloc(PyDateTime_DateTime *self)
5530 {
5531     if (HASTZINFO(self)) {
5532         Py_XDECREF(self->tzinfo);
5533     }
5534     Py_TYPE(self)->tp_free((PyObject *)self);
5535 }
5536 
5537 /*
5538  * Indirect access to tzinfo methods.
5539  */
5540 
5541 /* These are all METH_NOARGS, so don't need to check the arglist. */
5542 static PyObject *
datetime_utcoffset(PyObject * self,PyObject * unused)5543 datetime_utcoffset(PyObject *self, PyObject *unused) {
5544     return call_utcoffset(GET_DT_TZINFO(self), self);
5545 }
5546 
5547 static PyObject *
datetime_dst(PyObject * self,PyObject * unused)5548 datetime_dst(PyObject *self, PyObject *unused) {
5549     return call_dst(GET_DT_TZINFO(self), self);
5550 }
5551 
5552 static PyObject *
datetime_tzname(PyObject * self,PyObject * unused)5553 datetime_tzname(PyObject *self, PyObject *unused) {
5554     return call_tzname(GET_DT_TZINFO(self), self);
5555 }
5556 
5557 /*
5558  * datetime arithmetic.
5559  */
5560 
5561 /* factor must be 1 (to add) or -1 (to subtract).  The result inherits
5562  * the tzinfo state of date.
5563  */
5564 static PyObject *
add_datetime_timedelta(PyDateTime_DateTime * date,PyDateTime_Delta * delta,int factor)5565 add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
5566                        int factor)
5567 {
5568     /* Note that the C-level additions can't overflow, because of
5569      * invariant bounds on the member values.
5570      */
5571     int year = GET_YEAR(date);
5572     int month = GET_MONTH(date);
5573     int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
5574     int hour = DATE_GET_HOUR(date);
5575     int minute = DATE_GET_MINUTE(date);
5576     int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
5577     int microsecond = DATE_GET_MICROSECOND(date) +
5578                       GET_TD_MICROSECONDS(delta) * factor;
5579 
5580     assert(factor == 1 || factor == -1);
5581     if (normalize_datetime(&year, &month, &day,
5582                            &hour, &minute, &second, &microsecond) < 0) {
5583         return NULL;
5584     }
5585 
5586     return new_datetime_subclass_ex(year, month, day,
5587                                     hour, minute, second, microsecond,
5588                                     HASTZINFO(date) ? date->tzinfo : Py_None,
5589                                     (PyObject *)Py_TYPE(date));
5590 }
5591 
5592 static PyObject *
datetime_add(PyObject * left,PyObject * right)5593 datetime_add(PyObject *left, PyObject *right)
5594 {
5595     if (PyDateTime_Check(left)) {
5596         /* datetime + ??? */
5597         if (PyDelta_Check(right))
5598             /* datetime + delta */
5599             return add_datetime_timedelta(
5600                             (PyDateTime_DateTime *)left,
5601                             (PyDateTime_Delta *)right,
5602                             1);
5603     }
5604     else if (PyDelta_Check(left)) {
5605         /* delta + datetime */
5606         return add_datetime_timedelta((PyDateTime_DateTime *) right,
5607                                       (PyDateTime_Delta *) left,
5608                                       1);
5609     }
5610     Py_RETURN_NOTIMPLEMENTED;
5611 }
5612 
5613 static PyObject *
datetime_subtract(PyObject * left,PyObject * right)5614 datetime_subtract(PyObject *left, PyObject *right)
5615 {
5616     PyObject *result = Py_NotImplemented;
5617 
5618     if (PyDateTime_Check(left)) {
5619         /* datetime - ??? */
5620         if (PyDateTime_Check(right)) {
5621             /* datetime - datetime */
5622             PyObject *offset1, *offset2, *offdiff = NULL;
5623             int delta_d, delta_s, delta_us;
5624 
5625             if (GET_DT_TZINFO(left) == GET_DT_TZINFO(right)) {
5626                 offset2 = offset1 = Py_None;
5627                 Py_INCREF(offset1);
5628                 Py_INCREF(offset2);
5629             }
5630             else {
5631                 offset1 = datetime_utcoffset(left, NULL);
5632                 if (offset1 == NULL)
5633                     return NULL;
5634                 offset2 = datetime_utcoffset(right, NULL);
5635                 if (offset2 == NULL) {
5636                     Py_DECREF(offset1);
5637                     return NULL;
5638                 }
5639                 if ((offset1 != Py_None) != (offset2 != Py_None)) {
5640                     PyErr_SetString(PyExc_TypeError,
5641                                     "can't subtract offset-naive and "
5642                                     "offset-aware datetimes");
5643                     Py_DECREF(offset1);
5644                     Py_DECREF(offset2);
5645                     return NULL;
5646                 }
5647             }
5648             if ((offset1 != offset2) &&
5649                 delta_cmp(offset1, offset2) != 0) {
5650                 offdiff = delta_subtract(offset1, offset2);
5651                 if (offdiff == NULL) {
5652                     Py_DECREF(offset1);
5653                     Py_DECREF(offset2);
5654                     return NULL;
5655                 }
5656             }
5657             Py_DECREF(offset1);
5658             Py_DECREF(offset2);
5659             delta_d = ymd_to_ord(GET_YEAR(left),
5660                                  GET_MONTH(left),
5661                                  GET_DAY(left)) -
5662                       ymd_to_ord(GET_YEAR(right),
5663                                  GET_MONTH(right),
5664                                  GET_DAY(right));
5665             /* These can't overflow, since the values are
5666              * normalized.  At most this gives the number of
5667              * seconds in one day.
5668              */
5669             delta_s = (DATE_GET_HOUR(left) -
5670                        DATE_GET_HOUR(right)) * 3600 +
5671                       (DATE_GET_MINUTE(left) -
5672                        DATE_GET_MINUTE(right)) * 60 +
5673                       (DATE_GET_SECOND(left) -
5674                        DATE_GET_SECOND(right));
5675             delta_us = DATE_GET_MICROSECOND(left) -
5676                        DATE_GET_MICROSECOND(right);
5677             result = new_delta(delta_d, delta_s, delta_us, 1);
5678             if (result == NULL)
5679                 return NULL;
5680 
5681             if (offdiff != NULL) {
5682                 Py_SETREF(result, delta_subtract(result, offdiff));
5683                 Py_DECREF(offdiff);
5684             }
5685         }
5686         else if (PyDelta_Check(right)) {
5687             /* datetime - delta */
5688             result = add_datetime_timedelta(
5689                             (PyDateTime_DateTime *)left,
5690                             (PyDateTime_Delta *)right,
5691                             -1);
5692         }
5693     }
5694 
5695     if (result == Py_NotImplemented)
5696         Py_INCREF(result);
5697     return result;
5698 }
5699 
5700 /* Various ways to turn a datetime into a string. */
5701 
5702 static PyObject *
datetime_repr(PyDateTime_DateTime * self)5703 datetime_repr(PyDateTime_DateTime *self)
5704 {
5705     const char *type_name = Py_TYPE(self)->tp_name;
5706     PyObject *baserepr;
5707 
5708     if (DATE_GET_MICROSECOND(self)) {
5709         baserepr = PyUnicode_FromFormat(
5710                       "%s(%d, %d, %d, %d, %d, %d, %d)",
5711                       type_name,
5712                       GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
5713                       DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
5714                       DATE_GET_SECOND(self),
5715                       DATE_GET_MICROSECOND(self));
5716     }
5717     else if (DATE_GET_SECOND(self)) {
5718         baserepr = PyUnicode_FromFormat(
5719                       "%s(%d, %d, %d, %d, %d, %d)",
5720                       type_name,
5721                       GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
5722                       DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
5723                       DATE_GET_SECOND(self));
5724     }
5725     else {
5726         baserepr = PyUnicode_FromFormat(
5727                       "%s(%d, %d, %d, %d, %d)",
5728                       type_name,
5729                       GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
5730                       DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
5731     }
5732     if (baserepr != NULL && DATE_GET_FOLD(self) != 0)
5733         baserepr = append_keyword_fold(baserepr, DATE_GET_FOLD(self));
5734     if (baserepr == NULL || ! HASTZINFO(self))
5735         return baserepr;
5736     return append_keyword_tzinfo(baserepr, self->tzinfo);
5737 }
5738 
5739 static PyObject *
datetime_str(PyDateTime_DateTime * self)5740 datetime_str(PyDateTime_DateTime *self)
5741 {
5742     return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "s", " ");
5743 }
5744 
5745 static PyObject *
datetime_isoformat(PyDateTime_DateTime * self,PyObject * args,PyObject * kw)5746 datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
5747 {
5748     int sep = 'T';
5749     char *timespec = NULL;
5750     static char *keywords[] = {"sep", "timespec", NULL};
5751     char buffer[100];
5752     PyObject *result = NULL;
5753     int us = DATE_GET_MICROSECOND(self);
5754     static const char *specs[][2] = {
5755         {"hours", "%04d-%02d-%02d%c%02d"},
5756         {"minutes", "%04d-%02d-%02d%c%02d:%02d"},
5757         {"seconds", "%04d-%02d-%02d%c%02d:%02d:%02d"},
5758         {"milliseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%03d"},
5759         {"microseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%06d"},
5760     };
5761     size_t given_spec;
5762 
5763     if (!PyArg_ParseTupleAndKeywords(args, kw, "|Cs:isoformat", keywords, &sep, &timespec))
5764         return NULL;
5765 
5766     if (timespec == NULL || strcmp(timespec, "auto") == 0) {
5767         if (us == 0) {
5768             /* seconds */
5769             given_spec = 2;
5770         }
5771         else {
5772             /* microseconds */
5773             given_spec = 4;
5774         }
5775     }
5776     else {
5777         for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) {
5778             if (strcmp(timespec, specs[given_spec][0]) == 0) {
5779                 if (given_spec == 3) {
5780                     us = us / 1000;
5781                 }
5782                 break;
5783             }
5784         }
5785     }
5786 
5787     if (given_spec == Py_ARRAY_LENGTH(specs)) {
5788         PyErr_Format(PyExc_ValueError, "Unknown timespec value");
5789         return NULL;
5790     }
5791     else {
5792         result = PyUnicode_FromFormat(specs[given_spec][1],
5793                                       GET_YEAR(self), GET_MONTH(self),
5794                                       GET_DAY(self), (int)sep,
5795                                       DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
5796                                       DATE_GET_SECOND(self), us);
5797     }
5798 
5799     if (!result || !HASTZINFO(self))
5800         return result;
5801 
5802     /* We need to append the UTC offset. */
5803     if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
5804                          (PyObject *)self) < 0) {
5805         Py_DECREF(result);
5806         return NULL;
5807     }
5808     PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buffer));
5809     return result;
5810 }
5811 
5812 static PyObject *
datetime_ctime(PyDateTime_DateTime * self,PyObject * Py_UNUSED (ignored))5813 datetime_ctime(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
5814 {
5815     return format_ctime((PyDateTime_Date *)self,
5816                         DATE_GET_HOUR(self),
5817                         DATE_GET_MINUTE(self),
5818                         DATE_GET_SECOND(self));
5819 }
5820 
5821 /* Miscellaneous methods. */
5822 
5823 static PyObject *
flip_fold(PyObject * dt)5824 flip_fold(PyObject *dt)
5825 {
5826     return new_datetime_ex2(GET_YEAR(dt),
5827                             GET_MONTH(dt),
5828                             GET_DAY(dt),
5829                             DATE_GET_HOUR(dt),
5830                             DATE_GET_MINUTE(dt),
5831                             DATE_GET_SECOND(dt),
5832                             DATE_GET_MICROSECOND(dt),
5833                             HASTZINFO(dt) ?
5834                              ((PyDateTime_DateTime *)dt)->tzinfo : Py_None,
5835                             !DATE_GET_FOLD(dt),
5836                             Py_TYPE(dt));
5837 }
5838 
5839 static PyObject *
get_flip_fold_offset(PyObject * dt)5840 get_flip_fold_offset(PyObject *dt)
5841 {
5842     PyObject *result, *flip_dt;
5843 
5844     flip_dt = flip_fold(dt);
5845     if (flip_dt == NULL)
5846         return NULL;
5847     result = datetime_utcoffset(flip_dt, NULL);
5848     Py_DECREF(flip_dt);
5849     return result;
5850 }
5851 
5852 /* PEP 495 exception: Whenever one or both of the operands in
5853  * inter-zone comparison is such that its utcoffset() depends
5854  * on the value of its fold attribute, the result is False.
5855  *
5856  * Return 1 if exception applies, 0 if not,  and -1 on error.
5857  */
5858 static int
pep495_eq_exception(PyObject * self,PyObject * other,PyObject * offset_self,PyObject * offset_other)5859 pep495_eq_exception(PyObject *self, PyObject *other,
5860                     PyObject *offset_self, PyObject *offset_other)
5861 {
5862     int result = 0;
5863     PyObject *flip_offset;
5864 
5865     flip_offset = get_flip_fold_offset(self);
5866     if (flip_offset == NULL)
5867         return -1;
5868     if (flip_offset != offset_self &&
5869         delta_cmp(flip_offset, offset_self))
5870     {
5871         result = 1;
5872         goto done;
5873     }
5874     Py_DECREF(flip_offset);
5875 
5876     flip_offset = get_flip_fold_offset(other);
5877     if (flip_offset == NULL)
5878         return -1;
5879     if (flip_offset != offset_other &&
5880         delta_cmp(flip_offset, offset_other))
5881         result = 1;
5882  done:
5883     Py_DECREF(flip_offset);
5884     return result;
5885 }
5886 
5887 static PyObject *
datetime_richcompare(PyObject * self,PyObject * other,int op)5888 datetime_richcompare(PyObject *self, PyObject *other, int op)
5889 {
5890     PyObject *result = NULL;
5891     PyObject *offset1, *offset2;
5892     int diff;
5893 
5894     if (! PyDateTime_Check(other)) {
5895         if (PyDate_Check(other)) {
5896             /* Prevent invocation of date_richcompare.  We want to
5897                return NotImplemented here to give the other object
5898                a chance.  But since DateTime is a subclass of
5899                Date, if the other object is a Date, it would
5900                compute an ordering based on the date part alone,
5901                and we don't want that.  So force unequal or
5902                uncomparable here in that case. */
5903             if (op == Py_EQ)
5904                 Py_RETURN_FALSE;
5905             if (op == Py_NE)
5906                 Py_RETURN_TRUE;
5907             return cmperror(self, other);
5908         }
5909         Py_RETURN_NOTIMPLEMENTED;
5910     }
5911 
5912     if (GET_DT_TZINFO(self) == GET_DT_TZINFO(other)) {
5913         diff = memcmp(((PyDateTime_DateTime *)self)->data,
5914                       ((PyDateTime_DateTime *)other)->data,
5915                       _PyDateTime_DATETIME_DATASIZE);
5916         return diff_to_bool(diff, op);
5917     }
5918     offset1 = datetime_utcoffset(self, NULL);
5919     if (offset1 == NULL)
5920         return NULL;
5921     offset2 = datetime_utcoffset(other, NULL);
5922     if (offset2 == NULL)
5923         goto done;
5924     /* If they're both naive, or both aware and have the same offsets,
5925      * we get off cheap.  Note that if they're both naive, offset1 ==
5926      * offset2 == Py_None at this point.
5927      */
5928     if ((offset1 == offset2) ||
5929         (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
5930          delta_cmp(offset1, offset2) == 0)) {
5931         diff = memcmp(((PyDateTime_DateTime *)self)->data,
5932                       ((PyDateTime_DateTime *)other)->data,
5933                       _PyDateTime_DATETIME_DATASIZE);
5934         if ((op == Py_EQ || op == Py_NE) && diff == 0) {
5935             int ex = pep495_eq_exception(self, other, offset1, offset2);
5936             if (ex == -1)
5937                 goto done;
5938             if (ex)
5939                 diff = 1;
5940         }
5941         result = diff_to_bool(diff, op);
5942     }
5943     else if (offset1 != Py_None && offset2 != Py_None) {
5944         PyDateTime_Delta *delta;
5945 
5946         assert(offset1 != offset2); /* else last "if" handled it */
5947         delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
5948                                                        other);
5949         if (delta == NULL)
5950             goto done;
5951         diff = GET_TD_DAYS(delta);
5952         if (diff == 0)
5953             diff = GET_TD_SECONDS(delta) |
5954                    GET_TD_MICROSECONDS(delta);
5955         Py_DECREF(delta);
5956         if ((op == Py_EQ || op == Py_NE) && diff == 0) {
5957             int ex = pep495_eq_exception(self, other, offset1, offset2);
5958             if (ex == -1)
5959                 goto done;
5960             if (ex)
5961                 diff = 1;
5962         }
5963         result = diff_to_bool(diff, op);
5964     }
5965     else if (op == Py_EQ) {
5966         result = Py_False;
5967         Py_INCREF(result);
5968     }
5969     else if (op == Py_NE) {
5970         result = Py_True;
5971         Py_INCREF(result);
5972     }
5973     else {
5974         PyErr_SetString(PyExc_TypeError,
5975                         "can't compare offset-naive and "
5976                         "offset-aware datetimes");
5977     }
5978  done:
5979     Py_DECREF(offset1);
5980     Py_XDECREF(offset2);
5981     return result;
5982 }
5983 
5984 static Py_hash_t
datetime_hash(PyDateTime_DateTime * self)5985 datetime_hash(PyDateTime_DateTime *self)
5986 {
5987     if (self->hashcode == -1) {
5988         PyObject *offset, *self0;
5989         if (DATE_GET_FOLD(self)) {
5990             self0 = new_datetime_ex2(GET_YEAR(self),
5991                                      GET_MONTH(self),
5992                                      GET_DAY(self),
5993                                      DATE_GET_HOUR(self),
5994                                      DATE_GET_MINUTE(self),
5995                                      DATE_GET_SECOND(self),
5996                                      DATE_GET_MICROSECOND(self),
5997                                      HASTZINFO(self) ? self->tzinfo : Py_None,
5998                                      0, Py_TYPE(self));
5999             if (self0 == NULL)
6000                 return -1;
6001         }
6002         else {
6003             self0 = (PyObject *)self;
6004             Py_INCREF(self0);
6005         }
6006         offset = datetime_utcoffset(self0, NULL);
6007         Py_DECREF(self0);
6008 
6009         if (offset == NULL)
6010             return -1;
6011 
6012         /* Reduce this to a hash of another object. */
6013         if (offset == Py_None)
6014             self->hashcode = generic_hash(
6015                 (unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
6016         else {
6017             PyObject *temp1, *temp2;
6018             int days, seconds;
6019 
6020             assert(HASTZINFO(self));
6021             days = ymd_to_ord(GET_YEAR(self),
6022                               GET_MONTH(self),
6023                               GET_DAY(self));
6024             seconds = DATE_GET_HOUR(self) * 3600 +
6025                       DATE_GET_MINUTE(self) * 60 +
6026                       DATE_GET_SECOND(self);
6027             temp1 = new_delta(days, seconds,
6028                               DATE_GET_MICROSECOND(self),
6029                               1);
6030             if (temp1 == NULL) {
6031                 Py_DECREF(offset);
6032                 return -1;
6033             }
6034             temp2 = delta_subtract(temp1, offset);
6035             Py_DECREF(temp1);
6036             if (temp2 == NULL) {
6037                 Py_DECREF(offset);
6038                 return -1;
6039             }
6040             self->hashcode = PyObject_Hash(temp2);
6041             Py_DECREF(temp2);
6042         }
6043         Py_DECREF(offset);
6044     }
6045     return self->hashcode;
6046 }
6047 
6048 static PyObject *
datetime_replace(PyDateTime_DateTime * self,PyObject * args,PyObject * kw)6049 datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
6050 {
6051     PyObject *clone;
6052     PyObject *tuple;
6053     int y = GET_YEAR(self);
6054     int m = GET_MONTH(self);
6055     int d = GET_DAY(self);
6056     int hh = DATE_GET_HOUR(self);
6057     int mm = DATE_GET_MINUTE(self);
6058     int ss = DATE_GET_SECOND(self);
6059     int us = DATE_GET_MICROSECOND(self);
6060     PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
6061     int fold = DATE_GET_FOLD(self);
6062 
6063     if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO$i:replace",
6064                                       datetime_kws,
6065                                       &y, &m, &d, &hh, &mm, &ss, &us,
6066                                       &tzinfo, &fold))
6067         return NULL;
6068     if (fold != 0 && fold != 1) {
6069         PyErr_SetString(PyExc_ValueError,
6070                         "fold must be either 0 or 1");
6071         return NULL;
6072     }
6073     tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
6074     if (tuple == NULL)
6075         return NULL;
6076     clone = datetime_new(Py_TYPE(self), tuple, NULL);
6077     if (clone != NULL) {
6078         DATE_SET_FOLD(clone, fold);
6079     }
6080     Py_DECREF(tuple);
6081     return clone;
6082 }
6083 
6084 static PyObject *
local_timezone_from_timestamp(time_t timestamp)6085 local_timezone_from_timestamp(time_t timestamp)
6086 {
6087     PyObject *result = NULL;
6088     PyObject *delta;
6089     struct tm local_time_tm;
6090     PyObject *nameo = NULL;
6091     const char *zone = NULL;
6092 
6093     if (_PyTime_localtime(timestamp, &local_time_tm) != 0)
6094         return NULL;
6095 #ifdef HAVE_STRUCT_TM_TM_ZONE
6096     zone = local_time_tm.tm_zone;
6097     delta = new_delta(0, local_time_tm.tm_gmtoff, 0, 1);
6098 #else /* HAVE_STRUCT_TM_TM_ZONE */
6099     {
6100         PyObject *local_time, *utc_time;
6101         struct tm utc_time_tm;
6102         char buf[100];
6103         strftime(buf, sizeof(buf), "%Z", &local_time_tm);
6104         zone = buf;
6105         local_time = new_datetime(local_time_tm.tm_year + 1900,
6106                                   local_time_tm.tm_mon + 1,
6107                                   local_time_tm.tm_mday,
6108                                   local_time_tm.tm_hour,
6109                                   local_time_tm.tm_min,
6110                                   local_time_tm.tm_sec, 0, Py_None, 0);
6111         if (local_time == NULL) {
6112             return NULL;
6113         }
6114         if (_PyTime_gmtime(timestamp, &utc_time_tm) != 0)
6115             return NULL;
6116         utc_time = new_datetime(utc_time_tm.tm_year + 1900,
6117                                 utc_time_tm.tm_mon + 1,
6118                                 utc_time_tm.tm_mday,
6119                                 utc_time_tm.tm_hour,
6120                                 utc_time_tm.tm_min,
6121                                 utc_time_tm.tm_sec, 0, Py_None, 0);
6122         if (utc_time == NULL) {
6123             Py_DECREF(local_time);
6124             return NULL;
6125         }
6126         delta = datetime_subtract(local_time, utc_time);
6127         Py_DECREF(local_time);
6128         Py_DECREF(utc_time);
6129     }
6130 #endif /* HAVE_STRUCT_TM_TM_ZONE */
6131     if (delta == NULL) {
6132             return NULL;
6133     }
6134     if (zone != NULL) {
6135         nameo = PyUnicode_DecodeLocale(zone, "surrogateescape");
6136         if (nameo == NULL)
6137             goto error;
6138     }
6139     result = new_timezone(delta, nameo);
6140     Py_XDECREF(nameo);
6141   error:
6142     Py_DECREF(delta);
6143     return result;
6144 }
6145 
6146 static PyObject *
local_timezone(PyDateTime_DateTime * utc_time)6147 local_timezone(PyDateTime_DateTime *utc_time)
6148 {
6149     time_t timestamp;
6150     PyObject *delta;
6151     PyObject *one_second;
6152     PyObject *seconds;
6153 
6154     delta = datetime_subtract((PyObject *)utc_time, PyDateTime_Epoch);
6155     if (delta == NULL)
6156         return NULL;
6157     one_second = new_delta(0, 1, 0, 0);
6158     if (one_second == NULL) {
6159         Py_DECREF(delta);
6160         return NULL;
6161     }
6162     seconds = divide_timedelta_timedelta((PyDateTime_Delta *)delta,
6163                                          (PyDateTime_Delta *)one_second);
6164     Py_DECREF(one_second);
6165     Py_DECREF(delta);
6166     if (seconds == NULL)
6167         return NULL;
6168     timestamp = _PyLong_AsTime_t(seconds);
6169     Py_DECREF(seconds);
6170     if (timestamp == -1 && PyErr_Occurred())
6171         return NULL;
6172     return local_timezone_from_timestamp(timestamp);
6173 }
6174 
6175 static long long
6176 local_to_seconds(int year, int month, int day,
6177                  int hour, int minute, int second, int fold);
6178 
6179 static PyObject *
local_timezone_from_local(PyDateTime_DateTime * local_dt)6180 local_timezone_from_local(PyDateTime_DateTime *local_dt)
6181 {
6182     long long seconds;
6183     time_t timestamp;
6184     seconds = local_to_seconds(GET_YEAR(local_dt),
6185                                GET_MONTH(local_dt),
6186                                GET_DAY(local_dt),
6187                                DATE_GET_HOUR(local_dt),
6188                                DATE_GET_MINUTE(local_dt),
6189                                DATE_GET_SECOND(local_dt),
6190                                DATE_GET_FOLD(local_dt));
6191     if (seconds == -1)
6192         return NULL;
6193     /* XXX: add bounds check */
6194     timestamp = seconds - epoch;
6195     return local_timezone_from_timestamp(timestamp);
6196 }
6197 
6198 static PyDateTime_DateTime *
datetime_astimezone(PyDateTime_DateTime * self,PyObject * args,PyObject * kw)6199 datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
6200 {
6201     PyDateTime_DateTime *result;
6202     PyObject *offset;
6203     PyObject *temp;
6204     PyObject *self_tzinfo;
6205     PyObject *tzinfo = Py_None;
6206     static char *keywords[] = {"tz", NULL};
6207 
6208     if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:astimezone", keywords,
6209                                       &tzinfo))
6210         return NULL;
6211 
6212     if (check_tzinfo_subclass(tzinfo) == -1)
6213         return NULL;
6214 
6215     if (!HASTZINFO(self) || self->tzinfo == Py_None) {
6216   naive:
6217         self_tzinfo = local_timezone_from_local(self);
6218         if (self_tzinfo == NULL)
6219             return NULL;
6220     } else {
6221         self_tzinfo = self->tzinfo;
6222         Py_INCREF(self_tzinfo);
6223     }
6224 
6225     /* Conversion to self's own time zone is a NOP. */
6226     if (self_tzinfo == tzinfo) {
6227         Py_DECREF(self_tzinfo);
6228         Py_INCREF(self);
6229         return self;
6230     }
6231 
6232     /* Convert self to UTC. */
6233     offset = call_utcoffset(self_tzinfo, (PyObject *)self);
6234     Py_DECREF(self_tzinfo);
6235     if (offset == NULL)
6236         return NULL;
6237     else if(offset == Py_None) {
6238         Py_DECREF(offset);
6239         goto naive;
6240     }
6241     else if (!PyDelta_Check(offset)) {
6242         Py_DECREF(offset);
6243         PyErr_Format(PyExc_TypeError, "utcoffset() returned %.200s,"
6244                      " expected timedelta or None", Py_TYPE(offset)->tp_name);
6245         return NULL;
6246     }
6247     /* result = self - offset */
6248     result = (PyDateTime_DateTime *)add_datetime_timedelta(self,
6249                                        (PyDateTime_Delta *)offset, -1);
6250     Py_DECREF(offset);
6251     if (result == NULL)
6252         return NULL;
6253 
6254     /* Make sure result is aware and UTC. */
6255     if (!HASTZINFO(result)) {
6256         temp = (PyObject *)result;
6257         result = (PyDateTime_DateTime *)
6258                    new_datetime_ex2(GET_YEAR(result),
6259                                     GET_MONTH(result),
6260                                     GET_DAY(result),
6261                                     DATE_GET_HOUR(result),
6262                                     DATE_GET_MINUTE(result),
6263                                     DATE_GET_SECOND(result),
6264                                     DATE_GET_MICROSECOND(result),
6265                                     PyDateTime_TimeZone_UTC,
6266                                     DATE_GET_FOLD(result),
6267                                     Py_TYPE(result));
6268         Py_DECREF(temp);
6269         if (result == NULL)
6270             return NULL;
6271     }
6272     else {
6273         /* Result is already aware - just replace tzinfo. */
6274         temp = result->tzinfo;
6275         result->tzinfo = PyDateTime_TimeZone_UTC;
6276         Py_INCREF(result->tzinfo);
6277         Py_DECREF(temp);
6278     }
6279 
6280     /* Attach new tzinfo and let fromutc() do the rest. */
6281     temp = result->tzinfo;
6282     if (tzinfo == Py_None) {
6283         tzinfo = local_timezone(result);
6284         if (tzinfo == NULL) {
6285             Py_DECREF(result);
6286             return NULL;
6287         }
6288     }
6289     else
6290       Py_INCREF(tzinfo);
6291     result->tzinfo = tzinfo;
6292     Py_DECREF(temp);
6293 
6294     temp = (PyObject *)result;
6295     result = (PyDateTime_DateTime *)
6296         _PyObject_CallMethodIdOneArg(tzinfo, &PyId_fromutc, temp);
6297     Py_DECREF(temp);
6298 
6299     return result;
6300 }
6301 
6302 static PyObject *
datetime_timetuple(PyDateTime_DateTime * self,PyObject * Py_UNUSED (ignored))6303 datetime_timetuple(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
6304 {
6305     int dstflag = -1;
6306 
6307     if (HASTZINFO(self) && self->tzinfo != Py_None) {
6308         PyObject * dst;
6309 
6310         dst = call_dst(self->tzinfo, (PyObject *)self);
6311         if (dst == NULL)
6312             return NULL;
6313 
6314         if (dst != Py_None)
6315             dstflag = delta_bool((PyDateTime_Delta *)dst);
6316         Py_DECREF(dst);
6317     }
6318     return build_struct_time(GET_YEAR(self),
6319                              GET_MONTH(self),
6320                              GET_DAY(self),
6321                              DATE_GET_HOUR(self),
6322                              DATE_GET_MINUTE(self),
6323                              DATE_GET_SECOND(self),
6324                              dstflag);
6325 }
6326 
6327 static long long
local_to_seconds(int year,int month,int day,int hour,int minute,int second,int fold)6328 local_to_seconds(int year, int month, int day,
6329                  int hour, int minute, int second, int fold)
6330 {
6331     long long t, a, b, u1, u2, t1, t2, lt;
6332     t = utc_to_seconds(year, month, day, hour, minute, second);
6333     /* Our goal is to solve t = local(u) for u. */
6334     lt = local(t);
6335     if (lt == -1)
6336         return -1;
6337     a = lt - t;
6338     u1 = t - a;
6339     t1 = local(u1);
6340     if (t1 == -1)
6341         return -1;
6342     if (t1 == t) {
6343         /* We found one solution, but it may not be the one we need.
6344          * Look for an earlier solution (if `fold` is 0), or a
6345          * later one (if `fold` is 1). */
6346         if (fold)
6347             u2 = u1 + max_fold_seconds;
6348         else
6349             u2 = u1 - max_fold_seconds;
6350         lt = local(u2);
6351         if (lt == -1)
6352             return -1;
6353         b = lt - u2;
6354         if (a == b)
6355             return u1;
6356     }
6357     else {
6358         b = t1 - u1;
6359         assert(a != b);
6360     }
6361     u2 = t - b;
6362     t2 = local(u2);
6363     if (t2 == -1)
6364         return -1;
6365     if (t2 == t)
6366         return u2;
6367     if (t1 == t)
6368         return u1;
6369     /* We have found both offsets a and b, but neither t - a nor t - b is
6370      * a solution.  This means t is in the gap. */
6371     return fold?Py_MIN(u1, u2):Py_MAX(u1, u2);
6372 }
6373 
6374 /* date(1970,1,1).toordinal() == 719163 */
6375 #define EPOCH_SECONDS (719163LL * 24 * 60 * 60)
6376 
6377 static PyObject *
datetime_timestamp(PyDateTime_DateTime * self,PyObject * Py_UNUSED (ignored))6378 datetime_timestamp(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
6379 {
6380     PyObject *result;
6381 
6382     if (HASTZINFO(self) && self->tzinfo != Py_None) {
6383         PyObject *delta;
6384         delta = datetime_subtract((PyObject *)self, PyDateTime_Epoch);
6385         if (delta == NULL)
6386             return NULL;
6387         result = delta_total_seconds(delta, NULL);
6388         Py_DECREF(delta);
6389     }
6390     else {
6391         long long seconds;
6392         seconds = local_to_seconds(GET_YEAR(self),
6393                                    GET_MONTH(self),
6394                                    GET_DAY(self),
6395                                    DATE_GET_HOUR(self),
6396                                    DATE_GET_MINUTE(self),
6397                                    DATE_GET_SECOND(self),
6398                                    DATE_GET_FOLD(self));
6399         if (seconds == -1)
6400             return NULL;
6401         result = PyFloat_FromDouble(seconds - EPOCH_SECONDS +
6402                                     DATE_GET_MICROSECOND(self) / 1e6);
6403     }
6404     return result;
6405 }
6406 
6407 static PyObject *
datetime_getdate(PyDateTime_DateTime * self,PyObject * Py_UNUSED (ignored))6408 datetime_getdate(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
6409 {
6410     return new_date(GET_YEAR(self),
6411                     GET_MONTH(self),
6412                     GET_DAY(self));
6413 }
6414 
6415 static PyObject *
datetime_gettime(PyDateTime_DateTime * self,PyObject * Py_UNUSED (ignored))6416 datetime_gettime(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
6417 {
6418     return new_time(DATE_GET_HOUR(self),
6419                     DATE_GET_MINUTE(self),
6420                     DATE_GET_SECOND(self),
6421                     DATE_GET_MICROSECOND(self),
6422                     Py_None,
6423                     DATE_GET_FOLD(self));
6424 }
6425 
6426 static PyObject *
datetime_gettimetz(PyDateTime_DateTime * self,PyObject * Py_UNUSED (ignored))6427 datetime_gettimetz(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
6428 {
6429     return new_time(DATE_GET_HOUR(self),
6430                     DATE_GET_MINUTE(self),
6431                     DATE_GET_SECOND(self),
6432                     DATE_GET_MICROSECOND(self),
6433                     GET_DT_TZINFO(self),
6434                     DATE_GET_FOLD(self));
6435 }
6436 
6437 static PyObject *
datetime_utctimetuple(PyDateTime_DateTime * self,PyObject * Py_UNUSED (ignored))6438 datetime_utctimetuple(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
6439 {
6440     int y, m, d, hh, mm, ss;
6441     PyObject *tzinfo;
6442     PyDateTime_DateTime *utcself;
6443 
6444     tzinfo = GET_DT_TZINFO(self);
6445     if (tzinfo == Py_None) {
6446         utcself = self;
6447         Py_INCREF(utcself);
6448     }
6449     else {
6450         PyObject *offset;
6451         offset = call_utcoffset(tzinfo, (PyObject *)self);
6452         if (offset == NULL)
6453             return NULL;
6454         if (offset == Py_None) {
6455             Py_DECREF(offset);
6456             utcself = self;
6457             Py_INCREF(utcself);
6458         }
6459         else {
6460             utcself = (PyDateTime_DateTime *)add_datetime_timedelta(self,
6461                                                 (PyDateTime_Delta *)offset, -1);
6462             Py_DECREF(offset);
6463             if (utcself == NULL)
6464                 return NULL;
6465         }
6466     }
6467     y = GET_YEAR(utcself);
6468     m = GET_MONTH(utcself);
6469     d = GET_DAY(utcself);
6470     hh = DATE_GET_HOUR(utcself);
6471     mm = DATE_GET_MINUTE(utcself);
6472     ss = DATE_GET_SECOND(utcself);
6473 
6474     Py_DECREF(utcself);
6475     return build_struct_time(y, m, d, hh, mm, ss, 0);
6476 }
6477 
6478 /* Pickle support, a simple use of __reduce__. */
6479 
6480 /* Let basestate be the non-tzinfo data string.
6481  * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
6482  * So it's a tuple in any (non-error) case.
6483  * __getstate__ isn't exposed.
6484  */
6485 static PyObject *
datetime_getstate(PyDateTime_DateTime * self,int proto)6486 datetime_getstate(PyDateTime_DateTime *self, int proto)
6487 {
6488     PyObject *basestate;
6489     PyObject *result = NULL;
6490 
6491     basestate = PyBytes_FromStringAndSize((char *)self->data,
6492                                            _PyDateTime_DATETIME_DATASIZE);
6493     if (basestate != NULL) {
6494         if (proto > 3 && DATE_GET_FOLD(self))
6495             /* Set the first bit of the third byte */
6496             PyBytes_AS_STRING(basestate)[2] |= (1 << 7);
6497         if (! HASTZINFO(self) || self->tzinfo == Py_None)
6498             result = PyTuple_Pack(1, basestate);
6499         else
6500             result = PyTuple_Pack(2, basestate, self->tzinfo);
6501         Py_DECREF(basestate);
6502     }
6503     return result;
6504 }
6505 
6506 static PyObject *
datetime_reduce_ex(PyDateTime_DateTime * self,PyObject * args)6507 datetime_reduce_ex(PyDateTime_DateTime *self, PyObject *args)
6508 {
6509     int proto;
6510     if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto))
6511         return NULL;
6512 
6513     return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, proto));
6514 }
6515 
6516 static PyObject *
datetime_reduce(PyDateTime_DateTime * self,PyObject * arg)6517 datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
6518 {
6519     return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, 2));
6520 }
6521 
6522 static PyMethodDef datetime_methods[] = {
6523 
6524     /* Class methods: */
6525 
6526     DATETIME_DATETIME_NOW_METHODDEF
6527 
6528     {"utcnow",         (PyCFunction)datetime_utcnow,
6529      METH_NOARGS | METH_CLASS,
6530      PyDoc_STR("Return a new datetime representing UTC day and time.")},
6531 
6532     {"fromtimestamp", _PyCFunction_CAST(datetime_fromtimestamp),
6533      METH_VARARGS | METH_KEYWORDS | METH_CLASS,
6534      PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
6535 
6536     {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
6537      METH_VARARGS | METH_CLASS,
6538      PyDoc_STR("Construct a naive UTC datetime from a POSIX timestamp.")},
6539 
6540     {"strptime", (PyCFunction)datetime_strptime,
6541      METH_VARARGS | METH_CLASS,
6542      PyDoc_STR("string, format -> new datetime parsed from a string "
6543                "(like time.strptime()).")},
6544 
6545     {"combine", _PyCFunction_CAST(datetime_combine),
6546      METH_VARARGS | METH_KEYWORDS | METH_CLASS,
6547      PyDoc_STR("date, time -> datetime with same date and time fields")},
6548 
6549     {"fromisoformat", (PyCFunction)datetime_fromisoformat,
6550      METH_O | METH_CLASS,
6551      PyDoc_STR("string -> datetime from a string in most ISO 8601 formats")},
6552 
6553     /* Instance methods: */
6554 
6555     {"date",   (PyCFunction)datetime_getdate, METH_NOARGS,
6556      PyDoc_STR("Return date object with same year, month and day.")},
6557 
6558     {"time",   (PyCFunction)datetime_gettime, METH_NOARGS,
6559      PyDoc_STR("Return time object with same time but with tzinfo=None.")},
6560 
6561     {"timetz",   (PyCFunction)datetime_gettimetz, METH_NOARGS,
6562      PyDoc_STR("Return time object with same time and tzinfo.")},
6563 
6564     {"ctime",       (PyCFunction)datetime_ctime,        METH_NOARGS,
6565      PyDoc_STR("Return ctime() style string.")},
6566 
6567     {"timetuple",   (PyCFunction)datetime_timetuple, METH_NOARGS,
6568      PyDoc_STR("Return time tuple, compatible with time.localtime().")},
6569 
6570     {"timestamp",   (PyCFunction)datetime_timestamp, METH_NOARGS,
6571      PyDoc_STR("Return POSIX timestamp as float.")},
6572 
6573     {"utctimetuple",   (PyCFunction)datetime_utctimetuple, METH_NOARGS,
6574      PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
6575 
6576     {"isoformat",   _PyCFunction_CAST(datetime_isoformat), METH_VARARGS | METH_KEYWORDS,
6577      PyDoc_STR("[sep] -> string in ISO 8601 format, "
6578                "YYYY-MM-DDT[HH[:MM[:SS[.mmm[uuu]]]]][+HH:MM].\n"
6579                "sep is used to separate the year from the time, and "
6580                "defaults to 'T'.\n"
6581                "The optional argument timespec specifies the number "
6582                "of additional terms\nof the time to include. Valid "
6583                "options are 'auto', 'hours', 'minutes',\n'seconds', "
6584                "'milliseconds' and 'microseconds'.\n")},
6585 
6586     {"utcoffset",       (PyCFunction)datetime_utcoffset, METH_NOARGS,
6587      PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
6588 
6589     {"tzname",          (PyCFunction)datetime_tzname,   METH_NOARGS,
6590      PyDoc_STR("Return self.tzinfo.tzname(self).")},
6591 
6592     {"dst",             (PyCFunction)datetime_dst, METH_NOARGS,
6593      PyDoc_STR("Return self.tzinfo.dst(self).")},
6594 
6595     {"replace",     _PyCFunction_CAST(datetime_replace),      METH_VARARGS | METH_KEYWORDS,
6596      PyDoc_STR("Return datetime with new specified fields.")},
6597 
6598     {"astimezone",  _PyCFunction_CAST(datetime_astimezone), METH_VARARGS | METH_KEYWORDS,
6599      PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
6600 
6601     {"__reduce_ex__", (PyCFunction)datetime_reduce_ex,     METH_VARARGS,
6602      PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")},
6603 
6604     {"__reduce__", (PyCFunction)datetime_reduce,     METH_NOARGS,
6605      PyDoc_STR("__reduce__() -> (cls, state)")},
6606 
6607     {NULL,      NULL}
6608 };
6609 
6610 static const char datetime_doc[] =
6611 PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
6612 \n\
6613 The year, month and day arguments are required. tzinfo may be None, or an\n\
6614 instance of a tzinfo subclass. The remaining arguments may be ints.\n");
6615 
6616 static PyNumberMethods datetime_as_number = {
6617     datetime_add,                               /* nb_add */
6618     datetime_subtract,                          /* nb_subtract */
6619     0,                                          /* nb_multiply */
6620     0,                                          /* nb_remainder */
6621     0,                                          /* nb_divmod */
6622     0,                                          /* nb_power */
6623     0,                                          /* nb_negative */
6624     0,                                          /* nb_positive */
6625     0,                                          /* nb_absolute */
6626     0,                                          /* nb_bool */
6627 };
6628 
6629 static PyTypeObject PyDateTime_DateTimeType = {
6630     PyVarObject_HEAD_INIT(NULL, 0)
6631     "datetime.datetime",                        /* tp_name */
6632     sizeof(PyDateTime_DateTime),                /* tp_basicsize */
6633     0,                                          /* tp_itemsize */
6634     (destructor)datetime_dealloc,               /* tp_dealloc */
6635     0,                                          /* tp_vectorcall_offset */
6636     0,                                          /* tp_getattr */
6637     0,                                          /* tp_setattr */
6638     0,                                          /* tp_as_async */
6639     (reprfunc)datetime_repr,                    /* tp_repr */
6640     &datetime_as_number,                        /* tp_as_number */
6641     0,                                          /* tp_as_sequence */
6642     0,                                          /* tp_as_mapping */
6643     (hashfunc)datetime_hash,                    /* tp_hash */
6644     0,                                          /* tp_call */
6645     (reprfunc)datetime_str,                     /* tp_str */
6646     PyObject_GenericGetAttr,                    /* tp_getattro */
6647     0,                                          /* tp_setattro */
6648     0,                                          /* tp_as_buffer */
6649     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
6650     datetime_doc,                               /* tp_doc */
6651     0,                                          /* tp_traverse */
6652     0,                                          /* tp_clear */
6653     datetime_richcompare,                       /* tp_richcompare */
6654     0,                                          /* tp_weaklistoffset */
6655     0,                                          /* tp_iter */
6656     0,                                          /* tp_iternext */
6657     datetime_methods,                           /* tp_methods */
6658     0,                                          /* tp_members */
6659     datetime_getset,                            /* tp_getset */
6660     0,                                          /* tp_base; filled in
6661                                                    PyInit__datetime */
6662     0,                                          /* tp_dict */
6663     0,                                          /* tp_descr_get */
6664     0,                                          /* tp_descr_set */
6665     0,                                          /* tp_dictoffset */
6666     0,                                          /* tp_init */
6667     datetime_alloc,                             /* tp_alloc */
6668     datetime_new,                               /* tp_new */
6669     0,                                          /* tp_free */
6670 };
6671 
6672 /* ---------------------------------------------------------------------------
6673  * Module methods and initialization.
6674  */
6675 
6676 static PyMethodDef module_methods[] = {
6677     {NULL, NULL}
6678 };
6679 
6680 /* Get a new C API by calling this function.
6681  * Clients get at C API via PyDateTime_IMPORT, defined in datetime.h.
6682  */
6683 static inline PyDateTime_CAPI *
get_datetime_capi(void)6684 get_datetime_capi(void)
6685 {
6686     PyDateTime_CAPI *capi = PyMem_Malloc(sizeof(PyDateTime_CAPI));
6687     if (capi == NULL) {
6688         PyErr_NoMemory();
6689         return NULL;
6690     }
6691     capi->DateType = &PyDateTime_DateType;
6692     capi->DateTimeType = &PyDateTime_DateTimeType;
6693     capi->TimeType = &PyDateTime_TimeType;
6694     capi->DeltaType = &PyDateTime_DeltaType;
6695     capi->TZInfoType = &PyDateTime_TZInfoType;
6696     capi->Date_FromDate = new_date_ex;
6697     capi->DateTime_FromDateAndTime = new_datetime_ex;
6698     capi->Time_FromTime = new_time_ex;
6699     capi->Delta_FromDelta = new_delta_ex;
6700     capi->TimeZone_FromTimeZone = new_timezone;
6701     capi->DateTime_FromTimestamp = datetime_fromtimestamp;
6702     capi->Date_FromTimestamp = datetime_date_fromtimestamp_capi;
6703     capi->DateTime_FromDateAndTimeAndFold = new_datetime_ex2;
6704     capi->Time_FromTimeAndFold = new_time_ex2;
6705     // Make sure this function is called after PyDateTime_TimeZone_UTC has
6706     // been initialized.
6707     assert(PyDateTime_TimeZone_UTC != NULL);
6708     capi->TimeZone_UTC = PyDateTime_TimeZone_UTC; // borrowed ref
6709     return capi;
6710 }
6711 
6712 static void
datetime_destructor(PyObject * op)6713 datetime_destructor(PyObject *op)
6714 {
6715     void *ptr = PyCapsule_GetPointer(op, PyDateTime_CAPSULE_NAME);
6716     PyMem_Free(ptr);
6717 }
6718 
6719 static int
_datetime_exec(PyObject * module)6720 _datetime_exec(PyObject *module)
6721 {
6722     // `&...` is not a constant expression according to a strict reading
6723     // of C standards. Fill tp_base at run-time rather than statically.
6724     // See https://bugs.python.org/issue40777
6725     PyDateTime_IsoCalendarDateType.tp_base = &PyTuple_Type;
6726     PyDateTime_TimeZoneType.tp_base = &PyDateTime_TZInfoType;
6727     PyDateTime_DateTimeType.tp_base = &PyDateTime_DateType;
6728 
6729     PyTypeObject *types[] = {
6730         &PyDateTime_DateType,
6731         &PyDateTime_DateTimeType,
6732         &PyDateTime_TimeType,
6733         &PyDateTime_DeltaType,
6734         &PyDateTime_TZInfoType,
6735         &PyDateTime_TimeZoneType,
6736     };
6737 
6738     for (size_t i = 0; i < Py_ARRAY_LENGTH(types); i++) {
6739         if (PyModule_AddType(module, types[i]) < 0) {
6740             return -1;
6741         }
6742     }
6743 
6744     if (PyType_Ready(&PyDateTime_IsoCalendarDateType) < 0) {
6745         return -1;
6746     }
6747 
6748 #define DATETIME_ADD_MACRO(dict, c, value_expr)         \
6749     do {                                                \
6750         PyObject *value = (value_expr);                 \
6751         if (value == NULL) {                            \
6752             return -1;                                  \
6753         }                                               \
6754         if (PyDict_SetItemString(dict, c, value) < 0) { \
6755             Py_DECREF(value);                           \
6756             return -1;                                  \
6757         }                                               \
6758         Py_DECREF(value);                               \
6759     } while(0)
6760 
6761     /* timedelta values */
6762     PyObject *d = PyDateTime_DeltaType.tp_dict;
6763     DATETIME_ADD_MACRO(d, "resolution", new_delta(0, 0, 1, 0));
6764     DATETIME_ADD_MACRO(d, "min", new_delta(-MAX_DELTA_DAYS, 0, 0, 0));
6765     DATETIME_ADD_MACRO(d, "max",
6766                        new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0));
6767 
6768     /* date values */
6769     d = PyDateTime_DateType.tp_dict;
6770     DATETIME_ADD_MACRO(d, "min", new_date(1, 1, 1));
6771     DATETIME_ADD_MACRO(d, "max", new_date(MAXYEAR, 12, 31));
6772     DATETIME_ADD_MACRO(d, "resolution", new_delta(1, 0, 0, 0));
6773 
6774     /* time values */
6775     d = PyDateTime_TimeType.tp_dict;
6776     DATETIME_ADD_MACRO(d, "min", new_time(0, 0, 0, 0, Py_None, 0));
6777     DATETIME_ADD_MACRO(d, "max", new_time(23, 59, 59, 999999, Py_None, 0));
6778     DATETIME_ADD_MACRO(d, "resolution", new_delta(0, 0, 1, 0));
6779 
6780     /* datetime values */
6781     d = PyDateTime_DateTimeType.tp_dict;
6782     DATETIME_ADD_MACRO(d, "min",
6783                        new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None, 0));
6784     DATETIME_ADD_MACRO(d, "max", new_datetime(MAXYEAR, 12, 31, 23, 59, 59,
6785                                               999999, Py_None, 0));
6786     DATETIME_ADD_MACRO(d, "resolution", new_delta(0, 0, 1, 0));
6787 
6788     /* timezone values */
6789     d = PyDateTime_TimeZoneType.tp_dict;
6790     PyObject *delta = new_delta(0, 0, 0, 0);
6791     if (delta == NULL) {
6792         return -1;
6793     }
6794 
6795     PyObject *x = create_timezone(delta, NULL);
6796     Py_DECREF(delta);
6797     if (x == NULL) {
6798         return -1;
6799     }
6800     if (PyDict_SetItemString(d, "utc", x) < 0) {
6801         Py_DECREF(x);
6802         return -1;
6803     }
6804 
6805     PyDateTime_TimeZone_UTC = x;
6806 
6807     /* bpo-37642: These attributes are rounded to the nearest minute for backwards
6808      * compatibility, even though the constructor will accept a wider range of
6809      * values. This may change in the future.*/
6810     delta = new_delta(-1, 60, 0, 1); /* -23:59 */
6811     if (delta == NULL) {
6812         return -1;
6813     }
6814 
6815     x = create_timezone(delta, NULL);
6816     Py_DECREF(delta);
6817     DATETIME_ADD_MACRO(d, "min", x);
6818 
6819     delta = new_delta(0, (23 * 60 + 59) * 60, 0, 0); /* +23:59 */
6820     if (delta == NULL) {
6821         return -1;
6822     }
6823 
6824     x = create_timezone(delta, NULL);
6825     Py_DECREF(delta);
6826     DATETIME_ADD_MACRO(d, "max", x);
6827 
6828     /* Epoch */
6829     PyDateTime_Epoch = new_datetime(1970, 1, 1, 0, 0, 0, 0,
6830                                     PyDateTime_TimeZone_UTC, 0);
6831     if (PyDateTime_Epoch == NULL) {
6832         return -1;
6833     }
6834 
6835     /* module initialization */
6836     if (PyModule_AddIntMacro(module, MINYEAR) < 0) {
6837         return -1;
6838     }
6839     if (PyModule_AddIntMacro(module, MAXYEAR) < 0) {
6840         return -1;
6841     }
6842 
6843     PyDateTime_CAPI *capi = get_datetime_capi();
6844     if (capi == NULL) {
6845         return -1;
6846     }
6847     x = PyCapsule_New(capi, PyDateTime_CAPSULE_NAME, datetime_destructor);
6848     if (x == NULL) {
6849         PyMem_Free(capi);
6850         return -1;
6851     }
6852 
6853     if (PyModule_AddObject(module, "datetime_CAPI", x) < 0) {
6854         Py_DECREF(x);
6855         return -1;
6856     }
6857 
6858     if (PyModule_AddObjectRef(module, "UTC", PyDateTime_TimeZone_UTC) < 0) {
6859         return -1;
6860     }
6861 
6862     /* A 4-year cycle has an extra leap day over what we'd get from
6863      * pasting together 4 single years.
6864      */
6865     static_assert(DI4Y == 4 * 365 + 1, "DI4Y");
6866     assert(DI4Y == days_before_year(4+1));
6867 
6868     /* Similarly, a 400-year cycle has an extra leap day over what we'd
6869      * get from pasting together 4 100-year cycles.
6870      */
6871     static_assert(DI400Y == 4 * DI100Y + 1, "DI400Y");
6872     assert(DI400Y == days_before_year(400+1));
6873 
6874     /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
6875      * pasting together 25 4-year cycles.
6876      */
6877     static_assert(DI100Y == 25 * DI4Y - 1, "DI100Y");
6878     assert(DI100Y == days_before_year(100+1));
6879 
6880     us_per_ms = PyLong_FromLong(1000);
6881     us_per_second = PyLong_FromLong(1000000);
6882     us_per_minute = PyLong_FromLong(60000000);
6883     seconds_per_day = PyLong_FromLong(24 * 3600);
6884     if (us_per_ms == NULL || us_per_second == NULL ||
6885         us_per_minute == NULL || seconds_per_day == NULL) {
6886         return -1;
6887     }
6888 
6889     /* The rest are too big for 32-bit ints, but even
6890      * us_per_week fits in 40 bits, so doubles should be exact.
6891      */
6892     us_per_hour = PyLong_FromDouble(3600000000.0);
6893     us_per_day = PyLong_FromDouble(86400000000.0);
6894     us_per_week = PyLong_FromDouble(604800000000.0);
6895     if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL) {
6896         return -1;
6897     }
6898     return 0;
6899 }
6900 
6901 static struct PyModuleDef datetimemodule = {
6902     PyModuleDef_HEAD_INIT,
6903     .m_name = "_datetime",
6904     .m_doc = "Fast implementation of the datetime type.",
6905     .m_size = -1,
6906     .m_methods = module_methods,
6907 };
6908 
6909 PyMODINIT_FUNC
PyInit__datetime(void)6910 PyInit__datetime(void)
6911 {
6912     PyObject *mod = PyModule_Create(&datetimemodule);
6913     if (mod == NULL)
6914         return NULL;
6915 
6916     if (_datetime_exec(mod) < 0) {
6917         Py_DECREF(mod);
6918         return NULL;
6919     }
6920 
6921     return mod;
6922 }
6923 
6924 /* ---------------------------------------------------------------------------
6925 Some time zone algebra.  For a datetime x, let
6926     x.n = x stripped of its timezone -- its naive time.
6927     x.o = x.utcoffset(), and assuming that doesn't raise an exception or
6928       return None
6929     x.d = x.dst(), and assuming that doesn't raise an exception or
6930       return None
6931     x.s = x's standard offset, x.o - x.d
6932 
6933 Now some derived rules, where k is a duration (timedelta).
6934 
6935 1. x.o = x.s + x.d
6936    This follows from the definition of x.s.
6937 
6938 2. If x and y have the same tzinfo member, x.s = y.s.
6939    This is actually a requirement, an assumption we need to make about
6940    sane tzinfo classes.
6941 
6942 3. The naive UTC time corresponding to x is x.n - x.o.
6943    This is again a requirement for a sane tzinfo class.
6944 
6945 4. (x+k).s = x.s
6946    This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
6947 
6948 5. (x+k).n = x.n + k
6949    Again follows from how arithmetic is defined.
6950 
6951 Now we can explain tz.fromutc(x).  Let's assume it's an interesting case
6952 (meaning that the various tzinfo methods exist, and don't blow up or return
6953 None when called).
6954 
6955 The function wants to return a datetime y with timezone tz, equivalent to x.
6956 x is already in UTC.
6957 
6958 By #3, we want
6959 
6960     y.n - y.o = x.n                             [1]
6961 
6962 The algorithm starts by attaching tz to x.n, and calling that y.  So
6963 x.n = y.n at the start.  Then it wants to add a duration k to y, so that [1]
6964 becomes true; in effect, we want to solve [2] for k:
6965 
6966    (y+k).n - (y+k).o = x.n                      [2]
6967 
6968 By #1, this is the same as
6969 
6970    (y+k).n - ((y+k).s + (y+k).d) = x.n          [3]
6971 
6972 By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
6973 Substituting that into [3],
6974 
6975    x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
6976    k - (y+k).s - (y+k).d = 0; rearranging,
6977    k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
6978    k = y.s - (y+k).d
6979 
6980 On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
6981 approximate k by ignoring the (y+k).d term at first.  Note that k can't be
6982 very large, since all offset-returning methods return a duration of magnitude
6983 less than 24 hours.  For that reason, if y is firmly in std time, (y+k).d must
6984 be 0, so ignoring it has no consequence then.
6985 
6986 In any case, the new value is
6987 
6988     z = y + y.s                                 [4]
6989 
6990 It's helpful to step back at look at [4] from a higher level:  it's simply
6991 mapping from UTC to tz's standard time.
6992 
6993 At this point, if
6994 
6995     z.n - z.o = x.n                             [5]
6996 
6997 we have an equivalent time, and are almost done.  The insecurity here is
6998 at the start of daylight time.  Picture US Eastern for concreteness.  The wall
6999 time jumps from 1:59 to 3:00, and wall hours of the form 2:MM don't make good
7000 sense then.  The docs ask that an Eastern tzinfo class consider such a time to
7001 be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
7002 on the day DST starts.  We want to return the 1:MM EST spelling because that's
7003 the only spelling that makes sense on the local wall clock.
7004 
7005 In fact, if [5] holds at this point, we do have the standard-time spelling,
7006 but that takes a bit of proof.  We first prove a stronger result.  What's the
7007 difference between the LHS and RHS of [5]?  Let
7008 
7009     diff = x.n - (z.n - z.o)                    [6]
7010 
7011 Now
7012     z.n =                       by [4]
7013     (y + y.s).n =               by #5
7014     y.n + y.s =                 since y.n = x.n
7015     x.n + y.s =                 since z and y are have the same tzinfo member,
7016                                     y.s = z.s by #2
7017     x.n + z.s
7018 
7019 Plugging that back into [6] gives
7020 
7021     diff =
7022     x.n - ((x.n + z.s) - z.o) =     expanding
7023     x.n - x.n - z.s + z.o =         cancelling
7024     - z.s + z.o =                   by #2
7025     z.d
7026 
7027 So diff = z.d.
7028 
7029 If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
7030 spelling we wanted in the endcase described above.  We're done.  Contrarily,
7031 if z.d = 0, then we have a UTC equivalent, and are also done.
7032 
7033 If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
7034 add to z (in effect, z is in tz's standard time, and we need to shift the
7035 local clock into tz's daylight time).
7036 
7037 Let
7038 
7039     z' = z + z.d = z + diff                     [7]
7040 
7041 and we can again ask whether
7042 
7043     z'.n - z'.o = x.n                           [8]
7044 
7045 If so, we're done.  If not, the tzinfo class is insane, according to the
7046 assumptions we've made.  This also requires a bit of proof.  As before, let's
7047 compute the difference between the LHS and RHS of [8] (and skipping some of
7048 the justifications for the kinds of substitutions we've done several times
7049 already):
7050 
7051     diff' = x.n - (z'.n - z'.o) =           replacing z'.n via [7]
7052         x.n  - (z.n + diff - z'.o) =    replacing diff via [6]
7053         x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
7054         x.n - z.n - x.n + z.n - z.o + z'.o =    cancel x.n
7055         - z.n + z.n - z.o + z'.o =              cancel z.n
7056         - z.o + z'.o =                      #1 twice
7057         -z.s - z.d + z'.s + z'.d =          z and z' have same tzinfo
7058         z'.d - z.d
7059 
7060 So z' is UTC-equivalent to x iff z'.d = z.d at this point.  If they are equal,
7061 we've found the UTC-equivalent so are done.  In fact, we stop with [7] and
7062 return z', not bothering to compute z'.d.
7063 
7064 How could z.d and z'd differ?  z' = z + z.d [7], so merely moving z' by
7065 a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
7066 would have to change the result dst() returns:  we start in DST, and moving
7067 a little further into it takes us out of DST.
7068 
7069 There isn't a sane case where this can happen.  The closest it gets is at
7070 the end of DST, where there's an hour in UTC with no spelling in a hybrid
7071 tzinfo class.  In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT.  During
7072 that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
7073 UTC) because the docs insist on that, but 0:MM is taken as being in daylight
7074 time (4:MM UTC).  There is no local time mapping to 5:MM UTC.  The local
7075 clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
7076 standard time.  Since that's what the local clock *does*, we want to map both
7077 UTC hours 5:MM and 6:MM to 1:MM Eastern.  The result is ambiguous
7078 in local time, but so it goes -- it's the way the local clock works.
7079 
7080 When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
7081 so z=0:MM.  z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
7082 z' = z + z.d = 1:MM then, and z'.d=0, and z'.d - z.d = -60 != 0 so [8]
7083 (correctly) concludes that z' is not UTC-equivalent to x.
7084 
7085 Because we know z.d said z was in daylight time (else [5] would have held and
7086 we would have stopped then), and we know z.d != z'.d (else [8] would have held
7087 and we would have stopped then), and there are only 2 possible values dst() can
7088 return in Eastern, it follows that z'.d must be 0 (which it is in the example,
7089 but the reasoning doesn't depend on the example -- it depends on there being
7090 two possible dst() outcomes, one zero and the other non-zero).  Therefore
7091 z' must be in standard time, and is the spelling we want in this case.
7092 
7093 Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
7094 concerned (because it takes z' as being in standard time rather than the
7095 daylight time we intend here), but returning it gives the real-life "local
7096 clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
7097 tz.
7098 
7099 When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
7100 the 1:MM standard time spelling we want.
7101 
7102 So how can this break?  One of the assumptions must be violated.  Two
7103 possibilities:
7104 
7105 1) [2] effectively says that y.s is invariant across all y belong to a given
7106    time zone.  This isn't true if, for political reasons or continental drift,
7107    a region decides to change its base offset from UTC.
7108 
7109 2) There may be versions of "double daylight" time where the tail end of
7110    the analysis gives up a step too early.  I haven't thought about that
7111    enough to say.
7112 
7113 In any case, it's clear that the default fromutc() is strong enough to handle
7114 "almost all" time zones:  so long as the standard offset is invariant, it
7115 doesn't matter if daylight time transition points change from year to year, or
7116 if daylight time is skipped in some years; it doesn't matter how large or
7117 small dst() may get within its bounds; and it doesn't even matter if some
7118 perverse time zone returns a negative dst()).  So a breaking case must be
7119 pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
7120 --------------------------------------------------------------------------- */
7121