diff --git a/CHANGES b/CHANGES index 6c7747f30..9c61a8b96 100644 --- a/CHANGES +++ b/CHANGES @@ -7,6 +7,11 @@ Dependencies Incompatible changes -------------------- +* #10031: autosummary: ``sphinx.ext.autosummary.import_by_name()`` now raises + ``ImportExceptionGroup`` instead of ``ImportError`` when it failed to import + target object. Please handle the exception if your extension uses the + function to import Python object. As a workaround, you can disable the + behavior via ``grouped_exception=False`` keyword argument until v7.0. * #9962: texinfo: Customizing styles of emphasized text via ``@definfoenclose`` command was not supported because the command was deprecated since texinfo 6.8 * #2068: :confval:`intersphinx_disabled_reftypes` has changed default value diff --git a/sphinx/ext/autosummary/__init__.py b/sphinx/ext/autosummary/__init__.py index e3a04d3c7..e766a414a 100644 --- a/sphinx/ext/autosummary/__init__.py +++ b/sphinx/ext/autosummary/__init__.py @@ -74,7 +74,7 @@ from sphinx import addnodes from sphinx.application import Sphinx from sphinx.config import Config from sphinx.deprecation import (RemovedInSphinx50Warning, RemovedInSphinx60Warning, - deprecated_alias) + RemovedInSphinx70Warning, deprecated_alias) from sphinx.environment import BuildEnvironment from sphinx.environment.adapters.toctree import TocTree from sphinx.ext.autodoc import INSTANCEATTR, Documenter @@ -306,7 +306,7 @@ class Autosummary(SphinxDirective): def import_by_name(self, name: str, prefixes: List[str]) -> Tuple[str, Any, Any, str]: with mock(self.config.autosummary_mock_imports): try: - return import_by_name(name, prefixes, grouped_exception=True) + return import_by_name(name, prefixes) except ImportExceptionGroup as exc: # check existence of instance attribute try: @@ -657,11 +657,17 @@ def get_import_prefixes_from_env(env: BuildEnvironment) -> List[str]: return prefixes -def import_by_name(name: str, prefixes: List[str] = [None], grouped_exception: bool = False +def import_by_name(name: str, prefixes: List[str] = [None], grouped_exception: bool = True ) -> Tuple[str, Any, Any, str]: """Import a Python object that has the given *name*, under one of the *prefixes*. The first name that succeeds is used. """ + if grouped_exception is False: + warnings.warn('Using grouped_exception keyword for import_by_name() is not ' + 'recommended. It will be removed at v7.0. Therefore you should ' + 'catch ImportExceptionGroup exception instead of ImportError.', + RemovedInSphinx70Warning, stacklevel=2) + tried = [] errors: List[ImportExceptionGroup] = [] for prefix in prefixes: @@ -685,7 +691,7 @@ def import_by_name(name: str, prefixes: List[str] = [None], grouped_exception: b raise ImportError('no module named %s' % ' or '.join(tried)) -def _import_by_name(name: str, grouped_exception: bool = False) -> Tuple[Any, Any, str]: +def _import_by_name(name: str, grouped_exception: bool = True) -> Tuple[Any, Any, str]: """Import a Python object given its full name.""" errors: List[BaseException] = [] @@ -733,7 +739,7 @@ def _import_by_name(name: str, grouped_exception: bool = False) -> Tuple[Any, An def import_ivar_by_name(name: str, prefixes: List[str] = [None], - grouped_exception: bool = False) -> Tuple[str, Any, Any, str]: + grouped_exception: bool = True) -> Tuple[str, Any, Any, str]: """Import an instance variable that has the given *name*, under one of the *prefixes*. The first name that succeeds is used. """ @@ -774,7 +780,7 @@ class AutoLink(SphinxRole): try: # try to import object by name prefixes = get_import_prefixes_from_env(self.env) - import_by_name(pending_xref['reftarget'], prefixes, grouped_exception=True) + import_by_name(pending_xref['reftarget'], prefixes) except ImportExceptionGroup: literal = cast(nodes.literal, pending_xref[0]) objects[0] = nodes.emphasis(self.rawtext, literal.astext(), diff --git a/sphinx/ext/autosummary/generate.py b/sphinx/ext/autosummary/generate.py index f11505998..4dee39493 100644 --- a/sphinx/ext/autosummary/generate.py +++ b/sphinx/ext/autosummary/generate.py @@ -431,7 +431,7 @@ def generate_autosummary_docs(sources: List[str], output_dir: str = None, ensuredir(path) try: - name, obj, parent, modname = import_by_name(entry.name, grouped_exception=True) + name, obj, parent, modname = import_by_name(entry.name) qualname = name.replace(modname + ".", "") except ImportExceptionGroup as exc: try: @@ -508,7 +508,7 @@ def find_autosummary_in_docstring(name: str, module: str = None, filename: str = RemovedInSphinx50Warning, stacklevel=2) try: - real_name, obj, parent, modname = import_by_name(name, grouped_exception=True) + real_name, obj, parent, modname = import_by_name(name) lines = pydoc.getdoc(obj).splitlines() return find_autosummary_in_lines(lines, module=name, filename=filename) except AttributeError: