mirror of https://github.com/python/cpython
The various datetime object __setstate__() methods are no longer public
(pickling no longer needs them, and immutable objects shouldn't have visible __setstate__() methods regardless). Rearranged the code to put the internal setstate functions in the constructor sections. Repaired the timedelta reduce() method, which was still producing stuff that required a public timedelta.__setstate__() when unpickling.
This commit is contained in:
parent
96940c971c
commit
506be287aa
|
@ -24,7 +24,7 @@ Core and builtins
|
|||
See SF bug #667147.
|
||||
|
||||
- Fixed an invalid RuntimeWarning and an undetected error when trying
|
||||
to convert a long integer into a float which couldn't fit.
|
||||
to convert a long integer into a float which couldn't fit.
|
||||
See SF bug #676155.
|
||||
|
||||
Extension modules
|
||||
|
@ -126,6 +126,11 @@ Extension modules
|
|||
possible to have timestamps that differ by a second, yet where
|
||||
datetimes constructed from them are equal.
|
||||
|
||||
The pickle format of date, time and datetime objects has changed
|
||||
completely. The undocumented pickler and unpickler functions no
|
||||
longer exist. The undocumented __setstate__() methods no longer
|
||||
exist either.
|
||||
|
||||
Library
|
||||
-------
|
||||
|
||||
|
|
|
@ -1959,6 +1959,7 @@ delta_getstate(PyDateTime_Delta *self)
|
|||
GET_TD_MICROSECONDS(self));
|
||||
}
|
||||
|
||||
/* __setstate__ isn't exposed. */
|
||||
static PyObject *
|
||||
delta_setstate(PyDateTime_Delta *self, PyObject *state)
|
||||
{
|
||||
|
@ -1988,7 +1989,11 @@ delta_reduce(PyDateTime_Delta* self)
|
|||
/* The funky "()" in the format string creates an empty
|
||||
* tuple as the 2nd component of the result 3-tuple.
|
||||
*/
|
||||
result = Py_BuildValue("O()O", self->ob_type, state);
|
||||
result = Py_BuildValue("O(iii)",
|
||||
self->ob_type,
|
||||
self->days,
|
||||
self->seconds,
|
||||
self->microseconds);
|
||||
Py_DECREF(state);
|
||||
}
|
||||
return result;
|
||||
|
@ -2010,10 +2015,6 @@ static PyMemberDef delta_members[] = {
|
|||
};
|
||||
|
||||
static PyMethodDef delta_methods[] = {
|
||||
|
||||
{"__setstate__", (PyCFunction)delta_setstate, METH_O,
|
||||
PyDoc_STR("__setstate__(state)")},
|
||||
|
||||
{"__getstate__", (PyCFunction)delta_getstate, METH_NOARGS,
|
||||
PyDoc_STR("__getstate__() -> state")},
|
||||
|
||||
|
@ -2145,7 +2146,35 @@ static PyGetSetDef date_getset[] = {
|
|||
|
||||
static char *date_kws[] = {"year", "month", "day", NULL};
|
||||
|
||||
static PyObject *date_setstate(PyDateTime_Date *self, PyObject *arg);
|
||||
/* __setstate__ isn't exposed. */
|
||||
static PyObject *
|
||||
date_setstate(PyDateTime_Date *self, PyObject *arg)
|
||||
{
|
||||
PyObject *state;
|
||||
int len;
|
||||
unsigned char *pdata;
|
||||
|
||||
if (!PyTuple_Check(arg) || PyTuple_GET_SIZE(arg) != 1)
|
||||
goto error;
|
||||
state = PyTuple_GET_ITEM(arg, 0);
|
||||
if (!PyString_Check(state))
|
||||
goto error;
|
||||
|
||||
len = PyString_Size(state);
|
||||
if (len != _PyDateTime_DATE_DATASIZE)
|
||||
goto error;
|
||||
|
||||
pdata = (unsigned char*)PyString_AsString(state);
|
||||
memcpy(self->data, pdata, _PyDateTime_DATE_DATASIZE);
|
||||
self->hashcode = -1;
|
||||
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
error:
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"bad argument to date.__setstate__");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
|
||||
|
@ -2541,35 +2570,6 @@ date_getstate(PyDateTime_Date *self)
|
|||
_PyDateTime_DATE_DATASIZE));
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
date_setstate(PyDateTime_Date *self, PyObject *arg)
|
||||
{
|
||||
PyObject *state;
|
||||
int len;
|
||||
unsigned char *pdata;
|
||||
|
||||
if (!PyTuple_Check(arg) || PyTuple_GET_SIZE(arg) != 1)
|
||||
goto error;
|
||||
state = PyTuple_GET_ITEM(arg, 0);
|
||||
if (!PyString_Check(state))
|
||||
goto error;
|
||||
|
||||
len = PyString_Size(state);
|
||||
if (len != _PyDateTime_DATE_DATASIZE)
|
||||
goto error;
|
||||
|
||||
pdata = (unsigned char*)PyString_AsString(state);
|
||||
memcpy(self->data, pdata, _PyDateTime_DATE_DATASIZE);
|
||||
self->hashcode = -1;
|
||||
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
error:
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"bad argument to date.__setstate__");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
date_reduce(PyDateTime_Date *self, PyObject *arg)
|
||||
{
|
||||
|
@ -2627,9 +2627,6 @@ static PyMethodDef date_methods[] = {
|
|||
{"replace", (PyCFunction)date_replace, METH_KEYWORDS,
|
||||
PyDoc_STR("Return date with new specified fields.")},
|
||||
|
||||
{"__setstate__", (PyCFunction)date_setstate, METH_O,
|
||||
PyDoc_STR("__setstate__(state)")},
|
||||
|
||||
{"__getstate__", (PyCFunction)date_getstate, METH_NOARGS,
|
||||
PyDoc_STR("__getstate__() -> state")},
|
||||
|
||||
|
@ -3012,7 +3009,41 @@ static PyGetSetDef time_getset[] = {
|
|||
static char *time_kws[] = {"hour", "minute", "second", "microsecond",
|
||||
"tzinfo", NULL};
|
||||
|
||||
static PyObject *time_setstate(PyDateTime_Time *self, PyObject *state);
|
||||
/* __setstate__ isn't exposed. */
|
||||
static PyObject *
|
||||
time_setstate(PyDateTime_Time *self, PyObject *state)
|
||||
{
|
||||
PyObject *basestate;
|
||||
PyObject *tzinfo = Py_None;
|
||||
|
||||
if (! PyArg_ParseTuple(state, "O!|O:__setstate__",
|
||||
&PyString_Type, &basestate,
|
||||
&tzinfo))
|
||||
return NULL;
|
||||
if (PyString_Size(basestate) != _PyDateTime_TIME_DATASIZE ||
|
||||
check_tzinfo_subclass(tzinfo) < 0) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"bad argument to time.__setstate__");
|
||||
return NULL;
|
||||
}
|
||||
if (tzinfo != Py_None && ! HASTZINFO(self)) {
|
||||
PyErr_SetString(PyExc_ValueError, "time.__setstate__ can't "
|
||||
"add a non-None tzinfo to a time object that "
|
||||
"doesn't have one already");
|
||||
return NULL;
|
||||
}
|
||||
memcpy((char *)self->data,
|
||||
PyString_AsString(basestate),
|
||||
_PyDateTime_TIME_DATASIZE);
|
||||
self->hashcode = -1;
|
||||
if (HASTZINFO(self)) {
|
||||
Py_INCREF(tzinfo);
|
||||
Py_XDECREF(self->tzinfo);
|
||||
self->tzinfo = tzinfo;
|
||||
}
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
|
||||
|
@ -3366,41 +3397,6 @@ time_getstate(PyDateTime_Time *self)
|
|||
return result;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
time_setstate(PyDateTime_Time *self, PyObject *state)
|
||||
{
|
||||
PyObject *basestate;
|
||||
PyObject *tzinfo = Py_None;
|
||||
|
||||
if (! PyArg_ParseTuple(state, "O!|O:__setstate__",
|
||||
&PyString_Type, &basestate,
|
||||
&tzinfo))
|
||||
return NULL;
|
||||
if (PyString_Size(basestate) != _PyDateTime_TIME_DATASIZE ||
|
||||
check_tzinfo_subclass(tzinfo) < 0) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"bad argument to time.__setstate__");
|
||||
return NULL;
|
||||
}
|
||||
if (tzinfo != Py_None && ! HASTZINFO(self)) {
|
||||
PyErr_SetString(PyExc_ValueError, "time.__setstate__ can't "
|
||||
"add a non-None tzinfo to a time object that "
|
||||
"doesn't have one already");
|
||||
return NULL;
|
||||
}
|
||||
memcpy((char *)self->data,
|
||||
PyString_AsString(basestate),
|
||||
_PyDateTime_TIME_DATASIZE);
|
||||
self->hashcode = -1;
|
||||
if (HASTZINFO(self)) {
|
||||
Py_INCREF(tzinfo);
|
||||
Py_XDECREF(self->tzinfo);
|
||||
self->tzinfo = tzinfo;
|
||||
}
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
time_reduce(PyDateTime_Time *self, PyObject *arg)
|
||||
{
|
||||
|
@ -3428,9 +3424,6 @@ static PyMethodDef time_methods[] = {
|
|||
{"replace", (PyCFunction)time_replace, METH_KEYWORDS,
|
||||
PyDoc_STR("Return time with new specified fields.")},
|
||||
|
||||
{"__setstate__", (PyCFunction)time_setstate, METH_O,
|
||||
PyDoc_STR("__setstate__(state)")},
|
||||
|
||||
{"__getstate__", (PyCFunction)time_getstate, METH_NOARGS,
|
||||
PyDoc_STR("__getstate__() -> state")},
|
||||
|
||||
|
@ -3559,7 +3552,41 @@ static char *datetime_kws[] = {
|
|||
"microsecond", "tzinfo", NULL
|
||||
};
|
||||
|
||||
static PyObject *datetime_setstate(PyDateTime_DateTime *self, PyObject *state);
|
||||
/* __setstate__ isn't exposed. */
|
||||
static PyObject *
|
||||
datetime_setstate(PyDateTime_DateTime *self, PyObject *state)
|
||||
{
|
||||
PyObject *basestate;
|
||||
PyObject *tzinfo = Py_None;
|
||||
|
||||
if (! PyArg_ParseTuple(state, "O!|O:__setstate__",
|
||||
&PyString_Type, &basestate,
|
||||
&tzinfo))
|
||||
return NULL;
|
||||
if (PyString_Size(basestate) != _PyDateTime_DATETIME_DATASIZE ||
|
||||
check_tzinfo_subclass(tzinfo) < 0) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"bad argument to datetime.__setstate__");
|
||||
return NULL;
|
||||
}
|
||||
if (tzinfo != Py_None && ! HASTZINFO(self)) {
|
||||
PyErr_SetString(PyExc_ValueError, "datetime.__setstate__ "
|
||||
"can't add a non-None tzinfo to a datetime "
|
||||
"object that doesn't have one already");
|
||||
return NULL;
|
||||
}
|
||||
memcpy((char *)self->data,
|
||||
PyString_AsString(basestate),
|
||||
_PyDateTime_DATETIME_DATASIZE);
|
||||
self->hashcode = -1;
|
||||
if (HASTZINFO(self)) {
|
||||
Py_INCREF(tzinfo);
|
||||
Py_XDECREF(self->tzinfo);
|
||||
self->tzinfo = tzinfo;
|
||||
}
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
|
||||
|
@ -4370,41 +4397,6 @@ datetime_getstate(PyDateTime_DateTime *self)
|
|||
return result;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
datetime_setstate(PyDateTime_DateTime *self, PyObject *state)
|
||||
{
|
||||
PyObject *basestate;
|
||||
PyObject *tzinfo = Py_None;
|
||||
|
||||
if (! PyArg_ParseTuple(state, "O!|O:__setstate__",
|
||||
&PyString_Type, &basestate,
|
||||
&tzinfo))
|
||||
return NULL;
|
||||
if (PyString_Size(basestate) != _PyDateTime_DATETIME_DATASIZE ||
|
||||
check_tzinfo_subclass(tzinfo) < 0) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"bad argument to datetime.__setstate__");
|
||||
return NULL;
|
||||
}
|
||||
if (tzinfo != Py_None && ! HASTZINFO(self)) {
|
||||
PyErr_SetString(PyExc_ValueError, "datetime.__setstate__ "
|
||||
"can't add a non-None tzinfo to a datetime "
|
||||
"object that doesn't have one already");
|
||||
return NULL;
|
||||
}
|
||||
memcpy((char *)self->data,
|
||||
PyString_AsString(basestate),
|
||||
_PyDateTime_DATETIME_DATASIZE);
|
||||
self->hashcode = -1;
|
||||
if (HASTZINFO(self)) {
|
||||
Py_INCREF(tzinfo);
|
||||
Py_XDECREF(self->tzinfo);
|
||||
self->tzinfo = tzinfo;
|
||||
}
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
|
||||
{
|
||||
|
@ -4477,9 +4469,6 @@ static PyMethodDef datetime_methods[] = {
|
|||
{"astimezone", (PyCFunction)datetime_astimezone, METH_KEYWORDS,
|
||||
PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
|
||||
|
||||
{"__setstate__", (PyCFunction)datetime_setstate, METH_O,
|
||||
PyDoc_STR("__setstate__(state)")},
|
||||
|
||||
{"__getstate__", (PyCFunction)datetime_getstate, METH_NOARGS,
|
||||
PyDoc_STR("__getstate__() -> state")},
|
||||
|
||||
|
|
Loading…
Reference in New Issue