mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Close #23: Added a `classmethod
directive along with
method
`
and ``staticmethod``.
This commit is contained in:
parent
1aa8baa0d8
commit
f13c3a00cd
3
CHANGES
3
CHANGES
@ -40,6 +40,9 @@ New features added
|
|||||||
- #6: Don't generate redundant ``<ul>`` for top-level TOC tree
|
- #6: Don't generate redundant ``<ul>`` for top-level TOC tree
|
||||||
items, which leads to a visual separation of TOC entries.
|
items, which leads to a visual separation of TOC entries.
|
||||||
|
|
||||||
|
- #23: Added a ``classmethod`` directive along with ``method``
|
||||||
|
and ``staticmethod``.
|
||||||
|
|
||||||
* Configuration:
|
* Configuration:
|
||||||
|
|
||||||
- The new ``html_add_permalinks`` config value can be used to
|
- The new ``html_add_permalinks`` config value can be used to
|
||||||
|
@ -205,6 +205,12 @@ The directives are:
|
|||||||
|
|
||||||
.. versionadded:: 0.4
|
.. versionadded:: 0.4
|
||||||
|
|
||||||
|
.. directive:: .. classmethod:: name(signature)
|
||||||
|
|
||||||
|
Like :dir:`method`, but indicates that the method is a class method.
|
||||||
|
|
||||||
|
.. versionadded:: 0.6
|
||||||
|
|
||||||
|
|
||||||
.. _signatures:
|
.. _signatures:
|
||||||
|
|
||||||
|
@ -58,6 +58,18 @@ def desc_index_text(desctype, module, name, add_modules):
|
|||||||
return _('%s() (%s.%s static method)') % (methname, module, clsname)
|
return _('%s() (%s.%s static method)') % (methname, module, clsname)
|
||||||
else:
|
else:
|
||||||
return _('%s() (%s static method)') % (methname, clsname)
|
return _('%s() (%s static method)') % (methname, clsname)
|
||||||
|
elif desctype == 'classmethod':
|
||||||
|
try:
|
||||||
|
clsname, methname = name.rsplit('.', 1)
|
||||||
|
except ValueError:
|
||||||
|
if module:
|
||||||
|
return '%s() (in module %s)' % (name, module)
|
||||||
|
else:
|
||||||
|
return '%s()' % name
|
||||||
|
if module:
|
||||||
|
return '%s() (%s.%s class method)' % (methname, module, clsname)
|
||||||
|
else:
|
||||||
|
return '%s() (%s class method)' % (methname, clsname)
|
||||||
elif desctype == 'attribute':
|
elif desctype == 'attribute':
|
||||||
try:
|
try:
|
||||||
clsname, attrname = name.rsplit('.', 1)
|
clsname, attrname = name.rsplit('.', 1)
|
||||||
@ -258,6 +270,8 @@ def parse_py_signature(signode, sig, desctype, module, env):
|
|||||||
|
|
||||||
if desctype == 'staticmethod':
|
if desctype == 'staticmethod':
|
||||||
signode += addnodes.desc_annotation('static ', 'static ')
|
signode += addnodes.desc_annotation('static ', 'static ')
|
||||||
|
elif desctype == 'classmethod':
|
||||||
|
signode += addnodes.desc_annotation('classmethod ', 'classmethod ')
|
||||||
|
|
||||||
if classname:
|
if classname:
|
||||||
signode += addnodes.desc_addname(classname, classname)
|
signode += addnodes.desc_addname(classname, classname)
|
||||||
@ -270,7 +284,7 @@ def parse_py_signature(signode, sig, desctype, module, env):
|
|||||||
|
|
||||||
signode += addnodes.desc_name(name, name)
|
signode += addnodes.desc_name(name, name)
|
||||||
if not arglist:
|
if not arglist:
|
||||||
if desctype in ('function', 'method', 'staticmethod'):
|
if desctype in ('function', 'method', 'staticmethod', 'classmethod'):
|
||||||
# for callables, add an empty parameter list
|
# for callables, add an empty parameter list
|
||||||
signode += addnodes.desc_parameterlist()
|
signode += addnodes.desc_parameterlist()
|
||||||
if retann:
|
if retann:
|
||||||
@ -433,7 +447,8 @@ def desc_directive(desctype, arguments, options, content, lineno,
|
|||||||
node.append(signode)
|
node.append(signode)
|
||||||
try:
|
try:
|
||||||
if desctype in ('function', 'data', 'class', 'exception',
|
if desctype in ('function', 'data', 'class', 'exception',
|
||||||
'method', 'staticmethod', 'attribute'):
|
'method', 'staticmethod', 'classmethod',
|
||||||
|
'attribute'):
|
||||||
name, clsname = parse_py_signature(signode, sig, desctype, module, env)
|
name, clsname = parse_py_signature(signode, sig, desctype, module, env)
|
||||||
elif desctype in ('cfunction', 'cmember', 'cmacro', 'ctype', 'cvar'):
|
elif desctype in ('cfunction', 'cmember', 'cmacro', 'ctype', 'cvar'):
|
||||||
name = parse_c_signature(signode, sig, desctype)
|
name = parse_c_signature(signode, sig, desctype)
|
||||||
@ -510,8 +525,8 @@ def desc_directive(desctype, arguments, options, content, lineno,
|
|||||||
if desctype in ('class', 'exception') and names:
|
if desctype in ('class', 'exception') and names:
|
||||||
env.currclass = names[0]
|
env.currclass = names[0]
|
||||||
clsname_set = True
|
clsname_set = True
|
||||||
elif desctype in ('method', 'staticmethod', 'attribute') and \
|
elif desctype in ('method', 'staticmethod', 'classmethod',
|
||||||
clsname and not env.currclass:
|
'attribute') and clsname and not env.currclass:
|
||||||
env.currclass = clsname.strip('.')
|
env.currclass = clsname.strip('.')
|
||||||
clsname_set = True
|
clsname_set = True
|
||||||
# needed for association of version{added,changed} directives
|
# needed for association of version{added,changed} directives
|
||||||
@ -536,6 +551,7 @@ desctypes = [
|
|||||||
'data',
|
'data',
|
||||||
'class',
|
'class',
|
||||||
'method',
|
'method',
|
||||||
|
'classmethod',
|
||||||
'staticmethod',
|
'staticmethod',
|
||||||
'attribute',
|
'attribute',
|
||||||
'exception',
|
'exception',
|
||||||
|
@ -46,15 +46,18 @@ class Options(object):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def is_static_method(obj):
|
def get_method_type(obj):
|
||||||
"""Check if the object given is a static method."""
|
"""
|
||||||
if isinstance(obj, (FunctionType, classmethod)):
|
Return the method type for an object: method, staticmethod or classmethod.
|
||||||
return True
|
"""
|
||||||
elif isinstance(obj, BuiltinFunctionType):
|
if isinstance(obj, classmethod) or \
|
||||||
return obj.__self__ is not None
|
(isinstance(obj, MethodType) and obj.im_self is not None):
|
||||||
elif isinstance(obj, MethodType):
|
return 'classmethod'
|
||||||
return obj.im_self is not None
|
elif isinstance(obj, FunctionType) or \
|
||||||
return False
|
(isinstance(obj, BuiltinFunctionType) and obj.__self__ is not None):
|
||||||
|
return 'staticmethod'
|
||||||
|
else:
|
||||||
|
return 'method'
|
||||||
|
|
||||||
|
|
||||||
class AutodocReporter(object):
|
class AutodocReporter(object):
|
||||||
@ -353,7 +356,8 @@ class RstGenerator(object):
|
|||||||
"""
|
"""
|
||||||
Return the signature of the object, formatted for display.
|
Return the signature of the object, formatted for display.
|
||||||
"""
|
"""
|
||||||
if what not in ('class', 'method', 'function'):
|
if what not in ('class', 'method', 'staticmethod', 'classmethod',
|
||||||
|
'function'):
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
err = None
|
err = None
|
||||||
@ -378,7 +382,8 @@ class RstGenerator(object):
|
|||||||
getargs = False
|
getargs = False
|
||||||
if getargs:
|
if getargs:
|
||||||
argspec = inspect.getargspec(obj)
|
argspec = inspect.getargspec(obj)
|
||||||
if what in ('class', 'method') and argspec[0] and \
|
if what in ('class', 'method', 'staticmethod',
|
||||||
|
'classmethod') and argspec[0] and \
|
||||||
argspec[0][0] in ('cls', 'self'):
|
argspec[0][0] in ('cls', 'self'):
|
||||||
del argspec[0][0]
|
del argspec[0][0]
|
||||||
args = inspect.formatargspec(*argspec)
|
args = inspect.formatargspec(*argspec)
|
||||||
@ -455,8 +460,10 @@ class RstGenerator(object):
|
|||||||
self.result.append(u'', '')
|
self.result.append(u'', '')
|
||||||
|
|
||||||
# now, create the directive header
|
# now, create the directive header
|
||||||
directive = (what == 'method' and is_static_method(todoc)) \
|
if what == 'method':
|
||||||
and 'staticmethod' or what
|
directive = get_method_type(todoc)
|
||||||
|
else:
|
||||||
|
directive = what
|
||||||
self.result.append(indent + u'.. %s:: %s%s' %
|
self.result.append(indent + u'.. %s:: %s%s' %
|
||||||
(directive, name_in_directive, sig), '<autodoc>')
|
(directive, name_in_directive, sig), '<autodoc>')
|
||||||
if what == 'module':
|
if what == 'module':
|
||||||
@ -507,7 +514,8 @@ class RstGenerator(object):
|
|||||||
self.result.append(indent + line, src[0], src[1])
|
self.result.append(indent + line, src[0], src[1])
|
||||||
|
|
||||||
# document members?
|
# document members?
|
||||||
if not members or what in ('function', 'method', 'data', 'attribute'):
|
if not members or what in ('function', 'method', 'staticmethod',
|
||||||
|
'classmethod', 'data', 'attribute'):
|
||||||
return
|
return
|
||||||
|
|
||||||
# set current namespace for finding members
|
# set current namespace for finding members
|
||||||
@ -591,7 +599,7 @@ class RstGenerator(object):
|
|||||||
source='')
|
source='')
|
||||||
else:
|
else:
|
||||||
memberwhat = 'class'
|
memberwhat = 'class'
|
||||||
elif callable(member):
|
elif inspect.isroutine(member):
|
||||||
memberwhat = 'method'
|
memberwhat = 'method'
|
||||||
elif isdescriptor(member):
|
elif isdescriptor(member):
|
||||||
memberwhat = 'attribute'
|
memberwhat = 'attribute'
|
||||||
|
@ -451,6 +451,35 @@
|
|||||||
\fi
|
\fi
|
||||||
}{\end{fulllineitems}}
|
}{\end{fulllineitems}}
|
||||||
|
|
||||||
|
% class method ----------------------------------------------------------
|
||||||
|
% \begin{classmethoddesc}[classname]{methodname}{args}
|
||||||
|
\newcommand{\classmethodline}[3][\@undefined]{
|
||||||
|
\classmethodlineni{#2}{#3}
|
||||||
|
\ifx\@undefined#1\relax
|
||||||
|
\index{#2@{\py@idxcode{#2()}} (\py@thisclass\ class method)}
|
||||||
|
\else
|
||||||
|
\index{#2@{\py@idxcode{#2()}} (#1 class method)}
|
||||||
|
\fi
|
||||||
|
}
|
||||||
|
\newenvironment{classmethoddesc}[3][\@undefined]{
|
||||||
|
\begin{fulllineitems}
|
||||||
|
\ifx\@undefined#1\relax
|
||||||
|
\classmethodline{#2}{#3}
|
||||||
|
\else
|
||||||
|
\def\py@thisclass{#1}
|
||||||
|
\classmethodline{#2}{#3}
|
||||||
|
\fi
|
||||||
|
}{\end{fulllineitems}}
|
||||||
|
|
||||||
|
% similar to {classmethoddesc}, but doesn't add to the index
|
||||||
|
% (never actually uses the optional argument)
|
||||||
|
\newcommand{\classmethodlineni}[3][\py@classbadkey]{%
|
||||||
|
\py@sigline{class \bfcode{#2}}{#3}}
|
||||||
|
\newenvironment{classmethoddescni}[3][\py@classbadkey]{
|
||||||
|
\begin{fulllineitems}
|
||||||
|
\classmethodlineni{#2}{#3}
|
||||||
|
}{\end{fulllineitems}}
|
||||||
|
|
||||||
% object data attribute --------------------------------------------------
|
% object data attribute --------------------------------------------------
|
||||||
% \begin{memberdesc}[classname]{membername}
|
% \begin{memberdesc}[classname]{membername}
|
||||||
\newcommand{\memberline}[2][\py@classbadkey]{%
|
\newcommand{\memberline}[2][\py@classbadkey]{%
|
||||||
|
@ -399,6 +399,7 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
|||||||
'function' : 'funcdesc',
|
'function' : 'funcdesc',
|
||||||
'class': 'classdesc',
|
'class': 'classdesc',
|
||||||
'method': 'methoddesc',
|
'method': 'methoddesc',
|
||||||
|
'classmethod': 'classmethoddesc',
|
||||||
'staticmethod': 'staticmethoddesc',
|
'staticmethod': 'staticmethoddesc',
|
||||||
'exception': 'excdesc',
|
'exception': 'excdesc',
|
||||||
'data': 'datadesc',
|
'data': 'datadesc',
|
||||||
@ -441,7 +442,7 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
|||||||
t2 = "{%s}{%s}" % (d.name, d.params)
|
t2 = "{%s}{%s}" % (d.name, d.params)
|
||||||
elif d.env in ('datadesc', 'excdesc', 'csimplemacrodesc'):
|
elif d.env in ('datadesc', 'excdesc', 'csimplemacrodesc'):
|
||||||
t2 = "{%s}" % (d.name)
|
t2 = "{%s}" % (d.name)
|
||||||
elif d.env in ('methoddesc', 'staticmethoddesc'):
|
elif d.env in ('methoddesc', 'classmethoddesc', 'staticmethoddesc'):
|
||||||
if d.cls:
|
if d.cls:
|
||||||
t2 = "[%s]{%s}{%s}" % (d.cls, d.name, d.params)
|
t2 = "[%s]{%s}{%s}" % (d.cls, d.name, d.params)
|
||||||
else:
|
else:
|
||||||
|
Loading…
Reference in New Issue
Block a user