annotate Python/pytime.c @ 74832:f8409b3d6449

PEP 410
author Victor Stinner <victor.stinner@haypocalc.com>
date Wed, 08 Feb 2012 14:31:50 +0100
parents bee7943d38c6
children 90eda29a8e03
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
63757
c16803bbd790 Issue #9079: Added _PyTime_gettimeofday(_PyTime_timeval *tp) to C API
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents:
diff changeset
1 #include "Python.h"
74821
bee7943d38c6 Issue #13845: time.time() now uses GetSystemTimeAsFileTime() instead of ftime()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 63757
diff changeset
2 #ifdef MS_WINDOWS
bee7943d38c6 Issue #13845: time.time() now uses GetSystemTimeAsFileTime() instead of ftime()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 63757
diff changeset
3 #include <windows.h>
bee7943d38c6 Issue #13845: time.time() now uses GetSystemTimeAsFileTime() instead of ftime()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 63757
diff changeset
4 #endif
63757
c16803bbd790 Issue #9079: Added _PyTime_gettimeofday(_PyTime_timeval *tp) to C API
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents:
diff changeset
5
74821
bee7943d38c6 Issue #13845: time.time() now uses GetSystemTimeAsFileTime() instead of ftime()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 63757
diff changeset
6 #if defined(__APPLE__) && defined(HAVE_GETTIMEOFDAY) && defined(HAVE_FTIME)
63757
c16803bbd790 Issue #9079: Added _PyTime_gettimeofday(_PyTime_timeval *tp) to C API
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents:
diff changeset
7 /*
c16803bbd790 Issue #9079: Added _PyTime_gettimeofday(_PyTime_timeval *tp) to C API
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents:
diff changeset
8 * _PyTime_gettimeofday falls back to ftime when getttimeofday fails because the latter
c16803bbd790 Issue #9079: Added _PyTime_gettimeofday(_PyTime_timeval *tp) to C API
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents:
diff changeset
9 * might fail on some platforms. This fallback is unwanted on MacOSX because
c16803bbd790 Issue #9079: Added _PyTime_gettimeofday(_PyTime_timeval *tp) to C API
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents:
diff changeset
10 * that makes it impossible to use a binary build on OSX 10.4 on earlier
c16803bbd790 Issue #9079: Added _PyTime_gettimeofday(_PyTime_timeval *tp) to C API
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents:
diff changeset
11 * releases of the OS. Therefore claim we don't support ftime.
c16803bbd790 Issue #9079: Added _PyTime_gettimeofday(_PyTime_timeval *tp) to C API
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents:
diff changeset
12 */
c16803bbd790 Issue #9079: Added _PyTime_gettimeofday(_PyTime_timeval *tp) to C API
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents:
diff changeset
13 # undef HAVE_FTIME
c16803bbd790 Issue #9079: Added _PyTime_gettimeofday(_PyTime_timeval *tp) to C API
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents:
diff changeset
14 #endif
c16803bbd790 Issue #9079: Added _PyTime_gettimeofday(_PyTime_timeval *tp) to C API
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents:
diff changeset
15
74821
bee7943d38c6 Issue #13845: time.time() now uses GetSystemTimeAsFileTime() instead of ftime()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 63757
diff changeset
16 #if defined(HAVE_FTIME) && !defined(MS_WINDOWS)
63757
c16803bbd790 Issue #9079: Added _PyTime_gettimeofday(_PyTime_timeval *tp) to C API
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents:
diff changeset
17 #include <sys/timeb.h>
c16803bbd790 Issue #9079: Added _PyTime_gettimeofday(_PyTime_timeval *tp) to C API
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents:
diff changeset
18 extern int ftime(struct timeb *);
74821
bee7943d38c6 Issue #13845: time.time() now uses GetSystemTimeAsFileTime() instead of ftime()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 63757
diff changeset
19 #endif
63757
c16803bbd790 Issue #9079: Added _PyTime_gettimeofday(_PyTime_timeval *tp) to C API
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents:
diff changeset
20
74832
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
21 #define MICROSECONDS 1000000
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
22
63757
c16803bbd790 Issue #9079: Added _PyTime_gettimeofday(_PyTime_timeval *tp) to C API
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents:
diff changeset
23 void
74832
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
24 _PyTime_get(_PyTime_t *ts)
63757
c16803bbd790 Issue #9079: Added _PyTime_gettimeofday(_PyTime_timeval *tp) to C API
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents:
diff changeset
25 {
74821
bee7943d38c6 Issue #13845: time.time() now uses GetSystemTimeAsFileTime() instead of ftime()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 63757
diff changeset
26 #ifdef MS_WINDOWS
bee7943d38c6 Issue #13845: time.time() now uses GetSystemTimeAsFileTime() instead of ftime()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 63757
diff changeset
27 FILETIME system_time;
bee7943d38c6 Issue #13845: time.time() now uses GetSystemTimeAsFileTime() instead of ftime()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 63757
diff changeset
28 ULARGE_INTEGER large;
74832
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
29 ULONGLONG value;
74821
bee7943d38c6 Issue #13845: time.time() now uses GetSystemTimeAsFileTime() instead of ftime()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 63757
diff changeset
30
bee7943d38c6 Issue #13845: time.time() now uses GetSystemTimeAsFileTime() instead of ftime()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 63757
diff changeset
31 GetSystemTimeAsFileTime(&system_time);
bee7943d38c6 Issue #13845: time.time() now uses GetSystemTimeAsFileTime() instead of ftime()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 63757
diff changeset
32 large.u.LowPart = system_time.dwLowDateTime;
bee7943d38c6 Issue #13845: time.time() now uses GetSystemTimeAsFileTime() instead of ftime()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 63757
diff changeset
33 large.u.HighPart = system_time.dwHighDateTime;
74832
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
34 /* 116,444,736,000,000,000: number of 100 ns between
74821
bee7943d38c6 Issue #13845: time.time() now uses GetSystemTimeAsFileTime() instead of ftime()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 63757
diff changeset
35 the 1st january 1601 and the 1st january 1970 (369 years + 89 leap
bee7943d38c6 Issue #13845: time.time() now uses GetSystemTimeAsFileTime() instead of ftime()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 63757
diff changeset
36 days). */
74832
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
37 value = large.QuadPart - 116444736000000000;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
38 ts->seconds = 0;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
39 ts->numerator = value;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
40 ts->denominator = (_PyTime_fraction_t)10000000;
74821
bee7943d38c6 Issue #13845: time.time() now uses GetSystemTimeAsFileTime() instead of ftime()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 63757
diff changeset
41 #else
74832
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
42
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
43 #ifdef HAVE_GETTIMEOFDAY
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
44 struct timeval tv;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
45 int err;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
46 #endif
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
47 #if defined(HAVE_FTIME)
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
48 struct timeb t;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
49 #endif
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
50
63757
c16803bbd790 Issue #9079: Added _PyTime_gettimeofday(_PyTime_timeval *tp) to C API
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents:
diff changeset
51 /* There are three ways to get the time:
c16803bbd790 Issue #9079: Added _PyTime_gettimeofday(_PyTime_timeval *tp) to C API
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents:
diff changeset
52 (1) gettimeofday() -- resolution in microseconds
c16803bbd790 Issue #9079: Added _PyTime_gettimeofday(_PyTime_timeval *tp) to C API
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents:
diff changeset
53 (2) ftime() -- resolution in milliseconds
c16803bbd790 Issue #9079: Added _PyTime_gettimeofday(_PyTime_timeval *tp) to C API
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents:
diff changeset
54 (3) time() -- resolution in seconds
c16803bbd790 Issue #9079: Added _PyTime_gettimeofday(_PyTime_timeval *tp) to C API
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents:
diff changeset
55 In all cases the return value in a timeval struct.
c16803bbd790 Issue #9079: Added _PyTime_gettimeofday(_PyTime_timeval *tp) to C API
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents:
diff changeset
56 Since on some systems (e.g. SCO ODT 3.0) gettimeofday() may
c16803bbd790 Issue #9079: Added _PyTime_gettimeofday(_PyTime_timeval *tp) to C API
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents:
diff changeset
57 fail, so we fall back on ftime() or time().
c16803bbd790 Issue #9079: Added _PyTime_gettimeofday(_PyTime_timeval *tp) to C API
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents:
diff changeset
58 Note: clock resolution does not imply clock accuracy! */
74821
bee7943d38c6 Issue #13845: time.time() now uses GetSystemTimeAsFileTime() instead of ftime()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 63757
diff changeset
59
63757
c16803bbd790 Issue #9079: Added _PyTime_gettimeofday(_PyTime_timeval *tp) to C API
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents:
diff changeset
60 #ifdef HAVE_GETTIMEOFDAY
c16803bbd790 Issue #9079: Added _PyTime_gettimeofday(_PyTime_timeval *tp) to C API
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents:
diff changeset
61 #ifdef GETTIMEOFDAY_NO_TZ
74832
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
62 err = gettimeofday(&tv);
63757
c16803bbd790 Issue #9079: Added _PyTime_gettimeofday(_PyTime_timeval *tp) to C API
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents:
diff changeset
63 #else /* !GETTIMEOFDAY_NO_TZ */
74832
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
64 err = gettimeofday(&tv, (struct timezone *)NULL);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
65 #endif /* !GETTIMEOFDAY_NO_TZ */
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
66 if (err == 0)
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
67 {
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
68 ts->seconds = tv.tv_sec;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
69 ts->numerator = tv.tv_usec;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
70 ts->denominator = MICROSECONDS;
63757
c16803bbd790 Issue #9079: Added _PyTime_gettimeofday(_PyTime_timeval *tp) to C API
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents:
diff changeset
71 return;
74832
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
72 }
63757
c16803bbd790 Issue #9079: Added _PyTime_gettimeofday(_PyTime_timeval *tp) to C API
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents:
diff changeset
73 #endif /* !HAVE_GETTIMEOFDAY */
74821
bee7943d38c6 Issue #13845: time.time() now uses GetSystemTimeAsFileTime() instead of ftime()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 63757
diff changeset
74
63757
c16803bbd790 Issue #9079: Added _PyTime_gettimeofday(_PyTime_timeval *tp) to C API
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents:
diff changeset
75 #if defined(HAVE_FTIME)
74832
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
76 ftime(&t);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
77 ts->seconds = t.time;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
78 ts->numerator = t.millitm;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
79 ts->denominator = 1000;
63757
c16803bbd790 Issue #9079: Added _PyTime_gettimeofday(_PyTime_timeval *tp) to C API
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents:
diff changeset
80 #else /* !HAVE_FTIME */
74832
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
81 ts->seconds = time(NULL);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
82 ts->numerator = 0;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
83 ts->denominator = 1;
63757
c16803bbd790 Issue #9079: Added _PyTime_gettimeofday(_PyTime_timeval *tp) to C API
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents:
diff changeset
84 #endif /* !HAVE_FTIME */
74821
bee7943d38c6 Issue #13845: time.time() now uses GetSystemTimeAsFileTime() instead of ftime()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 63757
diff changeset
85
bee7943d38c6 Issue #13845: time.time() now uses GetSystemTimeAsFileTime() instead of ftime()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 63757
diff changeset
86 #endif /* MS_WINDOWS */
63757
c16803bbd790 Issue #9079: Added _PyTime_gettimeofday(_PyTime_timeval *tp) to C API
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents:
diff changeset
87 }
c16803bbd790 Issue #9079: Added _PyTime_gettimeofday(_PyTime_timeval *tp) to C API
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents:
diff changeset
88
c16803bbd790 Issue #9079: Added _PyTime_gettimeofday(_PyTime_timeval *tp) to C API
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents:
diff changeset
89 void
74832
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
90 _PyTime_gettimeofday(_PyTime_timeval *tv)
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
91 {
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
92 _PyTime_t ts;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
93 _PyTime_fraction_t k;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
94 time_t sec;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
95
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
96 _PyTime_get(&ts);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
97 tv->tv_sec = ts.seconds;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
98 if (ts.numerator) {
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
99 if (ts.numerator > ts.denominator) {
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
100 sec = Py_SAFE_DOWNCAST(ts.numerator / ts.denominator,
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
101 _PyTime_fraction_t, time_t);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
102 /* ignore integer overflow because _PyTime_gettimeofday() has
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
103 no return value */
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
104 tv->tv_sec += sec;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
105 ts.numerator = ts.numerator % ts.denominator;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
106 }
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
107 if (MICROSECONDS >= ts.denominator) {
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
108 k = (_PyTime_fraction_t)MICROSECONDS / ts.denominator;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
109 tv->tv_usec = (long)(ts.numerator * k);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
110 }
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
111 else {
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
112 k = ts.denominator / (_PyTime_fraction_t)MICROSECONDS;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
113 tv->tv_usec = (long)(ts.numerator / k);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
114 }
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
115 }
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
116 else {
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
117 tv->tv_usec = 0;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
118 }
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
119 }
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
120
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
121 static PyObject*
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
122 _PyLong_FromTime_t(time_t value)
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
123 {
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
124 #if SIZEOF_TIME_T <= SIZEOF_LONG
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
125 return PyLong_FromLong(value);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
126 #else
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
127 assert(sizeof(time_t) <= sizeof(PY_LONG_LONG));
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
128 return PyLong_FromLongLong(value);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
129 #endif
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
130 }
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
131
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
132 #if defined(HAVE_LONG_LONG)
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
133 # define _PyLong_FromTimeFraction_t PyLong_FromLongLong
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
134 #else
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
135 # define _PyLong_FromTimeFraction_t PyLong_FromSize_t
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
136 #endif
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
137
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
138 /* Convert a timestamp to a PyFloat object */
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
139 static PyObject*
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
140 _PyTime_AsFloat(_PyTime_t *ts)
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
141 {
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
142 double d;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
143 d = (double)ts->seconds;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
144 d += (double)ts->numerator / (double)ts->denominator;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
145 return PyFloat_FromDouble(d);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
146 }
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
147
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
148 /* Convert a timestamp to a PyLong object */
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
149 static PyObject*
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
150 _PyTime_AsLong(_PyTime_t *ts)
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
151 {
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
152 PyObject *a, *b, *c;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
153
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
154 a = _PyLong_FromTime_t(ts->seconds);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
155 if (a == NULL)
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
156 return NULL;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
157 b = _PyLong_FromTimeFraction_t(ts->numerator / ts->denominator);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
158 if (b == NULL)
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
159 {
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
160 Py_DECREF(a);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
161 return NULL;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
162 }
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
163 c = PyNumber_Add(a, b);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
164 Py_DECREF(a);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
165 Py_DECREF(b);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
166 return c;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
167 }
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
168
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
169 /* Convert a timestamp to a decimal.Decimal object */
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
170 static PyObject*
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
171 _PyTime_AsDecimal(_PyTime_t *ts)
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
172 {
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
173 static PyObject* module = NULL;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
174 static PyObject* decimal = NULL;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
175 static PyObject* exponent_context = NULL;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
176 static PyObject* context = NULL;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
177 /* exponent cache, dictionary of:
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
178 int (denominator) => Decimal (1/denominator) */
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
179 static PyObject* exponent_cache = NULL;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
180 PyObject *t = NULL;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
181 PyObject *key, *exponent, *quantized;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
182 _Py_IDENTIFIER(quantize);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
183 _Py_IDENTIFIER(__truediv__);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
184
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
185 if (!module) {
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
186 module = PyImport_ImportModuleNoBlock("decimal");
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
187 if (module == NULL)
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
188 return NULL;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
189 }
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
190
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
191 if (!decimal) {
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
192 decimal = PyObject_GetAttrString(module, "Decimal");
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
193 if (decimal == NULL)
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
194 return NULL;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
195 }
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
196
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
197 if (context == NULL)
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
198 {
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
199 /* Use 12 decimal digits to store 10,000 years in seconds + 9
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
200 decimal digits for the floating part in nanoseconds + 1 decimal
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
201 digit to round correctly.
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
202
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
203 context = decimal.Context(22, rounding=decimal.ROUND_HALF_EVEN)
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
204 exponent_context = decimal.Context(1, rounding=decimal.ROUND_HALF_EVEN)
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
205 */
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
206 PyObject *context_class, *rounding;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
207 context_class = PyObject_GetAttrString(module, "Context");
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
208 if (context_class == NULL)
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
209 return NULL;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
210 rounding = PyObject_GetAttrString(module, "ROUND_HALF_EVEN");
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
211 if (rounding == NULL)
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
212 {
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
213 Py_DECREF(context_class);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
214 return NULL;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
215 }
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
216 context = PyObject_CallFunction(context_class, "iO", 22, rounding);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
217 if (context == NULL)
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
218 {
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
219 Py_DECREF(context_class);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
220 Py_DECREF(rounding);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
221 return NULL;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
222 }
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
223
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
224 exponent_context = PyObject_CallFunction(context_class, "iO", 1, rounding);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
225 Py_DECREF(context_class);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
226 Py_DECREF(rounding);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
227 if (exponent_context == NULL)
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
228 {
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
229 Py_CLEAR(context);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
230 return NULL;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
231 }
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
232 }
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
233
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
234 /* t = decimal.Decimal(value) */
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
235 if (ts->seconds) {
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
236 PyObject *f = _PyLong_FromTime_t(ts->seconds);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
237 t = PyObject_CallFunction(decimal, "O", f);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
238 Py_CLEAR(f);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
239 }
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
240 else {
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
241 t = PyObject_CallFunction(decimal, "iO", 0, context);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
242 }
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
243 if (t == NULL)
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
244 return NULL;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
245
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
246 if (ts->numerator)
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
247 {
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
248 /* t += decimal.Decimal(numerator, ctx) / decimal.Decimal(denominator, ctx) */
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
249 PyObject *a, *b, *c, *d, *x;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
250
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
251 x = _PyLong_FromTimeFraction_t(ts->numerator);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
252 if (x == NULL)
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
253 goto error;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
254 a = PyObject_CallFunction(decimal, "OO", x, context);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
255 Py_CLEAR(x);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
256 if (a == NULL)
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
257 goto error;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
258
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
259 x = _PyLong_FromTimeFraction_t(ts->denominator);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
260 if (x == NULL)
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
261 {
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
262 Py_DECREF(a);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
263 goto error;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
264 }
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
265 b = PyObject_CallFunction(decimal, "OO", x, context);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
266 Py_CLEAR(x);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
267 if (b == NULL)
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
268 {
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
269 Py_DECREF(a);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
270 goto error;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
271 }
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
272
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
273 c = _PyObject_CallMethodId(a, &PyId___truediv__, "OO",
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
274 b, context);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
275 Py_DECREF(a);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
276 Py_DECREF(b);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
277 if (c == NULL)
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
278 goto error;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
279
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
280 d = PyNumber_Add(t, c);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
281 Py_DECREF(c);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
282 if (d == NULL)
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
283 goto error;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
284 Py_DECREF(t);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
285 t = d;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
286 }
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
287
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
288 if (exponent_cache == NULL) {
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
289 exponent_cache = PyDict_New();
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
290 if (exponent_cache == NULL)
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
291 goto error;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
292 }
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
293
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
294 key = _PyLong_FromTimeFraction_t(ts->denominator);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
295 if (key == NULL)
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
296 goto error;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
297 exponent = PyDict_GetItem(exponent_cache, key);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
298 if (exponent == NULL) {
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
299 /* exponent = decimal.Decimal(1) / decimal.Decimal(resolution) */
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
300 PyObject *one, *denominator;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
301
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
302 one = PyObject_CallFunction(decimal, "i", 1);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
303 if (one == NULL) {
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
304 Py_DECREF(key);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
305 goto error;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
306 }
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
307
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
308 denominator = PyObject_CallFunction(decimal, "O", key);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
309 if (denominator == NULL) {
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
310 Py_DECREF(key);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
311 Py_DECREF(one);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
312 goto error;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
313 }
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
314
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
315 exponent = _PyObject_CallMethodId(one, &PyId___truediv__, "OO",
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
316 denominator, exponent_context);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
317 Py_DECREF(one);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
318 Py_DECREF(denominator);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
319 if (exponent == NULL) {
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
320 Py_DECREF(key);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
321 goto error;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
322 }
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
323
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
324 if (PyDict_SetItem(exponent_cache, key, exponent) < 0) {
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
325 Py_DECREF(key);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
326 Py_DECREF(exponent);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
327 goto error;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
328 }
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
329 Py_DECREF(key);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
330 }
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
331
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
332 /* t = t.quantize(exponent, None, context) */
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
333 quantized = _PyObject_CallMethodId(t, &PyId_quantize, "OOO",
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
334 exponent, Py_None, context);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
335 if (quantized == NULL)
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
336 goto error;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
337 Py_DECREF(t);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
338 t = quantized;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
339
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
340 return t;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
341
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
342 error:
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
343 Py_XDECREF(t);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
344 return NULL;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
345 }
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
346
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
347 PyObject*
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
348 _PyTime_Convert(_PyTime_t *ts, PyObject *format)
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
349 {
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
350 assert(ts->denominator != 0);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
351
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
352 if (format == NULL || (PyTypeObject *)format == &PyFloat_Type)
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
353 return _PyTime_AsFloat(ts);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
354 if ((PyTypeObject *)format == &PyLong_Type)
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
355 return _PyTime_AsLong(ts);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
356
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
357 if (PyType_Check(format))
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
358 {
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
359 PyObject *module, *name;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
360 _Py_IDENTIFIER(__name__);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
361 _Py_IDENTIFIER(__module__);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
362
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
363 module = _PyObject_GetAttrId(format, &PyId___module__);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
364 name = _PyObject_GetAttrId(format, &PyId___name__);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
365 if (module != NULL && PyUnicode_Check(module)
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
366 && name != NULL && PyUnicode_Check(name))
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
367 {
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
368 if (PyUnicode_CompareWithASCIIString(module, "decimal") == 0
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
369 && PyUnicode_CompareWithASCIIString(name, "Decimal") == 0)
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
370 return _PyTime_AsDecimal(ts);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
371 }
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
372 else
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
373 PyErr_Clear();
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
374 }
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
375
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
376 PyErr_Format(PyExc_ValueError, "Unknown timestamp format: %R", format);
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
377 return NULL;
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
378 }
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
379
f8409b3d6449 PEP 410
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74821
diff changeset
380 void
63757
c16803bbd790 Issue #9079: Added _PyTime_gettimeofday(_PyTime_timeval *tp) to C API
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents:
diff changeset
381 _PyTime_Init()
c16803bbd790 Issue #9079: Added _PyTime_gettimeofday(_PyTime_timeval *tp) to C API
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents:
diff changeset
382 {
c16803bbd790 Issue #9079: Added _PyTime_gettimeofday(_PyTime_timeval *tp) to C API
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents:
diff changeset
383 /* Do nothing. Needed to force linking. */
c16803bbd790 Issue #9079: Added _PyTime_gettimeofday(_PyTime_timeval *tp) to C API
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents:
diff changeset
384 }