Author: Matti Picus <matti.pi...@gmail.com>
Branch: cpyext-add_newdoc
Changeset: r91681:4e8cc878567f
Date: 2017-07-04 15:47 -0400
http://bitbucket.org/pypy/pypy/changeset/4e8cc878567f/

Log:    test, add more doc assignment from cpyext

diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py
--- a/pypy/interpreter/typedef.py
+++ b/pypy/interpreter/typedef.py
@@ -250,12 +250,13 @@
     return res
 
 class GetSetProperty(W_Root):
-    _immutable_fields_ = ["fget", "fset", "fdel"]
+    _immutable_fields_ = ["fget", "fset", "fdel", "is_cpyext"]
     w_objclass = None
 
     @specialize.arg(7)
     def __init__(self, fget, fset=None, fdel=None, doc=None,
-                 cls=None, use_closure=False, tag=None, name=None):
+                 cls=None, use_closure=False, tag=None, name=None,
+                 is_cpyext=False):
         objclass_getter, cls = make_objclass_getter(tag, fget, cls)
         fget = make_descr_typecheck_wrapper((tag, 0), fget,
                                             cls=cls, use_closure=use_closure)
@@ -264,10 +265,10 @@
         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,
-                   name)
+                   name, is_cpyext)
 
     def _init(self, fget, fset, fdel, doc, cls, objclass_getter, use_closure,
-              name):
+              name, is_cpyext):
         self.fget = fget
         self.fset = fset
         self.fdel = fdel
@@ -276,12 +277,13 @@
         self.objclass_getter = objclass_getter
         self.use_closure = use_closure
         self.name = name if name is not None else '<generic property>'
+        self.is_cpyext = is_cpyext
 
     def copy_for_type(self, w_objclass):
         if self.objclass_getter is None:
             new = instantiate(GetSetProperty)
             new._init(self.fget, self.fset, self.fdel, self.doc, self.reqcls,
-                      None, self.use_closure, self.name)
+                      None, self.use_closure, self.name, self.is_cpyext)
             new.w_objclass = w_objclass
             return new
         else:
@@ -348,6 +350,11 @@
             space._see_getsetproperty(self)      # only for fake/objspace.py
         return self
 
+    def descr__doc(space, w_self):
+        if w_self.doc is None and w_self.is_cpyext:
+            from pypy.module.cpyext.typeobject import maybe_set_getset_doc
+            maybe_set_getset_doc(space, w_self)
+        return space.newtext_or_none(w_self.doc)
 
 def interp_attrproperty(name, cls, doc=None, wrapfn=None):
     "NOT_RPYTHON: initialization-time only"
@@ -374,7 +381,8 @@
     __delete__ = interp2app(GetSetProperty.descr_property_del),
     __name__ = interp_attrproperty('name', cls=GetSetProperty, 
wrapfn="newtext_or_none"),
     __objclass__ = GetSetProperty(GetSetProperty.descr_get_objclass),
-    __doc__ = interp_attrproperty('doc', cls=GetSetProperty, 
wrapfn="newtext_or_none"),
+    __doc__ = GetSetProperty(GetSetProperty.descr__doc, 
+                                        cls=GetSetProperty, name="__doc__"),
     )
 assert not GetSetProperty.typedef.acceptable_as_base_class  # no __new__
 
diff --git a/pypy/module/cpyext/methodobject.py 
b/pypy/module/cpyext/methodobject.py
--- a/pypy/module/cpyext/methodobject.py
+++ b/pypy/module/cpyext/methodobject.py
@@ -245,6 +245,7 @@
         wrapfn="newtext_or_none"),
     __objclass__ = interp_attrproperty_w('w_objclass', cls=W_PyCMethodObject),
     __repr__ = interp2app(W_PyCMethodObject.descr_method_repr),
+    __doc__ = GetSetProperty(W_PyCFunctionObject.get_doc),
     )
 W_PyCMethodObject.typedef.acceptable_as_base_class = False
 
@@ -257,6 +258,7 @@
     __objclass__ = interp_attrproperty_w('w_objclass',
                                          cls=W_PyCClassMethodObject),
     __repr__ = interp2app(W_PyCClassMethodObject.descr_method_repr),
+    __doc__ = GetSetProperty(W_PyCFunctionObject.get_doc),
     )
 W_PyCClassMethodObject.typedef.acceptable_as_base_class = False
 
diff --git a/pypy/module/cpyext/test/test_typeobject.py 
b/pypy/module/cpyext/test/test_typeobject.py
--- a/pypy/module/cpyext/test/test_typeobject.py
+++ b/pypy/module/cpyext/test/test_typeobject.py
@@ -1356,25 +1356,72 @@
                 return (PyObject *)&FooType_Type;
             '''
             ),
-            ("add_doc_string", "METH_O",
+            ("add_doc_string_type", "METH_O",
             '''
                 PyTypeObject* obj = (PyTypeObject *)args;
                 obj->tp_doc = "A docstring";
                 Py_INCREF(Py_None);
                 return Py_None;
             '''
+            ),
+            ("add_doc_string_getset", "METH_O",
+            '''
+                PyGetSetDescrObject * obj = (PyGetSetDescrObject*)args;
+                obj->d_getset->doc = "A docstring";
+                Py_INCREF(Py_None);
+                return Py_None;
+            '''
+            ),
+            ("add_doc_string_method", "METH_O",
+            '''
+                PyMethodDescrObject * obj = (PyMethodDescrObject*)args;
+                obj->d_method->ml_doc = "A docstring";
+                Py_INCREF(Py_None);
+                return Py_None;
+            '''
             )], prologue='''
             static PyTypeObject FooType_Type = {
                 PyVarObject_HEAD_INIT(NULL, 0)
                 "foo.Type",
             };
+
+            static PyObject *
+            foo_42(void *self)
+            {
+                return PyInt_FromLong(42L);
+            };
+
+            static PyObject *
+            foo_43(void *self)
+            {
+                return PyInt_FromLong(43L);
+            };
+
+            static PyGetSetDef foo_getsetlist[] = {
+                {"foo_42",
+                    (getter)foo_42,
+                    NULL,
+                    NULL, NULL},
+                {NULL, NULL, NULL, NULL, NULL},
+            };
+
+            static PyMethodDef foo_methods[] = {
+                {"foo_43", (PyCFunction)foo_43, METH_NOARGS, NULL},
+                {NULL, NULL, 0, NULL}   /* sentinel */
+            };
             ''', more_init='''
                 FooType_Type.tp_flags = Py_TPFLAGS_DEFAULT;
                 FooType_Type.tp_base = &PyType_Type;
+                FooType_Type.tp_getset = foo_getsetlist;
+                FooType_Type.tp_methods = foo_methods;
                 if (PyType_Ready(&FooType_Type) < 0) INITERROR;
             ''')
         a = module.getType()
-        module.add_doc_string(a)
+        module.add_doc_string_type(a)
         assert a.__doc__ == "A docstring"
         assert a.__dict__['__doc__'] == None # compatibility
+        module.add_doc_string_getset(a.foo_42)
+        assert a.foo_42.__doc__ == "A docstring"
+        module.add_doc_string_method(a.foo_43)
+        assert a.foo_43.__doc__ == "A docstring"
 
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
@@ -59,12 +59,12 @@
             set = GettersAndSetters.setter.im_func
         GetSetProperty.__init__(self, get, set, None, doc,
                                 cls=None, use_closure=True,
-                                tag="cpyext_1")
+                                tag="cpyext_1", is_cpyext=True)
 
 def PyDescr_NewGetSet(space, getset, w_type):
     return W_GetSetPropertyEx(getset, w_type)
 
-def make_GetSet(space, getsetprop):
+def make_PyGetSetDef(space, getsetprop):
     py_getsetdef = lltype.malloc(PyGetSetDef, flavor='raw')
     doc = getsetprop.doc
     if doc:
@@ -95,7 +95,13 @@
             set = GettersAndSetters.member_setter.im_func
         GetSetProperty.__init__(self, get, set, del_, doc,
                                 cls=None, use_closure=True,
-                                tag="cpyext_2")
+                                tag="cpyext_2", is_cpyext=True)
+
+    def descr__doc(space, w_self):
+        if w_self.doc is None and w_self.member.c_doc:
+            w_self.doc = rffi.charp2str(w_self.member.c_doc)
+        return space.newtext_or_none(w_self.doc)
+
 
 # change the typedef name
 W_MemberDescr.typedef = TypeDef(
@@ -106,8 +112,8 @@
     __name__ = interp_attrproperty('name', cls=GetSetProperty,
         wrapfn="newtext_or_none"),
     __objclass__ = GetSetProperty(GetSetProperty.descr_get_objclass),
-    __doc__ = interp_attrproperty('doc', cls=GetSetProperty,
-        wrapfn="newtext_or_none"),
+    __doc__ = GetSetProperty(W_MemberDescr.descr__doc, 
+                    cls=W_MemberDescr, name="__doc__"),
     )
 assert not W_MemberDescr.typedef.acceptable_as_base_class  # no __new__
 
@@ -183,16 +189,17 @@
     w_obj = space.allocate_instance(W_MemberDescr, w_type)
     w_obj.__init__(member, w_type)
     track_reference(space, obj, w_obj)
+    print 'memberdescr_realise called'
     return w_obj
 
 def getsetdescr_attach(space, py_obj, w_obj, w_userdata=None):
     """
-    Fills a newly allocated PyGetSetDescrObject with the given 
W_GetSetPropertyEx
-    object. The values must not be modified.
+    Fills a newly allocated PyGetSetDescrObject with the given
+    W_GetSetPropertyEx object. The values must not be modified.
     """
     py_getsetdescr = rffi.cast(PyGetSetDescrObject, py_obj)
-    if isinstance(w_obj, GetSetProperty):
-        py_getsetdef = make_GetSet(space, w_obj)
+    if type(w_obj) is GetSetProperty:
+        py_getsetdef = make_PyGetSetDef(space, w_obj)
         assert space.isinstance_w(w_userdata, space.w_type)
         w_obj = W_GetSetPropertyEx(py_getsetdef, w_userdata)
     # XXX assign to d_dname, d_type?
@@ -375,6 +382,12 @@
         # does not automatically assign to __dic__['__doc__']
         # w_type.dict_w.setdefault('__doc__', w_type.w_doc)
 
+def maybe_set_getset_doc(space, w_getset):
+    assert isinstance(w_getset, W_GetSetPropertyEx)
+    if not w_getset.doc and w_getset.getset.c_doc:
+        w_getset.doc = rffi.charp2str(
+                        cts.cast('char*', w_getset.getset.c_doc))
+
 @slot_function([PyObject, PyObject, PyObject], PyObject)
 def tp_new_wrapper(space, self, w_args, w_kwds):
     self_pytype = rffi.cast(PyTypeObjectPtr, self)
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to