Commit e9cd9005 authored by Brett Cannon's avatar Brett Cannon

Merge

parents fc70cbcb c1b5d34e
......@@ -1823,8 +1823,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)
......@@ -1841,8 +1839,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()
......
......@@ -34,7 +34,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.
......
......@@ -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):
......
......@@ -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.
......@@ -1837,6 +1841,9 @@ Tools/Demos
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.
......
......@@ -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
......
......@@ -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;
if (pylocaltime(&when, &buf) == 1)
return NULL;
return time_convert(when, localtime);
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,
......
......@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment