From: Robert Bradshaw Date: Sun, 15 Aug 2010 07:12:36 +0000 (-0700) Subject: Restore special method docstrings. X-Git-Tag: 0.13~20^2~2 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=ebba4723b67951e9f658e00b727e0fb39cdbc283;p=cython.git Restore special method docstrings. --- diff --git a/Cython/Compiler/ModuleNode.py b/Cython/Compiler/ModuleNode.py index e8099b8f..cfc04096 100644 --- a/Cython/Compiler/ModuleNode.py +++ b/Cython/Compiler/ModuleNode.py @@ -2041,6 +2041,29 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): "if (PyType_Ready(&%s) < 0) %s" % ( typeobj_cname, code.error_goto(entry.pos))) + # Fix special method docstrings. This is a bit of a hack, but + # unless we let PyType_Ready create the slot wrappers we have + # a significant performance hit. (See trac #561.) + for func in entry.type.scope.pyfunc_entries: + if func.is_special and func.doc: + code.putln("{"); + code.putln( + 'PyObject *wrapper = PyObject_GetAttrString((PyObject *)&%s, "%s"); %s' % ( + typeobj_cname, + func.name, + code.error_goto_if_null('wrapper', entry.pos))); + code.putln( + "if (Py_TYPE(wrapper) == &PyWrapperDescr_Type) {"); + code.putln( + "%s = *((PyWrapperDescrObject *)wrapper)->d_base;" % ( + func.wrapperbase_cname)); + code.putln( + "%s.doc = %s;" % (func.wrapperbase_cname, func.doc_cname)); + code.putln( + "((PyWrapperDescrObject *)wrapper)->d_base = &%s;" % ( + func.wrapperbase_cname)); + code.putln("}"); + code.putln("}"); if type.vtable_cname: code.putln( "if (__Pyx_SetVtable(%s.tp_dict, %s) < 0) %s" % ( diff --git a/Cython/Compiler/Naming.py b/Cython/Compiler/Naming.py index 9413a696..d351efd6 100644 --- a/Cython/Compiler/Naming.py +++ b/Cython/Compiler/Naming.py @@ -35,6 +35,7 @@ prop_set_prefix = pyrex_prefix + "setprop_" type_prefix = pyrex_prefix + "t_" typeobj_prefix = pyrex_prefix + "type_" var_prefix = pyrex_prefix + "v_" +wrapperbase_prefix= pyrex_prefix + "wrapperbase_" bufstruct_prefix = pyrex_prefix + "bstruct_" bufstride_prefix = pyrex_prefix + "bstride_" bufshape_prefix = pyrex_prefix + "bshape_" diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py index 05ce3c96..5c0d273b 100644 --- a/Cython/Compiler/Nodes.py +++ b/Cython/Compiler/Nodes.py @@ -2110,6 +2110,8 @@ class DefNode(FuncDefNode): entry.doc = embed_position(self.pos, self.doc) entry.doc_cname = \ Naming.funcdoc_prefix + prefix + name + if entry.is_special: + entry.wrapperbase_cname = Naming.wrapperbase_prefix + prefix + name else: entry.doc = None @@ -2224,10 +2226,7 @@ class DefNode(FuncDefNode): if proto_only: return if (Options.docstrings and self.entry.doc and - (not self.entry.is_special or - self.entry.signature.method_flags()) and - not self.entry.scope.is_property_scope - ): + not self.entry.scope.is_property_scope): docstr = self.entry.doc if docstr.is_unicode: docstr = docstr.utf8encode() @@ -2235,6 +2234,9 @@ class DefNode(FuncDefNode): 'static char %s[] = "%s";' % ( self.entry.doc_cname, split_string_literal(escape_byte_string(docstr)))) + if self.entry.is_special: + code.putln( + "struct wrapperbase %s;" % self.entry.wrapperbase_cname) if with_pymethdef: code.put( "static PyMethodDef %s = " %