Author: Matti Picus <[email protected]>
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
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit