mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Add static method support.
This commit is contained in:
parent
1cafce9101
commit
8b0f48a38b
3
CHANGES
3
CHANGES
@ -13,6 +13,9 @@ New features added
|
||||
* Sphinx now interprets field lists with fields like ``:param foo:``
|
||||
in description units.
|
||||
|
||||
* The new `staticmethod` directive can be used to mark methods as
|
||||
static methods.
|
||||
|
||||
* HTML output:
|
||||
|
||||
- The "previous" and "next" links have a more logical structure, so
|
||||
|
@ -199,6 +199,12 @@ The directives are:
|
||||
parameter. The description should include similar information to that
|
||||
described for ``function``. See also :ref:`signatures`.
|
||||
|
||||
.. directive:: .. staticmethod:: name(signature)
|
||||
|
||||
Like :dir:`method`, but indicates that the method is a static method.
|
||||
|
||||
.. versionadded:: 0.4
|
||||
|
||||
.. directive:: .. opcode:: name
|
||||
|
||||
Describes a Python bytecode instruction (this is not very useful for projects
|
||||
|
@ -23,7 +23,7 @@ class desc(nodes.Admonition, nodes.Element): pass
|
||||
class desc_addname(nodes.Part, nodes.Inline, nodes.TextElement): pass
|
||||
# compatibility alias
|
||||
desc_classname = desc_addname
|
||||
# return type (C), object type (Python)
|
||||
# return type (C); object type, e.g. -> annotation (Python)
|
||||
class desc_type(nodes.Part, nodes.Inline, nodes.TextElement): pass
|
||||
# main name of object
|
||||
class desc_name(nodes.Part, nodes.Inline, nodes.TextElement): pass
|
||||
@ -36,6 +36,8 @@ class desc_optional(nodes.Part, nodes.Inline, nodes.TextElement):
|
||||
child_text_separator = ', '
|
||||
def astext(self):
|
||||
return '[' + nodes.TextElement.astext(self) + ']'
|
||||
# annotation (not Python 3-style annotations)
|
||||
class desc_annotation(nodes.Part, nodes.Inline, nodes.TextElement): pass
|
||||
|
||||
# node for content
|
||||
class desc_content(nodes.General, nodes.Element): pass
|
||||
|
@ -45,6 +45,18 @@ def desc_index_text(desctype, module, name):
|
||||
return '%s() (%s.%s method)' % (methname, module, clsname)
|
||||
else:
|
||||
return '%s() (%s method)' % (methname, clsname)
|
||||
elif desctype == 'staticmethod':
|
||||
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 static method)' % (methname, module, clsname)
|
||||
else:
|
||||
return '%s() (%s static method)' % (methname, clsname)
|
||||
elif desctype == 'attribute':
|
||||
try:
|
||||
clsname, attrname = name.rsplit('.', 1)
|
||||
@ -91,6 +103,8 @@ doc_fields_with_arg = {
|
||||
'var': 'Variable',
|
||||
'ivar': 'Variable',
|
||||
'cvar': 'Variable',
|
||||
'returns': 'Returns',
|
||||
'return': 'Returns',
|
||||
}
|
||||
|
||||
doc_fields_without_arg = {
|
||||
@ -140,7 +154,7 @@ def handle_doc_fields(node):
|
||||
nfield = nodes.field()
|
||||
nfield += nodes.field_name(typ, typ)
|
||||
nfield += nodes.field_body()
|
||||
nfield[1] += children
|
||||
nfield[1] += fbody.children
|
||||
new_list += nfield
|
||||
except (KeyError, ValueError):
|
||||
fnametext = fname.astext()
|
||||
@ -199,6 +213,9 @@ def parse_py_signature(signode, sig, desctype, module, env):
|
||||
add_module = True
|
||||
fullname = classname and classname + name or name
|
||||
|
||||
if desctype == 'staticmethod':
|
||||
signode += addnodes.desc_annotation('static ', 'static ')
|
||||
|
||||
if classname:
|
||||
signode += addnodes.desc_addname(classname, classname)
|
||||
# exceptions are a special case, since they are documented in the
|
||||
@ -210,7 +227,7 @@ def parse_py_signature(signode, sig, desctype, module, env):
|
||||
|
||||
signode += addnodes.desc_name(name, name)
|
||||
if not arglist:
|
||||
if desctype in ('function', 'method'):
|
||||
if desctype in ('function', 'method', 'staticmethod'):
|
||||
# for callables, add an empty parameter list
|
||||
signode += addnodes.desc_parameterlist()
|
||||
return fullname, classname
|
||||
@ -383,7 +400,7 @@ def desc_directive(desctype, arguments, options, content, lineno,
|
||||
node.append(signode)
|
||||
try:
|
||||
if desctype in ('function', 'data', 'class', 'exception',
|
||||
'method', 'attribute'):
|
||||
'method', 'staticmethod', 'attribute'):
|
||||
name, clsname = parse_py_signature(signode, sig, desctype, module, env)
|
||||
elif desctype in ('cfunction', 'cmember', 'cmacro', 'ctype', 'cvar'):
|
||||
name = parse_c_signature(signode, sig, desctype)
|
||||
@ -457,7 +474,8 @@ def desc_directive(desctype, arguments, options, content, lineno,
|
||||
if desctype in ('class', 'exception') and names:
|
||||
env.currclass = names[0]
|
||||
clsname_set = True
|
||||
elif desctype in ('method', 'attribute') and clsname and not env.currclass:
|
||||
elif desctype in ('method', 'staticmethod', 'attribute') and \
|
||||
clsname and not env.currclass:
|
||||
env.currclass = clsname.strip('.')
|
||||
clsname_set = True
|
||||
# needed for association of version{added,changed} directives
|
||||
@ -482,6 +500,7 @@ desctypes = [
|
||||
'data',
|
||||
'class',
|
||||
'method',
|
||||
'staticmethod',
|
||||
'attribute',
|
||||
'exception',
|
||||
# the C ones
|
||||
|
@ -254,7 +254,6 @@ def format_signature(what, obj):
|
||||
def generate_rst(what, name, members, options, add_content, document, lineno,
|
||||
indent=u'', filename_set=None, check_module=False):
|
||||
env = document.settings.env
|
||||
is_static = False
|
||||
|
||||
result = None
|
||||
|
||||
|
@ -113,6 +113,11 @@ class HTMLTranslator(BaseTranslator):
|
||||
def depart_desc_optional(self, node):
|
||||
self.body.append('<span class="optional">]</span>')
|
||||
|
||||
def visit_desc_annotation(self, node):
|
||||
self.body.append(self.starttag(node, 'em', CLASS='property'))
|
||||
def depart_desc_annotation(self, node):
|
||||
self.body.append('</em>')
|
||||
|
||||
def visit_desc_content(self, node):
|
||||
self.body.append(self.starttag(node, 'dd', ''))
|
||||
def depart_desc_content(self, node):
|
||||
|
@ -86,7 +86,7 @@ class Desc(object):
|
||||
def __init__(self, node):
|
||||
self.env = LaTeXTranslator.desc_map.get(node['desctype'], 'describe')
|
||||
self.ni = node['noindex']
|
||||
self.type = self.cls = self.name = self.params = ''
|
||||
self.type = self.cls = self.name = self.params = self.annotation = ''
|
||||
self.count = 0
|
||||
|
||||
|
||||
@ -284,6 +284,7 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
||||
'function' : 'funcdesc',
|
||||
'class': 'classdesc',
|
||||
'method': 'methoddesc',
|
||||
'staticmethod': 'staticmethoddesc',
|
||||
'exception': 'excdesc',
|
||||
'data': 'datadesc',
|
||||
'attribute': 'memberdesc',
|
||||
@ -325,7 +326,7 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
||||
t2 = "{%s}{%s}" % (d.name, d.params)
|
||||
elif d.env in ('datadesc', 'classdesc*', 'excdesc', 'csimplemacrodesc'):
|
||||
t2 = "{%s}" % (d.name)
|
||||
elif d.env == 'methoddesc':
|
||||
elif d.env in ('methoddesc', 'staticmethoddesc'):
|
||||
if d.cls:
|
||||
t2 = "[%s]{%s}{%s}" % (d.cls, d.name, d.params)
|
||||
else:
|
||||
@ -390,6 +391,14 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
||||
self.descstack[-1].params = self.encode(node.astext().strip())
|
||||
raise nodes.SkipNode
|
||||
|
||||
def visit_desc_annotation(self, node):
|
||||
d = self.descstack[-1]
|
||||
if d.env == 'describe':
|
||||
d.name += self.encode(node.astext())
|
||||
else:
|
||||
self.descstack[-1].annotation = self.encode(node.astext().strip())
|
||||
raise nodes.SkipNode
|
||||
|
||||
def visit_refcount(self, node):
|
||||
self.body.append("\\emph{")
|
||||
def depart_refcount(self, node):
|
||||
|
@ -572,6 +572,35 @@
|
||||
\methodlineni{#2}{#3}
|
||||
}{\end{fulllineitems}}
|
||||
|
||||
% static method ----------------------------------------------------------
|
||||
% \begin{staticmethoddesc}[classname]{methodname}{args}
|
||||
\newcommand{\staticmethodline}[3][\@undefined]{
|
||||
\staticmethodlineni{#2}{#3}
|
||||
\ifx\@undefined#1\relax
|
||||
\index{#2@{\py@idxcode{#2()}} (\py@thisclass\ static method)}
|
||||
\else
|
||||
\index{#2@{\py@idxcode{#2()}} (#1 static method)}
|
||||
\fi
|
||||
}
|
||||
\newenvironment{staticmethoddesc}[3][\@undefined]{
|
||||
\begin{fulllineitems}
|
||||
\ifx\@undefined#1\relax
|
||||
\staticmethodline{#2}{#3}
|
||||
\else
|
||||
\def\py@thisclass{#1}
|
||||
\staticmethodline{#2}{#3}
|
||||
\fi
|
||||
}{\end{fulllineitems}}
|
||||
|
||||
% similar to {staticmethoddesc}, but doesn't add to the index
|
||||
% (never actually uses the optional argument)
|
||||
\newcommand{\staticmethodlineni}[3][\py@classbadkey]{%
|
||||
\py@sigline{static \bfcode{#2}}{#3}}
|
||||
\newenvironment{staticmethoddescni}[3][\py@classbadkey]{
|
||||
\begin{fulllineitems}
|
||||
\staticmethodlineni{#2}{#3}
|
||||
}{\end{fulllineitems}}
|
||||
|
||||
% object data attribute --------------------------------------------------
|
||||
% \begin{memberdesc}[classname]{membername}
|
||||
\newcommand{\memberline}[2][\py@classbadkey]{%
|
||||
|
Loading…
Reference in New Issue
Block a user