Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9c72f9b

Browse files
committed
Fix test_time on Windows
* Filter values which would overflow on conversion to the C long type (for timeval.tv_sec). * Adjust also the message of OverflowError on PyTime conversions * test_time: add debug information if a timestamp conversion fails
1 parent 4f1f6e4 commit 9c72f9b

2 files changed

Lines changed: 32 additions & 29 deletions

File tree

Lib/test/test_time.py

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -756,10 +756,15 @@ def convert_values(ns_timestamps):
756756
context.rounding = decimal_rnd
757757

758758
for value in valid_values:
759-
expected = expected_func(value)
760-
self.assertEqual(pytime_converter(value, time_rnd),
759+
debug_info = {'value': value, 'rounding': decimal_rnd}
760+
try:
761+
result = pytime_converter(value, time_rnd)
762+
expected = expected_func(value)
763+
except Exception as exc:
764+
self.fail("Error on timestamp conversion: %s" % debug_info)
765+
self.assertEqual(result,
761766
expected,
762-
{'value': value, 'rounding': decimal_rnd})
767+
debug_info)
763768

764769
# test overflow
765770
ns = self.OVERFLOW_SECONDS * SEC_TO_NS
@@ -770,14 +775,15 @@ def convert_values(ns_timestamps):
770775
with self.assertRaises(OverflowError):
771776
pytime_converter(value, time_rnd)
772777

773-
def check_int_rounding(self, pytime_converter, expected_func, unit_to_sec=1,
774-
value_filter=None):
778+
def check_int_rounding(self, pytime_converter, expected_func,
779+
unit_to_sec=1, value_filter=None):
775780
self._check_rounding(pytime_converter, expected_func,
776781
False, unit_to_sec, value_filter)
777782

778-
def check_float_rounding(self, pytime_converter, expected_func, unit_to_sec=1):
783+
def check_float_rounding(self, pytime_converter, expected_func,
784+
unit_to_sec=1, value_filter=None):
779785
self._check_rounding(pytime_converter, expected_func,
780-
True, unit_to_sec)
786+
True, unit_to_sec, value_filter)
781787

782788
def decimal_round(self, x):
783789
d = decimal.Decimal(x)
@@ -845,9 +851,19 @@ def timeval_converter(ns):
845851
us = us_converter(ns)
846852
return divmod(us, SEC_TO_US)
847853

854+
if sys.platform == 'win32':
855+
from _testcapi import LONG_MIN, LONG_MAX
856+
857+
# On Windows, timeval.tv_sec type is a C long
858+
def seconds_filter(secs):
859+
return LONG_MIN <= secs <= LONG_MAX
860+
else:
861+
seconds_filter = None
862+
848863
self.check_int_rounding(PyTime_AsTimeval,
849864
timeval_converter,
850-
NS_TO_SEC)
865+
NS_TO_SEC,
866+
value_filter=seconds_filter)
851867

852868
@unittest.skipUnless(hasattr(_testcapi, 'PyTime_AsTimespec'),
853869
'need _testcapi.PyTime_AsTimespec')
@@ -927,6 +943,5 @@ def test_object_to_timespec(self):
927943
self.create_converter(SEC_TO_NS))
928944

929945

930-
931946
if __name__ == "__main__":
932947
unittest.main()

Python/pytime.c

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -288,18 +288,21 @@ _PyTime_FromObject(_PyTime_t *t, PyObject *obj, _PyTime_round_t round,
288288
else {
289289
#ifdef HAVE_LONG_LONG
290290
PY_LONG_LONG sec;
291-
sec = PyLong_AsLongLong(obj);
292291
assert(sizeof(PY_LONG_LONG) <= sizeof(_PyTime_t));
292+
293+
sec = PyLong_AsLongLong(obj);
293294
#else
294295
long sec;
295-
sec = PyLong_AsLong(obj);
296296
assert(sizeof(PY_LONG_LONG) <= sizeof(_PyTime_t));
297+
298+
sec = PyLong_AsLong(obj);
297299
#endif
298300
if (sec == -1 && PyErr_Occurred()) {
299301
if (PyErr_ExceptionMatches(PyExc_OverflowError))
300302
_PyTime_overflow();
301303
return -1;
302304
}
305+
303306
*t = sec * unit_to_ns;
304307
if (*t / unit_to_ns != sec) {
305308
_PyTime_overflow();
@@ -404,27 +407,12 @@ _PyTime_AsTimeval_impl(_PyTime_t t, struct timeval *tv, _PyTime_round_t round,
404407
ns = t % SEC_TO_NS;
405408

406409
#ifdef MS_WINDOWS
407-
/* On Windows, timeval.tv_sec is a long (32 bit),
408-
whereas time_t can be 64-bit. */
409-
assert(sizeof(tv->tv_sec) == sizeof(long));
410-
#if SIZEOF_TIME_T > SIZEOF_LONG
411-
if (secs > LONG_MAX) {
412-
secs = LONG_MAX;
413-
res = -1;
414-
}
415-
else if (secs < LONG_MIN) {
416-
secs = LONG_MIN;
417-
res = -1;
418-
}
419-
#endif
420410
tv->tv_sec = (long)secs;
421411
#else
422-
/* On OpenBSD 5.4, timeval.tv_sec is a long.
423-
Example: long is 64-bit, whereas time_t is 32-bit. */
424412
tv->tv_sec = secs;
413+
#endif
425414
if ((_PyTime_t)tv->tv_sec != secs)
426415
res = -1;
427-
#endif
428416

429417
usec = (int)_PyTime_Divide(ns, US_TO_NS, round);
430418
if (usec < 0) {
@@ -440,7 +428,7 @@ _PyTime_AsTimeval_impl(_PyTime_t t, struct timeval *tv, _PyTime_round_t round,
440428
tv->tv_usec = usec;
441429

442430
if (res && raise)
443-
_PyTime_overflow();
431+
error_time_t_overflow();
444432
return res;
445433
}
446434

@@ -473,7 +461,7 @@ _PyTime_AsTimespec(_PyTime_t t, struct timespec *ts)
473461
ts->tv_nsec = nsec;
474462

475463
if ((_PyTime_t)ts->tv_sec != secs) {
476-
_PyTime_overflow();
464+
error_time_t_overflow();
477465
return -1;
478466
}
479467
return 0;

0 commit comments

Comments
 (0)