summaryrefslogtreecommitdiff
path: root/sphinx
diff options
context:
space:
mode:
authorGeorg Brandl <georg@python.org>2008-12-29 00:11:06 +0100
committerGeorg Brandl <georg@python.org>2008-12-29 00:11:06 +0100
commit4bf099d8d918da17f38cd82a099d23a764e0db8c (patch)
treed547fcdcf5da1ba25a4e6a92973b4547eeb503f4 /sphinx
parent9c80f3ece26e7fc5cbb3e3abec4ae3c697bb6604 (diff)
downloadsphinx-4bf099d8d918da17f38cd82a099d23a764e0db8c.tar.gz
Close #23: Added a ``classmethod`` directive along with ``method``
and ``staticmethod``.
Diffstat (limited to 'sphinx')
-rw-r--r--sphinx/directives/desc.py24
-rw-r--r--sphinx/ext/autodoc.py38
-rw-r--r--sphinx/texinputs/sphinx.sty29
-rw-r--r--sphinx/writers/latex.py3
4 files changed, 74 insertions, 20 deletions
diff --git a/sphinx/directives/desc.py b/sphinx/directives/desc.py
index b71cf176..a6c0fa15 100644
--- a/sphinx/directives/desc.py
+++ b/sphinx/directives/desc.py
@@ -58,6 +58,18 @@ def desc_index_text(desctype, module, name, add_modules):
return _('%s() (%s.%s static method)') % (methname, module, clsname)
else:
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':
try:
clsname, attrname = name.rsplit('.', 1)
@@ -258,6 +270,8 @@ def parse_py_signature(signode, sig, desctype, module, env):
if desctype == 'staticmethod':
signode += addnodes.desc_annotation('static ', 'static ')
+ elif desctype == 'classmethod':
+ signode += addnodes.desc_annotation('classmethod ', 'classmethod ')
if 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)
if not arglist:
- if desctype in ('function', 'method', 'staticmethod'):
+ if desctype in ('function', 'method', 'staticmethod', 'classmethod'):
# for callables, add an empty parameter list
signode += addnodes.desc_parameterlist()
if retann:
@@ -433,7 +447,8 @@ def desc_directive(desctype, arguments, options, content, lineno,
node.append(signode)
try:
if desctype in ('function', 'data', 'class', 'exception',
- 'method', 'staticmethod', 'attribute'):
+ 'method', 'staticmethod', 'classmethod',
+ '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)
@@ -510,8 +525,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', 'staticmethod', 'attribute') and \
- clsname and not env.currclass:
+ elif desctype in ('method', 'staticmethod', 'classmethod',
+ 'attribute') and clsname and not env.currclass:
env.currclass = clsname.strip('.')
clsname_set = True
# needed for association of version{added,changed} directives
@@ -536,6 +551,7 @@ desctypes = [
'data',
'class',
'method',
+ 'classmethod',
'staticmethod',
'attribute',
'exception',
diff --git a/sphinx/ext/autodoc.py b/sphinx/ext/autodoc.py
index bb717e0e..f94afc75 100644
--- a/sphinx/ext/autodoc.py
+++ b/sphinx/ext/autodoc.py
@@ -46,15 +46,18 @@ class Options(object):
pass
-def is_static_method(obj):
- """Check if the object given is a static method."""
- if isinstance(obj, (FunctionType, classmethod)):
- return True
- elif isinstance(obj, BuiltinFunctionType):
- return obj.__self__ is not None
- elif isinstance(obj, MethodType):
- return obj.im_self is not None
- return False
+def get_method_type(obj):
+ """
+ Return the method type for an object: method, staticmethod or classmethod.
+ """
+ if isinstance(obj, classmethod) or \
+ (isinstance(obj, MethodType) and obj.im_self is not None):
+ return 'classmethod'
+ elif isinstance(obj, FunctionType) or \
+ (isinstance(obj, BuiltinFunctionType) and obj.__self__ is not None):
+ return 'staticmethod'
+ else:
+ return 'method'
class AutodocReporter(object):
@@ -353,7 +356,8 @@ class RstGenerator(object):
"""
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 ''
err = None
@@ -378,7 +382,8 @@ class RstGenerator(object):
getargs = False
if getargs:
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'):
del argspec[0][0]
args = inspect.formatargspec(*argspec)
@@ -455,8 +460,10 @@ class RstGenerator(object):
self.result.append(u'', '')
# now, create the directive header
- directive = (what == 'method' and is_static_method(todoc)) \
- and 'staticmethod' or what
+ if what == 'method':
+ directive = get_method_type(todoc)
+ else:
+ directive = what
self.result.append(indent + u'.. %s:: %s%s' %
(directive, name_in_directive, sig), '<autodoc>')
if what == 'module':
@@ -507,7 +514,8 @@ class RstGenerator(object):
self.result.append(indent + line, src[0], src[1])
# 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
# set current namespace for finding members
@@ -591,7 +599,7 @@ class RstGenerator(object):
source='')
else:
memberwhat = 'class'
- elif callable(member):
+ elif inspect.isroutine(member):
memberwhat = 'method'
elif isdescriptor(member):
memberwhat = 'attribute'
diff --git a/sphinx/texinputs/sphinx.sty b/sphinx/texinputs/sphinx.sty
index e5ed4d79..bb247664 100644
--- a/sphinx/texinputs/sphinx.sty
+++ b/sphinx/texinputs/sphinx.sty
@@ -451,6 +451,35 @@
\fi
}{\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 --------------------------------------------------
% \begin{memberdesc}[classname]{membername}
\newcommand{\memberline}[2][\py@classbadkey]{%
diff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py
index 7695d6c5..24acd3db 100644
--- a/sphinx/writers/latex.py
+++ b/sphinx/writers/latex.py
@@ -399,6 +399,7 @@ class LaTeXTranslator(nodes.NodeVisitor):
'function' : 'funcdesc',
'class': 'classdesc',
'method': 'methoddesc',
+ 'classmethod': 'classmethoddesc',
'staticmethod': 'staticmethoddesc',
'exception': 'excdesc',
'data': 'datadesc',
@@ -441,7 +442,7 @@ class LaTeXTranslator(nodes.NodeVisitor):
t2 = "{%s}{%s}" % (d.name, d.params)
elif d.env in ('datadesc', 'excdesc', 'csimplemacrodesc'):
t2 = "{%s}" % (d.name)
- elif d.env in ('methoddesc', 'staticmethoddesc'):
+ elif d.env in ('methoddesc', 'classmethoddesc', 'staticmethoddesc'):
if d.cls:
t2 = "[%s]{%s}{%s}" % (d.cls, d.name, d.params)
else: