diff --git a/sphinx/application.py b/sphinx/application.py index df2fc00ee..6b1779016 100644 --- a/sphinx/application.py +++ b/sphinx/application.py @@ -29,9 +29,7 @@ from sphinx import package_dir, locale from sphinx.config import Config from sphinx.deprecation import RemovedInSphinx20Warning, RemovedInSphinx30Warning from sphinx.environment import BuildEnvironment -from sphinx.errors import ( - ApplicationError, ConfigError, ExtensionError, VersionRequirementError -) +from sphinx.errors import ApplicationError, ConfigError, VersionRequirementError from sphinx.events import EventManager from sphinx.locale import __ from sphinx.registry import SphinxComponentRegistry @@ -556,8 +554,6 @@ class Sphinx(object): """ logger.debug('[app] adding config value: %r', (name, default, rebuild) + ((types,) if types else ())) # type: ignore - if name in self.config: - raise ExtensionError(__('Config value %r already present') % name) if rebuild in (False, True): rebuild = rebuild and 'env' or '' self.config.add(name, default, rebuild, types) diff --git a/sphinx/config.py b/sphinx/config.py index 0ffa128f3..7818244e5 100644 --- a/sphinx/config.py +++ b/sphinx/config.py @@ -19,7 +19,7 @@ from typing import Any, NamedTuple, Union from six import PY2, PY3, iteritems, string_types, binary_type, text_type, integer_types from sphinx.deprecation import RemovedInSphinx30Warning -from sphinx.errors import ConfigError +from sphinx.errors import ConfigError, ExtensionError from sphinx.locale import _, __ from sphinx.util import logging from sphinx.util.i18n import format_date @@ -347,7 +347,10 @@ class Config(object): def add(self, name, default, rebuild, types): # type: (unicode, Any, Union[bool, unicode], Any) -> None - self.values[name] = (default, rebuild, types) + if name in self.values: + raise ExtensionError(__('Config value %r already present') % name) + else: + self.values[name] = (default, rebuild, types) def filter(self, rebuild): # type: (Union[unicode, List[unicode]]) -> Iterator[ConfigValue] diff --git a/sphinx/ext/autodoc/__init__.py b/sphinx/ext/autodoc/__init__.py index 132116d55..b956fdb7e 100644 --- a/sphinx/ext/autodoc/__init__.py +++ b/sphinx/ext/autodoc/__init__.py @@ -20,8 +20,8 @@ from docutils.statemachine import ViewList from six import iteritems, itervalues, text_type, class_types, string_types import sphinx -from sphinx.application import ExtensionError from sphinx.deprecation import RemovedInSphinx20Warning +from sphinx.errors import ExtensionError from sphinx.ext.autodoc.importer import mock, import_object, get_object_members from sphinx.ext.autodoc.importer import _MockImporter # to keep compatibility # NOQA from sphinx.ext.autodoc.inspector import format_annotation, formatargspec # to keep compatibility # NOQA diff --git a/sphinx/ext/jsmath.py b/sphinx/ext/jsmath.py index e523b54c8..ffa36969d 100644 --- a/sphinx/ext/jsmath.py +++ b/sphinx/ext/jsmath.py @@ -15,7 +15,7 @@ from typing import TYPE_CHECKING from docutils import nodes import sphinx -from sphinx.application import ExtensionError +from sphinx.errors import ExtensionError from sphinx.ext.mathbase import get_node_equation_number from sphinx.ext.mathbase import setup_math as mathbase_setup from sphinx.locale import _ diff --git a/tests/roots/test-root/conf.py b/tests/roots/test-root/conf.py index 38b17f57a..f96ea8821 100644 --- a/tests/roots/test-root/conf.py +++ b/tests/roots/test-root/conf.py @@ -12,7 +12,7 @@ from sphinx import addnodes sys.path.append(os.path.abspath('.')) extensions = ['sphinx.ext.autodoc', 'sphinx.ext.jsmath', 'sphinx.ext.todo', - 'sphinx.ext.coverage', 'sphinx.ext.extlinks', 'ext'] + 'sphinx.ext.coverage', 'sphinx.ext.extlinks'] jsmath_path = 'dummy.js' @@ -65,8 +65,6 @@ man_pages = [ 'Georg Brandl and someone else', 1), ] -value_from_conf_py = 84 - coverage_c_path = ['special/*.h'] coverage_c_regexes = {'function': r'^PyAPI_FUNC\(.*\)\s+([^_][\w_]+)'} @@ -104,7 +102,6 @@ class ClassDirective(Directive): def setup(app): import parsermod - app.add_config_value('value_from_conf_py', 42, False) app.add_directive('clsdir', ClassDirective) app.add_object_type('userdesc', 'userdescrole', '%s (userdesc)', userdesc_parse, objname='user desc') diff --git a/tests/roots/test-root/ext.py b/tests/roots/test-root/ext.py deleted file mode 100644 index 5665bea90..000000000 --- a/tests/roots/test-root/ext.py +++ /dev/null @@ -1,5 +0,0 @@ -# Test extension module - - -def setup(app): - app.add_config_value('value_from_ext', [], False) diff --git a/tests/test_application.py b/tests/test_application.py index babf95497..aa598b00a 100644 --- a/tests/test_application.py +++ b/tests/test_application.py @@ -11,7 +11,7 @@ import pytest from docutils import nodes -from sphinx.application import ExtensionError +from sphinx.errors import ExtensionError from sphinx.domains import Domain from sphinx.testing.util import strip_escseq from sphinx.util import logging diff --git a/tests/test_config.py b/tests/test_config.py index c3600ddca..e48c1c160 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -74,20 +74,24 @@ def test_core_config(app, status, warning): assert cfg['project'] == cfg.project == 'Sphinx Tests' -def test_extension_values(app, status, warning): - cfg = app.config +def test_extension_values(): + config = Config() - # default value - assert cfg.value_from_ext == [] - # non-default value - assert cfg.value_from_conf_py == 84 + # check standard settings + assert config.master_doc == 'contents' - # no duplicate values allowed + # can't override it by add_config_value() with pytest.raises(ExtensionError) as excinfo: - app.add_config_value('html_title', 'x', True) + config.add('master_doc', 'index', 'env', None) assert 'already present' in str(excinfo.value) + + # add a new config value + config.add('value_from_ext', [], 'env', None) + assert config.value_from_ext == [] + + # can't override it by add_config_value() with pytest.raises(ExtensionError) as excinfo: - app.add_config_value('value_from_ext', 'x', True) + config.add('value_from_ext', [], 'env', None) assert 'already present' in str(excinfo.value)