mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Merge pull request #6268 from tk0miya/refactor_py_domain
Refactoring python domain: Add new description classes for methods and attributes
This commit is contained in:
commit
a337cb793c
1
CHANGES
1
CHANGES
@ -33,6 +33,7 @@ Deprecated
|
|||||||
* ``sphinx.directives.TabularColumns``
|
* ``sphinx.directives.TabularColumns``
|
||||||
* ``sphinx.directives.TocTree``
|
* ``sphinx.directives.TocTree``
|
||||||
* ``sphinx.directives.VersionChange``
|
* ``sphinx.directives.VersionChange``
|
||||||
|
* ``sphinx.domains.python.PyClassmember``
|
||||||
* ``sphinx.domains.std.StandardDomain._resolve_citation_xref()``
|
* ``sphinx.domains.std.StandardDomain._resolve_citation_xref()``
|
||||||
* ``sphinx.domains.std.StandardDomain.note_citations()``
|
* ``sphinx.domains.std.StandardDomain.note_citations()``
|
||||||
* ``sphinx.domains.std.StandardDomain.note_citation_refs()``
|
* ``sphinx.domains.std.StandardDomain.note_citation_refs()``
|
||||||
|
@ -116,6 +116,14 @@ The following is a list of deprecated interfaces.
|
|||||||
- 4.0
|
- 4.0
|
||||||
- ``sphinx.directives.other.VersionChange``
|
- ``sphinx.directives.other.VersionChange``
|
||||||
|
|
||||||
|
* - ``sphinx.domains.python.PyClassmember``
|
||||||
|
- 2.1
|
||||||
|
- 4.0
|
||||||
|
- ``sphinx.domains.python.PyAttribute``,
|
||||||
|
``sphinx.domains.python.PyMethod``,
|
||||||
|
``sphinx.domains.python.PyClassMethod`` and
|
||||||
|
``sphinx.domains.python.PyStaticMethod``
|
||||||
|
|
||||||
* - ``sphinx.domains.std.StandardDomain._resolve_citation_xref()``
|
* - ``sphinx.domains.std.StandardDomain._resolve_citation_xref()``
|
||||||
- 2.1
|
- 2.1
|
||||||
- 4.0
|
- 4.0
|
||||||
|
@ -9,13 +9,16 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
import warnings
|
||||||
from typing import cast
|
from typing import cast
|
||||||
|
|
||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
from docutils.parsers.rst import directives
|
from docutils.parsers.rst import directives
|
||||||
|
|
||||||
from sphinx import addnodes, locale
|
from sphinx import addnodes, locale
|
||||||
from sphinx.deprecation import DeprecatedDict, RemovedInSphinx30Warning
|
from sphinx.deprecation import (
|
||||||
|
DeprecatedDict, RemovedInSphinx30Warning, RemovedInSphinx40Warning
|
||||||
|
)
|
||||||
from sphinx.directives import ObjectDescription
|
from sphinx.directives import ObjectDescription
|
||||||
from sphinx.domains import Domain, ObjType, Index, IndexEntry
|
from sphinx.domains import Domain, ObjType, Index, IndexEntry
|
||||||
from sphinx.locale import _, __
|
from sphinx.locale import _, __
|
||||||
@ -453,6 +456,13 @@ class PyClassmember(PyObject):
|
|||||||
Description of a class member (methods, attributes).
|
Description of a class member (methods, attributes).
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
# type: () -> List[nodes.Node]
|
||||||
|
warnings.warn('PyClassmember is deprecated.',
|
||||||
|
RemovedInSphinx40Warning)
|
||||||
|
|
||||||
|
return super().run()
|
||||||
|
|
||||||
def needs_arglist(self):
|
def needs_arglist(self):
|
||||||
# type: () -> bool
|
# type: () -> bool
|
||||||
return self.objtype.endswith('method')
|
return self.objtype.endswith('method')
|
||||||
@ -523,6 +533,94 @@ class PyClassmember(PyObject):
|
|||||||
return ''
|
return ''
|
||||||
|
|
||||||
|
|
||||||
|
class PyMethod(PyObject):
|
||||||
|
"""Description of a method."""
|
||||||
|
|
||||||
|
def needs_arglist(self):
|
||||||
|
# type: () -> bool
|
||||||
|
return True
|
||||||
|
|
||||||
|
def get_index_text(self, modname, name_cls):
|
||||||
|
# type: (str, Tuple[str, str]) -> str
|
||||||
|
name, cls = name_cls
|
||||||
|
try:
|
||||||
|
clsname, methname = name.rsplit('.', 1)
|
||||||
|
if modname and self.env.config.add_module_names:
|
||||||
|
clsname = '.'.join([modname, clsname])
|
||||||
|
except ValueError:
|
||||||
|
if modname:
|
||||||
|
return _('%s() (in module %s)') % (name, modname)
|
||||||
|
else:
|
||||||
|
return '%s()' % name
|
||||||
|
|
||||||
|
return _('%s() (%s method)') % (methname, clsname)
|
||||||
|
|
||||||
|
|
||||||
|
class PyClassMethod(PyMethod):
|
||||||
|
"""Description of a classmethod."""
|
||||||
|
|
||||||
|
def get_signature_prefix(self, sig):
|
||||||
|
# type: (str) -> str
|
||||||
|
return 'classmethod '
|
||||||
|
|
||||||
|
def get_index_text(self, modname, name_cls):
|
||||||
|
# type: (str, Tuple[str, str]) -> str
|
||||||
|
name, cls = name_cls
|
||||||
|
try:
|
||||||
|
clsname, methname = name.rsplit('.', 1)
|
||||||
|
if modname and self.env.config.add_module_names:
|
||||||
|
clsname = '.'.join([modname, clsname])
|
||||||
|
except ValueError:
|
||||||
|
if modname:
|
||||||
|
return _('%s() (in module %s)') % (name, modname)
|
||||||
|
else:
|
||||||
|
return '%s()' % name
|
||||||
|
|
||||||
|
return _('%s() (%s class method)') % (methname, clsname)
|
||||||
|
|
||||||
|
|
||||||
|
class PyStaticMethod(PyMethod):
|
||||||
|
"""Description of a staticmethod."""
|
||||||
|
|
||||||
|
def get_signature_prefix(self, sig):
|
||||||
|
# type: (str) -> str
|
||||||
|
return 'static '
|
||||||
|
|
||||||
|
def get_index_text(self, modname, name_cls):
|
||||||
|
# type: (str, Tuple[str, str]) -> str
|
||||||
|
name, cls = name_cls
|
||||||
|
try:
|
||||||
|
clsname, methname = name.rsplit('.', 1)
|
||||||
|
if modname and self.env.config.add_module_names:
|
||||||
|
clsname = '.'.join([modname, clsname])
|
||||||
|
except ValueError:
|
||||||
|
if modname:
|
||||||
|
return _('%s() (in module %s)') % (name, modname)
|
||||||
|
else:
|
||||||
|
return '%s()' % name
|
||||||
|
|
||||||
|
return _('%s() (%s static method)') % (methname, clsname)
|
||||||
|
|
||||||
|
|
||||||
|
class PyAttribute(PyObject):
|
||||||
|
"""Description of an attribute."""
|
||||||
|
|
||||||
|
def get_index_text(self, modname, name_cls):
|
||||||
|
# type: (str, Tuple[str, str]) -> str
|
||||||
|
name, cls = name_cls
|
||||||
|
try:
|
||||||
|
clsname, attrname = name.rsplit('.', 1)
|
||||||
|
if modname and self.env.config.add_module_names:
|
||||||
|
clsname = '.'.join([modname, clsname])
|
||||||
|
except ValueError:
|
||||||
|
if modname:
|
||||||
|
return _('%s (in module %s)') % (name, modname)
|
||||||
|
else:
|
||||||
|
return name
|
||||||
|
|
||||||
|
return _('%s (%s attribute)') % (attrname, clsname)
|
||||||
|
|
||||||
|
|
||||||
class PyDecoratorMixin:
|
class PyDecoratorMixin:
|
||||||
"""
|
"""
|
||||||
Mixin for decorator directives.
|
Mixin for decorator directives.
|
||||||
@ -745,10 +843,10 @@ class PythonDomain(Domain):
|
|||||||
'data': PyModulelevel,
|
'data': PyModulelevel,
|
||||||
'class': PyClasslike,
|
'class': PyClasslike,
|
||||||
'exception': PyClasslike,
|
'exception': PyClasslike,
|
||||||
'method': PyClassmember,
|
'method': PyMethod,
|
||||||
'classmethod': PyClassmember,
|
'classmethod': PyClassMethod,
|
||||||
'staticmethod': PyClassmember,
|
'staticmethod': PyStaticMethod,
|
||||||
'attribute': PyClassmember,
|
'attribute': PyAttribute,
|
||||||
'module': PyModule,
|
'module': PyModule,
|
||||||
'currentmodule': PyCurrentModule,
|
'currentmodule': PyCurrentModule,
|
||||||
'decorator': PyDecoratorFunction,
|
'decorator': PyDecoratorFunction,
|
||||||
|
@ -290,3 +290,85 @@ def test_pyobject_prefix(app):
|
|||||||
desc)])]))
|
desc)])]))
|
||||||
assert doctree[1][1][1].astext().strip() == 'say' # prefix is stripped
|
assert doctree[1][1][1].astext().strip() == 'say' # prefix is stripped
|
||||||
assert doctree[1][1][3].astext().strip() == 'FooBar.say' # not stripped
|
assert doctree[1][1][3].astext().strip() == 'FooBar.say' # not stripped
|
||||||
|
|
||||||
|
|
||||||
|
def test_pymethod(app):
|
||||||
|
text = (".. py:class:: Class\n"
|
||||||
|
"\n"
|
||||||
|
" .. py:method:: meth\n")
|
||||||
|
domain = app.env.get_domain('py')
|
||||||
|
doctree = restructuredtext.parse(app, text)
|
||||||
|
assert_node(doctree, (addnodes.index,
|
||||||
|
[desc, ([desc_signature, ([desc_annotation, "class "],
|
||||||
|
[desc_name, "Class"])],
|
||||||
|
[desc_content, (addnodes.index,
|
||||||
|
desc)])]))
|
||||||
|
|
||||||
|
assert_node(doctree[1][1][0], addnodes.index,
|
||||||
|
entries=[('single', 'meth() (Class method)', 'Class.meth', '', None)])
|
||||||
|
assert_node(doctree[1][1][1], ([desc_signature, ([desc_name, "meth"],
|
||||||
|
[desc_parameterlist, ()])],
|
||||||
|
[desc_content, ()]))
|
||||||
|
assert 'Class.meth' in domain.objects
|
||||||
|
assert domain.objects['Class.meth'] == ('index', 'method')
|
||||||
|
|
||||||
|
|
||||||
|
def test_pyclassmethod(app):
|
||||||
|
text = (".. py:class:: Class\n"
|
||||||
|
"\n"
|
||||||
|
" .. py:classmethod:: meth\n")
|
||||||
|
domain = app.env.get_domain('py')
|
||||||
|
doctree = restructuredtext.parse(app, text)
|
||||||
|
assert_node(doctree, (addnodes.index,
|
||||||
|
[desc, ([desc_signature, ([desc_annotation, "class "],
|
||||||
|
[desc_name, "Class"])],
|
||||||
|
[desc_content, (addnodes.index,
|
||||||
|
desc)])]))
|
||||||
|
assert_node(doctree[1][1][0], addnodes.index,
|
||||||
|
entries=[('single', 'meth() (Class class method)', 'Class.meth', '', None)])
|
||||||
|
assert_node(doctree[1][1][1], ([desc_signature, ([desc_annotation, "classmethod "],
|
||||||
|
[desc_name, "meth"],
|
||||||
|
[desc_parameterlist, ()])],
|
||||||
|
[desc_content, ()]))
|
||||||
|
assert 'Class.meth' in domain.objects
|
||||||
|
assert domain.objects['Class.meth'] == ('index', 'classmethod')
|
||||||
|
|
||||||
|
|
||||||
|
def test_pystaticmethod(app):
|
||||||
|
text = (".. py:class:: Class\n"
|
||||||
|
"\n"
|
||||||
|
" .. py:staticmethod:: meth\n")
|
||||||
|
domain = app.env.get_domain('py')
|
||||||
|
doctree = restructuredtext.parse(app, text)
|
||||||
|
assert_node(doctree, (addnodes.index,
|
||||||
|
[desc, ([desc_signature, ([desc_annotation, "class "],
|
||||||
|
[desc_name, "Class"])],
|
||||||
|
[desc_content, (addnodes.index,
|
||||||
|
desc)])]))
|
||||||
|
assert_node(doctree[1][1][0], addnodes.index,
|
||||||
|
entries=[('single', 'meth() (Class static method)', 'Class.meth', '', None)])
|
||||||
|
assert_node(doctree[1][1][1], ([desc_signature, ([desc_annotation, "static "],
|
||||||
|
[desc_name, "meth"],
|
||||||
|
[desc_parameterlist, ()])],
|
||||||
|
[desc_content, ()]))
|
||||||
|
assert 'Class.meth' in domain.objects
|
||||||
|
assert domain.objects['Class.meth'] == ('index', 'staticmethod')
|
||||||
|
|
||||||
|
|
||||||
|
def test_pyattribute(app):
|
||||||
|
text = (".. py:class:: Class\n"
|
||||||
|
"\n"
|
||||||
|
" .. py:attribute:: attr\n")
|
||||||
|
domain = app.env.get_domain('py')
|
||||||
|
doctree = restructuredtext.parse(app, text)
|
||||||
|
assert_node(doctree, (addnodes.index,
|
||||||
|
[desc, ([desc_signature, ([desc_annotation, "class "],
|
||||||
|
[desc_name, "Class"])],
|
||||||
|
[desc_content, (addnodes.index,
|
||||||
|
desc)])]))
|
||||||
|
assert_node(doctree[1][1][0], addnodes.index,
|
||||||
|
entries=[('single', 'attr (Class attribute)', 'Class.attr', '', None)])
|
||||||
|
assert_node(doctree[1][1][1], ([desc_signature, desc_name, "attr"],
|
||||||
|
[desc_content, ()]))
|
||||||
|
assert 'Class.attr' in domain.objects
|
||||||
|
assert domain.objects['Class.attr'] == ('index', 'attribute')
|
||||||
|
Loading…
Reference in New Issue
Block a user