Skip to content

Commit 8d16901

Browse files
author
marat
committed
Refactor make_dash_replacement func and add negative test
1 parent 2f6c0ce commit 8d16901

File tree

4 files changed

+33
-23
lines changed

4 files changed

+33
-23
lines changed

Lib/test/datetimetester.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1592,10 +1592,9 @@ def test_strftime(self):
15921592
# SF bug #137165
15931593
if platform.system() == 'Darwin':
15941594
self.assertEqual(t.strftime("m:%-m d:%-d y:%-y"), "m:3 d:2 y:05")
1595-
elif platform.system() == 'Windows':
1596-
self.assertEqual(t.strftime("m:%#m d:%#d y:%#y"), "m:3 d:2 y:5")
1597-
self.assertEqual(t.strftime("m:%-m d:%-d y:%-y"), "m:3 d:2 y:5")
15981595
else:
1596+
if platform.system() == 'Windows':
1597+
self.assertEqual(t.strftime("m:%#m d:%#d y:%#y"), "m:3 d:2 y:5")
15991598
self.assertEqual(t.strftime("m:%-m d:%-d y:%-y"), "m:3 d:2 y:5")
16001599

16011600
self.assertRaises(TypeError, t.strftime) # needs an arg

Misc/NEWS.d/next/Library/2025-09-16-15-36-18.gh-issue-137165.AclPcn.rst

Lines changed: 0 additions & 2 deletions
This file was deleted.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Standardized non-zero-padded date formatting in
2+
:func:`datetime.datetime.strftime` and :func:`datetime.date.strftime` across
3+
Windows and Unix. (e.g. ``"m:%-m d:%-d y:%-y"``).

Modules/_datetimemodule.c

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1860,32 +1860,42 @@ make_freplacement(PyObject *object)
18601860
static PyObject *
18611861
make_dash_replacement(PyObject *object, Py_UCS4 ch, PyObject *timetuple)
18621862
{
1863-
PyObject *strftime = PyImport_ImportModuleAttrString("time", "strftime");
1864-
if (!strftime) {
1865-
return NULL;
1863+
PyObject *strftime = NULL;
1864+
PyObject *fmt_obj = NULL;
1865+
PyObject *res = NULL;
1866+
PyObject *stripped = NULL;
1867+
1868+
strftime = PyImport_ImportModuleAttrString("time", "strftime");
1869+
if (strftime == NULL) {
1870+
goto error;
18661871
}
18671872

1868-
char fmt[3] = {'%', (char)ch, 0};
1869-
PyObject *fmt_obj = PyUnicode_FromString(fmt);
1870-
if (!fmt_obj) {
1871-
Py_DECREF(strftime);
1872-
return NULL;
1873+
fmt_obj = PyUnicode_FromFormat("%%%c", (char)ch);
1874+
if (fmt_obj == NULL) {
1875+
goto error;
18731876
}
18741877

1875-
PyObject *res = PyObject_CallFunctionObjArgs(strftime, fmt_obj, timetuple, NULL);
1876-
Py_DECREF(fmt_obj);
1877-
Py_DECREF(strftime);
1878-
if (!res) {
1879-
return NULL;
1878+
res = PyObject_CallFunctionObjArgs(strftime, fmt_obj, timetuple, NULL);
1879+
if (res == NULL) {
1880+
goto error;
18801881
}
18811882

1882-
PyObject *stripped = PyObject_CallMethod(res, "lstrip", "s", "0");
1883-
Py_DECREF(res);
1884-
if (!stripped) {
1885-
return NULL;
1883+
stripped = PyObject_CallMethod(res, "lstrip", "s", "0");
1884+
if (stripped == NULL) {
1885+
goto error;
18861886
}
18871887

1888+
Py_DECREF(fmt_obj);
1889+
Py_DECREF(strftime);
1890+
Py_DECREF(res);
18881891
return stripped;
1892+
1893+
error:
1894+
Py_XDECREF(fmt_obj);
1895+
Py_XDECREF(strftime);
1896+
Py_XDECREF(res);
1897+
Py_XDECREF(stripped);
1898+
return NULL;
18891899
}
18901900
#endif
18911901

@@ -2036,7 +2046,7 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
20362046
continue;
20372047
}
20382048
#if defined(MS_WINDOWS) || defined(__ANDROID__)
2039-
/* non-0-pad Windows support */
2049+
/* non-0-pad Windows and Android support */
20402050
else if (ch == '-' && i < flen) {
20412051
Py_UCS4 next_ch = PyUnicode_READ_CHAR(format, i);
20422052
i++;

0 commit comments

Comments
 (0)