sphinx-doc / sphinx-doc/sphinx

Circular imports in builtin extensions Sphinx-4.0.1

Open
#9,243 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

type:bug
Dominant language
Python
Stars
8k
Forks
2.6k
PR merge metrics
No merged PRs in 30d

Description

Describe the bug
A project starts to fail building with with Sphinx-4.0.1 with ImportError(s) being raised during setup_extension in Sphinxs application constructor. Note that these extensions are builtin, so there seems nothing can be done on the user side to prevent this (right?).

# from sphinx/application.py:237

        # load all built-in extension modules
        for extension in builtin_extensions:
            self.setup_extension(extension)

Just booting Sphinx fails already, with this stacktrace:

runfile('sphinx', args=['-W', '-n', '-b', 'html', '-d', 'build/doctrees', 'doc', 'build/html', '--keep-going', '-v', '-D', 'nbsphinx_kernel_name=weldx', '-D', 'nbsphinx_execute=never'], wdir='/home/marscher/sources/weldx/', is_module=True)
Running Sphinx v4.0.1
Original exception:
Traceback (most recent call last):
  File "/home/marscher/miniconda3/envs/weldx/lib/python3.9/site-packages/sphinx/registry.py", line 420, in load_extension
    mod = import_module(extname)
  File "/home/marscher/miniconda3/envs/weldx/lib/python3.9/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 680, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 790, in exec_module
  File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
  File "/home/marscher/miniconda3/envs/weldx/lib/python3.9/site-packages/sphinx/builders/epub3.py", line 18, in <module>
    from sphinx.builders import _epub_base
  File "/home/marscher/software/pycharm-2019.2.4/plugins/python/helpers/pydev/_pydev_bundle/pydev_import_hook.py", line 21, in do_import
    module = self._system_import(name, *args, **kwargs)
  File "/home/marscher/miniconda3/envs/weldx/lib/python3.9/site-packages/sphinx/builders/_epub_base.py", line 23, in <module>
    from sphinx.builders.html import BuildInfo, StandaloneHTMLBuilder
  File "/home/marscher/software/pycharm-2019.2.4/plugins/python/helpers/pydev/_pydev_bundle/pydev_import_hook.py", line 21, in do_import
    module = self._system_import(name, *args, **kwargs)
  File "/home/marscher/miniconda3/envs/weldx/lib/python3.9/site-packages/sphinx/builders/html/__init__.py", line 49, in <module>
    from sphinx.writers.html import HTMLTranslator, HTMLWriter
  File "/home/marscher/software/pycharm-2019.2.4/plugins/python/helpers/pydev/_pydev_bundle/pydev_import_hook.py", line 21, in do_import
    module = self._system_import(name, *args, **kwargs)
  File "/home/marscher/miniconda3/envs/weldx/lib/python3.9/site-packages/sphinx/writers/html.py", line 32, in <module>
    from sphinx.builders.html import StandaloneHTMLBuilder
ImportError: cannot import name 'StandaloneHTMLBuilder' from partially initialized module 'sphinx.builders.html' (most likely due to a circular import) (/home/marscher/miniconda3/envs/weldx/lib/python3.9/site-packages/sphinx/builders/html/__init__.py)
Traceback (most recent call last):
  File "/home/marscher/miniconda3/envs/weldx/lib/python3.9/site-packages/sphinx/registry.py", line 420, in load_extension
    mod = import_module(extname)
  File "/home/marscher/miniconda3/envs/weldx/lib/python3.9/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 680, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 790, in exec_module
  File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
  File "/home/marscher/miniconda3/envs/weldx/lib/python3.9/site-packages/sphinx/builders/epub3.py", line 18, in <module>
    from sphinx.builders import _epub_base
  File "/home/marscher/software/pycharm-2019.2.4/plugins/python/helpers/pydev/_pydev_bundle/pydev_import_hook.py", line 21, in do_import
    module = self._system_import(name, *args, **kwargs)
  File "/home/marscher/miniconda3/envs/weldx/lib/python3.9/site-packages/sphinx/builders/_epub_base.py", line 23, in <module>
    from sphinx.builders.html import BuildInfo, StandaloneHTMLBuilder
  File "/home/marscher/software/pycharm-2019.2.4/plugins/python/helpers/pydev/_pydev_bundle/pydev_import_hook.py", line 21, in do_import
    module = self._system_import(name, *args, **kwargs)
  File "/home/marscher/miniconda3/envs/weldx/lib/python3.9/site-packages/sphinx/builders/html/__init__.py", line 49, in <module>
    from sphinx.writers.html import HTMLTranslator, HTMLWriter
  File "/home/marscher/software/pycharm-2019.2.4/plugins/python/helpers/pydev/_pydev_bundle/pydev_import_hook.py", line 21, in do_import
    module = self._system_import(name, *args, **kwargs)
  File "/home/marscher/miniconda3/envs/weldx/lib/python3.9/site-packages/sphinx/writers/html.py", line 32, in <module>
    from sphinx.builders.html import StandaloneHTMLBuilder
ImportError: cannot import name 'StandaloneHTMLBuilder' from partially initialized module 'sphinx.builders.html' (most likely due to a circular import) (/home/marscher/miniconda3/envs/weldx/lib/python3.9/site-packages/sphinx/builders/html/__init__.py)
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
  File "/home/marscher/miniconda3/envs/weldx/lib/python3.9/site-packages/sphinx/cmd/build.py", line 281, in build_main
    app = Sphinx(args.sourcedir, args.confdir, args.outputdir,
  File "/home/marscher/miniconda3/envs/weldx/lib/python3.9/site-packages/sphinx/application.py", line 239, in __init__
    self.setup_extension(extension)
  File "/home/marscher/miniconda3/envs/weldx/lib/python3.9/site-packages/sphinx/application.py", line 400, in setup_extension
    self.registry.load_extension(self, extname)
  File "/home/marscher/miniconda3/envs/weldx/lib/python3.9/site-packages/sphinx/registry.py", line 423, in load_extension
    raise ExtensionError(__('Could not import extension %s') % extname,
sphinx.errors.ExtensionError: Could not import extension sphinx.builders.epub3 (exception: cannot import name 'StandaloneHTMLBuilder' from partially initialized module 'sphinx.builders.html' (most likely due to a circular import) (/home/marscher/miniconda3/envs/weldx/lib/python3.9/site-packages/sphinx/builders/html/__init__.py))
Extension error:
Could not import extension sphinx.builders.epub3 (exception: cannot import name 'StandaloneHTMLBuilder' from partially initialized module 'sphinx.builders.html' (most likely due to a circular import) (/home/marscher/miniconda3/envs/weldx/lib/python3.9/site-packages/sphinx/builders/html/__init__.py))
Process finished with exit code 2

To Reproduce
Steps to reproduce the behavior:

$ git clone https://github.com/BAMWelDX/weldx/
$ cd weldx
$ pip install -e .
$ sphinx-build -W -n -b html -d build/doctrees doc build/html --keep-going

Expected behavior
No circular imports during importing builtin extensions.

Your project
https://github.com/BAMWelDX/weldx/

Failing CI: https://github.com/BAMWelDX/weldx/pull/355/checks?check_run_id=2598128954
RTD: https://readthedocs.org/projects/weldx/builds/13779787/

Environment info

  • OS: Linux
  • Python version: 3.9.2
  • Sphinx version: 4.0.2
  • Sphinx extensions: recommonmark, sphinxcontrib.napoleon, nbsphinx, sphinx.ext.autodoc, sphinx.ext.autosummary, sphinx.ext.intersphinx, sphinx.ext.mathjax, sphinx_copybutton, sphinx_asdf, numpydoc, sphinx_autodoc_typehints

Workaround
Hack into sphinx/cmd/build.py:31

from sphinx.util.docutils import docutils_namespace, patch_docutils
# prevent circular imports...
import sphinx.builders.html
import sphinx.builders.latex
import sphinx.builders.texinfo
import sphinx.builders.text
import sphinx.ext.autodoc

def handle_exception(app: Sphinx, args: Any, exception: BaseException, stderr: IO = sys.stderr) -> None:  # NOQA

This makes the build passing again.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the builtin extension loading in sphinx/application.py and the import paths shown through sphinx/builders/epub3.py, sphinx/builders/_epub_base.py, sphinx/builders/html/init.py, and sphinx/writers/html.py. Reproduce the failure with the listed sphinx-build command and inspect why the HTML builder and writer import each other during setup. Done means builtin extensions load without circular-import errors and the documented reproduction builds successfully.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
documentation
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.