From ebba4723b67951e9f658e00b727e0fb39cdbc283 Mon Sep 17 00:00:00 2001 From: Robert Bradshaw Date: Sun, 15 Aug 2010 00:12:36 -0700 Subject: [PATCH] Restore special method docstrings. --- Cython/Compiler/ModuleNode.py | 23 +++++++++++++++++++++++ Cython/Compiler/Naming.py | 1 + Cython/Compiler/Nodes.py | 10 ++++++---- 3 files changed, 30 insertions(+), 4 deletions(-) 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 = " % -- 2.26.2