@@ -96,7 +96,7 @@ typedef struct {
9696#define PyTZInfo_Check (op ) PyObject_TypeCheck(op, TZINFO_TYPE(NO_STATE))
9797#define PyTZInfo_CheckExact (op ) Py_IS_TYPE(op, TZINFO_TYPE(NO_STATE))
9898
99- #define _PyTimezone_CAST (op ) ((PyDateTime_TimeZone *)(op))
99+ #define _PyTimeZone_CAST (op ) ((PyDateTime_TimeZone *)(op))
100100#define PyTimezone_Check (op ) PyObject_TypeCheck(op, TIMEZONE_TYPE(NO_STATE))
101101
102102#define _PyIsoCalendarDate_CAST (op ) ((PyDateTime_IsoCalendarDate *)(op))
@@ -4255,28 +4255,31 @@ timezone_new(PyTypeObject *type, PyObject *args, PyObject *kw)
42554255}
42564256
42574257static void
4258- timezone_dealloc (PyDateTime_TimeZone * self )
4258+ timezone_dealloc (PyObject * op )
42594259{
4260+ PyDateTime_TimeZone * self = _PyTimeZone_CAST (op );
42604261 Py_CLEAR (self -> offset );
42614262 Py_CLEAR (self -> name );
4262- Py_TYPE (self )-> tp_free (( PyObject * ) self );
4263+ Py_TYPE (self )-> tp_free (self );
42634264}
42644265
42654266static PyObject *
4266- timezone_richcompare (PyDateTime_TimeZone * self ,
4267- PyDateTime_TimeZone * other , int op )
4267+ timezone_richcompare (PyObject * self , PyObject * other , int op )
42684268{
42694269 if (op != Py_EQ && op != Py_NE )
42704270 Py_RETURN_NOTIMPLEMENTED ;
42714271 if (!PyTimezone_Check (other )) {
42724272 Py_RETURN_NOTIMPLEMENTED ;
42734273 }
4274- return delta_richcompare (self -> offset , other -> offset , op );
4274+ PyDateTime_TimeZone * lhs = _PyTimeZone_CAST (self );
4275+ PyDateTime_TimeZone * rhs = _PyTimeZone_CAST (other );
4276+ return delta_richcompare (lhs -> offset , rhs -> offset , op );
42754277}
42764278
42774279static Py_hash_t
4278- timezone_hash (PyDateTime_TimeZone * self )
4280+ timezone_hash (PyObject * op )
42794281{
4282+ PyDateTime_TimeZone * self = _PyTimeZone_CAST (op );
42804283 return delta_hash (self -> offset );
42814284}
42824285
@@ -4295,13 +4298,14 @@ _timezone_check_argument(PyObject *dt, const char *meth)
42954298}
42964299
42974300static PyObject *
4298- timezone_repr (PyDateTime_TimeZone * self )
4301+ timezone_repr (PyObject * op )
42994302{
43004303 /* Note that although timezone is not subclassable, it is convenient
43014304 to use Py_TYPE(self)->tp_name here. */
4305+ PyDateTime_TimeZone * self = _PyTimeZone_CAST (op );
43024306 const char * type_name = Py_TYPE (self )-> tp_name ;
43034307
4304- if (( PyObject * ) self == CONST_UTC (NO_STATE )) {
4308+ if (op == CONST_UTC (NO_STATE )) {
43054309 return PyUnicode_FromFormat ("%s.utc" , type_name );
43064310 }
43074311
@@ -4312,10 +4316,10 @@ timezone_repr(PyDateTime_TimeZone *self)
43124316 self -> name );
43134317}
43144318
4315-
43164319static PyObject *
4317- timezone_str (PyDateTime_TimeZone * self )
4320+ timezone_str (PyObject * op )
43184321{
4322+ PyDateTime_TimeZone * self = _PyTimeZone_CAST (op );
43194323 int hours , minutes , seconds , microseconds ;
43204324 PyObject * offset ;
43214325 char sign ;
@@ -4360,25 +4364,26 @@ timezone_str(PyDateTime_TimeZone *self)
43604364}
43614365
43624366static PyObject *
4363- timezone_tzname (PyDateTime_TimeZone * self , PyObject * dt )
4367+ timezone_tzname (PyObject * op , PyObject * dt )
43644368{
43654369 if (_timezone_check_argument (dt , "tzname" ) == -1 )
43664370 return NULL ;
43674371
4368- return timezone_str (self );
4372+ return timezone_str (op );
43694373}
43704374
43714375static PyObject *
4372- timezone_utcoffset (PyDateTime_TimeZone * self , PyObject * dt )
4376+ timezone_utcoffset (PyObject * op , PyObject * dt )
43734377{
43744378 if (_timezone_check_argument (dt , "utcoffset" ) == -1 )
43754379 return NULL ;
43764380
4381+ PyDateTime_TimeZone * self = _PyTimeZone_CAST (op );
43774382 return Py_NewRef (self -> offset );
43784383}
43794384
43804385static PyObject *
4381- timezone_dst (PyObject * self , PyObject * dt )
4386+ timezone_dst (PyObject * op , PyObject * dt )
43824387{
43834388 if (_timezone_check_argument (dt , "dst" ) == -1 )
43844389 return NULL ;
@@ -4387,45 +4392,49 @@ timezone_dst(PyObject *self, PyObject *dt)
43874392}
43884393
43894394static PyObject *
4390- timezone_fromutc (PyDateTime_TimeZone * self , PyDateTime_DateTime * dt )
4395+ timezone_fromutc (PyObject * op , PyObject * arg )
43914396{
4392- if (!PyDateTime_Check (dt )) {
4397+ if (!PyDateTime_Check (arg )) {
43934398 PyErr_SetString (PyExc_TypeError ,
43944399 "fromutc: argument must be a datetime" );
43954400 return NULL ;
43964401 }
4397- if (!HASTZINFO (dt ) || dt -> tzinfo != (PyObject * )self ) {
4402+
4403+ PyDateTime_DateTime * dt = (PyDateTime_DateTime * )arg ; // fast safe cast
4404+ if (!HASTZINFO (dt ) || dt -> tzinfo != op ) {
43984405 PyErr_SetString (PyExc_ValueError , "fromutc: dt.tzinfo "
43994406 "is not self" );
44004407 return NULL ;
44014408 }
44024409
4410+ PyDateTime_TimeZone * self = _PyTimeZone_CAST (op );
44034411 return add_datetime_timedelta (dt , (PyDateTime_Delta * )self -> offset , 1 );
44044412}
44054413
44064414static PyObject *
4407- timezone_getinitargs (PyDateTime_TimeZone * self , PyObject * Py_UNUSED (ignored ))
4415+ timezone_getinitargs (PyObject * op , PyObject * Py_UNUSED (ignored ))
44084416{
4417+ PyDateTime_TimeZone * self = _PyTimeZone_CAST (op );
44094418 if (self -> name == NULL )
44104419 return PyTuple_Pack (1 , self -> offset );
44114420 return PyTuple_Pack (2 , self -> offset , self -> name );
44124421}
44134422
44144423static PyMethodDef timezone_methods [] = {
4415- {"tzname" , ( PyCFunction ) timezone_tzname , METH_O ,
4424+ {"tzname" , timezone_tzname , METH_O ,
44164425 PyDoc_STR ("If name is specified when timezone is created, returns the name."
44174426 " Otherwise returns offset as 'UTC(+|-)HH:MM'." )},
44184427
4419- {"utcoffset" , ( PyCFunction ) timezone_utcoffset , METH_O ,
4428+ {"utcoffset" , timezone_utcoffset , METH_O ,
44204429 PyDoc_STR ("Return fixed offset." )},
44214430
4422- {"dst" , ( PyCFunction ) timezone_dst , METH_O ,
4431+ {"dst" , timezone_dst , METH_O ,
44234432 PyDoc_STR ("Return None." )},
44244433
4425- {"fromutc" , ( PyCFunction ) timezone_fromutc , METH_O ,
4434+ {"fromutc" , timezone_fromutc , METH_O ,
44264435 PyDoc_STR ("datetime in UTC -> datetime in local time." )},
44274436
4428- {"__getinitargs__" , ( PyCFunction ) timezone_getinitargs , METH_NOARGS ,
4437+ {"__getinitargs__" , timezone_getinitargs , METH_NOARGS ,
44294438 PyDoc_STR ("pickle support" )},
44304439
44314440 {NULL , NULL }
@@ -4439,26 +4448,26 @@ static PyTypeObject PyDateTime_TimeZoneType = {
44394448 "datetime.timezone" , /* tp_name */
44404449 sizeof (PyDateTime_TimeZone ), /* tp_basicsize */
44414450 0 , /* tp_itemsize */
4442- ( destructor ) timezone_dealloc , /* tp_dealloc */
4451+ timezone_dealloc , /* tp_dealloc */
44434452 0 , /* tp_vectorcall_offset */
44444453 0 , /* tp_getattr */
44454454 0 , /* tp_setattr */
44464455 0 , /* tp_as_async */
4447- ( reprfunc ) timezone_repr , /* tp_repr */
4456+ timezone_repr , /* tp_repr */
44484457 0 , /* tp_as_number */
44494458 0 , /* tp_as_sequence */
44504459 0 , /* tp_as_mapping */
4451- ( hashfunc ) timezone_hash , /* tp_hash */
4460+ timezone_hash , /* tp_hash */
44524461 0 , /* tp_call */
4453- ( reprfunc ) timezone_str , /* tp_str */
4462+ timezone_str , /* tp_str */
44544463 0 , /* tp_getattro */
44554464 0 , /* tp_setattro */
44564465 0 , /* tp_as_buffer */
44574466 Py_TPFLAGS_DEFAULT , /* tp_flags */
44584467 timezone_doc , /* tp_doc */
44594468 0 , /* tp_traverse */
44604469 0 , /* tp_clear */
4461- ( richcmpfunc ) timezone_richcompare ,/* tp_richcompare */
4470+ timezone_richcompare , /* tp_richcompare */
44624471 0 , /* tp_weaklistoffset */
44634472 0 , /* tp_iter */
44644473 0 , /* tp_iternext */
0 commit comments