]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-117398: gh-119655: datetime: Init static state once & don't free it (GH-119662)
authorPetr Viktorin <encukou@gmail.com>
Tue, 28 May 2024 17:27:52 +0000 (19:27 +0200)
committerGitHub <noreply@github.com>
Tue, 28 May 2024 17:27:52 +0000 (17:27 +0000)
- While datetime uses global state, only initialize it once.
- While `capi` is static, don't free it (thanks @neonene in https://github.com/python/cpython/pull/119641/files#r1616710048)

Modules/_datetimemodule.c

index 271b37dfcded6cd8cc434ab6aaa62bfc954f8c2b..54383ca5177368767bab32378981fa5e4b0970f6 100644 (file)
@@ -48,6 +48,9 @@ typedef struct {
 
     /* The interned Unix epoch datetime instance */
     PyObject *epoch;
+
+    /* While we use a global state, we ensure it's only initialized once */
+    int initialized;
 } datetime_state;
 
 static datetime_state _datetime_global_state;
@@ -6841,6 +6844,12 @@ create_timezone_from_delta(int days, int sec, int ms, int normalize)
 static int
 init_state(datetime_state *st)
 {
+    // While datetime uses global module "state", we unly initialize it once.
+    // The PyLong objects created here (once per process) are not decref'd.
+    if (st->initialized) {
+        return 0;
+    }
+
     st->date_type = &PyDateTime_DateType;
     st->datetime_type = &PyDateTime_DateTimeType;
     st->delta_type = &PyDateTime_DeltaType;
@@ -6893,6 +6902,9 @@ init_state(datetime_state *st)
     if (st->epoch == NULL) {
         return -1;
     }
+
+    st->initialized = 1;
+
     return 0;
 }
 
@@ -7005,12 +7017,8 @@ _datetime_exec(PyObject *module)
         goto error;
     }
     PyObject *capsule = PyCapsule_New(capi, PyDateTime_CAPSULE_NAME, NULL);
-    if (capsule == NULL) {
-        PyMem_Free(capi);
-        goto error;
-    }
+    // (capsule == NULL) is handled by PyModule_Add
     if (PyModule_Add(module, "datetime_CAPI", capsule) < 0) {
-        PyMem_Free(capi);
         goto error;
     }