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

arigo at codespeak.net arigo at codespeak.net
Fri Apr 29 23:09:45 CEST 2005


Author: arigo
Date: Fri Apr 29 23:09:45 2005
New Revision: 11638

Modified:
   pypy/dist/pypy/objspace/descroperation.py
   pypy/dist/pypy/objspace/test/test_descroperation.py
Log:
- Strict type-checking of what __nonzero__() returned.
- Added a real space.nonzero() method, which was supposed to be there
  according to baseobjspace's MethodTable, but didn't actually work completely
  (it didn't try __len__() for example), unlike is_true().
- An XXX: do we want to type- and value-check the result of __len__() ?



Modified: pypy/dist/pypy/objspace/descroperation.py
==============================================================================
--- pypy/dist/pypy/objspace/descroperation.py	(original)
+++ pypy/dist/pypy/objspace/descroperation.py	Fri Apr 29 23:09:45 2005
@@ -154,14 +154,28 @@
         if w_obj == space.w_None:
             return False
         w_descr = space.lookup(w_obj, '__nonzero__')
-        if w_descr is not None:
-            w_res = space.get_and_call_function(w_descr, w_obj)
-            return space.is_true(w_res)
-        w_descr = space.lookup(w_obj, '__len__')
-        if w_descr is not None:
-            w_res = space.get_and_call_function(w_descr, w_obj)
+        if w_descr is None:
+            w_descr = space.lookup(w_obj, '__len__')
+            if w_descr is None:
+                return True
+        w_res = space.get_and_call_function(w_descr, w_obj)
+        w_restype = space.type(w_res)
+        if (space.is_w(w_restype, space.w_bool) or
+            space.is_w(w_restype, space.w_int)):
             return space.is_true(w_res)
-        return True
+        else:
+            raise OperationError(space.w_TypeError,
+                                 space.wrap('__nonzero__ should return '
+                                            'bool or int'))
+
+    def nonzero(self, w_obj):
+        if self.is_true(w_obj):
+            return self.w_True
+        else:
+            return self.w_False
+
+##    def len(self, w_obj):
+##        XXX needs to check that the result is an int (or long?) >= 0
 
     def iter(space, w_obj):
         w_descr = space.lookup(w_obj, '__iter__')

Modified: pypy/dist/pypy/objspace/test/test_descroperation.py
==============================================================================
--- pypy/dist/pypy/objspace/test/test_descroperation.py	(original)
+++ pypy/dist/pypy/objspace/test/test_descroperation.py	Fri Apr 29 23:09:45 2005
@@ -1,5 +1,19 @@
 
 
+class Test_DescrOperation:
+
+    def test_nonzero(self):
+        space = self.space
+        assert space.nonzero(space.w_True) is space.w_True
+        assert space.nonzero(space.w_False) is space.w_False
+        assert space.nonzero(space.wrap(42)) is space.w_True
+        assert space.nonzero(space.wrap(0)) is space.w_False
+        l = space.newlist([])
+        assert space.nonzero(l) is space.w_False
+        space.call_method(l, 'append', space.w_False)
+        assert space.nonzero(l) is space.w_True
+
+
 class AppTest_Descroperation:
 
     def test_getslice(self):
@@ -77,3 +91,11 @@
         x = 2
         x **= 5
         assert x == 32
+
+    def test_typechecks(self):
+        class myint(int):
+            pass
+        class X(object):
+            def __nonzero__(self):
+                return myint(1)
+        raises(TypeError, "not X()")



More information about the Pypy-commit mailing list