bpo-41531: Fix compilation of dict literals with more than 0xFFFF elements (GH-21850)

This commit is contained in:
Pablo Galindo 2020-08-13 09:48:41 +01:00 committed by GitHub
parent 8ecc0c4d39
commit c51db0ea40
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 13 additions and 1 deletions

View File

@ -752,6 +752,16 @@ if 1:
self.assertEqual(None, opcodes[0].argval) self.assertEqual(None, opcodes[0].argval)
self.assertEqual('RETURN_VALUE', opcodes[1].opname) self.assertEqual('RETURN_VALUE', opcodes[1].opname)
def test_big_dict_literal(self):
# The compiler has a flushing point in "compiler_dict" that calls compiles
# a portion of the dictionary literal when the loop that iterates over the items
# reaches 0xFFFF elements but the code was not including the boundary element,
# dropping the key at position 0xFFFF. See bpo-41531 for more information
dict_size = 0xFFFF + 1
the_dict = "{" + ",".join(f"{x}:{x}" for x in range(dict_size)) + "}"
self.assertEqual(len(eval(the_dict)), dict_size)
class TestExpressionStackSize(unittest.TestCase): class TestExpressionStackSize(unittest.TestCase):
# These tests check that the computed stack size for a code object # These tests check that the computed stack size for a code object
# stays within reasonable bounds (see issue #21523 for an example # stays within reasonable bounds (see issue #21523 for an example

View File

@ -0,0 +1,2 @@
Fix a bug that was dropping keys when compiling dict literals with more than
0xFFFF elements. Patch by Pablo Galindo.

View File

@ -3894,7 +3894,7 @@ compiler_dict(struct compiler *c, expr_ty e)
} }
else { else {
if (elements == 0xFFFF) { if (elements == 0xFFFF) {
if (!compiler_subdict(c, e, i - elements, i)) { if (!compiler_subdict(c, e, i - elements, i + 1)) {
return 0; return 0;
} }
if (have_dict) { if (have_dict) {