Skip to content

Commit c1f6a75

Browse files
committed
date.fromisocalendar() with converter
1 parent b21bded commit c1f6a75

File tree

1 file changed

+41
-20
lines changed

1 file changed

+41
-20
lines changed

Modules/_datetimemodule.c

Lines changed: 41 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,8 @@ class datetime.timezone "PyDateTime_TimeZone *" "clinic_state()->PyDateTime_Time
209209
[clinic start generated code]*/
210210
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=c941b310de347082]*/
211211

212+
static int calendar_int_converter(PyObject* arg, int *value);
213+
212214
#define clinic_state() (get_module_state_by_cls(defcls))
213215
#include "clinic/_datetimemodule.c.h"
214216
#undef clinic_state
@@ -3232,26 +3234,50 @@ datetime_date_fromisoformat_impl(PyObject *cls, PyTypeObject *defcls,
32323234
return NULL;
32333235
}
32343236

3235-
3236-
static PyObject *
3237-
date_fromisocalendar(PyObject *cls, PyObject *args, PyObject *kw)
3237+
static int
3238+
calendar_int_converter(PyObject* arg, int *value)
32383239
{
3239-
static char *keywords[] = {
3240-
"year", "week", "day", NULL
3241-
};
3242-
3243-
int year, week, day;
3244-
if (PyArg_ParseTupleAndKeywords(args, kw, "iii:fromisocalendar",
3245-
keywords,
3246-
&year, &week, &day) == 0) {
3240+
int face_value = PyLong_AsInt(arg);
3241+
if (face_value == -1 && PyErr_Occurred()) {
32473242
if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
32483243
PyErr_Format(PyExc_ValueError,
32493244
"ISO calendar component out of range");
3250-
32513245
}
3252-
return NULL;
3246+
*value = -1;
3247+
return 0;
32533248
}
3249+
*value = face_value;
3250+
return 1;
3251+
}
32543252

3253+
/*[python input]
3254+
class calendar_int_converter(CConverter):
3255+
type = 'int'
3256+
converter = 'calendar_int_converter'
3257+
[python start generated code]*/
3258+
/*[python end generated code: output=da39a3ee5e6b4b0d input=62a8ae38ff2c9c0b]*/
3259+
3260+
3261+
/*[clinic input]
3262+
@classmethod
3263+
datetime.date.fromisocalendar
3264+
3265+
cls: self(type="PyObject *")
3266+
defcls: defining_class
3267+
year: calendar_int
3268+
week: calendar_int
3269+
day: calendar_int
3270+
3271+
int, int, int -> Construct a date from the ISO year, week number and weekday.
3272+
3273+
This is the inverse of the date.isocalendar() function.
3274+
[clinic start generated code]*/
3275+
3276+
static PyObject *
3277+
datetime_date_fromisocalendar_impl(PyObject *cls, PyTypeObject *defcls,
3278+
int year, int week, int day)
3279+
/*[clinic end generated code: output=bcf68c1effd051aa input=44ba1ccacefc1617]*/
3280+
{
32553281
int month;
32563282
int rv = iso_to_ymd(year, week, day, &year, &month, &day);
32573283

@@ -3270,7 +3296,7 @@ date_fromisocalendar(PyObject *cls, PyObject *args, PyObject *kw)
32703296
day);
32713297
return NULL;
32723298
}
3273-
datetime_state *st = find_module_state_by_def(cls);
3299+
datetime_state *st = get_module_state_by_cls(defcls);
32743300
return new_date_subclass_ex(st, year, month, day, cls);
32753301
}
32763302

@@ -3744,12 +3770,7 @@ static PyMethodDef date_methods[] = {
37443770
DATETIME_DATE_FROMTIMESTAMP_METHODDEF
37453771
DATETIME_DATE_FROMORDINAL_METHODDEF
37463772
DATETIME_DATE_FROMISOFORMAT_METHODDEF
3747-
3748-
{"fromisocalendar", _PyCFunction_CAST(date_fromisocalendar),
3749-
METH_VARARGS | METH_KEYWORDS | METH_CLASS,
3750-
PyDoc_STR("int, int, int -> Construct a date from the ISO year, week "
3751-
"number and weekday.\n\n"
3752-
"This is the inverse of the date.isocalendar() function")},
3773+
DATETIME_DATE_FROMISOCALENDAR_METHODDEF
37533774

37543775
{"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
37553776
PyDoc_STR("Current date or datetime: same as "

0 commit comments

Comments
 (0)