Move the function documentation code to a separate function.

This commit is contained in:
Christophe de Vienne 2013-04-04 21:50:20 +02:00
parent 83bc4b596b
commit d78a48c7ba

View File

@ -371,6 +371,104 @@ class FunctionDirective(PyClassmember):
return 'function '
def document_function(funcdef, docstrings=None, protocols=['restjson']):
"""A helper function to complete a function documentation with return and
parameter types"""
# If the function doesn't have a docstring, add an empty list
# so the default behaviors below work correctly.
if not docstrings:
docstrings = [[]]
found_params = set()
for si, docstring in enumerate(docstrings):
for i, line in enumerate(docstring):
m = field_re.match(line)
if m and m.group('field') == 'param':
found_params.add(m.group('name'))
next_param_pos = (0, 0)
for arg in funcdef.arguments:
content = [
u':type %s: :wsme:type:`%s`' % (
arg.name, datatypename(arg.datatype))
]
if arg.name not in found_params:
content.insert(0, u':param %s: ' % (arg.name))
pos = next_param_pos
else:
for si, docstring in enumerate(docstrings):
for i, line in enumerate(docstring):
m = field_re.match(line)
if m and m.group('field') == 'param' \
and m.group('name') == arg.name:
pos = (si, i + 1)
break
docstring = docstrings[pos[0]]
docstring[pos[1]:pos[1]] = content
next_param_pos = (pos[0], pos[1] + len(content))
if funcdef.return_type:
content = [
u':rtype: %s' % datatypename(funcdef.return_type)
]
pos = None
for si, docstring in enumerate(docstrings):
for i, line in enumerate(docstring):
m = field_re.match(line)
if m and m.group('field') == 'return':
pos = (si, i + 1)
break
else:
pos = next_param_pos
docstring = docstrings[pos[0]]
docstring[pos[1]:pos[1]] = content
codesamples = []
if protocols:
params = []
for arg in funcdef.arguments:
params.append((arg.name, arg.datatype,
make_sample_object(arg.datatype)))
codesamples.extend([
u':%s:' % l_(u'Parameters samples'),
u' .. cssclass:: toggle',
u''
])
for name, protocol in protocols:
language, sample = protocol.encode_sample_params(
params, format=True)
codesamples.extend([
u' ' * 4 + name,
u' .. code-block:: ' + language,
u'',
])
codesamples.extend((
u' ' * 12 + line for line in sample.split('\n')))
if funcdef.return_type:
codesamples.extend([
u':%s:' % l_(u'Return samples'),
u' .. cssclass:: toggle',
u''
])
sample_obj = make_sample_object(funcdef.return_type)
for name, protocol in protocols:
language, sample = protocol.encode_sample_result(
funcdef.return_type, sample_obj, format=True)
codesamples.extend([
u' ' * 4 + name,
u' .. code-block:: ' + language,
u'',
])
codesamples.extend((
u' ' * 12 + line for line in sample.split('\n')))
docstrings[0:0] = [codesamples]
return docstrings
class FunctionDocumenter(autodoc.MethodDocumenter):
domain = 'wsme'
directivetype = 'function'
@ -404,103 +502,14 @@ class FunctionDocumenter(autodoc.MethodDocumenter):
"""Inject the type and param fields into the docstrings so that the
user can add its own param fields to document the parameters"""
docstrings = super(FunctionDocumenter, self).get_doc(encoding)
# If the function doesn't have a docstring, add an empty list
# so the default behaviors below work correctly.
if not docstrings:
docstrings.append([])
found_params = set()
protocols = get_protocols(
self.options.protocols or self.env.app.config.wsme_protocols
)
for si, docstring in enumerate(docstrings):
for i, line in enumerate(docstring):
m = field_re.match(line)
if m and m.group('field') == 'param':
found_params.add(m.group('name'))
next_param_pos = (0, 0)
for arg in self.wsme_fd.arguments:
content = [
u':type %s: :wsme:type:`%s`' % (
arg.name, datatypename(arg.datatype))
]
if arg.name not in found_params:
content.insert(0, u':param %s: ' % (arg.name))
pos = next_param_pos
else:
for si, docstring in enumerate(docstrings):
for i, line in enumerate(docstring):
m = field_re.match(line)
if m and m.group('field') == 'param' \
and m.group('name') == arg.name:
pos = (si, i + 1)
break
docstring = docstrings[pos[0]]
docstring[pos[1]:pos[1]] = content
next_param_pos = (pos[0], pos[1] + len(content))
if self.wsme_fd.return_type:
content = [
u':rtype: %s' % datatypename(self.wsme_fd.return_type)
]
pos = None
for si, docstring in enumerate(docstrings):
for i, line in enumerate(docstring):
m = field_re.match(line)
if m and m.group('field') == 'return':
pos = (si, i + 1)
break
else:
pos = next_param_pos
docstring = docstrings[pos[0]]
docstring[pos[1]:pos[1]] = content
codesamples = []
if protocols:
params = []
for arg in self.wsme_fd.arguments:
params.append((arg.name, arg.datatype,
make_sample_object(arg.datatype)))
codesamples.extend([
u':%s:' % l_(u'Parameters samples'),
u' .. cssclass:: toggle',
u''
])
for name, protocol in protocols:
language, sample = protocol.encode_sample_params(
params, format=True)
codesamples.extend([
u' ' * 4 + name,
u' .. code-block:: ' + language,
u'',
])
codesamples.extend((
u' ' * 12 + line for line in sample.split('\n')))
if self.wsme_fd.return_type:
codesamples.extend([
u':%s:' % l_(u'Return samples'),
u' .. cssclass:: toggle',
u''
])
sample_obj = make_sample_object(self.wsme_fd.return_type)
for name, protocol in protocols:
language, sample = protocol.encode_sample_result(
self.wsme_fd.return_type, sample_obj, format=True)
codesamples.extend([
u' ' * 4 + name,
u' .. code-block:: ' + language,
u'',
])
codesamples.extend((
u' ' * 12 + line for line in sample.split('\n')))
docstrings[0:0] = [codesamples]
return docstrings
return document_function(
self.wsme_fd, docstrings, protocols
)
def add_content(self, more_content, no_docstring=False):
super(FunctionDocumenter, self).add_content(more_content, no_docstring)