summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKira <kp2pml30@gmail.com>2024-09-28 22:15:43 (GMT)
committerGitHub <noreply@github.com>2024-09-28 22:15:43 (GMT)
commit04c837d9d8a474777ef9c1412fbba14f0682366c (patch)
treef15aa115d8380ceea4f3b5f6f722751f0676bf8a
parent69a4063ca516360b5eb96f5432ad9f9dfc32a72e (diff)
downloadcpython-04c837d9d8a474777ef9c1412fbba14f0682366c.zip
cpython-04c837d9d8a474777ef9c1412fbba14f0682366c.tar.gz
cpython-04c837d9d8a474777ef9c1412fbba14f0682366c.tar.bz2
gh-124442: make `__static_attributes__` deterministic by sorting (#124492)
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>
-rw-r--r--Lib/test/test_compile.py17
-rw-r--r--Misc/NEWS.d/next/Core_and_Builtins/2024-09-25-11-53-22.gh-issue-124442.EXC1Ve.rst2
-rw-r--r--Python/compile.c12
3 files changed, 30 insertions, 1 deletions
diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py
index b81d847..f7ef7a1 100644
--- a/Lib/test/test_compile.py
+++ b/Lib/test/test_compile.py
@@ -1,6 +1,7 @@
import contextlib
import dis
import io
+import itertools
import math
import opcode
import os
@@ -2687,6 +2688,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
index 0000000..58e79f2
--- /dev/null
+++ b/Misc/NEWS.d/next/Core_and_Builtins/2024-09-25-11-53-22.gh-issue-124442.EXC1Ve.rst
@@ -0,0 +1,2 @@
+Fix nondeterminism in compilation by sorting the value of
+:attr:`~type.__static_attributes__`. Patch by kp2pml30.
diff --git a/Python/compile.c b/Python/compile.c
index 7b3e6f3..9826d3f 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -911,7 +911,17 @@ PyObject *
_PyCompile_StaticAttributesAsTuple(compiler *c)
{
assert(c->u->u_static_attributes);
- return PySequence_Tuple(c->u->u_static_attributes);
+ PyObject *static_attributes_unsorted = PySequence_List(c->u->u_static_attributes);
+ if (static_attributes_unsorted == NULL) {
+ return NULL;
+ }
+ if (PyList_Sort(static_attributes_unsorted) != 0) {
+ Py_DECREF(static_attributes_unsorted);
+ return NULL;
+ }
+ PyObject *static_attributes = PySequence_Tuple(static_attributes_unsorted);
+ Py_DECREF(static_attributes_unsorted);
+ return static_attributes;
}
int