Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/sphinx-doc/sphinx.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakeshi KOMIYA <i.tkomiya@gmail.com>2020-03-11 18:54:39 +0300
committerTakeshi KOMIYA <i.tkomiya@gmail.com>2021-03-10 19:56:39 +0300
commit204f86f736ae59b7f2a26ef31ba48f8165fcd10e (patch)
tree692a224c04cc21e9085ae1e486d6054a832e58bc /sphinx/domains
parent3693ffe232260c9ba083a231480f1be5ab818641 (diff)
py domain: Add py:property directive to describe a property (refs: #7068)
Diffstat (limited to 'sphinx/domains')
-rw-r--r--sphinx/domains/python.py53
1 files changed, 52 insertions, 1 deletions
diff --git a/sphinx/domains/python.py b/sphinx/domains/python.py
index 40a67f82c..f4958a536 100644
--- a/sphinx/domains/python.py
+++ b/sphinx/domains/python.py
@@ -825,6 +825,46 @@ class PyAttribute(PyObject):
return _('%s (%s attribute)') % (attrname, clsname)
+class PyProperty(PyObject):
+ """Description of an attribute."""
+
+ option_spec = PyObject.option_spec.copy()
+ option_spec.update({
+ 'abstractmethod': directives.flag,
+ 'type': directives.unchanged,
+ })
+
+ def handle_signature(self, sig: str, signode: desc_signature) -> Tuple[str, str]:
+ fullname, prefix = super().handle_signature(sig, signode)
+
+ typ = self.options.get('type')
+ if typ:
+ signode += addnodes.desc_annotation(typ, ': ' + typ)
+
+ return fullname, prefix
+
+ def get_signature_prefix(self, sig: str) -> str:
+ prefix = ['property']
+ if 'abstractmethod' in self.options:
+ prefix.insert(0, 'abstract')
+
+ return ' '.join(prefix) + ' '
+
+ def get_index_text(self, modname: str, name_cls: 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 property)') % (attrname, clsname)
+
+
class PyDecoratorMixin:
"""
Mixin for decorator directives.
@@ -1056,6 +1096,7 @@ class PythonDomain(Domain):
'classmethod': ObjType(_('class method'), 'meth', 'obj'),
'staticmethod': ObjType(_('static method'), 'meth', 'obj'),
'attribute': ObjType(_('attribute'), 'attr', 'obj'),
+ 'property': ObjType(_('property'), 'attr', '_prop', 'obj'),
'module': ObjType(_('module'), 'mod', 'obj'),
} # type: Dict[str, ObjType]
@@ -1068,6 +1109,7 @@ class PythonDomain(Domain):
'classmethod': PyClassMethod,
'staticmethod': PyStaticMethod,
'attribute': PyAttribute,
+ 'property': PyProperty,
'module': PyModule,
'currentmodule': PyCurrentModule,
'decorator': PyDecoratorFunction,
@@ -1205,8 +1247,17 @@ class PythonDomain(Domain):
type, searchmode)
if not matches and type == 'attr':
- # fallback to meth (for property)
+ # fallback to meth (for property; Sphinx-2.4.x)
+ # this ensures that `:attr:` role continues to refer to the old property entry
+ # that defined by ``method`` directive in old reST files.
matches = self.find_obj(env, modname, clsname, target, 'meth', searchmode)
+ if not matches and type == 'meth':
+ # fallback to attr (for property)
+ # this ensures that `:meth:` in the old reST files can refer to the property
+ # entry that defined by ``property`` directive.
+ #
+ # Note: _prop is a secret role only for internal look-up.
+ matches = self.find_obj(env, modname, clsname, target, '_prop', searchmode)
if not matches:
return None