mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2026-10-25 14:40:22 -05:00
Fix viewcode extension importing modules more than once (#13380)
Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com>
This commit is contained in:
1 parent
7e1bf28c28
commit
8ef07089ee
3 files changed
+15
-8
No files matched your search
@@ -45,6 +45,7 @@ Contributors
|
||||
* Daniel Eades -- improved static typing
|
||||
* Daniel Hahler -- testing and CI improvements
|
||||
* Daniel Pizetta -- inheritance diagram improvements
|
||||
* Dave Hoese -- ``sphinx.ext.viewcode`` bug fix
|
||||
* Dave Kuhlman -- original LaTeX writer
|
||||
* Dimitri Papadopoulos Orfanos -- linting and spelling
|
||||
* Dmitry Shachnev -- modernisation and reproducibility
|
||||
|
||||
@@ -19,6 +19,8 @@ Bugs fixed
|
||||
* #13377: Restore support for using ``sphinx.testing.path`` paths with
|
||||
``sphinx.testing.fixtures``.
|
||||
Patch by Kazuya Takei.
|
||||
* #13380: viewcode: Fix importing modules more than once.
|
||||
Patch by Dave Hoese.
|
||||
|
||||
Testing
|
||||
-------
|
||||
|
||||
+12
-8
@@ -2,7 +2,7 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import importlib.util
|
||||
import importlib
|
||||
import operator
|
||||
import posixpath
|
||||
import traceback
|
||||
@@ -62,16 +62,20 @@ def _get_full_modname(modname: str, attribute: str) -> str | None:
|
||||
num_parts = len(module_path)
|
||||
for i in range(num_parts, 0, -1):
|
||||
mod_root = '.'.join(module_path[:i])
|
||||
module_spec = importlib.util.find_spec(mod_root)
|
||||
if module_spec is not None:
|
||||
try:
|
||||
# import_module() caches the module in sys.modules
|
||||
module = importlib.import_module(mod_root)
|
||||
break
|
||||
except ModuleNotFoundError:
|
||||
continue
|
||||
except BaseException as exc:
|
||||
# Importing modules may cause any side effects, including
|
||||
# SystemExit, so we need to catch all errors.
|
||||
msg = f"viewcode failed to import '{mod_root}'."
|
||||
raise ImportError(msg) from exc
|
||||
else:
|
||||
return None
|
||||
# Load and execute the module
|
||||
module = importlib.util.module_from_spec(module_spec)
|
||||
if module_spec.loader is None:
|
||||
return None
|
||||
module_spec.loader.exec_module(module)
|
||||
|
||||
if i != num_parts:
|
||||
for mod in module_path[i:]:
|
||||
module = getattr(module, mod)
|
||||
|
||||
Reference in new issue
Block a user