summaryrefslogtreecommitdiff
path: root/sphinx
diff options
context:
space:
mode:
authorJon Dufresne <jon.dufresne@gmail.com>2019-08-17 11:45:39 -0700
committerJon Dufresne <jon.dufresne@gmail.com>2019-08-17 11:45:39 -0700
commitecb1e763ad0917ac37061b648a53793a687cc760 (patch)
treeda14d950c57dd801c1ac2d01995eaec574dcff4e /sphinx
parentbf573ae1454fd0a6f5bbcb316fbabc42a056da3a (diff)
downloadsphinx-git-ecb1e763ad0917ac37061b648a53793a687cc760.tar.gz
Switch uses of __import__ to importlib.get_module()
The Python docs for __import__ recommend using importlib.get_module(). https://docs.python.org/3/library/functions.html#__import__ > Note: This is an advanced function that is not needed in everyday > Python programming, unlike importlib.import_module(). As importlib.get_module() uses the Python module cache and returns the module, this also allows simplifying many module cache checks of use of sys.modules. importlib.get_module() has been available since Python 3.3.
Diffstat (limited to 'sphinx')
-rw-r--r--sphinx/deprecation.py5
-rw-r--r--sphinx/ext/autodoc/importer.py7
-rw-r--r--sphinx/ext/coverage.py3
-rw-r--r--sphinx/ext/inheritance_diagram.py12
-rw-r--r--sphinx/highlighting.py3
-rw-r--r--sphinx/registry.py8
-rw-r--r--sphinx/search/__init__.py4
-rw-r--r--sphinx/util/__init__.py19
8 files changed, 30 insertions, 31 deletions
diff --git a/sphinx/deprecation.py b/sphinx/deprecation.py
index 7cdb1d3d1..57f4b3ddf 100644
--- a/sphinx/deprecation.py
+++ b/sphinx/deprecation.py
@@ -31,10 +31,7 @@ RemovedInNextVersionWarning = RemovedInSphinx30Warning
def deprecated_alias(modname, objects, warning):
# type: (str, Dict, Type[Warning]) -> None
- module = sys.modules.get(modname)
- if module is None:
- module = import_module(modname)
-
+ module = import_module(modname)
sys.modules[modname] = _ModuleWrapper(module, modname, objects, warning) # type: ignore
diff --git a/sphinx/ext/autodoc/importer.py b/sphinx/ext/autodoc/importer.py
index fc934958d..54901be44 100644
--- a/sphinx/ext/autodoc/importer.py
+++ b/sphinx/ext/autodoc/importer.py
@@ -8,7 +8,7 @@
:license: BSD, see LICENSE for details.
"""
-import sys
+import importlib
import traceback
import warnings
from collections import namedtuple
@@ -23,14 +23,13 @@ logger = logging.getLogger(__name__)
def import_module(modname: str, warningiserror: bool = False) -> Any:
"""
- Call __import__(modname), convert exceptions to ImportError
+ Call importlib.import_module(modname), convert exceptions to ImportError
"""
try:
with warnings.catch_warnings():
warnings.filterwarnings("ignore", category=ImportWarning)
with logging.skip_warningiserror(not warningiserror):
- __import__(modname)
- return sys.modules[modname]
+ return importlib.import_module(modname)
except BaseException as exc:
# Importing modules may cause any side effects, including
# SystemExit, so we need to catch all errors.
diff --git a/sphinx/ext/coverage.py b/sphinx/ext/coverage.py
index 24f51b856..7d53e7bb9 100644
--- a/sphinx/ext/coverage.py
+++ b/sphinx/ext/coverage.py
@@ -13,6 +13,7 @@ import glob
import inspect
import pickle
import re
+from importlib import import_module
from os import path
from typing import Any, Dict, IO, List, Pattern, Set, Tuple
@@ -144,7 +145,7 @@ class CoverageBuilder(Builder):
continue
try:
- mod = __import__(mod_name, fromlist=['foo'])
+ mod = import_module(mod_name)
except ImportError as err:
logger.warning(__('module %s could not be imported: %s'), mod_name, err)
self.py_undoc[mod_name] = {'error': err}
diff --git a/sphinx/ext/inheritance_diagram.py b/sphinx/ext/inheritance_diagram.py
index f52a990bf..ecb6302d1 100644
--- a/sphinx/ext/inheritance_diagram.py
+++ b/sphinx/ext/inheritance_diagram.py
@@ -38,8 +38,8 @@ r"""
import builtins
import inspect
import re
-import sys
from hashlib import md5
+from importlib import import_module
from typing import Any, Dict, Iterable, List, Tuple
from typing import cast
@@ -74,8 +74,10 @@ def try_import(objname: str) -> Any:
Returns imported object or module. If failed, returns None value.
"""
try:
- __import__(objname)
- return sys.modules.get(objname)
+ return import_module(objname)
+ except TypeError:
+ # Relative import
+ return None
except ImportError:
matched = module_sig_re.match(objname)
@@ -87,8 +89,8 @@ def try_import(objname: str) -> Any:
if modname is None:
return None
try:
- __import__(modname)
- return getattr(sys.modules.get(modname), attrname, None)
+ module = import_module(modname)
+ return getattr(module, attrname, None)
except ImportError:
return None
diff --git a/sphinx/highlighting.py b/sphinx/highlighting.py
index b4e63209f..977b71f28 100644
--- a/sphinx/highlighting.py
+++ b/sphinx/highlighting.py
@@ -11,6 +11,7 @@
import html
import warnings
from functools import partial
+from importlib import import_module
from pygments import highlight
from pygments.filters import ErrorToken
@@ -92,7 +93,7 @@ class PygmentsBridge:
return NoneStyle
elif '.' in stylename:
module, stylename = stylename.rsplit('.', 1)
- return getattr(__import__(module, None, None, ['__name__']), stylename)
+ return getattr(import_module(module), stylename)
else:
return get_style_by_name(stylename)
diff --git a/sphinx/registry.py b/sphinx/registry.py
index f8ee39466..3666c758b 100644
--- a/sphinx/registry.py
+++ b/sphinx/registry.py
@@ -10,6 +10,7 @@
import traceback
import warnings
+from importlib import import_module
from inspect import isclass
from types import MethodType
@@ -471,18 +472,19 @@ class SphinxComponentRegistry:
prefix = __('while setting up extension %s:') % extname
with prefixed_warnings(prefix):
try:
- mod = __import__(extname, None, None, ['setup'])
+ mod = import_module(extname)
except ImportError as err:
logger.verbose(__('Original exception:\n') + traceback.format_exc())
raise ExtensionError(__('Could not import extension %s') % extname, err)
- if not hasattr(mod, 'setup'):
+ setup = getattr(mod, 'setup', None)
+ if setup is None:
logger.warning(__('extension %r has no setup() function; is it really '
'a Sphinx extension module?'), extname)
metadata = {} # type: Dict[str, Any]
else:
try:
- metadata = mod.setup(app)
+ metadata = setup(app)
except VersionRequirementError as err:
# add the extension name to the version required
raise VersionRequirementError(
diff --git a/sphinx/search/__init__.py b/sphinx/search/__init__.py
index 1b4f7ea59..22ba14d40 100644
--- a/sphinx/search/__init__.py
+++ b/sphinx/search/__init__.py
@@ -11,6 +11,7 @@ import html
import pickle
import re
import warnings
+from importlib import import_module
from os import path
from docutils import nodes
@@ -278,8 +279,7 @@ class IndexBuilder:
self.lang = SearchEnglish(options) # type: SearchLanguage
elif isinstance(lang_class, str):
module, classname = lang_class.rsplit('.', 1)
- lang_class = getattr(__import__(module, None, None, [classname]),
- classname)
+ lang_class = getattr(import_module(module), classname)
self.lang = lang_class(options)
else:
# it's directly a class (e.g. added by app.add_search_language)
diff --git a/sphinx/util/__init__.py b/sphinx/util/__init__.py
index f06720695..b75e80034 100644
--- a/sphinx/util/__init__.py
+++ b/sphinx/util/__init__.py
@@ -22,6 +22,7 @@ from codecs import BOM_UTF8
from collections import deque
from datetime import datetime
from hashlib import md5
+from importlib import import_module
from os import path
from time import mktime, strptime
from typing import Any, Callable, Dict, IO, Iterable, Iterator, List, Pattern, Set, Tuple
@@ -270,12 +271,10 @@ def get_module_source(modname: str) -> Tuple[str, str]:
Can return ('file', 'filename') in which case the source is in the given
file, or ('string', 'source') which which case the source is the string.
"""
- if modname not in sys.modules:
- try:
- __import__(modname)
- except Exception as err:
- raise PycodeError('error importing %r' % modname, err)
- mod = sys.modules[modname]
+ try:
+ mod = import_module(modname)
+ except Exception as err:
+ raise PycodeError('error importing %r' % modname, err)
filename = getattr(mod, '__file__', None)
loader = getattr(mod, '__loader__', None)
if loader and getattr(loader, 'get_filename', None):
@@ -316,8 +315,7 @@ def get_full_modname(modname: str, attribute: str) -> str:
# Prevents a TypeError: if the last getattr() call will return None
# then it's better to return it directly
return None
- __import__(modname)
- module = sys.modules[modname]
+ module = import_module(modname)
# Allow an attribute to have multiple parts and incidentially allow
# repeated .s in the attribute.
@@ -572,14 +570,13 @@ def import_object(objname: str, source: str = None) -> Any:
try:
objpath = objname.split('.')
modname = objpath.pop(0)
- obj = __import__(modname)
+ obj = import_module(modname)
for name in objpath:
modname += '.' + name
try:
obj = getattr(obj, name)
except AttributeError:
- __import__(modname)
- obj = getattr(obj, name)
+ obj = import_module(modname)
return obj
except (AttributeError, ImportError) as exc: