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