@@ -97,13 +97,12 @@ typedef struct {
97
97
PyObject * TIMEDELTA_CACHE ;
98
98
PyObject * ZONEINFO_WEAK_CACHE ;
99
99
StrongCacheNode * ZONEINFO_STRONG_CACHE ;
100
+ _ttinfo NO_TTINFO ;
100
101
} zoneinfo_state ;
101
102
102
103
// Globals
103
104
static zoneinfo_state global_state ;
104
105
105
- static _ttinfo NO_TTINFO = {NULL , NULL , NULL , 0 };
106
-
107
106
// Constants
108
107
static const int EPOCHORDINAL = 719163 ;
109
108
static int DAYS_IN_MONTH [] = {
@@ -173,7 +172,7 @@ load_timedelta(zoneinfo_state *state, long seconds);
173
172
static int
174
173
get_local_timestamp (PyObject * dt , int64_t * local_ts );
175
174
static _ttinfo *
176
- find_ttinfo (PyZoneInfo_ZoneInfo * self , PyObject * dt );
175
+ find_ttinfo (zoneinfo_state * state , PyZoneInfo_ZoneInfo * self , PyObject * dt );
177
176
178
177
static int
179
178
ymd_to_ord (int y , int m , int d );
@@ -533,32 +532,70 @@ zoneinfo_ZoneInfo_clear_cache_impl(PyTypeObject *type, PyTypeObject *cls,
533
532
Py_RETURN_NONE ;
534
533
}
535
534
535
+ /*[clinic input]
536
+ zoneinfo.ZoneInfo.utcoffset
537
+
538
+ cls: defining_class
539
+ dt: object
540
+ /
541
+
542
+ Retrieve a timedelta representing the UTC offset in a zone at the given datetime.
543
+ [clinic start generated code]*/
544
+
536
545
static PyObject *
537
- zoneinfo_utcoffset (PyObject * self , PyObject * dt )
546
+ zoneinfo_ZoneInfo_utcoffset_impl (PyObject * self , PyTypeObject * cls ,
547
+ PyObject * dt )
548
+ /*[clinic end generated code: output=b71016c319ba1f91 input=2bb6c5364938f19c]*/
538
549
{
539
- _ttinfo * tti = find_ttinfo ((PyZoneInfo_ZoneInfo * )self , dt );
550
+ zoneinfo_state * state = zoneinfo_get_state_by_cls (cls );
551
+ _ttinfo * tti = find_ttinfo (state , (PyZoneInfo_ZoneInfo * )self , dt );
540
552
if (tti == NULL ) {
541
553
return NULL ;
542
554
}
543
555
Py_INCREF (tti -> utcoff );
544
556
return tti -> utcoff ;
545
557
}
546
558
559
+ /*[clinic input]
560
+ zoneinfo.ZoneInfo.dst
561
+
562
+ cls: defining_class
563
+ dt: object
564
+ /
565
+
566
+ Retrieve a timedelta representing the amount of DST applied in a zone at the given datetime.
567
+ [clinic start generated code]*/
568
+
547
569
static PyObject *
548
- zoneinfo_dst (PyObject * self , PyObject * dt )
570
+ zoneinfo_ZoneInfo_dst_impl (PyObject * self , PyTypeObject * cls , PyObject * dt )
571
+ /*[clinic end generated code: output=cb6168d7723a6ae6 input=2167fb80cf8645c6]*/
549
572
{
550
- _ttinfo * tti = find_ttinfo ((PyZoneInfo_ZoneInfo * )self , dt );
573
+ zoneinfo_state * state = zoneinfo_get_state_by_cls (cls );
574
+ _ttinfo * tti = find_ttinfo (state , (PyZoneInfo_ZoneInfo * )self , dt );
551
575
if (tti == NULL ) {
552
576
return NULL ;
553
577
}
554
578
Py_INCREF (tti -> dstoff );
555
579
return tti -> dstoff ;
556
580
}
557
581
582
+ /*[clinic input]
583
+ zoneinfo.ZoneInfo.tzname
584
+
585
+ cls: defining_class
586
+ dt: object
587
+ /
588
+
589
+ Retrieve a string containing the abbreviation for the time zone that applies in a zone at a given datetime.
590
+ [clinic start generated code]*/
591
+
558
592
static PyObject *
559
- zoneinfo_tzname (PyObject * self , PyObject * dt )
593
+ zoneinfo_ZoneInfo_tzname_impl (PyObject * self , PyTypeObject * cls ,
594
+ PyObject * dt )
595
+ /*[clinic end generated code: output=3b6ae6c3053ea75a input=15a59a4f92ed1f1f]*/
560
596
{
561
- _ttinfo * tti = find_ttinfo ((PyZoneInfo_ZoneInfo * )self , dt );
597
+ zoneinfo_state * state = zoneinfo_get_state_by_cls (cls );
598
+ _ttinfo * tti = find_ttinfo (state , (PyZoneInfo_ZoneInfo * )self , dt );
562
599
if (tti == NULL ) {
563
600
return NULL ;
564
601
}
@@ -2213,7 +2250,7 @@ _bisect(const int64_t value, const int64_t *arr, size_t size)
2213
2250
2214
2251
/* Find the ttinfo rules that apply at a given local datetime. */
2215
2252
static _ttinfo *
2216
- find_ttinfo (PyZoneInfo_ZoneInfo * self , PyObject * dt )
2253
+ find_ttinfo (zoneinfo_state * state , PyZoneInfo_ZoneInfo * self , PyObject * dt )
2217
2254
{
2218
2255
// datetime.time has a .tzinfo attribute that passes None as the dt
2219
2256
// argument; it only really has meaning for fixed-offset zones.
@@ -2222,7 +2259,7 @@ find_ttinfo(PyZoneInfo_ZoneInfo *self, PyObject *dt)
2222
2259
return & (self -> tzrule_after .std );
2223
2260
}
2224
2261
else {
2225
- return & NO_TTINFO ;
2262
+ return & ( state -> NO_TTINFO ) ;
2226
2263
}
2227
2264
}
2228
2265
@@ -2644,15 +2681,9 @@ static PyMethodDef zoneinfo_methods[] = {
2644
2681
ZONEINFO_ZONEINFO_CLEAR_CACHE_METHODDEF
2645
2682
ZONEINFO_ZONEINFO_NO_CACHE_METHODDEF
2646
2683
ZONEINFO_ZONEINFO_FROM_FILE_METHODDEF
2647
- {"utcoffset" , (PyCFunction )zoneinfo_utcoffset , METH_O ,
2648
- PyDoc_STR ("Retrieve a timedelta representing the UTC offset in a zone at "
2649
- "the given datetime." )},
2650
- {"dst" , (PyCFunction )zoneinfo_dst , METH_O ,
2651
- PyDoc_STR ("Retrieve a timedelta representing the amount of DST applied "
2652
- "in a zone at the given datetime." )},
2653
- {"tzname" , (PyCFunction )zoneinfo_tzname , METH_O ,
2654
- PyDoc_STR ("Retrieve a string containing the abbreviation for the time "
2655
- "zone that applies in a zone at a given datetime." )},
2684
+ ZONEINFO_ZONEINFO_UTCOFFSET_METHODDEF
2685
+ ZONEINFO_ZONEINFO_DST_METHODDEF
2686
+ ZONEINFO_ZONEINFO_TZNAME_METHODDEF
2656
2687
{"fromutc" , (PyCFunction )zoneinfo_fromutc , METH_O ,
2657
2688
PyDoc_STR ("Given a datetime with local time in UTC, retrieve an adjusted "
2658
2689
"datetime in local time." )},
@@ -2711,7 +2742,7 @@ module_free(void *m)
2711
2742
Py_CLEAR (state -> _tzpath_find_tzfile );
2712
2743
Py_CLEAR (state -> _common_mod );
2713
2744
2714
- xdecref_ttinfo (& NO_TTINFO );
2745
+ xdecref_ttinfo (& ( state -> NO_TTINFO ) );
2715
2746
2716
2747
if (state -> TIMEDELTA_CACHE != NULL &&
2717
2748
Py_REFCNT (state -> TIMEDELTA_CACHE ) > 1 )
@@ -2773,14 +2804,10 @@ zoneinfomodule_exec(PyObject *m)
2773
2804
goto error ;
2774
2805
}
2775
2806
2776
- if (NO_TTINFO .utcoff == NULL ) {
2777
- NO_TTINFO .utcoff = Py_None ;
2778
- NO_TTINFO .dstoff = Py_None ;
2779
- NO_TTINFO .tzname = Py_None ;
2780
-
2781
- for (size_t i = 0 ; i < 3 ; ++ i ) {
2782
- Py_INCREF (Py_None );
2783
- }
2807
+ if (state -> NO_TTINFO .utcoff == NULL ) {
2808
+ state -> NO_TTINFO .utcoff = Py_NewRef (Py_None );
2809
+ state -> NO_TTINFO .dstoff = Py_NewRef (Py_None );
2810
+ state -> NO_TTINFO .tzname = Py_NewRef (Py_None );
2784
2811
}
2785
2812
2786
2813
if (initialize_caches (state )) {
0 commit comments