[pypy-commit] pypy default: Preserve the order of a literal set: previously, it would be built in

arigo pypy.commits at gmail.com
Fri Dec 2 10:48:13 EST 2016


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r88824:a5a64897d7a4
Date: 2016-12-02 16:47 +0100
http://bitbucket.org/pypy/pypy/changeset/a5a64897d7a4/

Log:	Preserve the order of a literal set: previously, it would be built
	in reverse order

diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py
--- a/pypy/interpreter/pyopcode.py
+++ b/pypy/interpreter/pyopcode.py
@@ -1295,9 +1295,10 @@
     @jit.unroll_safe
     def BUILD_SET(self, itemcount, next_instr):
         w_set = self.space.newset()
-        for i in range(itemcount):
-            w_item = self.popvalue()
+        for i in range(itemcount-1, -1, -1):
+            w_item = self.peekvalue(i)
             self.space.call_method(w_set, 'add', w_item)
+        self.popvalues(itemcount)
         self.pushvalue(w_set)
 
     def STORE_MAP(self, oparg, next_instr):
diff --git a/pypy/interpreter/test/test_compiler.py b/pypy/interpreter/test/test_compiler.py
--- a/pypy/interpreter/test/test_compiler.py
+++ b/pypy/interpreter/test/test_compiler.py
@@ -729,6 +729,10 @@
 
 
 class AppTestCompiler:
+    def setup_class(cls):
+        cls.w_host_is_pypy = cls.space.wrap(
+            '__pypy__' in sys.builtin_module_names)
+
     def test_bom_with_future(self):
         s = '\xef\xbb\xbffrom __future__ import division\nx = 1/2'
         ns = {}
@@ -771,6 +775,18 @@
         assert math.copysign(1., c[0]) == -1.0
         assert math.copysign(1., c[1]) == -1.0
 
+    def test_dict_and_set_literal_order(self):
+        x = 1
+        l1 = list({1:'a', 3:'b', 2:'c', 4:'d'})
+        l2 = list({1, 3, 2, 4})
+        l3 = list({x:'a', 3:'b', 2:'c', 4:'d'})
+        l4 = list({x, 3, 2, 4})
+        if not self.host_is_pypy:
+            # the full test relies on the host Python providing ordered dicts
+            assert set(l1) == set(l2) == set(l3) == set(l4) == {1, 3, 2, 4}
+        else:
+            assert l1 == l2 == l3 == l4 == [1, 3, 2, 4]
+
 
 ##class TestPythonAstCompiler(BaseTestCompiler):
 ##    def setup_method(self, method):


More information about the pypy-commit mailing list