Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 2b3bd1f

Browse files
committed
Use @DocInherit to put docstrings on render dispatch functions in base class.
1 parent 089cd84 commit 2b3bd1f

2 files changed

Lines changed: 102 additions & 27 deletions

File tree

decorators.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
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

nbconvert.py

Lines changed: 34 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
from IPython.external import argparse
1717
from IPython.nbformat import current as nbformat
1818
from IPython.utils.text import indent
19-
19+
from decorators import DocInherit
2020

2121
# Cell converters
2222

@@ -88,21 +88,46 @@ def save(self, infile=None, encoding=None):
8888
return infile
8989

9090
def render_heading(self, cell):
91+
"""convert a heading cell
92+
93+
Returns list."""
9194
raise NotImplementedError
9295

9396
def render_code(self, cell):
97+
"""Convert a code cell
98+
99+
Returns list."""
94100
raise NotImplementedError
95101

96102
def render_markdown(self, cell):
103+
"""convert a markdown cell
104+
105+
Returns list."""
97106
raise NotImplementedError
98107

99108
def render_pyout(self, cell):
109+
"""convert pyout part of a code cell
110+
111+
Returns list."""
100112
raise NotImplementedError
101113

102114
def render_display_data(self, cell):
115+
"""convert display data from the output of a code cell
116+
117+
Returns list.
118+
"""
103119
raise NotImplementedError
104120

105121
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."""
106131
raise NotImplementedError
107132

108133

@@ -111,18 +136,13 @@ class ConverterRST(Converter):
111136
figures_counter = 0
112137
heading_level = {1: '=', 2: '-', 3: '`', 4: '\'', 5: '.', 6: '~'}
113138

139+
@DocInherit
114140
def render_heading(self, cell):
115-
"""convert a heading cell to rst
116-
117-
Returns list."""
118141
marker = self.heading_level[cell.level]
119142
return ['{0}\n{1}\n'.format(cell.source, marker * len(cell.source))]
120143

144+
@DocInherit
121145
def render_code(self, cell):
122-
"""Convert a code cell to rst
123-
124-
Returns list."""
125-
126146
if not cell.input:
127147
return []
128148

@@ -132,26 +152,19 @@ def render_code(self, cell):
132152
for output in cell.outputs:
133153
conv_fn = self.dispatch(output.output_type)
134154
lines.extend(conv_fn(output))
135-
155+
136156
return lines
137157

158+
@DocInherit
138159
def render_markdown(self, cell):
139-
"""convert a markdown cell to rst
140-
141-
Returns list."""
142160
return [cell.source]
143161

162+
@DocInherit
144163
def render_plaintext(self, cell):
145-
"""convert plain text to rst
146-
147-
Returns list."""
148164
return [cell.source]
149165

166+
@DocInherit
150167
def render_pyout(self, output):
151-
"""convert pyout part of a code cell to rst
152-
153-
Returns list."""
154-
155168
lines = ['Out[%s]:' % output.prompt_number, '']
156169

157170
# output is a dictionary like object with type as a key
@@ -163,11 +176,8 @@ def render_pyout(self, output):
163176

164177
return lines
165178

179+
@DocInherit
166180
def render_display_data(self, output):
167-
"""convert display data from the output of a code cell to rst.
168-
169-
Returns list.
170-
"""
171181
lines = []
172182

173183
if 'png' in output:
@@ -182,11 +192,8 @@ def render_display_data(self, output):
182192

183193
return lines
184194

195+
@DocInherit
185196
def render_stream(self, output):
186-
"""convert stream part of a code cell to rst
187-
188-
Returns list."""
189-
190197
lines = []
191198

192199
if 'text' in output:

0 commit comments

Comments
 (0)