Merge pull request #10036 from tk0miya/9555_autosummary_raise_ImportExceptionGroup_by_default

autosummary: autosummary: import_by_name() now raises ImportExceptionGroup
This commit is contained in:
Takeshi KOMIYA 2022-01-02 13:03:10 +09:00 committed by GitHub
commit 2d92be7a1a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 19 additions and 8 deletions

View File

@ -7,6 +7,11 @@ Dependencies
Incompatible changes 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`` * #9962: texinfo: Customizing styles of emphasized text via ``@definfoenclose``
command was not supported because the command was deprecated since texinfo 6.8 command was not supported because the command was deprecated since texinfo 6.8
* #2068: :confval:`intersphinx_disabled_reftypes` has changed default value * #2068: :confval:`intersphinx_disabled_reftypes` has changed default value

View File

@ -74,7 +74,7 @@ from sphinx import addnodes
from sphinx.application import Sphinx from sphinx.application import Sphinx
from sphinx.config import Config from sphinx.config import Config
from sphinx.deprecation import (RemovedInSphinx50Warning, RemovedInSphinx60Warning, from sphinx.deprecation import (RemovedInSphinx50Warning, RemovedInSphinx60Warning,
deprecated_alias) RemovedInSphinx70Warning, deprecated_alias)
from sphinx.environment import BuildEnvironment from sphinx.environment import BuildEnvironment
from sphinx.environment.adapters.toctree import TocTree from sphinx.environment.adapters.toctree import TocTree
from sphinx.ext.autodoc import INSTANCEATTR, Documenter 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]: def import_by_name(self, name: str, prefixes: List[str]) -> Tuple[str, Any, Any, str]:
with mock(self.config.autosummary_mock_imports): with mock(self.config.autosummary_mock_imports):
try: try:
return import_by_name(name, prefixes, grouped_exception=True) return import_by_name(name, prefixes)
except ImportExceptionGroup as exc: except ImportExceptionGroup as exc:
# check existence of instance attribute # check existence of instance attribute
try: try:
@ -657,11 +657,17 @@ def get_import_prefixes_from_env(env: BuildEnvironment) -> List[str]:
return prefixes 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]: ) -> Tuple[str, Any, Any, str]:
"""Import a Python object that has the given *name*, under one of the """Import a Python object that has the given *name*, under one of the
*prefixes*. The first name that succeeds is used. *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 = [] tried = []
errors: List[ImportExceptionGroup] = [] errors: List[ImportExceptionGroup] = []
for prefix in prefixes: 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)) 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.""" """Import a Python object given its full name."""
errors: List[BaseException] = [] 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], 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 """Import an instance variable that has the given *name*, under one of the
*prefixes*. The first name that succeeds is used. *prefixes*. The first name that succeeds is used.
""" """
@ -774,7 +780,7 @@ class AutoLink(SphinxRole):
try: try:
# try to import object by name # try to import object by name
prefixes = get_import_prefixes_from_env(self.env) 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: except ImportExceptionGroup:
literal = cast(nodes.literal, pending_xref[0]) literal = cast(nodes.literal, pending_xref[0])
objects[0] = nodes.emphasis(self.rawtext, literal.astext(), objects[0] = nodes.emphasis(self.rawtext, literal.astext(),

View File

@ -431,7 +431,7 @@ def generate_autosummary_docs(sources: List[str], output_dir: str = None,
ensuredir(path) ensuredir(path)
try: 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 + ".", "") qualname = name.replace(modname + ".", "")
except ImportExceptionGroup as exc: except ImportExceptionGroup as exc:
try: try:
@ -508,7 +508,7 @@ def find_autosummary_in_docstring(name: str, module: str = None, filename: str =
RemovedInSphinx50Warning, stacklevel=2) RemovedInSphinx50Warning, stacklevel=2)
try: 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() lines = pydoc.getdoc(obj).splitlines()
return find_autosummary_in_lines(lines, module=name, filename=filename) return find_autosummary_in_lines(lines, module=name, filename=filename)
except AttributeError: except AttributeError: