Merge pull request #9128 from tk0miya/9121_duplicated_warning_for_canonical

Fix #9121: py domain: duplicated warning for canonical and alias
This commit is contained in:
Takeshi KOMIYA 2021-04-24 01:56:34 +09:00 committed by GitHub
commit 5e1e747e8f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 52 additions and 9 deletions

View File

@ -23,6 +23,8 @@ Features added
* #9098: html: copy-range protection for doctests doesn't work in Safari
* #9103: LaTeX: imgconverter: conversion runs even if not needed
* #8127: py domain: Ellipsis in info-field-list causes nit-picky warning
* #9121: py domain: duplicated warning is emitted when both canonical and its
alias objects are defined on the document
* #9023: More CSS classes on domain descriptions, see :ref:`nodes` for details.
Bugs fixed

View File

@ -68,7 +68,7 @@ class ObjectEntry(NamedTuple):
docname: str
node_id: str
objtype: str
canonical: bool
aliased: bool
class ModuleEntry(NamedTuple):
@ -505,7 +505,7 @@ class PyObject(ObjectDescription[Tuple[str, str]]):
canonical_name = self.options.get('canonical')
if canonical_name:
domain.note_object(canonical_name, self.objtype, node_id, canonical=True,
domain.note_object(canonical_name, self.objtype, node_id, aliased=True,
location=signode)
if 'noindexentry' not in self.options:
@ -1138,17 +1138,25 @@ class PythonDomain(Domain):
return self.data.setdefault('objects', {}) # fullname -> ObjectEntry
def note_object(self, name: str, objtype: str, node_id: str,
canonical: bool = False, location: Any = None) -> None:
aliased: bool = False, location: Any = None) -> None:
"""Note a python object for cross reference.
.. versionadded:: 2.1
"""
if name in self.objects:
other = self.objects[name]
logger.warning(__('duplicate object description of %s, '
'other instance in %s, use :noindex: for one of them'),
name, other.docname, location=location)
self.objects[name] = ObjectEntry(self.env.docname, node_id, objtype, canonical)
if other.aliased and aliased is False:
# The original definition found. Override it!
pass
elif other.aliased is False and aliased:
# The original definition is already registered.
return
else:
# duplicated
logger.warning(__('duplicate object description of %s, '
'other instance in %s, use :noindex: for one of them'),
name, other.docname, location=location)
self.objects[name] = ObjectEntry(self.env.docname, node_id, objtype, aliased)
@property
def modules(self) -> Dict[str, ModuleEntry]:
@ -1326,8 +1334,8 @@ class PythonDomain(Domain):
yield (modname, modname, 'module', mod.docname, mod.node_id, 0)
for refname, obj in self.objects.items():
if obj.objtype != 'module': # modules are already handled
if obj.canonical:
# canonical names are not full-text searchable.
if obj.aliased:
# aliased names are not full-text searchable.
yield (refname, refname, obj.objtype, obj.docname, obj.node_id, -1)
else:
yield (refname, refname, obj.objtype, obj.docname, obj.node_id, 1)

View File

@ -870,6 +870,39 @@ def test_canonical(app):
assert domain.objects['_io.StringIO'] == ('index', 'io.StringIO', 'class', True)
def test_canonical_definition_overrides(app, warning):
text = (".. py:class:: io.StringIO\n"
" :canonical: _io.StringIO\n"
".. py:class:: _io.StringIO\n")
restructuredtext.parse(app, text)
assert warning.getvalue() == ""
domain = app.env.get_domain('py')
assert domain.objects['_io.StringIO'] == ('index', 'id0', 'class', False)
def test_canonical_definition_skip(app, warning):
text = (".. py:class:: _io.StringIO\n"
".. py:class:: io.StringIO\n"
" :canonical: _io.StringIO\n")
restructuredtext.parse(app, text)
assert warning.getvalue() == ""
domain = app.env.get_domain('py')
assert domain.objects['_io.StringIO'] == ('index', 'io.StringIO', 'class', False)
def test_canonical_duplicated(app, warning):
text = (".. py:class:: mypackage.StringIO\n"
" :canonical: _io.StringIO\n"
".. py:class:: io.StringIO\n"
" :canonical: _io.StringIO\n")
restructuredtext.parse(app, text)
assert warning.getvalue() != ""
def test_info_field_list(app):
text = (".. py:module:: example\n"
".. py:class:: Class\n"