diff --git a/CHANGES b/CHANGES index 36177d28ba..87b35403da 100644 --- a/CHANGES +++ b/CHANGES @@ -7,6 +7,9 @@ Dependencies Incompatible changes -------------------- +* #10474: :confval:`language` does not accept ``None`` as it value. The default + value of ``language`` becomes to ``'en'`` now. + Deprecated ---------- diff --git a/doc/usage/configuration.rst b/doc/usage/configuration.rst index 677eb39271..f297e5c5cb 100644 --- a/doc/usage/configuration.rst +++ b/doc/usage/configuration.rst @@ -725,7 +725,7 @@ documentation on :ref:`intl` for details. (e.g. the German version of ``myfigure.png`` will be ``myfigure.de.png`` by default setting) and substitute them for original figures. In the LaTeX builder, a suitable language will be selected as an option for the *Babel* - package. Default is ``None``, which means that no translation will be done. + package. Default is ``'en'``. .. versionadded:: 0.5 @@ -733,6 +733,8 @@ documentation on :ref:`intl` for details. Support figure substitution + .. versionchanged:: 5.0 + Currently supported languages by Sphinx are: * ``ar`` -- Arabic @@ -745,7 +747,7 @@ documentation on :ref:`intl` for details. * ``da`` -- Danish * ``de`` -- German * ``el`` -- Greek - * ``en`` -- English + * ``en`` -- English (default) * ``eo`` -- Esperanto * ``es`` -- Spanish * ``et`` -- Estonian diff --git a/sphinx/config.py b/sphinx/config.py index 5f92479d38..15337e924d 100644 --- a/sphinx/config.py +++ b/sphinx/config.py @@ -163,6 +163,17 @@ def read(cls, confdir: str, overrides: Dict = None, tags: Tags = None) -> "Confi raise ConfigError(__("config directory doesn't contain a conf.py file (%s)") % confdir) namespace = eval_config_file(filename, tags) + + # Note: Old sphinx projects have been configured as "langugae = None" because + # sphinx-quickstart previously generated this by default. + # To keep compatibility, they should be fallback to 'en' for a while + # (This conversion should not be removed before 2025-01-01). + if namespace.get("language", ...) is None: + logger.warning(__("Invalid configuration value found: 'language = None'. " + "Update your configuration to a valid langauge code. " + "Falling back to 'en' (English).")) + namespace["language"] = "en" + return cls(namespace, overrides or {}) def convert_overrides(self, name: str, value: Any) -> Any: diff --git a/tests/test_config.py b/tests/test_config.py index 3d72a6b0f0..c0b8864e00 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -381,3 +381,49 @@ def test_nitpick_ignore_regex_fullmatch(app, status, warning): assert len(warning) == len(nitpick_warnings) for actual, expected in zip(warning, nitpick_warnings): assert expected in actual + + +def test_conf_py_language_none(tempdir): + """Regression test for #10474.""" + + # Given a conf.py file with language = None + (tempdir / 'conf.py').write_text("language = None", encoding='utf-8') + + # When we load conf.py into a Config object + cfg = Config.read(tempdir, {}, None) + cfg.init_values() + + # Then the language is coerced to English + assert cfg.language == "en" + + +@mock.patch("sphinx.config.logger") +def test_conf_py_language_none_warning(logger, tempdir): + """Regression test for #10474.""" + + # Given a conf.py file with language = None + (tempdir / 'conf.py').write_text("language = None", encoding='utf-8') + + # When we load conf.py into a Config object + Config.read(tempdir, {}, None) + + # Then a warning is raised + assert logger.warning.called + assert logger.warning.call_args[0][0] == ( + "Invalid configuration value found: 'language = None'. " + "Update your configuration to a valid langauge code. " + "Falling back to 'en' (English).") + + +def test_conf_py_no_language(tempdir): + """Regression test for #10474.""" + + # Given a conf.py file with no language attribute + (tempdir / 'conf.py').write_text("", encoding='utf-8') + + # When we load conf.py into a Config object + cfg = Config.read(tempdir, {}, None) + cfg.init_values() + + # Then the language is coerced to English + assert cfg.language == "en"