[pypy-svn] r19583 - in pypy/dist/pypy: interpreter interpreter/test objspace/std

arigo at codespeak.net arigo at codespeak.net
Sun Nov 6 18:28:26 CET 2005


Author: arigo
Date: Sun Nov  6 18:28:25 2005
New Revision: 19583

Modified:
   pypy/dist/pypy/interpreter/test/test_typedef.py
   pypy/dist/pypy/interpreter/typedef.py
   pypy/dist/pypy/objspace/std/stdtypedef.py
Log:
(pedronis, arigo)
Give getset_property objects the correct type name
and __name__ and __objclass__ attributes.  The latter does
not make absolute sense in PyPy because of the mismatch between
interp-level classes vs. app-level types, but well, this is
a best-effort (and obscure) approach.


Modified: pypy/dist/pypy/interpreter/test/test_typedef.py
==============================================================================
--- pypy/dist/pypy/interpreter/test/test_typedef.py	(original)
+++ pypy/dist/pypy/interpreter/test/test_typedef.py	Sun Nov  6 18:28:25 2005
@@ -49,3 +49,11 @@
         assert member.__objclass__ is X
         raises((TypeError, AttributeError), "member.__name__ = 'x'")
         raises((TypeError, AttributeError), "member.__objclass__ = X")
+
+    def test_descr_getsetproperty(self):
+        from types import FrameType
+        assert FrameType.f_lineno.__name__ == 'f_lineno'
+        assert FrameType.f_lineno.__objclass__ is FrameType
+        class A(object):
+            pass
+        assert A.__dict__['__dict__'].__name__ == '__dict__'

Modified: pypy/dist/pypy/interpreter/typedef.py
==============================================================================
--- pypy/dist/pypy/interpreter/typedef.py	(original)
+++ pypy/dist/pypy/interpreter/typedef.py	Sun Nov  6 18:28:25 2005
@@ -18,14 +18,18 @@
         self.hasdict = '__dict__' in rawdict
         if __base is not None:
             self.hasdict |= __base.hasdict
-        self.rawdict = rawdict
+        self.rawdict = {}
         self.acceptable_as_base_class = True
         # xxx used by faking
         self.fakedcpytype = None
+        self.add_entries(**rawdict)
+
+    def add_entries(self, **rawdict):
         # xxx fix the names of the methods to match what app-level expects
         for key, value in rawdict.items():
-            if isinstance(value, interp2app):
+            if isinstance(value, (interp2app, GetSetProperty)):
                 value.name = key
+        self.rawdict.update(rawdict)
 
     def _freeze_(self):
         # hint for the annotator: track individual constant instances of TypeDef
@@ -149,13 +153,11 @@
 def make_descr_typecheck_wrapper(func, extraargs=(), cls=None):
     if func is None:
         return None
+    if cls is None:
+        return func
     if hasattr(func, 'im_func'):
-        assert not cls or cls is func.im_class
-        cls = func.im_class
+        assert func.im_class is cls
         func = func.im_func
-    if not cls:
-        #print "UNCHECKED", func.__module__ or '?', func.__name__
-        return func
 
     miniglobals = {
          func.__name__: func,
@@ -194,10 +196,35 @@
     exec compile2(source) in miniglobals
     return miniglobals['descr_typecheck_%s' % func.__name__]    
 
+def unknown_objclass_getter(space):
+    raise OperationError(space.w_TypeError,
+                         space.wrap("generic property has no __objclass__"))
+
+def make_objclass_getter(func, cls):
+    if hasattr(func, 'im_func'):
+        assert not cls or cls is func.im_class
+        cls = func.im_class
+    if not cls:
+        return unknown_objclass_getter, cls
+    miniglobals = {}
+    if isinstance(cls, str):
+        assert cls.startswith('<'),"pythontype typecheck should begin with <"
+        cls_name = cls[1:]
+        typeexpr = "space.w_%s" % cls_name
+    else:
+        miniglobals['cls'] = cls
+        typeexpr = "space.gettypeobject(cls.typedef)"
+    source = """if 1:
+        def objclass_getter(space):
+            return %s
+        \n""" % (typeexpr,)
+    exec compile2(source) in miniglobals
+    return miniglobals['objclass_getter'], cls
 
 class GetSetProperty(Wrappable):
     def __init__(self, fget, fset=None, fdel=None, doc=None, cls=None):
         "NOT_RPYTHON: initialization-time only"
+        objclass_getter, cls = make_objclass_getter(fget, cls)
         fget = make_descr_typecheck_wrapper(fget, cls=cls) 
         fset = make_descr_typecheck_wrapper(fset, ('w_value',), cls=cls)
         fdel = make_descr_typecheck_wrapper(fdel, cls=cls) 
@@ -205,6 +232,8 @@
         self.fset = fset
         self.fdel = fdel
         self.doc = doc
+        self.name = '<generic property>'
+        self.objclass_getter = objclass_getter
 
     def descr_property_get(space, property, w_obj, w_cls=None):
         """property.__get__(obj[, type]) -> value
@@ -235,18 +264,8 @@
                                  space.wrap("cannot delete attribute"))
         fdel(space, w_obj)
 
-GetSetProperty.typedef = TypeDef(
-    "GetSetProperty",
-    __get__ = interp2app(GetSetProperty.descr_property_get.im_func,
-                         unwrap_spec = [ObjSpace,
-                                        GetSetProperty, W_Root, W_Root]),
-    __set__ = interp2app(GetSetProperty.descr_property_set.im_func,
-                         unwrap_spec = [ObjSpace,
-                                        GetSetProperty, W_Root, W_Root]),
-    __delete__ = interp2app(GetSetProperty.descr_property_del.im_func,
-                            unwrap_spec = [ObjSpace,
-                                           GetSetProperty, W_Root]),
-    )
+    def descr_get_objclass(space, property):
+        return property.objclass_getter(space)
 
 def interp_attrproperty(name, cls):
     "NOT_RPYTHON: initialization-time only"
@@ -265,6 +284,22 @@
 
     return GetSetProperty(fget, cls=cls)
 
+GetSetProperty.typedef = TypeDef(
+    "getset_descriptor",
+    __get__ = interp2app(GetSetProperty.descr_property_get.im_func,
+                         unwrap_spec = [ObjSpace,
+                                        GetSetProperty, W_Root, W_Root]),
+    __set__ = interp2app(GetSetProperty.descr_property_set.im_func,
+                         unwrap_spec = [ObjSpace,
+                                        GetSetProperty, W_Root, W_Root]),
+    __delete__ = interp2app(GetSetProperty.descr_property_del.im_func,
+                            unwrap_spec = [ObjSpace,
+                                           GetSetProperty, W_Root]),
+    __name__ = interp_attrproperty('name', cls=GetSetProperty),
+    __objclass__ = GetSetProperty(GetSetProperty.descr_get_objclass),
+    )
+
+
 class Member(Wrappable):
     """For slots."""
     def __init__(self, index, name, w_cls):

Modified: pypy/dist/pypy/objspace/std/stdtypedef.py
==============================================================================
--- pypy/dist/pypy/objspace/std/stdtypedef.py	(original)
+++ pypy/dist/pypy/objspace/std/stdtypedef.py	Sun Nov  6 18:28:25 2005
@@ -37,6 +37,7 @@
     w_obj.setdict(space, space.newdict([]))
 
 std_dict_descr = GetSetProperty(descr_get_dict, descr_set_dict, descr_del_dict)
+std_dict_descr.name = '__dict__'
 
 def newmethod(descr_new, unwrap_spec=None):
     "NOT_RPYTHON: initialization-time only."



More information about the Pypy-commit mailing list