Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 1f336ad

Browse files
committed
Issue #15368: make bytecode generation deterministic.
2 parents c5afd42 + 2ca6315 commit 1f336ad

2 files changed

Lines changed: 25 additions & 2 deletions

File tree

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ What's New in Python 3.3.0 Beta 2?
1010
Core and Builtins
1111
-----------------
1212

13+
- Issue #15368: An issue that caused bytecode generation to be
14+
non-deterministic has been fixed.
15+
1316
- Issue #15202: Consistently use the name "follow_symlinks" for
1417
new parameters in os and shutil functions.
1518

Python/compile.c

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -397,29 +397,48 @@ each key.
397397
static PyObject *
398398
dictbytype(PyObject *src, int scope_type, int flag, int offset)
399399
{
400-
Py_ssize_t pos = 0, i = offset, scope;
400+
Py_ssize_t pos = 0, i = offset, scope, num_keys, key_i;
401401
PyObject *k, *v, *dest = PyDict_New();
402+
PyObject *sorted_keys;
402403

403404
assert(offset >= 0);
404405
if (dest == NULL)
405406
return NULL;
406407

407-
while (PyDict_Next(src, &pos, &k, &v)) {
408+
/* Sort the keys so that we have a deterministic order on the indexes
409+
saved in the returned dictionary. These indexes are used as indexes
410+
into the free and cell var storage. Therefore if they aren't
411+
deterministic, then the generated bytecode is not deterministic.
412+
*/
413+
sorted_keys = PyDict_Keys(src);
414+
if (sorted_keys == NULL)
415+
return NULL;
416+
if (PyList_Sort(sorted_keys) != 0) {
417+
Py_DECREF(sorted_keys);
418+
return NULL;
419+
}
420+
num_keys = PyList_GET_SIZE(src);
421+
422+
for (key_i = 0; key_i < num_keys; key_i++) {
408423
/* XXX this should probably be a macro in symtable.h */
409424
long vi;
425+
k = PyList_GET_ITEM(sorted_keys, key_i);
426+
v = PyDict_GetItem(src, k);
410427
assert(PyLong_Check(v));
411428
vi = PyLong_AS_LONG(v);
412429
scope = (vi >> SCOPE_OFFSET) & SCOPE_MASK;
413430

414431
if (scope == scope_type || vi & flag) {
415432
PyObject *tuple, *item = PyLong_FromLong(i);
416433
if (item == NULL) {
434+
Py_DECREF(sorted_keys);
417435
Py_DECREF(dest);
418436
return NULL;
419437
}
420438
i++;
421439
tuple = PyTuple_Pack(2, k, k->ob_type);
422440
if (!tuple || PyDict_SetItem(dest, tuple, item) < 0) {
441+
Py_DECREF(sorted_keys);
423442
Py_DECREF(item);
424443
Py_DECREF(dest);
425444
Py_XDECREF(tuple);
@@ -429,6 +448,7 @@ dictbytype(PyObject *src, int scope_type, int flag, int offset)
429448
Py_DECREF(tuple);
430449
}
431450
}
451+
Py_DECREF(sorted_keys);
432452
return dest;
433453
}
434454

0 commit comments

Comments
 (0)