@@ -1027,6 +1027,40 @@ new_datetime_ex(int year, int month, int day, int hour, int minute,
1027
1027
new_datetime_ex2(y, m, d, hh, mm, ss, us, tzinfo, fold, \
1028
1028
&PyDateTime_DateTimeType)
1029
1029
1030
+ static PyObject *
1031
+ call_subclass_fold (PyObject * cls , int fold , const char * format , ...)
1032
+ {
1033
+ PyObject * kwargs = NULL , * res = NULL ;
1034
+ va_list va ;
1035
+
1036
+ va_start (va , format );
1037
+ PyObject * args = Py_VaBuildValue (format , va );
1038
+ va_end (va );
1039
+ if (args == NULL ) {
1040
+ return NULL ;
1041
+ }
1042
+ if (fold ) {
1043
+ kwargs = PyDict_New ();
1044
+ if (kwargs == NULL ) {
1045
+ goto Done ;
1046
+ }
1047
+ PyObject * obj = PyLong_FromLong (fold );
1048
+ if (obj == NULL ) {
1049
+ goto Done ;
1050
+ }
1051
+ int err = PyDict_SetItemString (kwargs , "fold" , obj );
1052
+ Py_DECREF (obj );
1053
+ if (err < 0 ) {
1054
+ goto Done ;
1055
+ }
1056
+ }
1057
+ res = PyObject_Call (cls , args , kwargs );
1058
+ Done :
1059
+ Py_DECREF (args );
1060
+ Py_XDECREF (kwargs );
1061
+ return res ;
1062
+ }
1063
+
1030
1064
static PyObject *
1031
1065
new_datetime_subclass_fold_ex (int year , int month , int day , int hour , int minute ,
1032
1066
int second , int usecond , PyObject * tzinfo ,
@@ -1036,17 +1070,11 @@ new_datetime_subclass_fold_ex(int year, int month, int day, int hour, int minute
1036
1070
// Use the fast path constructor
1037
1071
dt = new_datetime (year , month , day , hour , minute , second , usecond ,
1038
1072
tzinfo , fold );
1039
- } else {
1073
+ }
1074
+ else {
1040
1075
// Subclass
1041
- dt = PyObject_CallFunction (cls , "iiiiiiiO" ,
1042
- year ,
1043
- month ,
1044
- day ,
1045
- hour ,
1046
- minute ,
1047
- second ,
1048
- usecond ,
1049
- tzinfo );
1076
+ dt = call_subclass_fold (cls , fold , "iiiiiiiO" , year , month , day ,
1077
+ hour , minute , second , usecond , tzinfo );
1050
1078
}
1051
1079
1052
1080
return dt ;
@@ -1102,6 +1130,24 @@ new_time_ex(int hour, int minute, int second, int usecond,
1102
1130
#define new_time (hh , mm , ss , us , tzinfo , fold ) \
1103
1131
new_time_ex2(hh, mm, ss, us, tzinfo, fold, &PyDateTime_TimeType)
1104
1132
1133
+ static PyObject *
1134
+ new_time_subclass_fold_ex (int hour , int minute , int second , int usecond ,
1135
+ PyObject * tzinfo , int fold , PyObject * cls )
1136
+ {
1137
+ PyObject * t ;
1138
+ if ((PyTypeObject * )cls == & PyDateTime_TimeType ) {
1139
+ // Use the fast path constructor
1140
+ t = new_time (hour , minute , second , usecond , tzinfo , fold );
1141
+ }
1142
+ else {
1143
+ // Subclass
1144
+ t = call_subclass_fold (cls , fold , "iiiiO" , hour , minute , second ,
1145
+ usecond , tzinfo );
1146
+ }
1147
+
1148
+ return t ;
1149
+ }
1150
+
1105
1151
/* Create a timedelta instance. Normalize the members iff normalize is
1106
1152
* true. Passing false is a speed optimization, if you know for sure
1107
1153
* that seconds and microseconds are already in their proper ranges. In any
@@ -3430,21 +3476,14 @@ date_timetuple(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
3430
3476
static PyObject *
3431
3477
date_replace (PyDateTime_Date * self , PyObject * args , PyObject * kw )
3432
3478
{
3433
- PyObject * clone ;
3434
- PyObject * tuple ;
3435
3479
int year = GET_YEAR (self );
3436
3480
int month = GET_MONTH (self );
3437
3481
int day = GET_DAY (self );
3438
3482
3439
3483
if (! PyArg_ParseTupleAndKeywords (args , kw , "|iii:replace" , date_kws ,
3440
3484
& year , & month , & day ))
3441
3485
return NULL ;
3442
- tuple = Py_BuildValue ("iii" , year , month , day );
3443
- if (tuple == NULL )
3444
- return NULL ;
3445
- clone = date_new (Py_TYPE (self ), tuple , NULL );
3446
- Py_DECREF (tuple );
3447
- return clone ;
3486
+ return new_date_subclass_ex (year , month , day , (PyObject * )Py_TYPE (self ));
3448
3487
}
3449
3488
3450
3489
static Py_hash_t
@@ -4533,8 +4572,6 @@ time_hash(PyDateTime_Time *self)
4533
4572
static PyObject *
4534
4573
time_replace (PyDateTime_Time * self , PyObject * args , PyObject * kw )
4535
4574
{
4536
- PyObject * clone ;
4537
- PyObject * tuple ;
4538
4575
int hh = TIME_GET_HOUR (self );
4539
4576
int mm = TIME_GET_MINUTE (self );
4540
4577
int ss = TIME_GET_SECOND (self );
@@ -4551,15 +4588,8 @@ time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
4551
4588
"fold must be either 0 or 1" );
4552
4589
return NULL ;
4553
4590
}
4554
- tuple = Py_BuildValue ("iiiiO" , hh , mm , ss , us , tzinfo );
4555
- if (tuple == NULL )
4556
- return NULL ;
4557
- clone = time_new (Py_TYPE (self ), tuple , NULL );
4558
- if (clone != NULL ) {
4559
- TIME_SET_FOLD (clone , fold );
4560
- }
4561
- Py_DECREF (tuple );
4562
- return clone ;
4591
+ return new_time_subclass_fold_ex (hh , mm , ss , us , tzinfo , fold ,
4592
+ (PyObject * )Py_TYPE (self ));
4563
4593
}
4564
4594
4565
4595
static PyObject *
@@ -6003,8 +6033,6 @@ datetime_hash(PyDateTime_DateTime *self)
6003
6033
static PyObject *
6004
6034
datetime_replace (PyDateTime_DateTime * self , PyObject * args , PyObject * kw )
6005
6035
{
6006
- PyObject * clone ;
6007
- PyObject * tuple ;
6008
6036
int y = GET_YEAR (self );
6009
6037
int m = GET_MONTH (self );
6010
6038
int d = GET_DAY (self );
@@ -6025,15 +6053,8 @@ datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
6025
6053
"fold must be either 0 or 1" );
6026
6054
return NULL ;
6027
6055
}
6028
- tuple = Py_BuildValue ("iiiiiiiO" , y , m , d , hh , mm , ss , us , tzinfo );
6029
- if (tuple == NULL )
6030
- return NULL ;
6031
- clone = datetime_new (Py_TYPE (self ), tuple , NULL );
6032
- if (clone != NULL ) {
6033
- DATE_SET_FOLD (clone , fold );
6034
- }
6035
- Py_DECREF (tuple );
6036
- return clone ;
6056
+ return new_datetime_subclass_fold_ex (y , m , d , hh , mm , ss , us , tzinfo , fold ,
6057
+ (PyObject * )Py_TYPE (self ));
6037
6058
}
6038
6059
6039
6060
static PyObject *
0 commit comments