Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

autosummary: autosummary: import_by_name() now raises ImportExceptionGroup #10036

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGES
Expand Up @@ -9,6 +9,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
Expand Down
18 changes: 12 additions & 6 deletions sphinx/ext/autosummary/__init__.py
Expand Up @@ -74,7 +74,7 @@
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
Expand Down Expand Up @@ -306,7 +306,7 @@ def run(self) -> List[Node]:
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:
Expand Down Expand Up @@ -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:
Expand All @@ -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] = []

Expand Down Expand Up @@ -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.
"""
Expand Down Expand Up @@ -774,7 +780,7 @@ def run(self) -> Tuple[List[Node], List[system_message]]:
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(),
Expand Down
4 changes: 2 additions & 2 deletions sphinx/ext/autosummary/generate.py
Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand Down