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