@@ -359,27 +359,46 @@ each key.
359359static PyObject *
360360dictbytype (PyObject * src , int scope_type , int flag , int offset )
361361{
362- Py_ssize_t pos = 0 , i = offset , scope ;
362+ Py_ssize_t pos = 0 , i = offset , scope , num_keys , key_i ;
363363 PyObject * k , * v , * dest = PyDict_New ();
364+ PyObject * sorted_keys ;
364365
365366 assert (offset >= 0 );
366367 if (dest == NULL )
367368 return NULL ;
368369
369- while (PyDict_Next (src , & pos , & k , & v )) {
370+ /* Sort the keys so that we have a deterministic order on the indexes
371+ saved in the returned dictionary. These indexes are used as indexes
372+ into the free and cell var storage. Therefore if they aren't
373+ deterministic, then the generated bytecode is not deterministic.
374+ */
375+ sorted_keys = PyDict_Keys (src );
376+ if (sorted_keys == NULL )
377+ return NULL ;
378+ if (PyList_Sort (sorted_keys ) != 0 ) {
379+ Py_DECREF (sorted_keys );
380+ return NULL ;
381+ }
382+ num_keys = PyList_GET_SIZE (src );
383+
384+ for (key_i = 0 ; key_i < num_keys ; key_i ++ ) {
385+ k = PyList_GET_ITEM (sorted_keys , key_i );
386+ v = PyDict_GetItem (src , k );
370387 /* XXX this should probably be a macro in symtable.h */
371388 assert (PyInt_Check (v ));
372389 scope = (PyInt_AS_LONG (v ) >> SCOPE_OFF ) & SCOPE_MASK ;
373390
374391 if (scope == scope_type || PyInt_AS_LONG (v ) & flag ) {
375392 PyObject * tuple , * item = PyInt_FromLong (i );
376393 if (item == NULL ) {
394+ Py_DECREF (sorted_keys );
377395 Py_DECREF (dest );
378396 return NULL ;
379397 }
380398 i ++ ;
381399 tuple = PyTuple_Pack (2 , k , k -> ob_type );
382400 if (!tuple || PyDict_SetItem (dest , tuple , item ) < 0 ) {
401+ Py_DECREF (sorted_keys );
383402 Py_DECREF (item );
384403 Py_DECREF (dest );
385404 Py_XDECREF (tuple );
@@ -389,6 +408,7 @@ dictbytype(PyObject *src, int scope_type, int flag, int offset)
389408 Py_DECREF (tuple );
390409 }
391410 }
411+ Py_DECREF (sorted_keys );
392412 return dest ;
393413}
394414
0 commit comments