[pypy-commit] pypy better-PyDict_Next: progress - not yet assigning the {g, s}etter. Then generalize to all w_dict value usage

mattip pypy.commits at gmail.com
Fri Dec 9 07:28:22 EST 2016


Author: Matti Picus <matti.picus at gmail.com>
Branch: better-PyDict_Next
Changeset: r88986:d8c3c1c7812f
Date: 2016-12-09 14:26 +0200
http://bitbucket.org/pypy/pypy/changeset/d8c3c1c7812f/

Log:	progress - not yet assigning the {g,s}etter. Then generalize to all
	w_dict value usage

diff --git a/pypy/module/cpyext/dictobject.py b/pypy/module/cpyext/dictobject.py
--- a/pypy/module/cpyext/dictobject.py
+++ b/pypy/module/cpyext/dictobject.py
@@ -11,7 +11,7 @@
         make_typedescr, track_reference, create_ref, from_ref, Py_DecRef,
         Py_IncRef)
 from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall
-from pypy.module.cpyext.typeobject import W_GetSetPropertyEx
+from pypy.module.cpyext.typeobject import W_GetSetPropertyEx, make_GetSet
 
 PyDictObjectStruct = lltype.ForwardReference()
 PyDictObject = lltype.Ptr(PyDictObjectStruct)
@@ -264,13 +264,15 @@
     if pkey:
         pkey[0]   = as_pyobj(space, w_key)
     if pvalue:
-        if 0 and isinstance(w_value, GetSetProperty):
-            # XXX implement this method for all W_Dict storage strategies
-            w_type = w_dict.get_storage().get_original_type_object_if_classdict()
-            # XXX doesn't quite work, need to convert GetSetProperty
-            #     to PyGetSetDef, with c_name, c_get, c_set, c_doc, c_closure
-            #     Do this by calling a make_typedescr(GetSetProperty)?
-            py_getsetdef = as_pyobj(space, w_value)
+        if isinstance(w_value, GetSetProperty):
+            strategy = w_dict.get_strategy()
+            # for translation
+            assert isinstance(strategy, ClassDictStrategy)
+            w_type = strategy.unerase(w_dict.get_storage())
+            assert space.isinstance_w(w_type, space.w_type)
+            #XXX Could this by calling a make_typedescr(GetSetProperty),
+            #    but how to feed in w_type?
+            py_getsetdef = make_GetSet(space, w_value)
             w_value = W_GetSetPropertyEx(py_getsetdef, w_type)
         pvalue[0] = as_pyobj(space, w_value)
     return 1
diff --git a/pypy/module/cpyext/typeobject.py b/pypy/module/cpyext/typeobject.py
--- a/pypy/module/cpyext/typeobject.py
+++ b/pypy/module/cpyext/typeobject.py
@@ -32,7 +32,7 @@
 from pypy.module.cpyext.state import State
 from pypy.module.cpyext.structmember import PyMember_GetOne, PyMember_SetOne
 from pypy.module.cpyext.typeobjectdefs import (
-    PyGetSetDef, PyMemberDef, newfunc,
+    PyGetSetDef, PyMemberDef, newfunc, getter, setter,
     PyNumberMethods, PyMappingMethods, PySequenceMethods, PyBufferProcs)
 from pypy.objspace.std.typeobject import W_TypeObject, find_best_base
 
@@ -61,6 +61,7 @@
         self.w_type = w_type
         doc = set = get = None
         if doc:
+            # XXX dead code?
             doc = rffi.charp2str(getset.c_doc)
         if getset.c_get:
             get = GettersAndSetters.getter.im_func
@@ -73,6 +74,21 @@
 def PyDescr_NewGetSet(space, getset, w_type):
     return space.wrap(W_GetSetPropertyEx(getset, w_type))
 
+def make_GetSet(space, getsetprop):
+    py_getsetdef = lltype.malloc(PyGetSetDef, flavor='raw')
+    doc = getsetprop.doc
+    if doc:
+        py_getsetdef.c_doc = rffi.str2charp(doc)
+    else:
+        py_getsetdef.c_doc = rffi.cast(rffi.CCHARP, 0)
+    py_getsetdef.c_name = rffi.str2charp(getsetprop.getname(space))
+    # XXX FIXME - actually assign these !!!
+    py_getsetdef.c_get = rffi.cast(getter, 0)
+    py_getsetdef.c_set = rffi.cast(setter, 0)
+    py_getsetdef.c_closure = rffi.cast(rffi.VOIDP, 0)
+    return py_getsetdef
+    
+
 class W_MemberDescr(GetSetProperty):
     name = 'member_descriptor'
     def __init__(self, member, w_type):
diff --git a/pypy/objspace/std/dictmultiobject.py b/pypy/objspace/std/dictmultiobject.py
--- a/pypy/objspace/std/dictmultiobject.py
+++ b/pypy/objspace/std/dictmultiobject.py
@@ -356,6 +356,9 @@
         if strategy is not object_strategy:
             strategy.switch_to_object_strategy(self)
 
+    def get_storage(self): # for getting the w_type from a ClassDictStrategy
+        return self.dstorage
+
 
 class W_DictObject(W_DictMultiObject):
     """ a regular dict object """


More information about the pypy-commit mailing list