https://github.com/python/cpython/commit/acfa77671ce0f342585d6f557f526c3d0a1b0a5b
commit: acfa77671ce0f342585d6f557f526c3d0a1b0a5b
branch: main
author: Shamil <[email protected]>
committer: vstinner <[email protected]>
date: 2026-10-07T15:01:09Z
summary:

gh-157176: Make time.struct_time type immutable (#157179)

Co-authored-by: Victor Stinner <[email protected]>

files:
A 
Misc/NEWS.d/next/Core_and_Builtins/2026-09-08-15-55-00.gh-issue-157176.yZ8a1B.rst
M Lib/test/test_structseq.py
M Modules/timemodule.c

diff --git a/Lib/test/test_structseq.py b/Lib/test/test_structseq.py
index 74506fc54de50e..04b6497265809f 100644
--- a/Lib/test/test_structseq.py
+++ b/Lib/test/test_structseq.py
@@ -6,6 +6,7 @@
 import textwrap
 import time
 import unittest
+from test import support
 from test.support import script_helper
 
 
@@ -351,9 +352,9 @@ def test_reference_cycle(self):
         # was cleared first, the structseq instance would crash in the
         # destructor.
         script_helper.assert_python_ok("-c", textwrap.dedent(r"""
-            import time
-            t = time.gmtime()
-            type(t).refcyle = t
+            import os
+            t = os.stat('.')
+            type(t).refcycle = t
         """))
 
     def test_replace_gc_tracked(self):
@@ -365,5 +366,8 @@ def test_replace_gc_tracked(self):
 
         self.assertTrue(gc.is_tracked(replaced_struct))
 
+    def test_struct_time_type_immutable(self):
+        support.check_immutable_type(self, type(time.gmtime()))
+
 if __name__ == "__main__":
     unittest.main()
diff --git 
a/Misc/NEWS.d/next/Core_and_Builtins/2026-09-08-15-55-00.gh-issue-157176.yZ8a1B.rst
 
b/Misc/NEWS.d/next/Core_and_Builtins/2026-09-08-15-55-00.gh-issue-157176.yZ8a1B.rst
new file mode 100644
index 00000000000000..ac2bcf09a1f2fd
--- /dev/null
+++ 
b/Misc/NEWS.d/next/Core_and_Builtins/2026-09-08-15-55-00.gh-issue-157176.yZ8a1B.rst
@@ -0,0 +1 @@
+Make the :class:`time.struct_time` type immutable to prevent reference cycles 
between the type and its instances. Patch by Shamil Abdulaev.
diff --git a/Modules/timemodule.c b/Modules/timemodule.c
index 98db74c2222f20..e5162fd3b67855 100644
--- a/Modules/timemodule.c
+++ b/Modules/timemodule.c
@@ -5,6 +5,7 @@
 #include "pycore_moduleobject.h"  // _PyModule_GetState()
 #include "pycore_namespace.h"     // _PyNamespace_New()
 #include "pycore_runtime.h"       // _Py_ID()
+#include "pycore_structseq.h"     // _PyStructSequence_NewType()
 #include "pycore_time.h"          // _PyTimeFraction
 
 #include <time.h>                 // clock()
@@ -2164,7 +2165,8 @@ time_exec(PyObject *module)
     }
 
     // struct_time type
-    state->struct_time_type = PyStructSequence_NewType(&struct_time_type_desc);
+    state->struct_time_type = _PyStructSequence_NewType(
+        &struct_time_type_desc, Py_TPFLAGS_IMMUTABLETYPE);
     if (state->struct_time_type == NULL) {
         return -1;
     }

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to