[pypy-svn] r17470 - in pypy/dist/pypy: annotation rpython/test

arigo at codespeak.net arigo at codespeak.net
Sun Sep 11 19:36:40 CEST 2005


Author: arigo
Date: Sun Sep 11 19:36:39 2005
New Revision: 17470

Modified:
   pypy/dist/pypy/annotation/dictdef.py
   pypy/dist/pypy/rpython/test/test_objectmodel.py
Log:
Possibly slightly fragile fix for a test: we cannot
use emulate_pbc_call() when there is no position_key
on the bookkeeper.  Lifting this restriction looks
messy so I went for delaying the emulate_pbc_call()...



Modified: pypy/dist/pypy/annotation/dictdef.py
==============================================================================
--- pypy/dist/pypy/annotation/dictdef.py	(original)
+++ pypy/dist/pypy/annotation/dictdef.py	Sun Sep 11 19:36:39 2005
@@ -5,6 +5,7 @@
 
 class DictKey(ListItem):
     custom_eq_hash = False
+    pending_emulated_calls = ()
 
     def patch(self):
         for dictdef in self.itemof:
@@ -22,7 +23,7 @@
 
     def generalize(self, s_other_value):
         updated = ListItem.generalize(self, s_other_value)
-        if updated and self.custom_eq_hash:
+        if self.custom_eq_hash and (updated or self.pending_emulated_calls):
             self.emulate_rdict_calls()
         return updated
 
@@ -37,13 +38,23 @@
         self.emulate_rdict_calls(other=other)
 
     def emulate_rdict_calls(self, other=None):
+        # hackish: cannot emulate a call if we are not currently handling
+        # an operation
+        # (e.g. a link or a prebuilt constant coming from somewhere,
+        # as in rpython.test.test_objectmodel.test_rtype_constant_r_dicts)
+        if not hasattr(self.bookkeeper, 'position_key'):
+            self.pending_emulated_calls += (other,)
+            return
+
         myeq = (self, 'eq')
         myhash = (self, 'hash')
-        if other:
-            replace_othereq = [(other, 'eq')]
-            replace_otherhash = [(other, 'hash')]
-        else:
-            replace_othereq = replace_otherhash = ()
+        replace_othereq = []
+        replace_otherhash = []
+        for other in self.pending_emulated_calls + (other,):
+            if other:
+                replace_othereq.append((other, 'eq'))
+                replace_otherhash.append((other, 'hash'))
+        self.pending_emulated_calls = ()
 
         s_key = self.s_value
         s1 = self.bookkeeper.emulate_pbc_call(myeq, self.s_rdict_eqfn, [s_key, s_key],
@@ -86,6 +97,8 @@
             else:
                 position_key = self.bookkeeper.position_key
         self.dictkey.read_locations[position_key] = True
+        if self.dictkey.pending_emulated_calls:
+            self.dictkey.emulate_rdict_calls()
         return self.dictkey.s_value
 
     def read_value(self, position_key=None):

Modified: pypy/dist/pypy/rpython/test/test_objectmodel.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_objectmodel.py	(original)
+++ pypy/dist/pypy/rpython/test/test_objectmodel.py	Sun Sep 11 19:36:39 2005
@@ -124,3 +124,20 @@
 def test_rtype_r_dict_bm():
     res = interpret(test_r_dict_bm, [])
     assert res is True
+
+def test_rtype_constant_r_dicts():
+    d1 = r_dict(strange_key_eq, strange_key_hash)
+    d1['hello'] = 666
+    d2 = r_dict(strange_key_eq, strange_key_hash)
+    d2['hello'] = 777
+    d2['world'] = 888
+    def fn(i):
+        if i == 1:
+            d = d1
+        else:
+            d = d2
+        return len(d)
+    res = interpret(fn, [1])
+    assert res == 1
+    res = interpret(fn, [2])
+    assert res == 2



More information about the Pypy-commit mailing list