##// END OF EJS Templates
Use @DocInherit to put docstrings on render dispatch functions in base class.
Anton I. Sipos -
Show More
@@ -0,0 +1,68 b''
1 """
2 doc_inherit decorator
3
4 Usage:
5
6 class Foo(object):
7 def foo(self):
8 "Frobber"
9 pass
10
11 class Bar(Foo):
12 @doc_inherit
13 def foo(self):
14 pass
15
16 Now, Bar.foo.__doc__ == Bar().foo.__doc__ == Foo.foo.__doc__ == "Frobber"
17 See: http://stackoverflow.com/questions/2025562/inherit-docstrings-in-python-class-inheritance
18 """
19
20 from functools import wraps
21
22
23 class DocInherit(object):
24 """
25 Docstring inheriting method descriptor
26
27 The class itself is also used as a decorator
28 """
29
30 def __init__(self, mthd):
31 self.mthd = mthd
32 self.name = mthd.__name__
33
34 def __get__(self, obj, cls):
35 if obj:
36 return self.get_with_inst(obj, cls)
37 else:
38 return self.get_no_inst(cls)
39
40 def get_with_inst(self, obj, cls):
41
42 overridden = getattr(super(cls, obj), self.name, None)
43
44 @wraps(self.mthd, assigned=('__name__', '__module__'))
45 def f(*args, **kwargs):
46 return self.mthd(obj, *args, **kwargs)
47
48 return self.use_parent_doc(f, overridden)
49
50 def get_no_inst(self, cls):
51
52 for parent in cls.__mro__[1:]:
53 overridden = getattr(parent, self.name, None)
54 if overridden: break
55
56 @wraps(self.mthd, assigned=('__name__', '__module__'))
57 def f(*args, **kwargs):
58 return self.mthd(*args, **kwargs)
59
60 return self.use_parent_doc(f, overridden)
61
62 def use_parent_doc(self, func, source):
63 if source is None:
64 raise NameError, ("Can't find '%s' in parents" % self.name)
65 func.__doc__ = source.__doc__
66 return func
67
68 doc_inherit = DocInherit
@@ -16,7 +16,7 b' import sys'
16 from IPython.external import argparse
16 from IPython.external import argparse
17 from IPython.nbformat import current as nbformat
17 from IPython.nbformat import current as nbformat
18 from IPython.utils.text import indent
18 from IPython.utils.text import indent
19
19 from decorators import DocInherit
20
20
21 # Cell converters
21 # Cell converters
22
22
@@ -88,21 +88,46 b' class Converter(object):'
88 return infile
88 return infile
89
89
90 def render_heading(self, cell):
90 def render_heading(self, cell):
91 """convert a heading cell
92
93 Returns list."""
91 raise NotImplementedError
94 raise NotImplementedError
92
95
93 def render_code(self, cell):
96 def render_code(self, cell):
97 """Convert a code cell
98
99 Returns list."""
94 raise NotImplementedError
100 raise NotImplementedError
95
101
96 def render_markdown(self, cell):
102 def render_markdown(self, cell):
103 """convert a markdown cell
104
105 Returns list."""
97 raise NotImplementedError
106 raise NotImplementedError
98
107
99 def render_pyout(self, cell):
108 def render_pyout(self, cell):
109 """convert pyout part of a code cell
110
111 Returns list."""
100 raise NotImplementedError
112 raise NotImplementedError
101
113
102 def render_display_data(self, cell):
114 def render_display_data(self, cell):
115 """convert display data from the output of a code cell
116
117 Returns list.
118 """
103 raise NotImplementedError
119 raise NotImplementedError
104
120
105 def render_stream(self, cell):
121 def render_stream(self, cell):
122 """convert stream part of a code cell
123
124 Returns list."""
125 raise NotImplementedError
126
127 def render_plaintext(self, cell):
128 """convert plain text
129
130 Returns list."""
106 raise NotImplementedError
131 raise NotImplementedError
107
132
108
133
@@ -111,18 +136,13 b' class ConverterRST(Converter):'
111 figures_counter = 0
136 figures_counter = 0
112 heading_level = {1: '=', 2: '-', 3: '`', 4: '\'', 5: '.', 6: '~'}
137 heading_level = {1: '=', 2: '-', 3: '`', 4: '\'', 5: '.', 6: '~'}
113
138
139 @DocInherit
114 def render_heading(self, cell):
140 def render_heading(self, cell):
115 """convert a heading cell to rst
116
117 Returns list."""
118 marker = self.heading_level[cell.level]
141 marker = self.heading_level[cell.level]
119 return ['{0}\n{1}\n'.format(cell.source, marker * len(cell.source))]
142 return ['{0}\n{1}\n'.format(cell.source, marker * len(cell.source))]
120
143
144 @DocInherit
121 def render_code(self, cell):
145 def render_code(self, cell):
122 """Convert a code cell to rst
123
124 Returns list."""
125
126 if not cell.input:
146 if not cell.input:
127 return []
147 return []
128
148
@@ -135,23 +155,16 b' class ConverterRST(Converter):'
135
155
136 return lines
156 return lines
137
157
158 @DocInherit
138 def render_markdown(self, cell):
159 def render_markdown(self, cell):
139 """convert a markdown cell to rst
140
141 Returns list."""
142 return [cell.source]
160 return [cell.source]
143
161
162 @DocInherit
144 def render_plaintext(self, cell):
163 def render_plaintext(self, cell):
145 """convert plain text to rst
146
147 Returns list."""
148 return [cell.source]
164 return [cell.source]
149
165
166 @DocInherit
150 def render_pyout(self, output):
167 def render_pyout(self, output):
151 """convert pyout part of a code cell to rst
152
153 Returns list."""
154
155 lines = ['Out[%s]:' % output.prompt_number, '']
168 lines = ['Out[%s]:' % output.prompt_number, '']
156
169
157 # output is a dictionary like object with type as a key
170 # output is a dictionary like object with type as a key
@@ -163,11 +176,8 b' class ConverterRST(Converter):'
163
176
164 return lines
177 return lines
165
178
179 @DocInherit
166 def render_display_data(self, output):
180 def render_display_data(self, output):
167 """convert display data from the output of a code cell to rst.
168
169 Returns list.
170 """
171 lines = []
181 lines = []
172
182
173 if 'png' in output:
183 if 'png' in output:
@@ -182,11 +192,8 b' class ConverterRST(Converter):'
182
192
183 return lines
193 return lines
184
194
195 @DocInherit
185 def render_stream(self, output):
196 def render_stream(self, output):
186 """convert stream part of a code cell to rst
187
188 Returns list."""
189
190 lines = []
197 lines = []
191
198
192 if 'text' in output:
199 if 'text' in output:
General Comments 0
You need to be logged in to leave comments. Login now