[pypy-svn] r8563 - in pypy/dist/pypy/objspace: . std/test test

hpk at codespeak.net hpk at codespeak.net
Tue Jan 25 15:16:17 CET 2005


Author: hpk
Date: Tue Jan 25 15:16:17 2005
New Revision: 8563

Modified:
   pypy/dist/pypy/objspace/descroperation.py
   pypy/dist/pypy/objspace/std/test/test_floatobject.py
   pypy/dist/pypy/objspace/std/test/test_intobject.py
   pypy/dist/pypy/objspace/test/test_descriptor.py
Log:
(jacek, holger)  

- added stricter implementations for
  space.int/float/long/str/oct/hex/repr  
  by means of funny string-templating (nobody 
  really wants to code all this manually, right?) 

- added a couple of tests although we were a bit
  unsure of where to best put them.  



Modified: pypy/dist/pypy/objspace/descroperation.py
==============================================================================
--- pypy/dist/pypy/objspace/descroperation.py	(original)
+++ pypy/dist/pypy/objspace/descroperation.py	Tue Jan 25 15:16:17 2005
@@ -150,30 +150,6 @@
             return space.is_true(w_res)
         return True
 
-    def str(space, w_obj):
-        w_descr = space.lookup(w_obj, '__str__')
-        return space.get_and_call_function(w_descr, w_obj)
-        # XXX PyObject_Str() checks that the result is a string
-
-    def int(space, w_obj):
-        w_impl = space.lookup(w_obj, '__int__')
-        if w_impl is None:
-            raise OperationError(space.w_TypeError,
-                   space.wrap("operand does not support unary %s" % symbol))
-        w_result = space.get_and_call_function(w_impl, w_obj)
-
-        if space.is_true(space.isinstance(w_result, space.w_int)) or \
-           space.is_true(space.isinstance(w_result, space.w_long)):
-            return w_result
-        w_typename = space.getattr(space.type(w_result), space.wrap('__name__'))
-        w_msg = space.mod(space.wrap("__int__ returned non-int (%s)"), w_typename)
-        raise OperationError(space.w_TypeError, w_msg)
-
-    def repr(space, w_obj):
-        w_descr = space.lookup(w_obj, '__repr__')
-        return space.get_and_call_function(w_descr, w_obj)
-        # XXX PyObject_Repr() probably checks that the result is a string
-
     def iter(space, w_obj):
         w_descr = space.lookup(w_obj, '__iter__')
         if w_descr is None:
@@ -402,9 +378,44 @@
                    space.wrap("operand does not support unary %s" % symbol))
         return space.get_and_call_function(w_impl, w_obj)
     return func_with_new_name(unaryop_impl, 'unaryop_%s_impl'%specialname.strip('_'))
-    
 
-# add regular methods
+# the following seven operations are really better to generate with
+# string-templating (and maybe we should consider this for
+# more of the above manually-coded operations as well) 
+
+for targetname, specialname, checkerspec in [
+    ('int', '__int__', ("space.w_int", "space.w_long")), 
+    ('long', '__long__', ("space.w_int", "space.w_long")), 
+    ('float', '__float__', ("space.w_float",)), 
+    ('str', '__str__', ("space.w_str",)), 
+    ('repr', '__repr__', ("space.w_str",)), 
+    ('oct', '__oct__', ("space.w_str",)), 
+    ('hex', '__hex__', ("space.w_str",))]: 
+
+    l = ["space.is_true(space.isinstance(w_result, %s))" % x 
+                for x in checkerspec]
+    checker = " or ".join(l) 
+    exec """
+def %(targetname)s(space, w_obj):
+    w_impl = space.lookup(w_obj, %(specialname)r) 
+    if w_impl is None:
+        raise OperationError(space.w_TypeError,
+               space.wrap("operand does not support unary %(targetname)s"))
+    w_result = space.get_and_call_function(w_impl, w_obj)
+
+    if %(checker)s: 
+        return w_result
+    typename = space.str_w(space.getattr(space.type(w_result), 
+                           space.wrap('__name__')))
+    msg = '%(specialname)s returned non-%(targetname)s (type %%s)' %% (typename,) 
+    raise OperationError(space.w_TypeError, space.wrap(msg)) 
+assert not hasattr(DescrOperation, %(targetname)r)
+DescrOperation.%(targetname)s = %(targetname)s
+del %(targetname)s 
+""" % locals() 
+
+
+# add default operation implementations for all still missing ops 
 
 for _name, _symbol, _arity, _specialnames in ObjSpace.MethodTable:
     if not hasattr(DescrOperation, _name):

Modified: pypy/dist/pypy/objspace/std/test/test_floatobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/test/test_floatobject.py	(original)
+++ pypy/dist/pypy/objspace/std/test/test_floatobject.py	Tue Jan 25 15:16:17 2005
@@ -75,3 +75,16 @@
         assert 22.2 == round(22.222222, 1)
         assert 20.0 == round(22.22222, -1)
         assert 0.0 == round(22.22222, -2)
+
+    def test_special_float_method(self):
+        class a:
+            def __float__(self): 
+                self.ar = True 
+                return None
+        inst = a()
+        raises(TypeError, float, inst) 
+        assert inst.ar 
+
+        class b: 
+            pass 
+        raises(TypeError, float, b()) 

Modified: pypy/dist/pypy/objspace/std/test/test_intobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/test/test_intobject.py	(original)
+++ pypy/dist/pypy/objspace/std/test/test_intobject.py	Tue Jan 25 15:16:17 2005
@@ -334,7 +334,28 @@
         raises(OverflowError,j,10000000000)
         raises(OverflowError,j,"10000000000")
 
-    def test_special_int_method(self):
+    def test_special_int(self):
         class a:
-            def __int__(self): return None
-        raises(TypeError, int, a())
+            def __int__(self): 
+                self.ar = True 
+                return None
+        inst = a()
+        raises(TypeError, int, inst) 
+        assert inst.ar == True 
+
+        class b: 
+            pass 
+        raises(TypeError, int, b()) 
+
+    def test_special_long(self):
+        class a:
+            def __long__(self): 
+                self.ar = True 
+                return None
+        inst = a()
+        raises(TypeError, long, inst) 
+        assert inst.ar == True 
+
+        class b: 
+            pass 
+        raises(TypeError, int, b()) 

Modified: pypy/dist/pypy/objspace/test/test_descriptor.py
==============================================================================
--- pypy/dist/pypy/objspace/test/test_descriptor.py	(original)
+++ pypy/dist/pypy/objspace/test/test_descriptor.py	Tue Jan 25 15:16:17 2005
@@ -23,3 +23,22 @@
         assert sys.stdin.softspace == 0
         raises(TypeError, delattr, sys.stdin, 'softspace')
         raises(TypeError, file.softspace.__delete__, sys.stdin)
+
+    def test_special_methods_returning_strings(self): 
+        class A: 
+            seen = []
+            def __str__(self): 
+                self.seen.append(1) 
+            def __repr__(self): 
+                self.seen.append(2) 
+            def __oct__(self): 
+                self.seen.append(3) 
+            def __hex__(self): 
+                self.seen.append(4) 
+
+        inst = A()
+        raises(TypeError, str, inst) 
+        raises(TypeError, repr, inst) 
+        raises(TypeError, oct, inst) 
+        raises(TypeError, hex, inst) 
+        assert A.seen == [1,2,3,4]



More information about the Pypy-commit mailing list