@@ -847,6 +847,27 @@ new_date_ex(int year, int month, int day, PyTypeObject *type)
847
847
#define new_date (year , month , day ) \
848
848
new_date_ex(year, month, day, &PyDateTime_DateType)
849
849
850
+ // Forward declaration
851
+ static PyObject * new_datetime_ex (int , int , int , int , int , int , int ,
852
+ PyObject * , PyTypeObject * );
853
+
854
+ /* Create date instance with no range checking, or call subclass constructor */
855
+ static PyObject *
856
+ new_date_subclass_ex (int year , int month , int day , PyObject * cls ) {
857
+ PyObject * result ;
858
+ // We have "fast path" constructors for two subclasses: date and datetime
859
+ if ((PyTypeObject * )cls == & PyDateTime_DateType ) {
860
+ result = new_date_ex (year , month , day , (PyTypeObject * )cls );
861
+ } else if ((PyTypeObject * )cls == & PyDateTime_DateTimeType ) {
862
+ result = new_datetime_ex (year , month , day , 0 , 0 , 0 , 0 , Py_None ,
863
+ (PyTypeObject * )cls );
864
+ } else {
865
+ result = PyObject_CallFunction (cls , "iii" , year , month , day );
866
+ }
867
+
868
+ return result ;
869
+ }
870
+
850
871
/* Create a datetime instance with no range checking. */
851
872
static PyObject *
852
873
new_datetime_ex2 (int year , int month , int day , int hour , int minute ,
@@ -894,6 +915,40 @@ new_datetime_ex(int year, int month, int day, int hour, int minute,
894
915
new_datetime_ex2(y, m, d, hh, mm, ss, us, tzinfo, fold, \
895
916
&PyDateTime_DateTimeType)
896
917
918
+ static PyObject *
919
+ new_datetime_subclass_fold_ex (int year , int month , int day , int hour , int minute ,
920
+ int second , int usecond , PyObject * tzinfo ,
921
+ int fold , PyObject * cls ) {
922
+ PyObject * dt ;
923
+ if ((PyTypeObject * )cls == & PyDateTime_DateTimeType ) {
924
+ // Use the fast path constructor
925
+ dt = new_datetime (year , month , day , hour , minute , second , usecond ,
926
+ tzinfo , fold );
927
+ } else {
928
+ // Subclass
929
+ dt = PyObject_CallFunction (cls , "iiiiiiiO" ,
930
+ year ,
931
+ month ,
932
+ day ,
933
+ hour ,
934
+ minute ,
935
+ second ,
936
+ usecond ,
937
+ tzinfo );
938
+ }
939
+
940
+ return dt ;
941
+ }
942
+
943
+ static PyObject *
944
+ new_datetime_subclass_ex (int year , int month , int day , int hour , int minute ,
945
+ int second , int usecond , PyObject * tzinfo ,
946
+ PyObject * cls ) {
947
+ return new_datetime_subclass_fold_ex (year , month , day , hour , minute ,
948
+ second , usecond , tzinfo , 0 ,
949
+ cls );
950
+ }
951
+
897
952
/* Create a time instance with no range checking. */
898
953
static PyObject *
899
954
new_time_ex2 (int hour , int minute , int second , int usecond ,
@@ -2743,10 +2798,10 @@ date_local_from_object(PyObject *cls, PyObject *obj)
2743
2798
if (_PyTime_localtime (t , & tm ) != 0 )
2744
2799
return NULL ;
2745
2800
2746
- return PyObject_CallFunction ( cls , "iii" ,
2747
- tm .tm_year + 1900 ,
2748
- tm .tm_mon + 1 ,
2749
- tm . tm_mday );
2801
+ return new_date_subclass_ex ( tm . tm_year + 1900 ,
2802
+ tm .tm_mon + 1 ,
2803
+ tm .tm_mday ,
2804
+ cls );
2750
2805
}
2751
2806
2752
2807
/* Return new date from current time.
@@ -2809,8 +2864,7 @@ date_fromordinal(PyObject *cls, PyObject *args)
2809
2864
">= 1" );
2810
2865
else {
2811
2866
ord_to_ymd (ordinal , & year , & month , & day );
2812
- result = PyObject_CallFunction (cls , "iii" ,
2813
- year , month , day );
2867
+ result = new_date_subclass_ex (year , month , day , cls );
2814
2868
}
2815
2869
}
2816
2870
return result ;
@@ -2845,14 +2899,7 @@ date_fromisoformat(PyObject *cls, PyObject *dtstr) {
2845
2899
return NULL ;
2846
2900
}
2847
2901
2848
- PyObject * result ;
2849
- if ( (PyTypeObject * )cls == & PyDateTime_DateType ) {
2850
- result = new_date_ex (year , month , day , (PyTypeObject * )cls );
2851
- } else {
2852
- result = PyObject_CallFunction (cls , "iii" , year , month , day );
2853
- }
2854
-
2855
- return result ;
2902
+ return new_date_subclass_ex (year , month , day , cls );
2856
2903
}
2857
2904
2858
2905
@@ -4596,9 +4643,8 @@ datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
4596
4643
fold = 1 ;
4597
4644
}
4598
4645
}
4599
- return new_datetime_ex2 (year , month , day , hour ,
4600
- minute , second , us , tzinfo , fold ,
4601
- (PyTypeObject * )cls );
4646
+ return new_datetime_subclass_fold_ex (year , month , day , hour , minute ,
4647
+ second , us , tzinfo , fold , cls );
4602
4648
}
4603
4649
4604
4650
/* Internal helper.
@@ -4764,17 +4810,16 @@ datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
4764
4810
else
4765
4811
tzinfo = Py_None ;
4766
4812
}
4767
- result = PyObject_CallFunction (cls , "iiiiiiiO" ,
4768
- GET_YEAR (date ),
4769
- GET_MONTH (date ),
4770
- GET_DAY (date ),
4771
- TIME_GET_HOUR (time ),
4772
- TIME_GET_MINUTE (time ),
4773
- TIME_GET_SECOND (time ),
4774
- TIME_GET_MICROSECOND (time ),
4775
- tzinfo );
4776
- if (result )
4777
- DATE_SET_FOLD (result , TIME_GET_FOLD (time ));
4813
+ result = new_datetime_subclass_fold_ex (GET_YEAR (date ),
4814
+ GET_MONTH (date ),
4815
+ GET_DAY (date ),
4816
+ TIME_GET_HOUR (time ),
4817
+ TIME_GET_MINUTE (time ),
4818
+ TIME_GET_SECOND (time ),
4819
+ TIME_GET_MICROSECOND (time ),
4820
+ tzinfo ,
4821
+ TIME_GET_FOLD (time ),
4822
+ cls );
4778
4823
}
4779
4824
return result ;
4780
4825
}
@@ -4832,23 +4877,8 @@ datetime_fromisoformat(PyObject* cls, PyObject *dtstr) {
4832
4877
return NULL ;
4833
4878
}
4834
4879
4835
- PyObject * dt ;
4836
- if ( (PyTypeObject * )cls == & PyDateTime_DateTimeType ) {
4837
- // Use the fast path constructor
4838
- dt = new_datetime (year , month , day , hour , minute , second , microsecond ,
4839
- tzinfo , 0 );
4840
- } else {
4841
- // Subclass
4842
- dt = PyObject_CallFunction (cls , "iiiiiiiO" ,
4843
- year ,
4844
- month ,
4845
- day ,
4846
- hour ,
4847
- minute ,
4848
- second ,
4849
- microsecond ,
4850
- tzinfo );
4851
- }
4880
+ PyObject * dt = new_datetime_subclass_ex (year , month , day , hour , minute ,
4881
+ second , microsecond , tzinfo , cls );
4852
4882
4853
4883
Py_DECREF (tzinfo );
4854
4884
return dt ;
0 commit comments