Cython has moved to github.
cython-devel
view Cython/Compiler/AutoDocTransforms.py @ 1476:31644ed14440
embed __init__ signature in class docstring
| author | Stefan Behnel <scoder@users.berlios.de> |
|---|---|
| date | Thu Dec 11 09:57:31 2008 +0100 (3 years ago) |
| parents | d065589d0191 |
| children | 4486c09becf3 |
line source
1 from Cython.Compiler.Visitor import CythonTransform
2 from Cython.Compiler.Nodes import DefNode, CFuncDefNode
3 from Cython.Compiler.Errors import CompileError
4 from Cython.Compiler.StringEncoding import EncodedString
5 from Cython.Compiler import Options
6 from Cython.Compiler import PyrexTypes
10 class EmbedSignature(CythonTransform):
12 def __init__(self, context):
13 super(EmbedSignature, self).__init__(context)
14 self.denv = None # XXX
15 self.class_name = None
16 self.class_node = None
18 def _fmt_arg_defv(self, arg):
19 if not arg.default:
20 return None
21 try:
22 denv = self.denv # XXX
23 ctval = arg.default.compile_time_value(self.denv)
24 return '%s' % ctval
25 except Exception:
26 try:
27 return arg.default.name # XXX
28 except AttributeError:
29 return '<???>'
31 def _fmt_arg(self, arg):
32 if arg.type is PyrexTypes.py_object_type or arg.is_self_arg:
33 doc = arg.name
34 else:
35 doc = arg.type.declaration_code(arg.name, for_display=1)
36 if arg.default:
37 arg_defv = self._fmt_arg_defv(arg)
38 if arg_defv:
39 doc = doc + ('=%s' % arg_defv)
40 return doc
42 def _fmt_arglist(self, args,
43 npargs=0, pargs=None,
44 nkargs=0, kargs=None,
45 hide_self=False):
46 arglist = []
47 for arg in args:
48 if not hide_self or not arg.entry.is_self_arg:
49 arg_doc = self._fmt_arg(arg)
50 arglist.append(arg_doc)
51 if pargs:
52 arglist.insert(npargs, '*%s' % pargs.name)
53 elif nkargs:
54 arglist.insert(npargs, '*')
55 if kargs:
56 arglist.append('**%s' % kargs.name)
57 return arglist
59 def _fmt_ret_type(self, ret):
60 if ret is PyrexTypes.py_object_type:
61 return None
62 else:
63 return ret.declaration_code("", for_display=1)
65 def _fmt_signature(self, cls_name, func_name, args,
66 npargs=0, pargs=None,
67 nkargs=0, kargs=None,
68 return_type=None, hide_self=False):
69 arglist = self._fmt_arglist(args,
70 npargs, pargs,
71 nkargs, kargs,
72 hide_self=hide_self)
73 arglist_doc = ', '.join(arglist)
74 func_doc = '%s(%s)' % (func_name, arglist_doc)
75 if cls_name:
76 func_doc = '%s.%s' % (cls_name, func_doc)
77 if return_type:
78 ret_doc = self._fmt_ret_type(return_type)
79 if ret_doc:
80 func_doc = '%s -> %s' % (func_doc, ret_doc)
81 return func_doc
83 def _embed_signature(self, signature, node_doc):
84 if node_doc:
85 return signature + '\n' + node_doc
86 else:
87 return signature
90 def __call__(self, node):
91 if not Options.docstrings:
92 return node
93 else:
94 return super(EmbedSignature, self).__call__(node)
96 def visit_ClassDefNode(self, node):
97 oldname = self.class_name
98 oldclass = self.class_node
99 self.class_node = node
100 try:
101 # PyClassDefNode
102 self.class_name = node.name
103 except AttributeError:
104 # CClassDefNode
105 self.class_name = node.class_name
106 self.visitchildren(node)
107 self.class_name = oldname
108 self.class_node = oldclass
109 return node
111 def visit_DefNode(self, node):
112 if not self.current_directives['embedsignature']:
113 return node
115 is_constructor = False
116 hide_self = False
117 if node.entry.is_special:
118 is_constructor = self.class_node and node.name == '__init__'
119 if not is_constructor:
120 return node
121 class_name, func_name = None, self.class_name
122 hide_self = True
123 else:
124 class_name, func_name = self.class_name, node.name
126 nkargs = getattr(node, 'num_kwonly_args', 0)
127 npargs = len(node.args) - nkargs
128 signature = self._fmt_signature(
129 class_name, func_name, node.args,
130 npargs, node.star_arg,
131 nkargs, node.starstar_arg,
132 return_type=None, hide_self=hide_self)
133 if signature:
134 if is_constructor:
135 doc_holder = self.class_node.entry.type.scope
136 else:
137 doc_holder = node.entry
138 new_doc = self._embed_signature(signature, doc_holder.doc)
139 doc_holder.doc = EncodedString(new_doc)
140 if not is_constructor and getattr(node, 'py_func', None) is not None:
141 node.py_func.entry.doc = EncodedString(new_doc)
142 return node
144 def visit_CFuncDefNode(self, node):
145 if not self.current_directives['embedsignature']:
146 return node
147 if not node.overridable: # not cpdef FOO(...):
148 return node
150 signature = self._fmt_signature(
151 self.class_name, node.declarator.base.name,
152 node.declarator.args,
153 return_type=node.return_type)
154 if signature:
155 new_doc = self._embed_signature(signature, node.entry.doc)
156 node.entry.doc = EncodedString(new_doc)
157 if hasattr(node, 'py_func') and node.py_func is not None:
158 node.py_func.entry.doc = EncodedString(new_doc)
159 return node
