Skip to content

Commit 0041087

Browse files
[3.13] gh-71587: Drop local reference cache to _strptime module in _datetime (gh-120424)
The _strptime module object was cached in a static local variable (in the datetime.strptime() implementation). That's a problem when it crosses isolation boundaries, such as reinitializing the runtme or between interpreters. This change fixes the problem by dropping the static variable, instead always relying on the normal sys.modules cache (via PyImport_Import()). (cherry picked from commit 127c1d2, AKA gh-120224) Co-authored-by: neonene <53406459+neonene@users.noreply.github.com>
1 parent 8e5caa7 commit 0041087

8 files changed

+24
-8
lines changed

Include/internal/pycore_global_objects_fini_generated.h

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/internal/pycore_global_strings.h

+1
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,7 @@ struct _Py_global_strings {
265265
STRUCT_FOR_ID(_showwarnmsg)
266266
STRUCT_FOR_ID(_shutdown)
267267
STRUCT_FOR_ID(_slotnames)
268+
STRUCT_FOR_ID(_strptime)
268269
STRUCT_FOR_ID(_strptime_datetime)
269270
STRUCT_FOR_ID(_swappedbytes_)
270271
STRUCT_FOR_ID(_type_)

Include/internal/pycore_runtime_init_generated.h

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/internal/pycore_unicodeobject_generated.h

+3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Lib/test/test_embed.py

+9
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,15 @@ def test_ucnhash_capi_reset(self):
404404
out, err = self.run_embedded_interpreter("test_repeated_init_exec", code)
405405
self.assertEqual(out, '9\n' * INIT_LOOPS)
406406

407+
def test_datetime_reset_strptime(self):
408+
code = (
409+
"import datetime;"
410+
"d = datetime.datetime.strptime('2000-01-01', '%Y-%m-%d');"
411+
"print(d.strftime('%Y%m%d'))"
412+
)
413+
out, err = self.run_embedded_interpreter("test_repeated_init_exec", code)
414+
self.assertEqual(out, '20000101\n' * INIT_LOOPS)
415+
407416

408417
@unittest.skipIf(_testinternalcapi is None, "requires _testinternalcapi")
409418
class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix crash in C version of :meth:`datetime.datetime.strptime` when called again
2+
on the restarted interpreter.

Modules/_datetimemodule.c

+7-7
Original file line numberDiff line numberDiff line change
@@ -5511,19 +5511,19 @@ datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
55115511
static PyObject *
55125512
datetime_strptime(PyObject *cls, PyObject *args)
55135513
{
5514-
static PyObject *module = NULL;
5515-
PyObject *string, *format;
5514+
PyObject *string, *format, *result;
55165515

55175516
if (!PyArg_ParseTuple(args, "UU:strptime", &string, &format))
55185517
return NULL;
55195518

5519+
PyObject *module = PyImport_Import(&_Py_ID(_strptime));
55205520
if (module == NULL) {
5521-
module = PyImport_ImportModule("_strptime");
5522-
if (module == NULL)
5523-
return NULL;
5521+
return NULL;
55245522
}
5525-
return PyObject_CallMethodObjArgs(module, &_Py_ID(_strptime_datetime),
5526-
cls, string, format, NULL);
5523+
result = PyObject_CallMethodObjArgs(module, &_Py_ID(_strptime_datetime),
5524+
cls, string, format, NULL);
5525+
Py_DECREF(module);
5526+
return result;
55275527
}
55285528

55295529
/* Return new datetime from date/datetime and time arguments. */

Tools/c-analyzer/cpython/globals-to-fix.tsv

-1
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,6 @@ Modules/_ctypes/_ctypes.c CreateSwappedType swapped_suffix -
434434
Modules/_ctypes/_ctypes.c - _unpickle -
435435
Modules/_ctypes/_ctypes.c PyCArrayType_from_ctype array_cache -
436436
Modules/_cursesmodule.c - ModDict -
437-
Modules/_datetimemodule.c datetime_strptime module -
438437

439438
## state
440439
Modules/_ctypes/_ctypes.c - _ctypes_ptrtype_cache -

0 commit comments

Comments
 (0)