https://github.com/python/cpython/commit/c637bce20aaaf836ab2cfbb123b9472e5ad0ab47
commit: c637bce20aaaf836ab2cfbb123b9472e5ad0ab47
branch: main
author: Bénédikt Tran <10796600+picn...@users.noreply.github.com>
committer: encukou <encu...@gmail.com>
date: 2025-02-19T11:18:37Z
summary:

gh-111178: fix UBSan failures in `Modules/_datetimemodule.c` (GH-129774)

Add cast macros for date and time objects

Fix UBSan failures for `PyDateTime_Delta`, `PyDateTime_Date`, 
`PyDateTime_TZInfo`, `PyDateTime_TimeZone`, `PyDateTime_Time`, 
`PyDateTime_DateTime`, `PyDateTime_IsoCalendarDate`

Fix up naming

files:
M Modules/_datetimemodule.c

diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c
index b5ccf2f7b65d63..07d7089be09d20 100644
--- a/Modules/_datetimemodule.c
+++ b/Modules/_datetimemodule.c
@@ -58,7 +58,13 @@ typedef struct {
  * the per-module objects stored in module state.  The macros for the
  * static objects don't need to be passed a state, but the consistency
  * of doing so is more clear.  We use a dedicated noop macro, NO_STATE,
- * to make the special case obvious. */
+ * to make the special case obvious.
+ *
+ * The casting macros perform a simple fast pointer cast without
+ * checking the runtime type. In the future, we may decide whether
+ * to include that check and whether to provide a fast pointer cast
+ * macro for pointers known to be of correct time.
+ */
 
 #define NO_STATE NULL
 
@@ -70,23 +76,31 @@ typedef struct {
 #define TIMEZONE_TYPE(st) &PyDateTime_TimeZoneType
 #define ISOCALENDAR_DATE_TYPE(st) st->isocalendar_date_type
 
+#define PyDate_CAST(op) ((PyDateTime_Date *)(op))
 #define PyDate_Check(op) PyObject_TypeCheck(op, DATE_TYPE(NO_STATE))
 #define PyDate_CheckExact(op) Py_IS_TYPE(op, DATE_TYPE(NO_STATE))
 
+#define PyDateTime_CAST(op) ((PyDateTime_DateTime *)(op))
 #define PyDateTime_Check(op) PyObject_TypeCheck(op, DATETIME_TYPE(NO_STATE))
 #define PyDateTime_CheckExact(op) Py_IS_TYPE(op, DATETIME_TYPE(NO_STATE))
 
+#define PyTime_CAST(op) ((PyDateTime_Time *)(op))
 #define PyTime_Check(op) PyObject_TypeCheck(op, TIME_TYPE(NO_STATE))
 #define PyTime_CheckExact(op) Py_IS_TYPE(op, TIME_TYPE(NO_STATE))
 
+#define PyDelta_CAST(op) ((PyDateTime_Delta *)(op))
 #define PyDelta_Check(op) PyObject_TypeCheck(op, DELTA_TYPE(NO_STATE))
 #define PyDelta_CheckExact(op) Py_IS_TYPE(op, DELTA_TYPE(NO_STATE))
 
+#define PyTZInfo_CAST(op) ((PyDateTime_TZInfo *)(op))
 #define PyTZInfo_Check(op) PyObject_TypeCheck(op, TZINFO_TYPE(NO_STATE))
 #define PyTZInfo_CheckExact(op) Py_IS_TYPE(op, TZINFO_TYPE(NO_STATE))
 
+#define PyTimeZone_CAST(op) ((PyDateTime_TimeZone *)(op))
 #define PyTimezone_Check(op) PyObject_TypeCheck(op, TIMEZONE_TYPE(NO_STATE))
 
+#define PyIsoCalendarDate_CAST(op) ((PyDateTime_IsoCalendarDate *)(op))
+
 #define CONST_US_PER_MS(st) st->us_per_ms
 #define CONST_US_PER_SECOND(st) st->us_per_second
 #define CONST_US_PER_MINUTE(st) st->us_per_minute
@@ -295,9 +309,9 @@ clear_current_module(PyInterpreterState *interp, PyObject 
*expected)
 #define TIME_SET_FOLD(o, v)   (PyDateTime_TIME_GET_FOLD(o) = (v))
 
 /* Delta accessors for timedelta. */
-#define GET_TD_DAYS(o)          (((PyDateTime_Delta *)(o))->days)
-#define GET_TD_SECONDS(o)       (((PyDateTime_Delta *)(o))->seconds)
-#define GET_TD_MICROSECONDS(o)  (((PyDateTime_Delta *)(o))->microseconds)
+#define GET_TD_DAYS(o)          (PyDelta_CAST(o)->days)
+#define GET_TD_SECONDS(o)       (PyDelta_CAST(o)->seconds)
+#define GET_TD_MICROSECONDS(o)  (PyDelta_CAST(o)->microseconds)
 
 #define SET_TD_DAYS(o, v)       ((o)->days = (v))
 #define SET_TD_SECONDS(o, v)    ((o)->seconds = (v))
@@ -1418,7 +1432,7 @@ create_timezone(PyObject *offset, PyObject *name)
     return (PyObject *)self;
 }
 
-static int delta_bool(PyDateTime_Delta *self);
+static int delta_bool(PyObject *op);
 static PyDateTime_TimeZone utc_timezone;
 
 static PyObject *
@@ -1428,7 +1442,7 @@ new_timezone(PyObject *offset, PyObject *name)
     assert(PyDelta_Check(offset));
     assert(name == NULL || PyUnicode_Check(name));
 
-    if (name == NULL && delta_bool((PyDateTime_Delta *)offset) == 0) {
+    if (name == NULL && delta_bool(offset) == 0) {
         return Py_NewRef(CONST_UTC(NO_STATE));
     }
     if ((GET_TD_DAYS(offset) == -1 &&
@@ -1663,7 +1677,7 @@ tzinfo_from_isoformat_results(int rv, int tzoffset, int 
tz_useconds)
  */
 
 static PyObject *
-format_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds)
+format_ctime(PyObject *date, int hours, int minutes, int seconds)
 {
     static const char * const DayNames[] = {
         "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
@@ -1681,7 +1695,7 @@ format_ctime(PyDateTime_Date *date, int hours, int 
minutes, int seconds)
                                 GET_YEAR(date));
 }
 
-static PyObject *delta_negative(PyDateTime_Delta *self);
+static PyObject *delta_negative(PyObject *op);
 
 /* Add formatted UTC offset string to buf.  buf has no more than
  * buflen bytes remaining.  The UTC offset is gotten by calling
@@ -1714,7 +1728,7 @@ format_utcoffset(char *buf, size_t buflen, const char 
*sep,
     /* Offset is normalized, so it is negative if days < 0 */
     if (GET_TD_DAYS(offset) < 0) {
         sign = '-';
-        Py_SETREF(offset, delta_negative((PyDateTime_Delta *)offset));
+        Py_SETREF(offset, delta_negative(offset));
         if (offset == NULL)
             return -1;
     }
@@ -2416,7 +2430,7 @@ delta_add(PyObject *left, PyObject *right)
 }
 
 static PyObject *
-delta_negative(PyDateTime_Delta *self)
+delta_negative(PyObject *self)
 {
     return new_delta(-GET_TD_DAYS(self),
                      -GET_TD_SECONDS(self),
@@ -2425,7 +2439,7 @@ delta_negative(PyDateTime_Delta *self)
 }
 
 static PyObject *
-delta_positive(PyDateTime_Delta *self)
+delta_positive(PyObject *self)
 {
     /* Could optimize this (by returning self) if this isn't a
      * subclass -- but who uses unary + ?  Approximately nobody.
@@ -2437,7 +2451,7 @@ delta_positive(PyDateTime_Delta *self)
 }
 
 static PyObject *
-delta_abs(PyDateTime_Delta *self)
+delta_abs(PyObject *self)
 {
     PyObject *result;
 
@@ -2502,8 +2516,9 @@ delta_richcompare(PyObject *self, PyObject *other, int op)
 static PyObject *delta_getstate(PyDateTime_Delta *self);
 
 static Py_hash_t
-delta_hash(PyDateTime_Delta *self)
+delta_hash(PyObject *op)
 {
+    PyDateTime_Delta *self = PyDelta_CAST(op);
     if (self->hashcode == -1) {
         PyObject *temp = delta_getstate(self);
         if (temp != NULL) {
@@ -2867,7 +2882,7 @@ delta_new(PyTypeObject *type, PyObject *args, PyObject 
*kw)
 }
 
 static int
-delta_bool(PyDateTime_Delta *self)
+delta_bool(PyObject *self)
 {
     return (GET_TD_DAYS(self) != 0
         || GET_TD_SECONDS(self) != 0
@@ -2875,7 +2890,7 @@ delta_bool(PyDateTime_Delta *self)
 }
 
 static PyObject *
-delta_repr(PyDateTime_Delta *self)
+delta_repr(PyObject *self)
 {
     PyObject *args = Py_GetConstant(Py_CONSTANT_EMPTY_STR);
 
@@ -2924,7 +2939,7 @@ delta_repr(PyDateTime_Delta *self)
 }
 
 static PyObject *
-delta_str(PyDateTime_Delta *self)
+delta_str(PyObject *self)
 {
     int us = GET_TD_MICROSECONDS(self);
     int seconds = GET_TD_SECONDS(self);
@@ -2964,12 +2979,12 @@ delta_getstate(PyDateTime_Delta *self)
 }
 
 static PyObject *
-delta_total_seconds(PyObject *self, PyObject *Py_UNUSED(ignored))
+delta_total_seconds(PyObject *op, PyObject *Py_UNUSED(dummy))
 {
     PyObject *total_seconds;
     PyObject *total_microseconds;
 
-    total_microseconds = delta_to_microseconds((PyDateTime_Delta *)self);
+    total_microseconds = delta_to_microseconds(PyDelta_CAST(op));
     if (total_microseconds == NULL)
         return NULL;
 
@@ -2984,8 +2999,9 @@ delta_total_seconds(PyObject *self, PyObject 
*Py_UNUSED(ignored))
 }
 
 static PyObject *
-delta_reduce(PyDateTime_Delta* self, PyObject *Py_UNUSED(ignored))
+delta_reduce(PyObject *op, PyObject *Py_UNUSED(dummy))
 {
+    PyDateTime_Delta *self = PyDelta_CAST(op);
     return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
 }
 
@@ -3008,7 +3024,7 @@ static PyMethodDef delta_methods[] = {
     {"total_seconds", delta_total_seconds, METH_NOARGS,
      PyDoc_STR("Total seconds in the duration.")},
 
-    {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
+    {"__reduce__", delta_reduce, METH_NOARGS,
      PyDoc_STR("__reduce__() -> (cls, state)")},
 
     {NULL,      NULL},
@@ -3028,10 +3044,10 @@ static PyNumberMethods delta_as_number = {
     delta_remainder,                            /* nb_remainder */
     delta_divmod,                               /* nb_divmod */
     0,                                          /* nb_power */
-    (unaryfunc)delta_negative,                  /* nb_negative */
-    (unaryfunc)delta_positive,                  /* nb_positive */
-    (unaryfunc)delta_abs,                       /* nb_absolute */
-    (inquiry)delta_bool,                        /* nb_bool */
+    delta_negative,                             /* nb_negative */
+    delta_positive,                             /* nb_positive */
+    delta_abs,                                  /* nb_absolute */
+    delta_bool,                                 /* nb_bool */
     0,                                          /*nb_invert*/
     0,                                          /*nb_lshift*/
     0,                                          /*nb_rshift*/
@@ -3067,13 +3083,13 @@ static PyTypeObject PyDateTime_DeltaType = {
     0,                                                  /* tp_getattr */
     0,                                                  /* tp_setattr */
     0,                                                  /* tp_as_async */
-    (reprfunc)delta_repr,                               /* tp_repr */
+    delta_repr,                                         /* tp_repr */
     &delta_as_number,                                   /* tp_as_number */
     0,                                                  /* tp_as_sequence */
     0,                                                  /* tp_as_mapping */
-    (hashfunc)delta_hash,                               /* tp_hash */
+    delta_hash,                                         /* tp_hash */
     0,                                                  /* tp_call */
-    (reprfunc)delta_str,                                /* tp_str */
+    delta_str,                                          /* tp_str */
     PyObject_GenericGetAttr,                            /* tp_getattro */
     0,                                                  /* tp_setattro */
     0,                                                  /* tp_as_buffer */
@@ -3125,27 +3141,30 @@ look_up_delta(int days, int seconds, int microseconds, 
PyTypeObject *type)
 /* Accessor properties. */
 
 static PyObject *
-date_year(PyDateTime_Date *self, void *unused)
+date_year(PyObject *op, void *Py_UNUSED(closure))
 {
+    PyDateTime_Date *self = PyDate_CAST(op);
     return PyLong_FromLong(GET_YEAR(self));
 }
 
 static PyObject *
-date_month(PyDateTime_Date *self, void *unused)
+date_month(PyObject *op, void *Py_UNUSED(closure))
 {
+    PyDateTime_Date *self = PyDate_CAST(op);
     return PyLong_FromLong(GET_MONTH(self));
 }
 
 static PyObject *
-date_day(PyDateTime_Date *self, void *unused)
+date_day(PyObject *op, void *Py_UNUSED(closure))
 {
+    PyDateTime_Date *self = PyDate_CAST(op);
     return PyLong_FromLong(GET_DAY(self));
 }
 
 static PyGetSetDef date_getset[] = {
-    {"year",        (getter)date_year},
-    {"month",       (getter)date_month},
-    {"day",         (getter)date_day},
+    {"year", date_year},
+    {"month", date_month},
+    {"day", date_day},
     {NULL}
 };
 
@@ -3238,7 +3257,7 @@ date_fromtimestamp(PyObject *cls, PyObject *obj)
  * generally the same as calling C's time.
  */
 static PyObject *
-date_today(PyObject *cls, PyObject *dummy)
+date_today(PyObject *cls, PyObject *Py_UNUSED(dummy))
 {
     PyObject *time;
     PyObject *result;
@@ -3505,36 +3524,38 @@ date_subtract(PyObject *left, PyObject *right)
 /* Various ways to turn a date into a string. */
 
 static PyObject *
-date_repr(PyDateTime_Date *self)
+date_repr(PyObject *op)
 {
+    PyDateTime_Date *self = PyDate_CAST(op);
     return PyUnicode_FromFormat("%s(%d, %d, %d)",
                                 Py_TYPE(self)->tp_name,
                                 GET_YEAR(self), GET_MONTH(self), 
GET_DAY(self));
 }
 
 static PyObject *
-date_isoformat(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
+date_isoformat(PyObject *op, PyObject *Py_UNUSED(dummy))
 {
+    PyDateTime_Date *self = PyDate_CAST(op);
     return PyUnicode_FromFormat("%04d-%02d-%02d",
                                 GET_YEAR(self), GET_MONTH(self), 
GET_DAY(self));
 }
 
 /* str() calls the appropriate isoformat() method. */
 static PyObject *
-date_str(PyDateTime_Date *self)
+date_str(PyObject *self)
 {
-    return PyObject_CallMethodNoArgs((PyObject *)self, &_Py_ID(isoformat));
+    return PyObject_CallMethodNoArgs(self, &_Py_ID(isoformat));
 }
 
 
 static PyObject *
-date_ctime(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
+date_ctime(PyObject *self, PyObject *Py_UNUSED(dummy))
 {
     return format_ctime(self, 0, 0, 0);
 }
 
 static PyObject *
-date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
+date_strftime(PyObject *self, PyObject *args, PyObject *kw)
 {
     /* This method can be inherited, and needs to call the
      * timetuple() method appropriate to self's class.
@@ -3544,21 +3565,20 @@ date_strftime(PyDateTime_Date *self, PyObject *args, 
PyObject *kw)
     PyObject *format;
     static char *keywords[] = {"format", NULL};
 
-    if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
-                                      &format))
+    if (!PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
+                                     &format))
         return NULL;
 
-    tuple = PyObject_CallMethodNoArgs((PyObject *)self, &_Py_ID(timetuple));
+    tuple = PyObject_CallMethodNoArgs(self, &_Py_ID(timetuple));
     if (tuple == NULL)
         return NULL;
-    result = wrap_strftime((PyObject *)self, format, tuple,
-                           (PyObject *)self);
+    result = wrap_strftime(self, format, tuple, self);
     Py_DECREF(tuple);
     return result;
 }
 
 static PyObject *
-date_format(PyDateTime_Date *self, PyObject *args)
+date_format(PyObject *self, PyObject *args)
 {
     PyObject *format;
 
@@ -3567,16 +3587,15 @@ date_format(PyDateTime_Date *self, PyObject *args)
 
     /* if the format is zero length, return str(self) */
     if (PyUnicode_GetLength(format) == 0)
-        return PyObject_Str((PyObject *)self);
+        return PyObject_Str(self);
 
-    return PyObject_CallMethodOneArg((PyObject *)self, &_Py_ID(strftime),
-                                        format);
+    return PyObject_CallMethodOneArg(self, &_Py_ID(strftime), format);
 }
 
 /* ISO methods. */
 
 static PyObject *
-date_isoweekday(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
+date_isoweekday(PyObject *self, PyObject *Py_UNUSED(dummy))
 {
     int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
 
@@ -3594,17 +3613,17 @@ typedef struct {
 } PyDateTime_IsoCalendarDate;
 
 static PyObject *
-iso_calendar_date_repr(PyDateTime_IsoCalendarDate *self)
+iso_calendar_date_repr(PyObject *self)
 {
-    PyObject* year = PyTuple_GetItem((PyObject *)self, 0);
+    PyObject *year = PyTuple_GetItem(self, 0);
     if (year == NULL) {
         return NULL;
     }
-    PyObject* week = PyTuple_GetItem((PyObject *)self, 1);
+    PyObject *week = PyTuple_GetItem(self, 1);
     if (week == NULL) {
         return NULL;
     }
-    PyObject* weekday = PyTuple_GetItem((PyObject *)self, 2);
+    PyObject *weekday = PyTuple_GetItem(self, 2);
     if (weekday == NULL) {
         return NULL;
     }
@@ -3617,7 +3636,7 @@ static PyObject *
 iso_calendar_date_reduce(PyObject *self, PyObject *Py_UNUSED(ignored))
 {
     // Construct the tuple that this reduces to
-    PyObject * reduce_tuple = Py_BuildValue(
+    PyObject *reduce_tuple = Py_BuildValue(
         "O((OOO))", &PyTuple_Type,
         PyTuple_GET_ITEM(self, 0),
         PyTuple_GET_ITEM(self, 1),
@@ -3628,9 +3647,9 @@ iso_calendar_date_reduce(PyObject *self, PyObject 
*Py_UNUSED(ignored))
 }
 
 static PyObject *
-iso_calendar_date_year(PyDateTime_IsoCalendarDate *self, void *unused)
+iso_calendar_date_year(PyObject *self, void *Py_UNUSED(closure))
 {
-    PyObject *year = PyTuple_GetItem((PyObject *)self, 0);
+    PyObject *year = PyTuple_GetItem(self, 0);
     if (year == NULL) {
         return NULL;
     }
@@ -3638,9 +3657,9 @@ iso_calendar_date_year(PyDateTime_IsoCalendarDate *self, 
void *unused)
 }
 
 static PyObject *
-iso_calendar_date_week(PyDateTime_IsoCalendarDate *self, void *unused)
+iso_calendar_date_week(PyObject *self, void *Py_UNUSED(closure))
 {
-    PyObject *week = PyTuple_GetItem((PyObject *)self, 1);
+    PyObject *week = PyTuple_GetItem(self, 1);
     if (week == NULL) {
         return NULL;
     }
@@ -3648,9 +3667,9 @@ iso_calendar_date_week(PyDateTime_IsoCalendarDate *self, 
void *unused)
 }
 
 static PyObject *
-iso_calendar_date_weekday(PyDateTime_IsoCalendarDate *self, void *unused)
+iso_calendar_date_weekday(PyObject *self, void *Py_UNUSED(closure))
 {
-    PyObject *weekday = PyTuple_GetItem((PyObject *)self, 2);
+    PyObject *weekday = PyTuple_GetItem(self, 2);
     if (weekday == NULL) {
         return NULL;
     }
@@ -3658,31 +3677,30 @@ iso_calendar_date_weekday(PyDateTime_IsoCalendarDate 
*self, void *unused)
 }
 
 static PyGetSetDef iso_calendar_date_getset[] = {
-    {"year",        (getter)iso_calendar_date_year},
-    {"week",      (getter)iso_calendar_date_week},
-    {"weekday",      (getter)iso_calendar_date_weekday},
+    {"year", iso_calendar_date_year},
+    {"week", iso_calendar_date_week},
+    {"weekday", iso_calendar_date_weekday},
     {NULL}
 };
 
 static PyMethodDef iso_calendar_date_methods[] = {
-    {"__reduce__", (PyCFunction)iso_calendar_date_reduce, METH_NOARGS,
+    {"__reduce__", iso_calendar_date_reduce, METH_NOARGS,
      PyDoc_STR("__reduce__() -> (cls, state)")},
     {NULL, NULL},
 };
 
 static int
-iso_calendar_date_traverse(PyDateTime_IsoCalendarDate *self, visitproc visit,
-                           void *arg)
+iso_calendar_date_traverse(PyObject *self, visitproc visit, void *arg)
 {
     Py_VISIT(Py_TYPE(self));
-    return PyTuple_Type.tp_traverse((PyObject *)self, visit, arg);
+    return PyTuple_Type.tp_traverse(self, visit, arg);
 }
 
 static void
-iso_calendar_date_dealloc(PyDateTime_IsoCalendarDate *self)
+iso_calendar_date_dealloc(PyObject *self)
 {
     PyTypeObject *tp = Py_TYPE(self);
-    PyTuple_Type.tp_dealloc((PyObject *)self);  // delegate GC-untrack as well
+    PyTuple_Type.tp_dealloc(self);  // delegate GC-untrack as well
     Py_DECREF(tp);
 }
 
@@ -3734,7 +3752,7 @@ iso_calendar_date_new_impl(PyTypeObject *type, int year, 
int week,
 }
 
 static PyObject *
-date_isocalendar(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
+date_isocalendar(PyObject *self, PyObject *Py_UNUSED(dummy))
 {
     int  year         = GET_YEAR(self);
     int  week1_monday = iso_week1_monday(year);
@@ -3789,7 +3807,7 @@ date_richcompare(PyObject *self, PyObject *other, int op)
 }
 
 static PyObject *
-date_timetuple(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
+date_timetuple(PyObject *self, PyObject *Py_UNUSED(dummy))
 {
     return build_struct_time(GET_YEAR(self),
                              GET_MONTH(self),
@@ -3825,8 +3843,9 @@ generic_hash(unsigned char *data, int len)
 static PyObject *date_getstate(PyDateTime_Date *self);
 
 static Py_hash_t
-date_hash(PyDateTime_Date *self)
+date_hash(PyObject *op)
 {
+    PyDateTime_Date *self = PyDate_CAST(op);
     if (self->hashcode == -1) {
         self->hashcode = generic_hash(
             (unsigned char *)self->data, _PyDateTime_DATE_DATASIZE);
@@ -3836,17 +3855,16 @@ date_hash(PyDateTime_Date *self)
 }
 
 static PyObject *
-date_toordinal(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
+date_toordinal(PyObject *self, PyObject *Py_UNUSED(dummy))
 {
     return PyLong_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
-                                     GET_DAY(self)));
+                                      GET_DAY(self)));
 }
 
 static PyObject *
-date_weekday(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
+date_weekday(PyObject *self, PyObject *Py_UNUSED(dummy))
 {
     int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
-
     return PyLong_FromLong(dow);
 }
 
@@ -3863,8 +3881,9 @@ date_getstate(PyDateTime_Date *self)
 }
 
 static PyObject *
-date_reduce(PyDateTime_Date *self, PyObject *arg)
+date_reduce(PyObject *op, PyObject *Py_UNUSED(dummy))
 {
+    PyDateTime_Date *self = PyDate_CAST(op);
     return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
 }
 
@@ -3873,13 +3892,11 @@ static PyMethodDef date_methods[] = {
     /* Class methods: */
     DATETIME_DATE_FROMTIMESTAMP_METHODDEF
 
-    {"fromordinal", (PyCFunction)date_fromordinal,      METH_VARARGS |
-                                                    METH_CLASS,
+    {"fromordinal", date_fromordinal, METH_VARARGS | METH_CLASS,
      PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
                "ordinal.")},
 
-     {"fromisoformat", (PyCFunction)date_fromisoformat,  METH_O |
-                                                         METH_CLASS,
+     {"fromisoformat", date_fromisoformat,  METH_O | METH_CLASS,
       PyDoc_STR("str -> Construct a date from a string in ISO 8601 format.")},
 
      {"fromisocalendar", _PyCFunction_CAST(date_fromisocalendar),
@@ -3888,45 +3905,44 @@ static PyMethodDef date_methods[] = {
                 "number and weekday.\n\n"
                 "This is the inverse of the date.isocalendar() function")},
 
-    {"strptime", (PyCFunction)date_strptime,
-     METH_VARARGS | METH_CLASS,
+    {"strptime", date_strptime, METH_VARARGS | METH_CLASS,
      PyDoc_STR("string, format -> new date parsed from a string "
                "(like time.strptime()).")},
 
-    {"today",         (PyCFunction)date_today,   METH_NOARGS | METH_CLASS,
+    {"today", date_today, METH_NOARGS | METH_CLASS,
      PyDoc_STR("Current date or datetime:  same as "
                "self.__class__.fromtimestamp(time.time()).")},
 
     /* Instance methods: */
 
-    {"ctime",       (PyCFunction)date_ctime,        METH_NOARGS,
+    {"ctime", date_ctime, METH_NOARGS,
      PyDoc_STR("Return ctime() style string.")},
 
-    {"strftime",        _PyCFunction_CAST(date_strftime),     METH_VARARGS | 
METH_KEYWORDS,
+    {"strftime", _PyCFunction_CAST(date_strftime), METH_VARARGS | 
METH_KEYWORDS,
      PyDoc_STR("format -> strftime() style string.")},
 
-    {"__format__",      (PyCFunction)date_format,       METH_VARARGS,
+    {"__format__", date_format, METH_VARARGS,
      PyDoc_STR("Formats self with strftime.")},
 
-    {"timetuple",   (PyCFunction)date_timetuple,    METH_NOARGS,
+    {"timetuple", date_timetuple, METH_NOARGS,
      PyDoc_STR("Return time tuple, compatible with time.localtime().")},
 
-    {"isocalendar", (PyCFunction)date_isocalendar,  METH_NOARGS,
+    {"isocalendar", date_isocalendar,  METH_NOARGS,
      PyDoc_STR("Return a named tuple containing ISO year, week number, and "
                "weekday.")},
 
-    {"isoformat",   (PyCFunction)date_isoformat,        METH_NOARGS,
+    {"isoformat", date_isoformat, METH_NOARGS,
      PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
 
-    {"isoweekday",  (PyCFunction)date_isoweekday,   METH_NOARGS,
+    {"isoweekday", date_isoweekday, METH_NOARGS,
      PyDoc_STR("Return the day of the week represented by the date.\n"
                "Monday == 1 ... Sunday == 7")},
 
-    {"toordinal",   (PyCFunction)date_toordinal,    METH_NOARGS,
+    {"toordinal", date_toordinal, METH_NOARGS,
      PyDoc_STR("Return proleptic Gregorian ordinal.  January 1 of year "
                "1 is day 1.")},
 
-    {"weekday",     (PyCFunction)date_weekday,      METH_NOARGS,
+    {"weekday", date_weekday, METH_NOARGS,
      PyDoc_STR("Return the day of the week represented by the date.\n"
                "Monday == 0 ... Sunday == 6")},
 
@@ -3935,7 +3951,7 @@ static PyMethodDef date_methods[] = {
     {"__replace__", _PyCFunction_CAST(datetime_date_replace), METH_FASTCALL | 
METH_KEYWORDS,
      PyDoc_STR("__replace__($self, /, **changes)\n--\n\nThe same as 
replace().")},
 
-    {"__reduce__", (PyCFunction)date_reduce,        METH_NOARGS,
+    {"__reduce__", date_reduce, METH_NOARGS,
      PyDoc_STR("__reduce__() -> (cls, state)")},
 
     {NULL,      NULL}
@@ -3967,13 +3983,13 @@ static PyTypeObject PyDateTime_DateType = {
     0,                                                  /* tp_getattr */
     0,                                                  /* tp_setattr */
     0,                                                  /* tp_as_async */
-    (reprfunc)date_repr,                                /* tp_repr */
+    date_repr,                                          /* tp_repr */
     &date_as_number,                                    /* tp_as_number */
     0,                                                  /* tp_as_sequence */
     0,                                                  /* tp_as_mapping */
-    (hashfunc)date_hash,                                /* tp_hash */
+    date_hash,                                          /* tp_hash */
     0,                                                  /* tp_call */
-    (reprfunc)date_str,                                 /* tp_str */
+    date_str,                                           /* tp_str */
     PyObject_GenericGetAttr,                            /* tp_getattro */
     0,                                                  /* tp_setattro */
     0,                                                  /* tp_as_buffer */
@@ -4028,19 +4044,19 @@ tzinfo_nogo(const char* methodname)
 /* Methods.  A subclass must implement these. */
 
 static PyObject *
-tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
+tzinfo_tzname(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(dt))
 {
     return tzinfo_nogo("tzname");
 }
 
 static PyObject *
-tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
+tzinfo_utcoffset(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(dt))
 {
     return tzinfo_nogo("utcoffset");
 }
 
 static PyObject *
-tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
+tzinfo_dst(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(dt))
 {
     return tzinfo_nogo("dst");
 }
@@ -4053,7 +4069,7 @@ static PyObject *datetime_utcoffset(PyObject *self, 
PyObject *);
 static PyObject *datetime_dst(PyObject *self, PyObject *);
 
 static PyObject *
-tzinfo_fromutc(PyDateTime_TZInfo *self, PyObject *dt)
+tzinfo_fromutc(PyObject *self, PyObject *dt)
 {
     PyObject *result = NULL;
     PyObject *off = NULL, *dst = NULL;
@@ -4064,7 +4080,7 @@ tzinfo_fromutc(PyDateTime_TZInfo *self, PyObject *dt)
                         "fromutc: argument must be a datetime");
         return NULL;
     }
-    if (GET_DT_TZINFO(dt) != (PyObject *)self) {
+    if (GET_DT_TZINFO(dt) != self) {
         PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
                         "is not self");
         return NULL;
@@ -4101,7 +4117,7 @@ tzinfo_fromutc(PyDateTime_TZInfo *self, PyObject *dt)
         goto Fail;
     if (dst == Py_None)
         goto Inconsistent;
-    if (delta_bool((PyDateTime_Delta *)dst) != 0) {
+    if (delta_bool(dst) != 0) {
         Py_SETREF(result, add_datetime_timedelta((PyDateTime_DateTime *)result,
                                                  (PyDateTime_Delta *)dst, 1));
         if (result == NULL)
@@ -4131,7 +4147,7 @@ tzinfo_fromutc(PyDateTime_TZInfo *self, PyObject *dt)
  */
 
 static PyObject *
-tzinfo_reduce(PyObject *self, PyObject *Py_UNUSED(ignored))
+tzinfo_reduce(PyObject *self, PyObject *Py_UNUSED(dummy))
 {
     PyObject *args, *state;
     PyObject *getinitargs;
@@ -4161,20 +4177,20 @@ tzinfo_reduce(PyObject *self, PyObject 
*Py_UNUSED(ignored))
 
 static PyMethodDef tzinfo_methods[] = {
 
-    {"tzname",          (PyCFunction)tzinfo_tzname,             METH_O,
+    {"tzname", tzinfo_tzname, METH_O,
      PyDoc_STR("datetime -> string name of time zone.")},
 
-    {"utcoffset",       (PyCFunction)tzinfo_utcoffset,          METH_O,
+    {"utcoffset", tzinfo_utcoffset, METH_O,
      PyDoc_STR("datetime -> timedelta showing offset from UTC, negative "
            "values indicating West of UTC")},
 
-    {"dst",             (PyCFunction)tzinfo_dst,                METH_O,
+    {"dst", tzinfo_dst, METH_O,
      PyDoc_STR("datetime -> DST offset as timedelta positive east of UTC.")},
 
-    {"fromutc",         (PyCFunction)tzinfo_fromutc,            METH_O,
+    {"fromutc", tzinfo_fromutc, METH_O,
      PyDoc_STR("datetime in UTC -> datetime in local time.")},
 
-    {"__reduce__",  tzinfo_reduce,             METH_NOARGS,
+    {"__reduce__",  tzinfo_reduce, METH_NOARGS,
      PyDoc_STR("-> (cls, state)")},
 
     {NULL, NULL}
@@ -4240,29 +4256,32 @@ timezone_new(PyTypeObject *type, PyObject *args, 
PyObject *kw)
 }
 
 static void
-timezone_dealloc(PyDateTime_TimeZone *self)
+timezone_dealloc(PyObject *op)
 {
+    PyDateTime_TimeZone *self = PyTimeZone_CAST(op);
     Py_CLEAR(self->offset);
     Py_CLEAR(self->name);
-    Py_TYPE(self)->tp_free((PyObject *)self);
+    Py_TYPE(self)->tp_free(self);
 }
 
 static PyObject *
-timezone_richcompare(PyDateTime_TimeZone *self,
-                     PyDateTime_TimeZone *other, int op)
+timezone_richcompare(PyObject *self, PyObject *other, int op)
 {
     if (op != Py_EQ && op != Py_NE)
         Py_RETURN_NOTIMPLEMENTED;
     if (!PyTimezone_Check(other)) {
         Py_RETURN_NOTIMPLEMENTED;
     }
-    return delta_richcompare(self->offset, other->offset, op);
+    PyDateTime_TimeZone *lhs = PyTimeZone_CAST(self);
+    PyDateTime_TimeZone *rhs = PyTimeZone_CAST(other);
+    return delta_richcompare(lhs->offset, rhs->offset, op);
 }
 
 static Py_hash_t
-timezone_hash(PyDateTime_TimeZone *self)
+timezone_hash(PyObject *op)
 {
-    return delta_hash((PyDateTime_Delta *)self->offset);
+    PyDateTime_TimeZone *self = PyTimeZone_CAST(op);
+    return delta_hash(self->offset);
 }
 
 /* Check argument type passed to tzname, utcoffset, or dst methods.
@@ -4280,13 +4299,14 @@ _timezone_check_argument(PyObject *dt, const char *meth)
 }
 
 static PyObject *
-timezone_repr(PyDateTime_TimeZone *self)
+timezone_repr(PyObject *op)
 {
     /* Note that although timezone is not subclassable, it is convenient
        to use Py_TYPE(self)->tp_name here. */
+    PyDateTime_TimeZone *self = PyTimeZone_CAST(op);
     const char *type_name = Py_TYPE(self)->tp_name;
 
-    if ((PyObject *)self == CONST_UTC(NO_STATE)) {
+    if (op == CONST_UTC(NO_STATE)) {
         return PyUnicode_FromFormat("%s.utc", type_name);
     }
 
@@ -4297,10 +4317,10 @@ timezone_repr(PyDateTime_TimeZone *self)
                                 self->name);
 }
 
-
 static PyObject *
-timezone_str(PyDateTime_TimeZone *self)
+timezone_str(PyObject *op)
 {
+    PyDateTime_TimeZone *self = PyTimeZone_CAST(op);
     int hours, minutes, seconds, microseconds;
     PyObject *offset;
     char sign;
@@ -4318,7 +4338,7 @@ timezone_str(PyDateTime_TimeZone *self)
     /* Offset is normalized, so it is negative if days < 0 */
     if (GET_TD_DAYS(self->offset) < 0) {
         sign = '-';
-        offset = delta_negative((PyDateTime_Delta *)self->offset);
+        offset = delta_negative(self->offset);
         if (offset == NULL)
             return NULL;
     }
@@ -4345,25 +4365,26 @@ timezone_str(PyDateTime_TimeZone *self)
 }
 
 static PyObject *
-timezone_tzname(PyDateTime_TimeZone *self, PyObject *dt)
+timezone_tzname(PyObject *op, PyObject *dt)
 {
     if (_timezone_check_argument(dt, "tzname") == -1)
         return NULL;
 
-    return timezone_str(self);
+    return timezone_str(op);
 }
 
 static PyObject *
-timezone_utcoffset(PyDateTime_TimeZone *self, PyObject *dt)
+timezone_utcoffset(PyObject *op, PyObject *dt)
 {
     if (_timezone_check_argument(dt, "utcoffset") == -1)
         return NULL;
 
+    PyDateTime_TimeZone *self = PyTimeZone_CAST(op);
     return Py_NewRef(self->offset);
 }
 
 static PyObject *
-timezone_dst(PyObject *self, PyObject *dt)
+timezone_dst(PyObject *op, PyObject *dt)
 {
     if (_timezone_check_argument(dt, "dst") == -1)
         return NULL;
@@ -4372,44 +4393,48 @@ timezone_dst(PyObject *self, PyObject *dt)
 }
 
 static PyObject *
-timezone_fromutc(PyDateTime_TimeZone *self, PyDateTime_DateTime *dt)
+timezone_fromutc(PyObject *op, PyObject *arg)
 {
-    if (!PyDateTime_Check(dt)) {
+    if (!PyDateTime_Check(arg)) {
         PyErr_SetString(PyExc_TypeError,
                         "fromutc: argument must be a datetime");
         return NULL;
     }
-    if (!HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
+
+    PyDateTime_DateTime *dt = (PyDateTime_DateTime *)arg;  // fast safe cast
+    if (!HASTZINFO(dt) || dt->tzinfo != op) {
         PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo is not self");
         return NULL;
     }
 
+    PyDateTime_TimeZone *self = PyTimeZone_CAST(op);
     return add_datetime_timedelta(dt, (PyDateTime_Delta *)self->offset, 1);
 }
 
 static PyObject *
-timezone_getinitargs(PyDateTime_TimeZone *self, PyObject *Py_UNUSED(ignored))
+timezone_getinitargs(PyObject *op, PyObject *Py_UNUSED(dummy))
 {
+    PyDateTime_TimeZone *self = PyTimeZone_CAST(op);
     if (self->name == NULL)
         return PyTuple_Pack(1, self->offset);
     return PyTuple_Pack(2, self->offset, self->name);
 }
 
 static PyMethodDef timezone_methods[] = {
-    {"tzname", (PyCFunction)timezone_tzname, METH_O,
+    {"tzname", timezone_tzname, METH_O,
      PyDoc_STR("If name is specified when timezone is created, returns the 
name."
                "  Otherwise returns offset as 'UTC(+|-)HH:MM'.")},
 
-    {"utcoffset", (PyCFunction)timezone_utcoffset, METH_O,
+    {"utcoffset", timezone_utcoffset, METH_O,
      PyDoc_STR("Return fixed offset.")},
 
-    {"dst", (PyCFunction)timezone_dst, METH_O,
+    {"dst", timezone_dst, METH_O,
      PyDoc_STR("Return None.")},
 
-    {"fromutc", (PyCFunction)timezone_fromutc, METH_O,
+    {"fromutc", timezone_fromutc, METH_O,
      PyDoc_STR("datetime in UTC -> datetime in local time.")},
 
-    {"__getinitargs__", (PyCFunction)timezone_getinitargs, METH_NOARGS,
+    {"__getinitargs__", timezone_getinitargs, METH_NOARGS,
      PyDoc_STR("pickle support")},
 
     {NULL, NULL}
@@ -4423,18 +4448,18 @@ static PyTypeObject PyDateTime_TimeZoneType = {
     "datetime.timezone",              /* tp_name */
     sizeof(PyDateTime_TimeZone),      /* tp_basicsize */
     0,                                /* tp_itemsize */
-    (destructor)timezone_dealloc,     /* tp_dealloc */
+    timezone_dealloc,                 /* tp_dealloc */
     0,                                /* tp_vectorcall_offset */
     0,                                /* tp_getattr */
     0,                                /* tp_setattr */
     0,                                /* tp_as_async */
-    (reprfunc)timezone_repr,          /* tp_repr */
+    timezone_repr,                    /* tp_repr */
     0,                                /* tp_as_number */
     0,                                /* tp_as_sequence */
     0,                                /* tp_as_mapping */
-    (hashfunc)timezone_hash,          /* tp_hash */
+    timezone_hash,                    /* tp_hash */
     0,                                /* tp_call */
-    (reprfunc)timezone_str,           /* tp_str */
+    timezone_str,                     /* tp_str */
     0,                                /* tp_getattro */
     0,                                /* tp_setattro */
     0,                                /* tp_as_buffer */
@@ -4442,7 +4467,7 @@ static PyTypeObject PyDateTime_TimeZoneType = {
     timezone_doc,                     /* tp_doc */
     0,                                /* tp_traverse */
     0,                                /* tp_clear */
-    (richcmpfunc)timezone_richcompare,/* tp_richcompare */
+    timezone_richcompare,             /* tp_richcompare */
     0,                                /* tp_weaklistoffset */
     0,                                /* tp_iter */
     0,                                /* tp_iternext */
@@ -4484,50 +4509,56 @@ look_up_timezone(PyObject *offset, PyObject *name)
  */
 
 static PyObject *
-time_hour(PyDateTime_Time *self, void *unused)
+time_hour(PyObject *op, void *Py_UNUSED(closure))
 {
+    PyDateTime_Time *self = PyTime_CAST(op);
     return PyLong_FromLong(TIME_GET_HOUR(self));
 }
 
 static PyObject *
-time_minute(PyDateTime_Time *self, void *unused)
+time_minute(PyObject *op, void *Py_UNUSED(closure))
 {
+    PyDateTime_Time *self = PyTime_CAST(op);
     return PyLong_FromLong(TIME_GET_MINUTE(self));
 }
 
 /* The name time_second conflicted with some platform header file. */
 static PyObject *
-py_time_second(PyDateTime_Time *self, void *unused)
+py_time_second(PyObject *op, void *Py_UNUSED(closure))
 {
+    PyDateTime_Time *self = PyTime_CAST(op);
     return PyLong_FromLong(TIME_GET_SECOND(self));
 }
 
 static PyObject *
-time_microsecond(PyDateTime_Time *self, void *unused)
+time_microsecond(PyObject *op, void *Py_UNUSED(closure))
 {
+    PyDateTime_Time *self = PyTime_CAST(op);
     return PyLong_FromLong(TIME_GET_MICROSECOND(self));
 }
 
 static PyObject *
-time_tzinfo(PyDateTime_Time *self, void *unused)
+time_tzinfo(PyObject *op, void *Py_UNUSED(closure))
 {
+    PyDateTime_Time *self = PyTime_CAST(op);
     PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
     return Py_NewRef(result);
 }
 
 static PyObject *
-time_fold(PyDateTime_Time *self, void *unused)
+time_fold(PyObject *op, void *Py_UNUSED(closure))
 {
+    PyDateTime_Time *self = PyTime_CAST(op);
     return PyLong_FromLong(TIME_GET_FOLD(self));
 }
 
 static PyGetSetDef time_getset[] = {
-    {"hour",        (getter)time_hour},
-    {"minute",      (getter)time_minute},
-    {"second",      (getter)py_time_second},
-    {"microsecond", (getter)time_microsecond},
-    {"tzinfo",      (getter)time_tzinfo},
-    {"fold",        (getter)time_fold},
+    {"hour", time_hour},
+    {"minute", time_minute},
+    {"second", py_time_second},
+    {"microsecond", time_microsecond},
+    {"tzinfo", time_tzinfo},
+    {"fold", time_fold},
     {NULL}
 };
 
@@ -4652,12 +4683,13 @@ time_strptime(PyObject *cls, PyObject *args)
  */
 
 static void
-time_dealloc(PyDateTime_Time *self)
+time_dealloc(PyObject *op)
 {
+    PyDateTime_Time *self = PyTime_CAST(op);
     if (HASTZINFO(self)) {
         Py_XDECREF(self->tzinfo);
     }
-    Py_TYPE(self)->tp_free((PyObject *)self);
+    Py_TYPE(self)->tp_free(self);
 }
 
 /*
@@ -4666,17 +4698,20 @@ time_dealloc(PyDateTime_Time *self)
 
 /* These are all METH_NOARGS, so don't need to check the arglist. */
 static PyObject *
-time_utcoffset(PyObject *self, PyObject *unused) {
+time_utcoffset(PyObject *op, PyObject *Py_UNUSED(dummy)) {
+    PyDateTime_Time *self = PyTime_CAST(op);
     return call_utcoffset(GET_TIME_TZINFO(self), Py_None);
 }
 
 static PyObject *
-time_dst(PyObject *self, PyObject *unused) {
+time_dst(PyObject *op, PyObject *Py_UNUSED(dummy)) {
+    PyDateTime_Time *self = PyTime_CAST(op);
     return call_dst(GET_TIME_TZINFO(self), Py_None);
 }
 
 static PyObject *
-time_tzname(PyDateTime_Time *self, PyObject *unused) {
+time_tzname(PyObject *op, PyObject *Py_UNUSED(dummy)) {
+    PyDateTime_Time *self = PyTime_CAST(op);
     return call_tzname(GET_TIME_TZINFO(self), Py_None);
 }
 
@@ -4685,8 +4720,9 @@ time_tzname(PyDateTime_Time *self, PyObject *unused) {
  */
 
 static PyObject *
-time_repr(PyDateTime_Time *self)
+time_repr(PyObject *op)
 {
+    PyDateTime_Time *self = PyTime_CAST(op);
     const char *type_name = Py_TYPE(self)->tp_name;
     int h = TIME_GET_HOUR(self);
     int m = TIME_GET_MINUTE(self);
@@ -4711,17 +4747,19 @@ time_repr(PyDateTime_Time *self)
 }
 
 static PyObject *
-time_str(PyDateTime_Time *self)
+time_str(PyObject *op)
 {
-    return PyObject_CallMethodNoArgs((PyObject *)self, &_Py_ID(isoformat));
+    return PyObject_CallMethodNoArgs(op, &_Py_ID(isoformat));
 }
 
 static PyObject *
-time_isoformat(PyDateTime_Time *self, PyObject *args, PyObject *kw)
+time_isoformat(PyObject *op, PyObject *args, PyObject *kw)
 {
     char buf[100];
     const char *timespec = NULL;
     static char *keywords[] = {"timespec", NULL};
+    PyDateTime_Time *self = PyTime_CAST(op);
+
     PyObject *result;
     int us = TIME_GET_MICROSECOND(self);
     static const char *specs[][2] = {
@@ -4782,12 +4820,13 @@ time_isoformat(PyDateTime_Time *self, PyObject *args, 
PyObject *kw)
 }
 
 static PyObject *
-time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
+time_strftime(PyObject *op, PyObject *args, PyObject *kw)
 {
     PyObject *result;
     PyObject *tuple;
     PyObject *format;
     static char *keywords[] = {"format", NULL};
+    PyDateTime_Time *self = PyTime_CAST(op);
 
     if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
                                       &format))
@@ -4888,8 +4927,9 @@ time_richcompare(PyObject *self, PyObject *other, int op)
 }
 
 static Py_hash_t
-time_hash(PyDateTime_Time *self)
+time_hash(PyObject *op)
 {
+    PyDateTime_Time *self = PyTime_CAST(op);
     if (self->hashcode == -1) {
         PyObject *offset, *self0;
         if (TIME_GET_FOLD(self)) {
@@ -5065,18 +5105,20 @@ time_getstate(PyDateTime_Time *self, int proto)
 }
 
 static PyObject *
-time_reduce_ex(PyDateTime_Time *self, PyObject *args)
+time_reduce_ex(PyObject *op, PyObject *args)
 {
     int proto;
     if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto))
         return NULL;
 
+    PyDateTime_Time *self = PyTime_CAST(op);
     return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, proto));
 }
 
 static PyObject *
-time_reduce(PyDateTime_Time *self, PyObject *arg)
+time_reduce(PyObject *op, PyObject *Py_UNUSED(dummy))
 {
+    PyDateTime_Time *self = PyTime_CAST(op);
     return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, 2));
 }
 
@@ -5084,14 +5126,14 @@ static PyMethodDef time_methods[] = {
 
     /* Class method: */
 
-    {"strptime", (PyCFunction)time_strptime,
+    {"strptime", time_strptime,
      METH_VARARGS | METH_CLASS,
      PyDoc_STR("string, format -> new time parsed from a string "
                "(like time.strptime()).")},
 
     /* Instance methods: */
 
-    {"isoformat",   _PyCFunction_CAST(time_isoformat),        METH_VARARGS | 
METH_KEYWORDS,
+    {"isoformat", _PyCFunction_CAST(time_isoformat), METH_VARARGS | 
METH_KEYWORDS,
      PyDoc_STR("Return string in ISO 8601 format, [HH[:MM[:SS[.mmm[uuu]]]]]"
                "[+HH:MM].\n\n"
                "The optional argument timespec specifies the number "
@@ -5099,19 +5141,19 @@ static PyMethodDef time_methods[] = {
                "options are 'auto', 'hours', 'minutes',\n'seconds', "
                "'milliseconds' and 'microseconds'.\n")},
 
-    {"strftime",        _PyCFunction_CAST(time_strftime),     METH_VARARGS | 
METH_KEYWORDS,
+    {"strftime", _PyCFunction_CAST(time_strftime), METH_VARARGS | 
METH_KEYWORDS,
      PyDoc_STR("format -> strftime() style string.")},
 
-    {"__format__",      (PyCFunction)date_format,       METH_VARARGS,
+    {"__format__", date_format, METH_VARARGS,
      PyDoc_STR("Formats self with strftime.")},
 
-    {"utcoffset",       (PyCFunction)time_utcoffset,    METH_NOARGS,
+    {"utcoffset", time_utcoffset, METH_NOARGS,
      PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
 
-    {"tzname",          (PyCFunction)time_tzname,       METH_NOARGS,
+    {"tzname", time_tzname, METH_NOARGS,
      PyDoc_STR("Return self.tzinfo.tzname(self).")},
 
-    {"dst",             (PyCFunction)time_dst,          METH_NOARGS,
+    {"dst", time_dst, METH_NOARGS,
      PyDoc_STR("Return self.tzinfo.dst(self).")},
 
     DATETIME_TIME_REPLACE_METHODDEF
@@ -5119,13 +5161,13 @@ static PyMethodDef time_methods[] = {
     {"__replace__", _PyCFunction_CAST(datetime_time_replace), METH_FASTCALL | 
METH_KEYWORDS,
      PyDoc_STR("__replace__($self, /, **changes)\n--\n\nThe same as 
replace().")},
 
-     {"fromisoformat", (PyCFunction)time_fromisoformat, METH_O | METH_CLASS,
+     {"fromisoformat", time_fromisoformat, METH_O | METH_CLASS,
      PyDoc_STR("string -> time from a string in ISO 8601 format")},
 
-    {"__reduce_ex__", (PyCFunction)time_reduce_ex,        METH_VARARGS,
+    {"__reduce_ex__", time_reduce_ex, METH_VARARGS,
      PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")},
 
-    {"__reduce__", (PyCFunction)time_reduce,        METH_NOARGS,
+    {"__reduce__", time_reduce, METH_NOARGS,
      PyDoc_STR("__reduce__() -> (cls, state)")},
 
     {NULL,      NULL}
@@ -5142,18 +5184,18 @@ static PyTypeObject PyDateTime_TimeType = {
     "datetime.time",                            /* tp_name */
     sizeof(PyDateTime_Time),                    /* tp_basicsize */
     0,                                          /* tp_itemsize */
-    (destructor)time_dealloc,                   /* tp_dealloc */
+    time_dealloc,                               /* tp_dealloc */
     0,                                          /* tp_vectorcall_offset */
     0,                                          /* tp_getattr */
     0,                                          /* tp_setattr */
     0,                                          /* tp_as_async */
-    (reprfunc)time_repr,                        /* tp_repr */
+    time_repr,                                  /* tp_repr */
     0,                                          /* tp_as_number */
     0,                                          /* tp_as_sequence */
     0,                                          /* tp_as_mapping */
-    (hashfunc)time_hash,                        /* tp_hash */
+    time_hash,                                  /* tp_hash */
     0,                                          /* tp_call */
-    (reprfunc)time_str,                         /* tp_str */
+    time_str,                                   /* tp_str */
     PyObject_GenericGetAttr,                    /* tp_getattro */
     0,                                          /* tp_setattro */
     0,                                          /* tp_as_buffer */
@@ -5188,49 +5230,55 @@ static PyTypeObject PyDateTime_TimeType = {
  */
 
 static PyObject *
-datetime_hour(PyDateTime_DateTime *self, void *unused)
+datetime_hour(PyObject *op, void *Py_UNUSED(closure))
 {
+    PyDateTime_DateTime *self = PyDateTime_CAST(op);
     return PyLong_FromLong(DATE_GET_HOUR(self));
 }
 
 static PyObject *
-datetime_minute(PyDateTime_DateTime *self, void *unused)
+datetime_minute(PyObject *op, void *Py_UNUSED(closure))
 {
+    PyDateTime_DateTime *self = PyDateTime_CAST(op);
     return PyLong_FromLong(DATE_GET_MINUTE(self));
 }
 
 static PyObject *
-datetime_second(PyDateTime_DateTime *self, void *unused)
+datetime_second(PyObject *op, void *Py_UNUSED(closure))
 {
+    PyDateTime_DateTime *self = PyDateTime_CAST(op);
     return PyLong_FromLong(DATE_GET_SECOND(self));
 }
 
 static PyObject *
-datetime_microsecond(PyDateTime_DateTime *self, void *unused)
+datetime_microsecond(PyObject *op, void *Py_UNUSED(closure))
 {
+    PyDateTime_DateTime *self = PyDateTime_CAST(op);
     return PyLong_FromLong(DATE_GET_MICROSECOND(self));
 }
 
 static PyObject *
-datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
+datetime_tzinfo(PyObject *op, void *Py_UNUSED(closure))
 {
+    PyDateTime_DateTime *self = PyDateTime_CAST(op);
     PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
     return Py_NewRef(result);
 }
 
 static PyObject *
-datetime_fold(PyDateTime_DateTime *self, void *unused)
+datetime_fold(PyObject *op, void *Py_UNUSED(closure))
 {
+    PyDateTime_DateTime *self = PyDateTime_CAST(op);
     return PyLong_FromLong(DATE_GET_FOLD(self));
 }
 
 static PyGetSetDef datetime_getset[] = {
-    {"hour",        (getter)datetime_hour},
-    {"minute",      (getter)datetime_minute},
-    {"second",      (getter)datetime_second},
-    {"microsecond", (getter)datetime_microsecond},
-    {"tzinfo",      (getter)datetime_tzinfo},
-    {"fold",        (getter)datetime_fold},
+    {"hour", datetime_hour},
+    {"minute", datetime_minute},
+    {"second", datetime_second},
+    {"microsecond", datetime_microsecond},
+    {"tzinfo", datetime_tzinfo},
+    {"fold", datetime_fold},
     {NULL}
 };
 
@@ -5934,12 +5982,13 @@ datetime_fromisoformat(PyObject *cls, PyObject *dtstr)
  */
 
 static void
-datetime_dealloc(PyDateTime_DateTime *self)
+datetime_dealloc(PyObject *op)
 {
+    PyDateTime_DateTime *self = PyDateTime_CAST(op);
     if (HASTZINFO(self)) {
         Py_XDECREF(self->tzinfo);
     }
-    Py_TYPE(self)->tp_free((PyObject *)self);
+    Py_TYPE(self)->tp_free(self);
 }
 
 /*
@@ -5948,18 +5997,21 @@ datetime_dealloc(PyDateTime_DateTime *self)
 
 /* These are all METH_NOARGS, so don't need to check the arglist. */
 static PyObject *
-datetime_utcoffset(PyObject *self, PyObject *unused) {
-    return call_utcoffset(GET_DT_TZINFO(self), self);
+datetime_utcoffset(PyObject *op, PyObject *Py_UNUSED(dummy)) {
+    PyDateTime_DateTime *self = PyDateTime_CAST(op);
+    return call_utcoffset(GET_DT_TZINFO(self), op);
 }
 
 static PyObject *
-datetime_dst(PyObject *self, PyObject *unused) {
-    return call_dst(GET_DT_TZINFO(self), self);
+datetime_dst(PyObject *op, PyObject *Py_UNUSED(dummy)) {
+    PyDateTime_DateTime *self = PyDateTime_CAST(op);
+    return call_dst(GET_DT_TZINFO(self), op);
 }
 
 static PyObject *
-datetime_tzname(PyObject *self, PyObject *unused) {
-    return call_tzname(GET_DT_TZINFO(self), self);
+datetime_tzname(PyObject *op, PyObject *Py_UNUSED(dummy)) {
+    PyDateTime_DateTime *self = PyDateTime_CAST(op);
+    return call_tzname(GET_DT_TZINFO(self), op);
 }
 
 /*
@@ -6107,8 +6159,9 @@ datetime_subtract(PyObject *left, PyObject *right)
 /* Various ways to turn a datetime into a string. */
 
 static PyObject *
-datetime_repr(PyDateTime_DateTime *self)
+datetime_repr(PyObject *op)
 {
+    PyDateTime_DateTime *self = PyDateTime_CAST(op);
     const char *type_name = Py_TYPE(self)->tp_name;
     PyObject *baserepr;
 
@@ -6144,25 +6197,26 @@ datetime_repr(PyDateTime_DateTime *self)
 }
 
 static PyObject *
-datetime_str(PyDateTime_DateTime *self)
+datetime_str(PyObject *op)
 {
     PyObject *space = PyUnicode_FromString(" ");
     if (space == NULL) {
         return NULL;
     }
-    PyObject *res = PyObject_CallMethodOneArg((PyObject *)self,
-                            &_Py_ID(isoformat), space);
+    PyObject *res = PyObject_CallMethodOneArg(op, &_Py_ID(isoformat), space);
     Py_DECREF(space);
     return res;
 }
 
 static PyObject *
-datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
+datetime_isoformat(PyObject *op, PyObject *args, PyObject *kw)
 {
     int sep = 'T';
     char *timespec = NULL;
     static char *keywords[] = {"sep", "timespec", NULL};
     char buffer[100];
+    PyDateTime_DateTime *self = PyDateTime_CAST(op);
+
     PyObject *result = NULL;
     int us = DATE_GET_MICROSECOND(self);
     static const char *specs[][2] = {
@@ -6214,8 +6268,7 @@ datetime_isoformat(PyDateTime_DateTime *self, PyObject 
*args, PyObject *kw)
         return result;
 
     /* We need to append the UTC offset. */
-    if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
-                         (PyObject *)self) < 0) {
+    if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo, op) < 0) {
         Py_DECREF(result);
         return NULL;
     }
@@ -6224,9 +6277,10 @@ datetime_isoformat(PyDateTime_DateTime *self, PyObject 
*args, PyObject *kw)
 }
 
 static PyObject *
-datetime_ctime(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
+datetime_ctime(PyObject *op, PyObject *Py_UNUSED(dummy))
 {
-    return format_ctime((PyDateTime_Date *)self,
+    PyDateTime_DateTime *self = PyDateTime_CAST(op);
+    return format_ctime(op,
                         DATE_GET_HOUR(self),
                         DATE_GET_MINUTE(self),
                         DATE_GET_SECOND(self));
@@ -6380,8 +6434,9 @@ datetime_richcompare(PyObject *self, PyObject *other, int 
op)
 }
 
 static Py_hash_t
-datetime_hash(PyDateTime_DateTime *self)
+datetime_hash(PyObject *op)
 {
+    PyDateTime_DateTime *self = PyDateTime_CAST(op);
     if (self->hashcode == -1) {
         PyObject *offset, *self0;
         if (DATE_GET_FOLD(self)) {
@@ -6604,9 +6659,10 @@ local_timezone_from_local(PyDateTime_DateTime *local_dt)
     return local_timezone_from_timestamp(timestamp);
 }
 
-static PyDateTime_DateTime *
-datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
+static PyObject *
+datetime_astimezone(PyObject *op, PyObject *args, PyObject *kw)
 {
+    PyDateTime_DateTime *self = PyDateTime_CAST(op);
     PyDateTime_DateTime *result;
     PyObject *offset;
     PyObject *temp;
@@ -6633,7 +6689,7 @@ datetime_astimezone(PyDateTime_DateTime *self, PyObject 
*args, PyObject *kw)
     /* Conversion to self's own time zone is a NOP. */
     if (self_tzinfo == tzinfo) {
         Py_DECREF(self_tzinfo);
-        return (PyDateTime_DateTime*)Py_NewRef(self);
+        return Py_NewRef(self);
     }
 
     /* Convert self to UTC. */
@@ -6698,23 +6754,24 @@ datetime_astimezone(PyDateTime_DateTime *self, PyObject 
*args, PyObject *kw)
         PyObject_CallMethodOneArg(tzinfo, &_Py_ID(fromutc), temp);
     Py_DECREF(temp);
 
-    return result;
+    return (PyObject *)result;
 }
 
 static PyObject *
-datetime_timetuple(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
+datetime_timetuple(PyObject *op, PyObject *Py_UNUSED(dummy))
 {
+    PyDateTime_DateTime *self = PyDateTime_CAST(op);
     int dstflag = -1;
 
     if (HASTZINFO(self) && self->tzinfo != Py_None) {
         PyObject * dst;
 
-        dst = call_dst(self->tzinfo, (PyObject *)self);
+        dst = call_dst(self->tzinfo, op);
         if (dst == NULL)
             return NULL;
 
         if (dst != Py_None)
-            dstflag = delta_bool((PyDateTime_Delta *)dst);
+            dstflag = delta_bool(dst);
         Py_DECREF(dst);
     }
     return build_struct_time(GET_YEAR(self),
@@ -6777,8 +6834,9 @@ local_to_seconds(int year, int month, int day,
 #define EPOCH_SECONDS (719163LL * 24 * 60 * 60)
 
 static PyObject *
-datetime_timestamp(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
+datetime_timestamp(PyObject *op, PyObject *Py_UNUSED(dummy))
 {
+    PyDateTime_DateTime *self = PyDateTime_CAST(op);
     PyObject *result;
 
     if (HASTZINFO(self) && self->tzinfo != Py_None) {
@@ -6786,7 +6844,7 @@ datetime_timestamp(PyDateTime_DateTime *self, PyObject 
*Py_UNUSED(ignored))
         datetime_state *st = GET_CURRENT_STATE(current_mod);
 
         PyObject *delta;
-        delta = datetime_subtract((PyObject *)self, CONST_EPOCH(st));
+        delta = datetime_subtract(op, CONST_EPOCH(st));
         RELEASE_CURRENT_STATE(st, current_mod);
         if (delta == NULL)
             return NULL;
@@ -6811,16 +6869,18 @@ datetime_timestamp(PyDateTime_DateTime *self, PyObject 
*Py_UNUSED(ignored))
 }
 
 static PyObject *
-datetime_getdate(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
+datetime_getdate(PyObject *op, PyObject *Py_UNUSED(dummy))
 {
+    PyDateTime_DateTime *self = PyDateTime_CAST(op);
     return new_date(GET_YEAR(self),
                     GET_MONTH(self),
                     GET_DAY(self));
 }
 
 static PyObject *
-datetime_gettime(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
+datetime_gettime(PyObject *op, PyObject *Py_UNUSED(dummy))
 {
+    PyDateTime_DateTime *self = PyDateTime_CAST(op);
     return new_time(DATE_GET_HOUR(self),
                     DATE_GET_MINUTE(self),
                     DATE_GET_SECOND(self),
@@ -6830,8 +6890,9 @@ datetime_gettime(PyDateTime_DateTime *self, PyObject 
*Py_UNUSED(ignored))
 }
 
 static PyObject *
-datetime_gettimetz(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
+datetime_gettimetz(PyObject *op, PyObject *Py_UNUSED(dummy))
 {
+    PyDateTime_DateTime *self = PyDateTime_CAST(op);
     return new_time(DATE_GET_HOUR(self),
                     DATE_GET_MINUTE(self),
                     DATE_GET_SECOND(self),
@@ -6841,11 +6902,12 @@ datetime_gettimetz(PyDateTime_DateTime *self, PyObject 
*Py_UNUSED(ignored))
 }
 
 static PyObject *
-datetime_utctimetuple(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
+datetime_utctimetuple(PyObject *op, PyObject *Py_UNUSED(dummy))
 {
     int y, m, d, hh, mm, ss;
     PyObject *tzinfo;
     PyDateTime_DateTime *utcself;
+    PyDateTime_DateTime *self = PyDateTime_CAST(op);
 
     tzinfo = GET_DT_TZINFO(self);
     if (tzinfo == Py_None) {
@@ -6908,19 +6970,23 @@ datetime_getstate(PyDateTime_DateTime *self, int proto)
 }
 
 static PyObject *
-datetime_reduce_ex(PyDateTime_DateTime *self, PyObject *args)
+datetime_reduce_ex(PyObject *op, PyObject *args)
 {
     int proto;
     if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto))
         return NULL;
 
-    return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, 
proto));
+    PyDateTime_DateTime *self = PyDateTime_CAST(op);
+    return Py_BuildValue("(ON)", Py_TYPE(self),
+                         datetime_getstate(self, proto));
 }
 
 static PyObject *
-datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
+datetime_reduce(PyObject *op, PyObject *Py_UNUSED(arg))
 {
-    return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, 2));
+    PyDateTime_DateTime *self = PyDateTime_CAST(op);
+    return Py_BuildValue("(ON)", Py_TYPE(self),
+                         datetime_getstate(self, 2));
 }
 
 static PyMethodDef datetime_methods[] = {
@@ -6929,7 +6995,7 @@ static PyMethodDef datetime_methods[] = {
 
     DATETIME_DATETIME_NOW_METHODDEF
 
-    {"utcnow",         (PyCFunction)datetime_utcnow,
+    {"utcnow", datetime_utcnow,
      METH_NOARGS | METH_CLASS,
      PyDoc_STR("Return a new datetime representing UTC day and time.")},
 
@@ -6937,11 +7003,11 @@ static PyMethodDef datetime_methods[] = {
      METH_VARARGS | METH_KEYWORDS | METH_CLASS,
      PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
 
-    {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
+    {"utcfromtimestamp", datetime_utcfromtimestamp,
      METH_VARARGS | METH_CLASS,
      PyDoc_STR("Construct a naive UTC datetime from a POSIX timestamp.")},
 
-    {"strptime", (PyCFunction)datetime_strptime,
+    {"strptime", datetime_strptime,
      METH_VARARGS | METH_CLASS,
      PyDoc_STR("string, format -> new datetime parsed from a string "
                "(like time.strptime()).")},
@@ -6950,34 +7016,34 @@ static PyMethodDef datetime_methods[] = {
      METH_VARARGS | METH_KEYWORDS | METH_CLASS,
      PyDoc_STR("date, time -> datetime with same date and time fields")},
 
-    {"fromisoformat", (PyCFunction)datetime_fromisoformat,
+    {"fromisoformat", datetime_fromisoformat,
      METH_O | METH_CLASS,
      PyDoc_STR("string -> datetime from a string in most ISO 8601 formats")},
 
     /* Instance methods: */
 
-    {"date",   (PyCFunction)datetime_getdate, METH_NOARGS,
+    {"date", datetime_getdate, METH_NOARGS,
      PyDoc_STR("Return date object with same year, month and day.")},
 
-    {"time",   (PyCFunction)datetime_gettime, METH_NOARGS,
+    {"time", datetime_gettime, METH_NOARGS,
      PyDoc_STR("Return time object with same time but with tzinfo=None.")},
 
-    {"timetz",   (PyCFunction)datetime_gettimetz, METH_NOARGS,
+    {"timetz", datetime_gettimetz, METH_NOARGS,
      PyDoc_STR("Return time object with same time and tzinfo.")},
 
-    {"ctime",       (PyCFunction)datetime_ctime,        METH_NOARGS,
+    {"ctime", datetime_ctime, METH_NOARGS,
      PyDoc_STR("Return ctime() style string.")},
 
-    {"timetuple",   (PyCFunction)datetime_timetuple, METH_NOARGS,
+    {"timetuple", datetime_timetuple, METH_NOARGS,
      PyDoc_STR("Return time tuple, compatible with time.localtime().")},
 
-    {"timestamp",   (PyCFunction)datetime_timestamp, METH_NOARGS,
+    {"timestamp", datetime_timestamp, METH_NOARGS,
      PyDoc_STR("Return POSIX timestamp as float.")},
 
-    {"utctimetuple",   (PyCFunction)datetime_utctimetuple, METH_NOARGS,
+    {"utctimetuple", datetime_utctimetuple, METH_NOARGS,
      PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
 
-    {"isoformat",   _PyCFunction_CAST(datetime_isoformat), METH_VARARGS | 
METH_KEYWORDS,
+    {"isoformat", _PyCFunction_CAST(datetime_isoformat), METH_VARARGS | 
METH_KEYWORDS,
      PyDoc_STR("[sep] -> string in ISO 8601 format, "
                "YYYY-MM-DDT[HH[:MM[:SS[.mmm[uuu]]]]][+HH:MM].\n"
                "sep is used to separate the year from the time, and "
@@ -6987,13 +7053,13 @@ static PyMethodDef datetime_methods[] = {
                "options are 'auto', 'hours', 'minutes',\n'seconds', "
                "'milliseconds' and 'microseconds'.\n")},
 
-    {"utcoffset",       (PyCFunction)datetime_utcoffset, METH_NOARGS,
+    {"utcoffset", datetime_utcoffset, METH_NOARGS,
      PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
 
-    {"tzname",          (PyCFunction)datetime_tzname,   METH_NOARGS,
+    {"tzname", datetime_tzname,   METH_NOARGS,
      PyDoc_STR("Return self.tzinfo.tzname(self).")},
 
-    {"dst",             (PyCFunction)datetime_dst, METH_NOARGS,
+    {"dst", datetime_dst, METH_NOARGS,
      PyDoc_STR("Return self.tzinfo.dst(self).")},
 
     DATETIME_DATETIME_REPLACE_METHODDEF
@@ -7004,10 +7070,10 @@ static PyMethodDef datetime_methods[] = {
     {"astimezone",  _PyCFunction_CAST(datetime_astimezone), METH_VARARGS | 
METH_KEYWORDS,
      PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
 
-    {"__reduce_ex__", (PyCFunction)datetime_reduce_ex,     METH_VARARGS,
+    {"__reduce_ex__", datetime_reduce_ex, METH_VARARGS,
      PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")},
 
-    {"__reduce__", (PyCFunction)datetime_reduce,     METH_NOARGS,
+    {"__reduce__", datetime_reduce, METH_NOARGS,
      PyDoc_STR("__reduce__() -> (cls, state)")},
 
     {NULL,      NULL}
@@ -7037,18 +7103,18 @@ static PyTypeObject PyDateTime_DateTimeType = {
     "datetime.datetime",                        /* tp_name */
     sizeof(PyDateTime_DateTime),                /* tp_basicsize */
     0,                                          /* tp_itemsize */
-    (destructor)datetime_dealloc,               /* tp_dealloc */
+    datetime_dealloc,                           /* tp_dealloc */
     0,                                          /* tp_vectorcall_offset */
     0,                                          /* tp_getattr */
     0,                                          /* tp_setattr */
     0,                                          /* tp_as_async */
-    (reprfunc)datetime_repr,                    /* tp_repr */
+    datetime_repr,                              /* tp_repr */
     &datetime_as_number,                        /* tp_as_number */
     0,                                          /* tp_as_sequence */
     0,                                          /* tp_as_mapping */
-    (hashfunc)datetime_hash,                    /* tp_hash */
+    datetime_hash,                              /* tp_hash */
     0,                                          /* tp_call */
-    (reprfunc)datetime_str,                     /* tp_str */
+    datetime_str,                               /* tp_str */
     PyObject_GenericGetAttr,                    /* tp_getattro */
     0,                                          /* tp_setattro */
     0,                                          /* tp_as_buffer */

_______________________________________________
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: arch...@mail-archive.com

Reply via email to