From 63fbfb02f1c30016a6c9251443f2621d2b9700eb Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Mon, 17 May 2021 00:21:08 +0900 Subject: [PATCH] refactor: Make the app argument for BuildEnvironment required At present, some attributes of env object are considered as optional because they have been initialized by None on the constructor. But they have always been fullfilled actually. To be clear the type hints of the env object, this makes the `app` argument for the BuildEnvironment class required. It can ensure the attributes of env object are not optional. --- CHANGES | 2 ++ doc/extdev/deprecated.rst | 5 +++++ sphinx/application.py | 3 +-- sphinx/environment/__init__.py | 5 +++++ sphinx/ext/autosummary/__init__.py | 19 ++++++++++++++++--- 5 files changed, 29 insertions(+), 5 deletions(-) diff --git a/CHANGES b/CHANGES index a65cbbcf0..2f54a3976 100644 --- a/CHANGES +++ b/CHANGES @@ -12,6 +12,8 @@ Incompatible changes Deprecated ---------- +* The ``app`` argument of ``sphinx.environment.BuildEnvironment`` becomes + required * ``sphinx.application.Sphinx.html_theme`` * ``sphinx.util.docstrings.extract_metadata()`` diff --git a/doc/extdev/deprecated.rst b/doc/extdev/deprecated.rst index 79081828b..f04b738de 100644 --- a/doc/extdev/deprecated.rst +++ b/doc/extdev/deprecated.rst @@ -22,6 +22,11 @@ The following is a list of deprecated interfaces. - (will be) Removed - Alternatives + * - The optional argument ``app`` for ``sphinx.environment.BuildEnvironment`` + - 4.1 + - 6.0 + - The required argument + * - ``sphinx.application.Sphinx.html_theme`` - 4.1 - 6.0 diff --git a/sphinx/application.py b/sphinx/application.py index 07049ffcd..4aeca54f4 100644 --- a/sphinx/application.py +++ b/sphinx/application.py @@ -300,8 +300,7 @@ class Sphinx: def _init_env(self, freshenv: bool) -> None: filename = path.join(self.doctreedir, ENV_PICKLE_FILENAME) if freshenv or not os.path.exists(filename): - self.env = BuildEnvironment() - self.env.setup(self) + self.env = BuildEnvironment(self) self.env.find_files(self.config, self.builder) else: try: diff --git a/sphinx/environment/__init__.py b/sphinx/environment/__init__.py index 2914a78af..15653a3fe 100644 --- a/sphinx/environment/__init__.py +++ b/sphinx/environment/__init__.py @@ -10,6 +10,7 @@ import os import pickle +import warnings from collections import defaultdict from copy import copy from datetime import datetime @@ -22,6 +23,7 @@ from docutils.nodes import Node from sphinx import addnodes from sphinx.config import Config +from sphinx.deprecation import RemovedInSphinx60Warning from sphinx.domains import Domain from sphinx.environment.adapters.toctree import TocTree from sphinx.errors import BuildEnvironmentError, DocumentError, ExtensionError, SphinxError @@ -181,6 +183,9 @@ class BuildEnvironment: # set up environment if app: self.setup(app) + else: + warnings.warn("The 'app' argument for BuildEnvironment() becomes required now.", + RemovedInSphinx60Warning, stacklevel=2) def __getstate__(self) -> Dict: """Obtains serializable data for pickling.""" diff --git a/sphinx/ext/autosummary/__init__.py b/sphinx/ext/autosummary/__init__.py index 0bf921f0b..32f11baff 100644 --- a/sphinx/ext/autosummary/__init__.py +++ b/sphinx/ext/autosummary/__init__.py @@ -80,7 +80,9 @@ from sphinx.ext.autodoc.directive import DocumenterBridge, Options from sphinx.ext.autodoc.importer import import_module from sphinx.ext.autodoc.mock import mock from sphinx.locale import __ +from sphinx.project import Project from sphinx.pycode import ModuleAnalyzer, PycodeError +from sphinx.registry import SphinxComponentRegistry from sphinx.util import logging, rst from sphinx.util.docutils import (NullReporter, SphinxDirective, SphinxRole, new_document, switch_source_input) @@ -168,13 +170,24 @@ def autosummary_table_visit_html(self: HTMLTranslator, node: autosummary_table) _app: Sphinx = None +class FakeApplication: + def __init__(self): + self.doctreedir = None + self.events = None + self.extensions = {} + self.srcdir = None + self.config = Config() + self.project = Project(None, None) + self.registry = SphinxComponentRegistry() + + class FakeDirective(DocumenterBridge): def __init__(self) -> None: settings = Struct(tab_width=8) document = Struct(settings=settings) - env = BuildEnvironment() - env.config = Config() - env.config.add('autodoc_class_signature', 'mixed', True, None) + app = FakeApplication() + app.config.add('autodoc_class_signature', 'mixed', True, None) + env = BuildEnvironment(app) # type: ignore state = Struct(document=document) super().__init__(env, None, Options(), 0, state)