[pypy-svn] r5033 - in pypy/trunk/src/pypy: interpreter interpreter/test module objspace/std

arigo at codespeak.net arigo at codespeak.net
Thu Jun 10 18:26:00 CEST 2004


Author: arigo
Date: Thu Jun 10 18:25:59 2004
New Revision: 5033

Modified:
   pypy/trunk/src/pypy/interpreter/function.py
   pypy/trunk/src/pypy/interpreter/test/test_class.py
   pypy/trunk/src/pypy/interpreter/typedef.py
   pypy/trunk/src/pypy/module/__builtin__module.py
   pypy/trunk/src/pypy/objspace/std/stdtypedef.py
   pypy/trunk/src/pypy/objspace/std/typeobject.py
   pypy/trunk/src/pypy/objspace/std/typetype.py
Log:
Eventually made __new__ a static method, as in CPython.


Modified: pypy/trunk/src/pypy/interpreter/function.py
==============================================================================
--- pypy/trunk/src/pypy/interpreter/function.py	(original)
+++ pypy/trunk/src/pypy/interpreter/function.py	Thu Jun 10 18:25:59 2004
@@ -235,3 +235,13 @@
         return self.call(space.newtuple(list(args_w)),
                          space.newdict([(space.wrap(key), w_item)
                                         for key, w_item in kwds_w.items()]))
+
+class StaticMethod(Wrappable):
+    """A static method.  Note that there is one class staticmethod at
+    app-level too currently; this is only used for __new__ methods."""
+
+    def __init__(self, w_function):
+        self.w_function = w_function
+
+    def descr_staticmethod_get(self, w_obj, w_cls):
+        return self.w_function

Modified: pypy/trunk/src/pypy/interpreter/test/test_class.py
==============================================================================
--- pypy/trunk/src/pypy/interpreter/test/test_class.py	(original)
+++ pypy/trunk/src/pypy/interpreter/test/test_class.py	Thu Jun 10 18:25:59 2004
@@ -79,5 +79,12 @@
         self.assertEquals(d.a, 42)
         self.assertEquals(D.a, 42)
 
+    def test___new__(self):
+        class A(object):
+            pass
+        self.assert_(isinstance(A(), A))
+        self.assert_(isinstance(object.__new__(A), A))
+        self.assert_(isinstance(A.__new__(A), A))
+
 if __name__ == '__main__':
     testit.main()

Modified: pypy/trunk/src/pypy/interpreter/typedef.py
==============================================================================
--- pypy/trunk/src/pypy/interpreter/typedef.py	(original)
+++ pypy/trunk/src/pypy/interpreter/typedef.py	Thu Jun 10 18:25:59 2004
@@ -80,7 +80,7 @@
 from pypy.interpreter.pycode import PyCode
 from pypy.interpreter.pyframe import PyFrame
 from pypy.interpreter.module import Module
-from pypy.interpreter.function import Function, Method
+from pypy.interpreter.function import Function, Method, StaticMethod
 from pypy.interpreter.pytraceback import PyTraceback
 from pypy.interpreter.generator import GeneratorIterator 
 
@@ -148,6 +148,11 @@
     # XXX getattribute/setattribute etc.pp 
     )
 
+StaticMethod.typedef = TypeDef("staticmethod",
+    __get__ = interp2app(StaticMethod.descr_staticmethod_get.im_func),
+    # XXX getattribute etc.pp
+    )
+
 PyTraceback.typedef = TypeDef("traceback",
     tb_frame  = attrproperty('frame'),
     tb_lasti  = attrproperty('lasti'),

Modified: pypy/trunk/src/pypy/module/__builtin__module.py
==============================================================================
--- pypy/trunk/src/pypy/module/__builtin__module.py	(original)
+++ pypy/trunk/src/pypy/module/__builtin__module.py	Thu Jun 10 18:25:59 2004
@@ -523,6 +523,8 @@
         self.fdel(obj, value)
 
 
+# XXX there is an interp-level pypy.interpreter.function.StaticMethod
+# XXX because __new__ needs to be a StaticMethod early.
 class staticmethod(object):
 
     def __init__(self, f):

Modified: pypy/trunk/src/pypy/objspace/std/stdtypedef.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/stdtypedef.py	(original)
+++ pypy/trunk/src/pypy/objspace/std/stdtypedef.py	Thu Jun 10 18:25:59 2004
@@ -27,7 +27,7 @@
             return [self]
 
 def newmethod(descr_new):
-    # XXX make the result a staticmethod
+    # this is turned into a static method by the constructor of W_TypeObject.
     return gateway.interp2app(descr_new)
 
 # ____________________________________________________________

Modified: pypy/trunk/src/pypy/objspace/std/typeobject.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/typeobject.py	(original)
+++ pypy/trunk/src/pypy/objspace/std/typeobject.py	Thu Jun 10 18:25:59 2004
@@ -1,4 +1,5 @@
 from pypy.objspace.std.objspace import *
+from pypy.interpreter.function import Function, StaticMethod
 from pypy.interpreter.typedef import attrproperty_w
 
 class W_TypeObject(W_Object):
@@ -9,6 +10,7 @@
         w_self.name = name
         w_self.bases_w = bases_w
         w_self.dict_w = dict_w
+        w_self.ensure_static__new__()
         w_self.needs_new_dict = False
         w_self.mro_w = compute_C3_mro(w_self)   # XXX call type(w_self).mro()
         if overridetypedef is not None:
@@ -40,6 +42,14 @@
             elif nd:
                 w_self.needs_new_dict = True
 
+    def ensure_static__new__(w_self):
+        # special-case __new__, as in CPython:
+        # if it is a Function, turn it into a static method
+        if '__new__' in w_self.dict_w:
+            w_new = w_self.dict_w['__new__']
+            if isinstance(w_new, Function):
+                w_self.dict_w['__new__'] = StaticMethod(w_new)
+
     def lookup(w_self, key):
         # note that this doesn't call __get__ on the result at all
         # XXX this should probably also return the (parent) class in which
@@ -58,6 +68,10 @@
         space = w_self.space
         if space.is_true(space.is_(w_self, w_subtype)):
             return w_obj
+        if not space.is_true(space.isinstance(w_subtype, space.w_type)):
+            raise OperationError(space.w_TypeError,
+                space.wrap("X is not a type object (%s)" % (
+                    space.type(w_subtype).name)))
         if not space.is_true(space.issubtype(w_subtype, w_self)):
             raise OperationError(space.w_TypeError,
                 space.wrap("%s.__new__(%s): %s is not a subtype of %s" % (
@@ -84,7 +98,7 @@
         len(args_w) == 1 and not space.is_true(w_kwds)):
         return space.type(args_w[0])
     # invoke the __new__ of the type
-    w_descr = w_type.lookup('__new__')
+    w_descr = space.getattr(w_type, space.wrap('__new__'))
     w_extendedargs = space.newtuple([w_type] + args_w)
     w_newobject = space.call(w_descr, w_extendedargs, w_kwds)
     # maybe invoke the __init__ of the type

Modified: pypy/trunk/src/pypy/objspace/std/typetype.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/typetype.py	(original)
+++ pypy/trunk/src/pypy/objspace/std/typetype.py	Thu Jun 10 18:25:59 2004
@@ -15,11 +15,6 @@
         key = space.unwrap(w_key)
         assert isinstance(key, str)
         dict_w[key] = space.getitem(w_dict, w_key)
-    # make '__new__' an unbound method on w_typetype
-    # XXX check if this is correct in all cases
-    if '__new__' in dict_w:
-        dict_w['__new__'] = space.get(dict_w['__new__'],
-                                      space.w_None, w_typetype)
     w_type = W_TypeObject(space, name, bases_w or [space.w_object], dict_w, None)
     return space.w_type.check_user_subclass(w_typetype, w_type)
 



More information about the Pypy-commit mailing list