[pypy-svn] r59109 - in pypy/trunk/pypy: annotation objspace/flow rpython/lltypesystem rpython/ootypesystem rpython/test

arigo at codespeak.net arigo at codespeak.net
Wed Oct 15 16:54:36 CEST 2008


Author: arigo
Date: Wed Oct 15 16:54:36 2008
New Revision: 59109

Modified:
   pypy/trunk/pypy/annotation/annrpython.py
   pypy/trunk/pypy/annotation/unaryop.py
   pypy/trunk/pypy/objspace/flow/objspace.py
   pypy/trunk/pypy/rpython/lltypesystem/rdict.py
   pypy/trunk/pypy/rpython/ootypesystem/rdict.py
   pypy/trunk/pypy/rpython/test/test_rdict.py
Log:
Test and fix for r_dict's "in" operator that can raise exceptions.


Modified: pypy/trunk/pypy/annotation/annrpython.py
==============================================================================
--- pypy/trunk/pypy/annotation/annrpython.py	(original)
+++ pypy/trunk/pypy/annotation/annrpython.py	Wed Oct 15 16:54:36 2008
@@ -593,7 +593,9 @@
                 can_only_throw = annmodel.read_can_only_throw(binop, arg1, arg2)
             elif op.opname in annmodel.UNARY_OPERATIONS:
                 arg1 = self.binding(op.args[0])
-                unop = getattr(arg1, op.opname, None)
+                opname = op.opname
+                if opname == 'contains': opname = 'op_contains'
+                unop = getattr(arg1, opname, None)
                 can_only_throw = annmodel.read_can_only_throw(unop, arg1)
             else:
                 can_only_throw = None

Modified: pypy/trunk/pypy/annotation/unaryop.py
==============================================================================
--- pypy/trunk/pypy/annotation/unaryop.py	(original)
+++ pypy/trunk/pypy/annotation/unaryop.py	Wed Oct 15 16:54:36 2008
@@ -182,6 +182,7 @@
 
     def op_contains(obj, s_element):
         return s_Bool
+    op_contains.can_only_throw = []
 
     def hint(self, *args_s):
         return self
@@ -331,6 +332,7 @@
     def op_contains(lst, s_element):
         lst.listdef.generalize(s_element)
         return s_Bool
+    op_contains.can_only_throw = []
 
     def hint(lst, *args_s):
         hints = args_s[-1].const
@@ -431,9 +433,15 @@
     def method_clear(dct):
         pass
 
+    def _can_only_throw(dic, *ignore):
+        if dic1.dictdef.dictkey.custom_eq_hash:
+            return None    # r_dict: can throw anything
+        return []          # else: no possible exception
+
     def op_contains(dct, s_element):
         dct.dictdef.generalize_key(s_element)
         return s_Bool
+    op_contains.can_only_throw = _can_only_throw
 
 
 class __extend__(SomeString,

Modified: pypy/trunk/pypy/objspace/flow/objspace.py
==============================================================================
--- pypy/trunk/pypy/objspace/flow/objspace.py	(original)
+++ pypy/trunk/pypy/objspace/flow/objspace.py	Wed Oct 15 16:54:36 2008
@@ -493,7 +493,8 @@
     # the annotator tests
     'getitem': [IndexError, KeyError, Exception],
     'setitem': [IndexError, KeyError, Exception],
-    'delitem': [IndexError, KeyError, Exception],    
+    'delitem': [IndexError, KeyError, Exception],
+    'contains': [Exception],    # from an r_dict
     }
 
 def _add_exceptions(names, exc):

Modified: pypy/trunk/pypy/rpython/lltypesystem/rdict.py
==============================================================================
--- pypy/trunk/pypy/rpython/lltypesystem/rdict.py	(original)
+++ pypy/trunk/pypy/rpython/lltypesystem/rdict.py	Wed Oct 15 16:54:36 2008
@@ -331,6 +331,7 @@
 
     def rtype_contains((r_dict, r_key), hop):
         v_dict, v_key = hop.inputargs(r_dict, r_dict.key_repr)
+        hop.exception_is_here()
         return hop.gendirectcall(ll_contains, v_dict, v_key)
         
 class __extend__(pairtype(DictRepr, DictRepr)):

Modified: pypy/trunk/pypy/rpython/ootypesystem/rdict.py
==============================================================================
--- pypy/trunk/pypy/rpython/ootypesystem/rdict.py	(original)
+++ pypy/trunk/pypy/rpython/ootypesystem/rdict.py	Wed Oct 15 16:54:36 2008
@@ -227,7 +227,7 @@
 
     def rtype_contains((r_dict, r_key), hop):
         vlist = hop.inputargs(r_dict, r_dict.key_repr)
-        hop.exception_cannot_occur()
+        hop.exception_is_here()
         return r_dict.send_message(hop, 'll_contains', v_args=vlist)
 
 def _get_call_vars(hop, r_func, arg, params_annotation):

Modified: pypy/trunk/pypy/rpython/test/test_rdict.py
==============================================================================
--- pypy/trunk/pypy/rpython/test/test_rdict.py	(original)
+++ pypy/trunk/pypy/rpython/test/test_rdict.py	Wed Oct 15 16:54:36 2008
@@ -3,6 +3,7 @@
 from pypy.rpython import rint
 from pypy.rpython.lltypesystem import rdict, rstr
 from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin
+from pypy.rlib.objectmodel import r_dict
 
 import py
 py.log.setconsumer("rtyper", py.log.STDOUT)
@@ -496,6 +497,41 @@
         res = self.interpret(g, [3])
         assert res == 77
 
+    def test_r_dict(self):
+        class FooError(Exception):
+            pass
+        def myeq(n, m):
+            return n == m
+        def myhash(n):
+            if n < 0:
+                raise FooError
+            return -n
+        def f(n):
+            d = r_dict(myeq, myhash)
+            for i in range(10):
+                d[i] = i*i
+            try:
+                value1 = d[n]
+            except FooError:
+                value1 = 99
+            try:
+                value2 = n in d
+            except FooError:
+                value2 = 99
+            try:
+                value3 = d[-n]
+            except FooError:
+                value3 = 99
+            try:
+                value4 = (-n) in d
+            except FooError:
+                value4 = 99
+            return (value1 * 1000000 +
+                    value2 * 10000 +
+                    value3 * 100 +
+                    value4)
+        res = self.interpret(f, [5])
+        assert res == 25019999
 
 class TestLLtype(BaseTestRdict, LLRtypeMixin):
     def test_dict_but_not_with_char_keys(self):



More information about the Pypy-commit mailing list