Skip to content

Commit e2926b7

Browse files
aixtoolsncoghlan
authored andcommitted
bpo-34373: fix test_mktime and test_pthread_getcpuclickid tests on AIX (GH-8726)
* Fix test_mktime on AIX by adding code to get mktime to behave the same way as it does on other *nix systems * Fix test_pthread_getcpuclickid in AIX by adjusting the test case expectations when running on AIX in 32-bit mode Patch by Michael Felt.
1 parent c465682 commit e2926b7

File tree

4 files changed

+57
-20
lines changed

4 files changed

+57
-20
lines changed

Lib/test/test_time.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,13 @@ def test_clock_monotonic(self):
119119
def test_pthread_getcpuclockid(self):
120120
clk_id = time.pthread_getcpuclockid(threading.get_ident())
121121
self.assertTrue(type(clk_id) is int)
122-
self.assertNotEqual(clk_id, time.CLOCK_THREAD_CPUTIME_ID)
122+
# when in 32-bit mode AIX only returns the predefined constant
123+
if not platform.system() == "AIX":
124+
self.assertNotEqual(clk_id, time.CLOCK_THREAD_CPUTIME_ID)
125+
elif (sys.maxsize.bit_length() > 32):
126+
self.assertNotEqual(clk_id, time.CLOCK_THREAD_CPUTIME_ID)
127+
else:
128+
self.assertEqual(clk_id, time.CLOCK_THREAD_CPUTIME_ID)
123129
t1 = time.clock_gettime(clk_id)
124130
t2 = time.clock_gettime(clk_id)
125131
self.assertLessEqual(t1, t2)
@@ -424,13 +430,6 @@ def test_localtime_without_arg(self):
424430
def test_mktime(self):
425431
# Issue #1726687
426432
for t in (-2, -1, 0, 1):
427-
if sys.platform.startswith('aix') and t == -1:
428-
# Issue #11188, #19748: mktime() returns -1 on error. On Linux,
429-
# the tm_wday field is used as a sentinel () to detect if -1 is
430-
# really an error or a valid timestamp. On AIX, tm_wday is
431-
# unchanged even on success and so cannot be used as a
432-
# sentinel.
433-
continue
434433
try:
435434
tt = time.localtime(t)
436435
except (OverflowError, OSError):
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix ``test_mktime`` and ``test_pthread_getcpuclickid`` tests for AIX
2+
Add range checking for ``_PyTime_localtime`` for AIX
3+
Patch by Michael Felt

Modules/timemodule.c

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -174,10 +174,15 @@ static PyObject *
174174
time_clock_gettime(PyObject *self, PyObject *args)
175175
{
176176
int ret;
177-
int clk_id;
178177
struct timespec tp;
179178

179+
#if defined(_AIX) && (SIZEOF_LONG == 8)
180+
long clk_id;
181+
if (!PyArg_ParseTuple(args, "l:clock_gettime", &clk_id)) {
182+
#else
183+
int clk_id;
180184
if (!PyArg_ParseTuple(args, "i:clock_gettime", &clk_id)) {
185+
#endif
181186
return NULL;
182187
}
183188

@@ -972,35 +977,51 @@ time_mktime(PyObject *self, PyObject *tup)
972977
{
973978
struct tm buf;
974979
time_t tt;
980+
#ifdef _AIX
981+
time_t clk;
982+
int year = buf.tm_year;
983+
int delta_days = 0;
984+
#endif
985+
975986
if (!gettmarg(tup, &buf,
976987
"iiiiiiiii;mktime(): illegal time tuple argument"))
977988
{
978989
return NULL;
979990
}
980-
#ifdef _AIX
991+
#ifndef _AIX
992+
buf.tm_wday = -1; /* sentinel; original value ignored */
993+
tt = mktime(&buf);
994+
#else
981995
/* year < 1902 or year > 2037 */
982-
if (buf.tm_year < 2 || buf.tm_year > 137) {
996+
if ((buf.tm_year < 2) || (buf.tm_year > 137)) {
983997
/* Issue #19748: On AIX, mktime() doesn't report overflow error for
984998
* timestamp < -2^31 or timestamp > 2**31-1. */
985999
PyErr_SetString(PyExc_OverflowError,
9861000
"mktime argument out of range");
9871001
return NULL;
9881002
}
989-
#else
990-
buf.tm_wday = -1; /* sentinel; original value ignored */
1003+
year = buf.tm_year;
1004+
/* year < 1970 - adjust buf.tm_year into legal range */
1005+
while (buf.tm_year < 70) {
1006+
buf.tm_year += 4;
1007+
delta_days -= (366 + (365 * 3));
1008+
}
1009+
1010+
buf.tm_wday = -1;
1011+
clk = mktime(&buf);
1012+
buf.tm_year = year;
1013+
1014+
if ((buf.tm_wday != -1) && delta_days)
1015+
buf.tm_wday = (buf.tm_wday + delta_days) % 7;
1016+
1017+
tt = clk + (delta_days * (24 * 3600));
9911018
#endif
992-
tt = mktime(&buf);
9931019
/* Return value of -1 does not necessarily mean an error, but tm_wday
9941020
* cannot remain set to -1 if mktime succeeded. */
9951021
if (tt == (time_t)(-1)
996-
#ifndef _AIX
9971022
/* Return value of -1 does not necessarily mean an error, but
9981023
* tm_wday cannot remain set to -1 if mktime succeeded. */
999-
&& buf.tm_wday == -1
1000-
#else
1001-
/* on AIX, tm_wday is always sets, even on error */
1002-
#endif
1003-
)
1024+
&& buf.tm_wday == -1)
10041025
{
10051026
PyErr_SetString(PyExc_OverflowError,
10061027
"mktime argument out of range");

Python/pytime.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1062,6 +1062,20 @@ _PyTime_localtime(time_t t, struct tm *tm)
10621062
}
10631063
return 0;
10641064
#else /* !MS_WINDOWS */
1065+
#ifdef _AIX
1066+
/* AIX does not return NULL on an error
1067+
so test ranges - asif!
1068+
(1902-01-01, -2145916800.0)
1069+
(2038-01-01, 2145916800.0) */
1070+
if (abs(t) > (time_t) 2145916800) {
1071+
#ifdef EINVAL
1072+
errno = EINVAL;
1073+
#endif
1074+
PyErr_SetString(PyExc_OverflowError,
1075+
"ctime argument out of range");
1076+
return -1;
1077+
}
1078+
#endif
10651079
if (localtime_r(&t, tm) == NULL) {
10661080
#ifdef EINVAL
10671081
if (errno == 0) {

0 commit comments

Comments
 (0)