From a3dd409b521107c08f918528991e33765ddda808 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 26 Jan 2012 00:31:49 +0100 Subject: [PATCH 1/4] Remove now useless arbitrary limit of module name length --- Python/import.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Python/import.c b/Python/import.c index d5b89d59668..8bd7a61722f 100644 --- a/Python/import.c +++ b/Python/import.c @@ -2052,12 +2052,6 @@ find_module(PyObject *fullname, PyObject *name, PyObject *search_path_list, if (p_loader != NULL) *p_loader = NULL; - if (PyUnicode_GET_LENGTH(name) > MAXPATHLEN) { - PyErr_SetString(PyExc_OverflowError, - "module name is too long"); - return NULL; - } - /* sys.meta_path import hook */ if (p_loader != NULL) { _Py_IDENTIFIER(find_module); From eaac4f0d30dba8b53b7ebd1e28b31863e871fa6b Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Thu, 26 Jan 2012 00:14:16 -0800 Subject: [PATCH 2/4] Issue 13870: Fix out of date comment. --- Lib/collections.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/collections.py b/Lib/collections.py index d2625fe03e3..eb2024352de 100644 --- a/Lib/collections.py +++ b/Lib/collections.py @@ -33,7 +33,7 @@ class OrderedDict(dict): # The circular doubly linked list starts and ends with a sentinel element. # The sentinel element never gets deleted (this simplifies the algorithm). # The sentinel is in self.__hardroot with a weakref proxy in self.__root. - # The prev/next links are weakref proxies (to prevent circular references). + # The prev links are weakref proxies (to prevent circular references). # Individual links are kept alive by the hard reference in self.__map. # Those hard references disappear when a key is deleted from an OrderedDict. From 65992c1c01115166375e1c6d8484f053919e30da Mon Sep 17 00:00:00 2001 From: Meador Inge Date: Thu, 26 Jan 2012 08:44:00 -0600 Subject: [PATCH 3/4] - Issue #13840: Fix ctypes.create_string_buffer exception message and docs. --- Doc/library/ctypes.rst | 4 ---- Misc/NEWS | 3 +++ Modules/_ctypes/_ctypes.c | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst index fce59135ace..df39c28cc98 100644 --- a/Doc/library/ctypes.rst +++ b/Doc/library/ctypes.rst @@ -1815,8 +1815,6 @@ Utility functions termination character. An integer can be passed as second argument which allows to specify the size of the array if the length of the bytes should not be used. - If the first parameter is a string, it is converted into a bytes object - according to ctypes conversion rules. .. function:: create_unicode_buffer(init_or_size, size=None) @@ -1833,8 +1831,6 @@ Utility functions allows to specify the size of the array if the length of the string should not be used. - If the first parameter is a bytes object, it is converted into an unicode string - according to ctypes conversion rules. .. function:: DllCanUnloadNow() diff --git a/Misc/NEWS b/Misc/NEWS index 5e2c47ee044..7005518d121 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -402,6 +402,9 @@ Tests Extension Modules ----------------- +- Issue #13840: The error message produced by ctypes.create_string_buffer + when given a Unicode string has been fixed. + - Issue #9975: socket: Fix incorrect use of flowinfo and scope_id. Patch by Vilmos Nebehaj. diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index 8f378e246df..8be5958b0a0 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -1096,7 +1096,7 @@ CharArray_set_value(CDataObject *self, PyObject *value) if (!PyBytes_Check(value)) { PyErr_Format(PyExc_TypeError, - "str/bytes expected instead of %s instance", + "bytes expected instead of %s instance", Py_TYPE(value)->tp_name); return -1; } else From c1b5d34ede2701cf45f35cf52d33d8dca5059ec6 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 27 Jan 2012 00:08:48 +0100 Subject: [PATCH 4/4] Issue #13847: time.localtime() and time.gmtime() now raise an OSError instead of ValueError on failure. time.ctime() and time.asctime() now raises an OSError if localtime() failed. --- Lib/test/test_time.py | 15 ++++++ Misc/NEWS | 4 ++ Modules/timemodule.c | 114 +++++++++++++++++++++++------------------- 3 files changed, 81 insertions(+), 52 deletions(-) diff --git a/Lib/test/test_time.py b/Lib/test/test_time.py index 685e821d40f..0533895d81f 100644 --- a/Lib/test/test_time.py +++ b/Lib/test/test_time.py @@ -343,6 +343,21 @@ class TimeTestCase(unittest.TestCase): dt = t2 - t1 self.assertAlmostEqual(dt, 0.1, delta=0.2) + def test_localtime_failure(self): + # Issue #13847: check for localtime() failure + invalid_time_t = 2**60 + try: + time.localtime(invalid_time_t) + except ValueError as err: + if str(err) == "timestamp out of range for platform time_t": + self.skipTest("need 64-bit time_t") + else: + raise + except OSError: + pass + self.assertRaises(OSError, time.localtime, invalid_time_t) + self.assertRaises(OSError, time.gmtime, invalid_time_t) + self.assertRaises(OSError, time.ctime, invalid_time_t) class TestLocale(unittest.TestCase): def setUp(self): diff --git a/Misc/NEWS b/Misc/NEWS index 70d80951f79..320e386c9ba 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -461,6 +461,10 @@ Core and Builtins Library ------- +- Issue #13847: time.localtime() and time.gmtime() now raise an OSError instead + of ValueError on failure. time.ctime() and time.asctime() now raises an + OSError if localtime() failed. + - Issue #13862: Fix spurious failure in test_zlib due to runtime/compile time minor versions not matching. diff --git a/Modules/timemodule.c b/Modules/timemodule.c index f7dac5b1918..d2cc62f6773 100644 --- a/Modules/timemodule.c +++ b/Modules/timemodule.c @@ -247,55 +247,53 @@ tmtotuple(struct tm *p) return v; } -static PyObject * -time_convert(double when, struct tm * (*function)(const time_t *)) -{ - struct tm *p; - time_t whent = _PyTime_DoubleToTimet(when); - - if (whent == (time_t)-1 && PyErr_Occurred()) - return NULL; - errno = 0; - p = function(&whent); - if (p == NULL) { -#ifdef EINVAL - if (errno == 0) - errno = EINVAL; -#endif - return PyErr_SetFromErrno(PyExc_ValueError); - } - return tmtotuple(p); -} - /* Parse arg tuple that can contain an optional float-or-None value; format needs to be "|O:name". Returns non-zero on success (parallels PyArg_ParseTuple). */ static int -parse_time_double_args(PyObject *args, char *format, double *pwhen) +parse_time_t_args(PyObject *args, char *format, time_t *pwhen) { PyObject *ot = NULL; + time_t whent; if (!PyArg_ParseTuple(args, format, &ot)) return 0; - if (ot == NULL || ot == Py_None) - *pwhen = floattime(); + if (ot == NULL || ot == Py_None) { + whent = time(NULL); + } else { - double when = PyFloat_AsDouble(ot); + double d = PyFloat_AsDouble(ot); if (PyErr_Occurred()) return 0; - *pwhen = when; + whent = _PyTime_DoubleToTimet(d); + if (whent == (time_t)-1 && PyErr_Occurred()) + return 0; } + *pwhen = whent; return 1; } static PyObject * time_gmtime(PyObject *self, PyObject *args) { - double when; - if (!parse_time_double_args(args, "|O:gmtime", &when)) + time_t when; + struct tm buf, *local; + + if (!parse_time_t_args(args, "|O:gmtime", &when)) return NULL; - return time_convert(when, gmtime); + + errno = 0; + local = gmtime(&when); + if (local == NULL) { +#ifdef EINVAL + if (errno == 0) + errno = EINVAL; +#endif + return PyErr_SetFromErrno(PyExc_OSError); + } + buf = *local; + return tmtotuple(&buf); } PyDoc_STRVAR(gmtime_doc, @@ -305,13 +303,37 @@ PyDoc_STRVAR(gmtime_doc, Convert seconds since the Epoch to a time tuple expressing UTC (a.k.a.\n\ GMT). When 'seconds' is not passed in, convert the current time instead."); +static int +pylocaltime(time_t *timep, struct tm *result) +{ + struct tm *local; + + assert (timep != NULL); + local = localtime(timep); + if (local == NULL) { + /* unconvertible time */ +#ifdef EINVAL + if (errno == 0) + errno = EINVAL; +#endif + PyErr_SetFromErrno(PyExc_OSError); + return -1; + } + *result = *local; + return 0; +} + static PyObject * time_localtime(PyObject *self, PyObject *args) { - double when; - if (!parse_time_double_args(args, "|O:localtime", &when)) + time_t when; + struct tm buf; + + if (!parse_time_t_args(args, "|O:localtime", &when)) return NULL; - return time_convert(when, localtime); + if (pylocaltime(&when, &buf) == 1) + return NULL; + return tmtotuple(&buf); } PyDoc_STRVAR(localtime_doc, @@ -462,7 +484,8 @@ time_strftime(PyObject *self, PyObject *args) if (tup == NULL) { time_t tt = time(NULL); - buf = *localtime(&tt); + if (pylocaltime(&tt, &buf) == -1) + return NULL; } else if (!gettmarg(tup, &buf) || !checktm(&buf)) return NULL; @@ -627,7 +650,9 @@ time_asctime(PyObject *self, PyObject *args) return NULL; if (tup == NULL) { time_t tt = time(NULL); - buf = *localtime(&tt); + if (pylocaltime(&tt, &buf) == -1) + return NULL; + } else if (!gettmarg(tup, &buf) || !checktm(&buf)) return NULL; return _asctime(&buf); @@ -643,28 +668,13 @@ is used."); static PyObject * time_ctime(PyObject *self, PyObject *args) { - PyObject *ot = NULL; time_t tt; - struct tm *timeptr; - - if (!PyArg_UnpackTuple(args, "ctime", 0, 1, &ot)) + struct tm buf; + if (!parse_time_t_args(args, "|O:ctime", &tt)) return NULL; - if (ot == NULL || ot == Py_None) - tt = time(NULL); - else { - double dt = PyFloat_AsDouble(ot); - if (PyErr_Occurred()) - return NULL; - tt = _PyTime_DoubleToTimet(dt); - if (tt == (time_t)-1 && PyErr_Occurred()) - return NULL; - } - timeptr = localtime(&tt); - if (timeptr == NULL) { - PyErr_SetString(PyExc_ValueError, "unconvertible time"); + if (pylocaltime(&tt, &buf) == -1) return NULL; - } - return _asctime(timeptr); + return _asctime(&buf); } PyDoc_STRVAR(ctime_doc,