]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.13] gh-124442: make `__static_attributes__` deterministic by sorting (GH-124492...
authorJelle Zijlstra <jelle.zijlstra@gmail.com>
Tue, 1 Oct 2024 01:53:17 +0000 (18:53 -0700)
committerGitHub <noreply@github.com>
Tue, 1 Oct 2024 01:53:17 +0000 (18:53 -0700)
* [3.13] gh-124442: make `__static_attributes__` deterministic by sorting (GH-124492)
(cherry picked from commit 04c837d9d8a474777ef9c1412fbba14f0682366c)

Co-authored-by: Kira <kp2pml30@gmail.com>
Signed-off-by: kp2pml30 <kp2pml30@gmail.com>
Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com>
Lib/test/test_compile.py
Misc/NEWS.d/next/Core_and_Builtins/2024-09-25-11-53-22.gh-issue-124442.EXC1Ve.rst [new file with mode: 0644]
Python/compile.c

index 9c6bc31ff4922ef25cadb52ac9ad4f19e8250189..cdd942b56cb7e55375872f8ee170c7bc51fe7a13 100644 (file)
@@ -1,6 +1,7 @@
 import contextlib
 import dis
 import io
+import itertools
 import math
 import opcode
 import os
@@ -2619,6 +2620,22 @@ class TestInstructionSequence(unittest.TestCase):
         self.compare_instructions(seq, [('LOAD_CONST', 1, 1, 0, 0, 0)])
         self.compare_instructions(seq.get_nested()[0], [('LOAD_CONST', 2, 2, 0, 0, 0)])
 
+    def test_static_attributes_are_sorted(self):
+        code = (
+            'class T:\n'
+            '    def __init__(self):\n'
+            '        self.{V1} = 10\n'
+            '        self.{V2} = 10\n'
+            '    def foo(self):\n'
+            '        self.{V3} = 10\n'
+        )
+        attributes = ("a", "b", "c")
+        for perm in itertools.permutations(attributes):
+            var_names = {f'V{i + 1}': name for i, name in enumerate(perm)}
+            ns = run_code(code.format(**var_names))
+            t = ns['T']
+            self.assertEqual(t.__static_attributes__, attributes)
+
 
 if __name__ == "__main__":
     unittest.main()
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-09-25-11-53-22.gh-issue-124442.EXC1Ve.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-09-25-11-53-22.gh-issue-124442.EXC1Ve.rst
new file mode 100644 (file)
index 0000000..58e79f2
--- /dev/null
@@ -0,0 +1,2 @@
+Fix nondeterminism in compilation by sorting the value of
+:attr:`~type.__static_attributes__`. Patch by kp2pml30.
index 7752a6885cc4e2598b3a9bc2f70b8e788b1446c9..7d93f2a05f66d92129e08fbec886e299fefc8080 100644 (file)
@@ -2544,7 +2544,18 @@ compiler_class_body(struct compiler *c, stmt_ty s, int firstlineno)
         return ERROR;
     }
     assert(c->u->u_static_attributes);
-    PyObject *static_attributes = PySequence_Tuple(c->u->u_static_attributes);
+    PyObject *static_attributes_unsorted = PySequence_List(c->u->u_static_attributes);
+    if (static_attributes_unsorted == NULL) {
+        compiler_exit_scope(c);
+        return ERROR;
+    }
+    if (PyList_Sort(static_attributes_unsorted) != 0) {
+        compiler_exit_scope(c);
+        Py_DECREF(static_attributes_unsorted);
+        return ERROR;
+    }
+    PyObject *static_attributes = PySequence_Tuple(static_attributes_unsorted);
+    Py_DECREF(static_attributes_unsorted);
     if (static_attributes == NULL) {
         compiler_exit_scope(c);
         return ERROR;