Skip to content

Commit 2ff8cc5

Browse files
committed
pythongh-120713: streamlined C code with better error handling
1 parent 0f8886d commit 2ff8cc5

File tree

1 file changed

+24
-15
lines changed

1 file changed

+24
-15
lines changed

Modules/_datetimemodule.c

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
#include "datetime.h"
2020

2121

22-
#include <stdlib.h>
2322
#include <time.h>
2423

2524
#ifdef MS_WINDOWS
@@ -1833,14 +1832,16 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
18331832
PyObject *tzinfoarg)
18341833
{
18351834
PyObject *result = NULL; /* guilty until proved innocent */
1835+
PyObject *strftime = NULL; /* time.strftime */
18361836

18371837
PyObject *zreplacement = NULL; /* py string, replacement for %z */
18381838
PyObject *colonzreplacement = NULL; /* py string, replacement for %:z */
18391839
PyObject *Zreplacement = NULL; /* py string, replacement for %Z */
18401840
PyObject *freplacement = NULL; /* py string, replacement for %f */
18411841
#ifdef NORMALIZE_CENTURY
1842-
long year; /* year of timetuple as long */
1843-
char year_formatted[12]; /* formatted year with century for %Y */
1842+
PyObject *year; /* year of timetuple */
1843+
long year_long; /* year of timetuple as long int */
1844+
char year_formatted[12]; /* formatted year with century for %Y/G */
18441845
#endif
18451846

18461847
const char *pin; /* pointer to next char in input format */
@@ -1878,10 +1879,10 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
18781879
pnew = PyBytes_AsString(newfmt);
18791880
usednew = 0;
18801881

1881-
PyObject *strftime = _PyImport_GetModuleAttrString("time", "strftime");
1882-
1883-
if (strftime == NULL)
1882+
strftime = _PyImport_GetModuleAttrString("time", "strftime");
1883+
if (strftime == NULL) {
18841884
goto Done;
1885+
}
18851886

18861887
while ((ch = *pin++) != '\0') {
18871888
if (ch != '%') {
@@ -1953,15 +1954,23 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
19531954
else if (ch == 'Y' || ch == 'G') {
19541955
/* 0-pad year with century as necessary */
19551956
if (ch == 'G') {
1956-
format = PyUnicode_FromString("%G");
1957-
result = PyObject_CallFunctionObjArgs(strftime, format,
1958-
timetuple, NULL);
1959-
year = atoi(PyUnicode_AsUTF8(result));
1960-
Py_DECREF(format);
1957+
result = PyObject_CallFunction(strftime, "sO", "%G", timetuple);
1958+
if (result == NULL) {
1959+
goto Done;
1960+
}
1961+
year = PyNumber_Long(result);
1962+
if (year == NULL) {
1963+
goto Done;
1964+
}
19611965
Py_DECREF(result);
1962-
} else
1963-
year = PyLong_AsLong(PyTuple_GET_ITEM(timetuple, 0));
1964-
ntoappend = sprintf(year_formatted, "%04ld", year);
1966+
} else {
1967+
year = PyTuple_GET_ITEM(timetuple, 0);
1968+
}
1969+
year_long = PyLong_AsLong(year);
1970+
if (year_long == -1 && PyErr_Occurred() != NULL) {
1971+
goto Done;
1972+
}
1973+
ntoappend = sprintf(year_formatted, "%04ld", year_long);
19651974
ptoappend = year_formatted;
19661975
}
19671976
#endif
@@ -2005,14 +2014,14 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
20052014
format, timetuple, NULL);
20062015
Py_DECREF(format);
20072016
}
2008-
Py_DECREF(strftime);
20092017
}
20102018
Done:
20112019
Py_XDECREF(freplacement);
20122020
Py_XDECREF(zreplacement);
20132021
Py_XDECREF(colonzreplacement);
20142022
Py_XDECREF(Zreplacement);
20152023
Py_XDECREF(newfmt);
2024+
Py_XDECREF(strftime);
20162025
return result;
20172026
}
20182027

0 commit comments

Comments
 (0)