[pypy-commit] pypy default: Change the approach to fix translation, add a test

arigo pypy.commits at gmail.com
Wed Jan 11 11:53:46 EST 2017


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r89496:8ad2a82f6189
Date: 2017-01-11 17:04 +0000
http://bitbucket.org/pypy/pypy/changeset/8ad2a82f6189/

Log:	Change the approach to fix translation, add a test

diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py
--- a/pypy/interpreter/typedef.py
+++ b/pypy/interpreter/typedef.py
@@ -8,6 +8,7 @@
 
 from rpython.rlib.jit import promote
 from rpython.rlib.objectmodel import compute_identity_hash, specialize
+from rpython.rlib.objectmodel import instantiate
 from rpython.tool.sourcetools import compile2, func_with_new_name
 
 
@@ -250,10 +251,12 @@
 
 class GetSetProperty(W_Root):
     _immutable_fields_ = ["fget", "fset", "fdel"]
+    name = '<generic property>'
+    w_objclass = None
 
     @specialize.arg(7)
     def __init__(self, fget, fset=None, fdel=None, doc=None,
-                 cls=None, use_closure=False, tag=None, w_type=None):
+                 cls=None, use_closure=False, tag=None):
         objclass_getter, cls = make_objclass_getter(tag, fget, cls)
         fget = make_descr_typecheck_wrapper((tag, 0), fget,
                                             cls=cls, use_closure=use_closure)
@@ -261,16 +264,25 @@
                                             cls=cls, use_closure=use_closure)
         fdel = make_descr_typecheck_wrapper((tag, 2), fdel,
                                             cls=cls, use_closure=use_closure)
+        self._init(fget, fset, fdel, doc, cls, objclass_getter, use_closure)
+
+    def _init(self, fget, fset, fdel, doc, cls, objclass_getter, use_closure):
         self.fget = fget
         self.fset = fset
         self.fdel = fdel
         self.doc = doc
         self.reqcls = cls
-        self.name = '<generic property>'
         self.objclass_getter = objclass_getter
-        self.w_type = w_type
         self.use_closure = use_closure
 
+    def copy_for_type(self, w_objclass):
+        new = instantiate(GetSetProperty)
+        new._init(self.fget, self.fset, self.fdel, self.doc, self.reqcls,
+                  None, self.use_closure)
+        new.name = self.name
+        new.w_objclass = w_objclass
+        return new
+
     @unwrap_spec(w_cls = WrappedDefault(None))
     def descr_property_get(self, space, w_obj, w_cls=None):
         """property.__get__(obj[, type]) -> value
@@ -319,8 +331,8 @@
                                                space.wrap(self.name)]))
 
     def descr_get_objclass(space, property):
-        if property.w_type is not None:
-            return property.w_type
+        if property.w_objclass is not None:
+            return property.w_objclass
         if property.objclass_getter is not None:
             return property.objclass_getter(space)
         # NB. this is an AttributeError to make inspect.py happy
@@ -470,13 +482,9 @@
         return space.w_None
     return lifeline.get_any_weakref(space)
 
-def make_dict_descr_for_type(w_type):
-    descr = GetSetProperty(descr_get_dict, descr_set_dict, descr_del_dict,
-                           w_type=w_type,
-                           doc="dictionary for instance variables")
-    descr.name = '__dict__'
-    return descr
-dict_descr = make_dict_descr_for_type(None)
+dict_descr = GetSetProperty(descr_get_dict, descr_set_dict, descr_del_dict,
+                            doc="dictionary for instance variables")
+dict_descr.name = '__dict__'
 
 
 def generic_ne(space, w_obj1, w_obj2):
@@ -506,12 +514,9 @@
     w_docstring = code.getdocstring(space)
     return space.newtuple([w_docstring])
 
-def make_weakref_descr_for_type(w_type):
-    descr = GetSetProperty(descr_get_weakref, w_type=w_type,
-                           doc="list of weak references to the object")
-    descr.name = '__weakref__'
-    return descr
-weakref_descr = make_weakref_descr_for_type(None)
+weakref_descr = GetSetProperty(descr_get_weakref,
+                               doc="list of weak references to the object")
+weakref_descr.name = '__weakref__'
 
 def make_weakref_descr(cls):
     """Make instances of the W_Root subclass 'cls' weakrefable.
diff --git a/pypy/objspace/std/test/test_typeobject.py b/pypy/objspace/std/test/test_typeobject.py
--- a/pypy/objspace/std/test/test_typeobject.py
+++ b/pypy/objspace/std/test/test_typeobject.py
@@ -1323,3 +1323,9 @@
         assert not self.compares_by_identity(X)
         del X.__eq__
         assert self.compares_by_identity(X)
+
+    def test_descriptor_objclass(self):
+        class X(object):
+            pass
+        assert X.__dict__['__dict__'].__objclass__ is X
+        assert X.__dict__['__weakref__'].__objclass__ is X
diff --git a/pypy/objspace/std/typeobject.py b/pypy/objspace/std/typeobject.py
--- a/pypy/objspace/std/typeobject.py
+++ b/pypy/objspace/std/typeobject.py
@@ -4,8 +4,7 @@
 from pypy.interpreter.error import OperationError, oefmt
 from pypy.interpreter.function import Function, StaticMethod
 from pypy.interpreter.typedef import (
-    make_weakref_descr_for_type, GetSetProperty, weakref_descr,
-    make_dict_descr_for_type, Member, TypeDef)
+    weakref_descr, GetSetProperty, dict_descr, Member, TypeDef)
 from pypy.interpreter.astcompiler.misc import mangle
 from pypy.module.__builtin__ import abstractinst
 
@@ -1118,16 +1117,16 @@
 
 def create_dict_slot(w_self):
     if not w_self.hasdict:
-        dict_descr = make_dict_descr_for_type(w_self)
+        descr = dict_descr.copy_for_type(w_self)
         w_self.dict_w.setdefault('__dict__',
-                                 w_self.space.wrap(dict_descr))
+                                 w_self.space.wrap(descr))
         w_self.hasdict = True
 
 def create_weakref_slot(w_self):
     if not w_self.weakrefable:
-        weakref_descr = make_weakref_descr_for_type(w_self)
+        descr = weakref_descr.copy_for_type(w_self)
         w_self.dict_w.setdefault('__weakref__',
-                                 w_self.space.wrap(weakref_descr))
+                                 w_self.space.wrap(descr))
         w_self.weakrefable = True
 
 def valid_slot_name(slot_name):


More information about the pypy-commit mailing list