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: catch all exceptions when importing modules #4212

Merged
merged 1 commit into from Nov 11, 2017
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
23 changes: 21 additions & 2 deletions sphinx/ext/autosummary/__init__.py
Expand Up @@ -58,6 +58,8 @@
import sys
import inspect
import posixpath
import traceback
import warnings
from six import string_types
from types import ModuleType

Expand Down Expand Up @@ -502,6 +504,22 @@ def import_by_name(name, prefixes=[None]):
raise ImportError('no module named %s' % ' or '.join(tried))


def _import_module(modname):
"""
Call __import__(modname), convert exceptions to ImportError
"""
try:
with warnings.catch_warnings():
warnings.filterwarnings("ignore", category=ImportWarning)
return __import__(modname)
except BaseException:
# Importing modules may cause any side effects, including
# SystemExit, so we need to catch all errors.
errmsg = "Failed to import %r: %s" % (
modname, traceback.format_exc())
raise ImportError(errmsg)


def _import_by_name(name):
# type: (str) -> Tuple[Any, Any, unicode]
"""Import a Python object given its full name."""
Expand All @@ -512,7 +530,7 @@ def _import_by_name(name):
modname = '.'.join(name_parts[:-1])
if modname:
try:
__import__(modname)
_import_module(modname)
mod = sys.modules[modname]
return getattr(mod, name_parts[-1]), mod, modname
except (ImportError, IndexError, AttributeError):
Expand All @@ -525,9 +543,10 @@ def _import_by_name(name):
last_j = j
modname = '.'.join(name_parts[:j])
try:
__import__(modname)
_import_module(modname)
except ImportError:
continue

if modname in sys.modules:
break

Expand Down
4 changes: 4 additions & 0 deletions tests/roots/test-ext-autosummary/autosummary_importfail.py
@@ -0,0 +1,4 @@
import sys

# Fail module import in a catastrophic way
sys.exit(1)
5 changes: 5 additions & 0 deletions tests/roots/test-ext-autosummary/contents.rst
@@ -1,6 +1,11 @@

:autolink:`autosummary_dummy_module.Foo`

:autolink:`autosummary_importfail`

.. autosummary::
:toctree: generated

autosummary_dummy_module
autosummary_dummy_module.Foo
autosummary_importfail