diff --git a/CHANGES b/CHANGES index e8c0561ab..df590535e 100644 --- a/CHANGES +++ b/CHANGES @@ -20,6 +20,8 @@ Incompatible changes Deprecated ---------- +* ``sphinx.domains.std.StandardDomain.add_object()`` + Features added -------------- @@ -27,6 +29,8 @@ Features added old stub file * #5923: autodoc: ``:inherited-members:`` option takes a name of anchestor class not to document inherited members of the class and uppers +* #6558: glossary: emit a warning for duplicated glossary entry +* #6558: std domain: emit a warning for duplicated generic objects Bugs fixed ---------- @@ -1971,7 +1975,7 @@ Features removed * ``termsep`` node * defindex.html template -* LDML format support in `today`, `today_fmt` and `html_last_updated_fmt` +* LDML format support in ``today``, ``today_fmt`` and ``html_last_updated_fmt`` * ``:inline:`` option for the directives of sphinx.ext.graphviz extension * sphinx.ext.pngmath extension * ``sphinx.util.compat.make_admonition()`` @@ -4775,7 +4779,7 @@ Features added - Added a "nitpicky" mode that emits warnings for all missing references. It is activated by the :option:`sphinx-build -n` command-line - switch or the `nitpicky` config value. + switch or the :confval:`nitpicky` config value. - Added ``latexpdf`` target in quickstart Makefile. * Markup: diff --git a/doc/conf.py b/doc/conf.py index 16594f038..aa513edf8 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -146,6 +146,9 @@ def setup(app): app.add_object_type('confval', 'confval', objname='configuration value', indextemplate='pair: %s; configuration value') + app.add_object_type('setuptools-confval', 'setuptools-confval', + objname='setuptools configuration value', + indextemplate='pair: %s; setuptools configuration value') fdesc = GroupedField('parameter', label='Parameters', names=['param'], can_collapse=True) app.add_object_type('event', 'event', 'pair: %s; event', parse_event, diff --git a/doc/extdev/deprecated.rst b/doc/extdev/deprecated.rst index 6159ae4f7..52dcddfdb 100644 --- a/doc/extdev/deprecated.rst +++ b/doc/extdev/deprecated.rst @@ -26,6 +26,11 @@ The following is a list of deprecated interfaces. - (will be) Removed - Alternatives + * - ``sphinx.domains.std.StandardDomain.add_object()`` + - 3.0 + - 5.0 + - ``sphinx.domains.std.StandardDomain.note_object()`` + * - ``sphinx.environment.BuildEnvironment.indexentries`` - 2.4 - 4.0 diff --git a/doc/usage/advanced/setuptools.rst b/doc/usage/advanced/setuptools.rst index 10cc6a77d..f4dfb7f66 100644 --- a/doc/usage/advanced/setuptools.rst +++ b/doc/usage/advanced/setuptools.rst @@ -57,7 +57,7 @@ Once configured, call this by calling the relevant command on ``setup.py``:: Options for setuptools integration ---------------------------------- -.. confval:: fresh-env +.. setuptools-confval:: fresh-env A boolean that determines whether the saved environment should be discarded on build. Default is false. @@ -68,7 +68,7 @@ Options for setuptools integration $ python setup.py build_sphinx -E -.. confval:: all-files +.. setuptools-confval:: all-files A boolean that determines whether all files should be built from scratch. Default is false. @@ -79,7 +79,7 @@ Options for setuptools integration $ python setup.py build_sphinx -a -.. confval:: source-dir +.. setuptools-confval:: source-dir The target source directory. This can be relative to the ``setup.py`` or ``setup.cfg`` file, or it can be absolute. It defaults to ``./doc`` or @@ -92,12 +92,12 @@ Options for setuptools integration $ python setup.py build_sphinx -s $SOURCE_DIR -.. confval:: build-dir +.. setuptools-confval:: build-dir The target build directory. This can be relative to the ``setup.py`` or ``setup.cfg`` file, or it can be absolute. Default is ``./build/sphinx``. -.. confval:: config-dir +.. setuptools-confval:: config-dir Location of the configuration directory. This can be relative to the ``setup.py`` or ``setup.cfg`` file, or it can be absolute. Default is to use @@ -111,7 +111,7 @@ Options for setuptools integration .. versionadded:: 1.0 -.. confval:: builder +.. setuptools-confval:: builder The builder or list of builders to use. Default is ``html``. @@ -124,7 +124,7 @@ Options for setuptools integration .. versionchanged:: 1.6 This can now be a comma- or space-separated list of builders -.. confval:: warning-is-error +.. setuptools-confval:: warning-is-error A boolean that ensures Sphinx warnings will result in a failed build. Default is false. @@ -137,32 +137,32 @@ Options for setuptools integration .. versionadded:: 1.5 -.. confval:: project +.. setuptools-confval:: project The documented project's name. Default is ``''``. .. versionadded:: 1.0 -.. confval:: version +.. setuptools-confval:: version The short X.Y version. Default is ``''``. .. versionadded:: 1.0 -.. confval:: release +.. setuptools-confval:: release The full version, including alpha/beta/rc tags. Default is ``''``. .. versionadded:: 1.0 -.. confval:: today +.. setuptools-confval:: today How to format the current date, used as the replacement for ``|today|``. Default is ``''``. .. versionadded:: 1.0 -.. confval:: link-index +.. setuptools-confval:: link-index A boolean that ensures index.html will be linked to the master doc. Default is false. @@ -175,13 +175,13 @@ Options for setuptools integration .. versionadded:: 1.0 -.. confval:: copyright +.. setuptools-confval:: copyright The copyright string. Default is ``''``. .. versionadded:: 1.3 -.. confval:: nitpicky +.. setuptools-confval:: nitpicky Run in nit-picky mode. Currently, this generates warnings for all missing references. See the config value :confval:`nitpick_ignore` for a way to @@ -189,7 +189,7 @@ Options for setuptools integration .. versionadded:: 1.8 -.. confval:: pdb +.. setuptools-confval:: pdb A boolean to configure ``pdb`` on exception. Default is false. diff --git a/sphinx/domains/std.py b/sphinx/domains/std.py index 10ca58c5b..dc35b1c2b 100644 --- a/sphinx/domains/std.py +++ b/sphinx/domains/std.py @@ -22,7 +22,7 @@ from docutils.statemachine import StringList from sphinx import addnodes from sphinx.addnodes import desc_signature, pending_xref -from sphinx.deprecation import RemovedInSphinx40Warning +from sphinx.deprecation import RemovedInSphinx40Warning, RemovedInSphinx50Warning from sphinx.directives import ObjectDescription from sphinx.domains import Domain, ObjType from sphinx.locale import _, __ @@ -81,7 +81,8 @@ class GenericObject(ObjectDescription): targetname, '', None)) std = cast(StandardDomain, self.env.get_domain('std')) - std.add_object(self.objtype, name, self.env.docname, targetname) + std.note_object(self.objtype, name, targetname, + location=(self.env.docname, self.lineno)) class EnvVar(GenericObject): @@ -143,7 +144,7 @@ class Target(SphinxDirective): _, name = self.name.split(':', 1) std = cast(StandardDomain, self.env.get_domain('std')) - std.add_object(name, fullname, self.env.docname, targetname) + std.note_object(name, fullname, targetname, location=(self.env.docname, self.lineno)) return ret @@ -261,7 +262,7 @@ def make_glossary_term(env: "BuildEnvironment", textnodes: Iterable[Node], index gloss_entries.add(new_id) std = cast(StandardDomain, env.get_domain('std')) - std.add_object('term', termtext.lower(), env.docname, new_id) + std.note_object('term', termtext.lower(), new_id, location=(env.docname, lineno)) # add an index entry too indexnode = addnodes.index() @@ -443,7 +444,8 @@ class ProductionList(SphinxDirective): if idname not in self.state.document.ids: subnode['ids'].append(idname) self.state.document.note_implicit_target(subnode, subnode) - domain.add_object('token', subnode['tokenname'], self.env.docname, idname) + domain.note_object('token', subnode['tokenname'], idname, + location=(self.env.docname, self.lineno)) subnode.extend(token_xrefs(tokens)) node.append(subnode) return [node] @@ -539,6 +541,23 @@ class StandardDomain(Domain): def objects(self) -> Dict[Tuple[str, str], Tuple[str, str]]: return self.data.setdefault('objects', {}) # (objtype, name) -> docname, labelid + def note_object(self, objtype: str, name: str, labelid: str, location: Any = None + ) -> None: + """Note a generic object for cross reference. + + .. versionadded:: 3.0 + """ + if (objtype, name) in self.objects: + docname = self.objects[objtype, name][0] + logger.warning(__('duplicate %s description of %s, other instance in %s'), + objtype, name, docname, location=location) + self.objects[objtype, name] = (self.env.docname, labelid) + + def add_object(self, objtype: str, name: str, docname: str, labelid: str) -> None: + warnings.warn('StandardDomain.add_object() is deprecated.', + RemovedInSphinx50Warning) + self.objects[objtype, name] = (docname, labelid) + @property def progoptions(self) -> Dict[Tuple[str, str], Tuple[str, str]]: return self.data.setdefault('progoptions', {}) # (program, name) -> docname, labelid @@ -620,9 +639,6 @@ class StandardDomain(Domain): continue self.labels[name] = docname, labelid, sectname - def add_object(self, objtype: str, name: str, docname: str, labelid: str) -> None: - self.objects[objtype, name] = (docname, labelid) - def add_program_option(self, program: str, name: str, docname: str, labelid: str) -> None: self.progoptions[program, name] = (docname, labelid) diff --git a/tests/test_domain_std.py b/tests/test_domain_std.py index c7a7b496a..db1346bcf 100644 --- a/tests/test_domain_std.py +++ b/tests/test_domain_std.py @@ -172,6 +172,15 @@ def test_glossary_warning(app, status, warning): assert ("case3.rst:4: WARNING: glossary term must be preceded by empty line" in warning.getvalue()) + # duplicated terms + text = (".. glossary::\n" + "\n" + " term-case4\n" + " term-case4\n") + restructuredtext.parse(app, text, "case4") + assert ("case4.txt:3: WARNING: duplicate term description of term-case4, " + "other instance in case4" in warning.getvalue()) + def test_glossary_comment(app): text = (".. glossary::\n"