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.
diff --git a/Misc/NEWS b/Misc/NEWS
index 8075943..38e7db2 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -24,7 +24,7 @@
   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 @@
   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
 -------
 
diff --git a/Modules/datetimemodule.c b/Modules/datetimemodule.c
index 520b01e..48635e7 100644
--- a/Modules/datetimemodule.c
+++ b/Modules/datetimemodule.c
@@ -1959,6 +1959,7 @@
 				    GET_TD_MICROSECONDS(self));
 }
 
+/* __setstate__ isn't exposed. */
 static PyObject *
 delta_setstate(PyDateTime_Delta *self, PyObject *state)
 {
@@ -1988,7 +1989,11 @@
 		/* 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 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 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)
@@ -2542,35 +2571,6 @@
 }
 
 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)
 {
 	return Py_BuildValue("(ON)", self->ob_type, date_getstate(self));
@@ -2627,9 +2627,6 @@
 	{"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 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)
@@ -3367,41 +3398,6 @@
 }
 
 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)
 {
 	return Py_BuildValue("(ON)", self->ob_type, time_getstate(self));
@@ -3428,9 +3424,6 @@
 	{"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 @@
 	"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)
@@ -4371,41 +4398,6 @@
 }
 
 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)
 {
 	return Py_BuildValue("(ON)", self->ob_type, datetime_getstate(self));
@@ -4477,9 +4469,6 @@
 	{"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")},