Simplified module_has_submodule on Python >= 3.3.

Stopped using the imp module on Python >= 3.3. Refs #21628.
This commit is contained in:
Aymeric Augustin 2014-06-07 21:55:16 +02:00
parent 47a9347b98
commit d7f1f316bc
1 changed files with 77 additions and 57 deletions

View File

@ -1,7 +1,6 @@
from __future__ import absolute_import # Avoid importing `importlib` from this package. from __future__ import absolute_import # Avoid importing `importlib` from this package.
import copy import copy
import imp
from importlib import import_module from importlib import import_module
import os import os
import sys import sys
@ -87,67 +86,88 @@ def autodiscover_modules(*args, **kwargs):
raise raise
def module_has_submodule(package, module_name): if sys.version_info[:2] >= (3, 3):
"""See if 'module' is in 'package'.""" if sys.version_info[:2] >= (3, 4):
name = ".".join([package.__name__, module_name]) from importlib.util import find_spec as importlib_find
try: else:
# None indicates a cached miss; see mark_miss() in Python/import.c. from importlib import find_loader as importlib_find
return sys.modules[name] is not None
except KeyError: def module_has_submodule(package, module_name):
pass """See if 'module' is in 'package'."""
try:
package_path = package.__path__ # No __path__, then not a package.
except AttributeError:
# Since the remainder of this function assumes that we're dealing with
# a package (module with a __path__), so if it's not, then bail here.
return False
for finder in sys.meta_path:
if finder.find_module(name, package_path):
return True
for entry in package_path:
try: try:
# Try the cached finder. package_name = package.__name__
finder = sys.path_importer_cache[entry] package_path = package.__path__
if finder is None: except AttributeError:
# Implicit import machinery should be used. # package isn't a package.
try: return False
file_, _, _ = imp.find_module(module_name, [entry])
if file_: full_module_name = package_name + '.' + module_name
file_.close() return importlib_find(full_module_name, package_path) is not None
return True
except ImportError: else:
continue import imp
# Else see if the finder knows of a loader.
elif finder.find_module(name): def module_has_submodule(package, module_name):
return True """See if 'module' is in 'package'."""
else: name = ".".join([package.__name__, module_name])
continue try:
# None indicates a cached miss; see mark_miss() in Python/import.c.
return sys.modules[name] is not None
except KeyError: except KeyError:
# No cached finder, so try and make one. pass
for hook in sys.path_hooks: try:
try: package_path = package.__path__ # No __path__, then not a package.
finder = hook(entry) except AttributeError:
# XXX Could cache in sys.path_importer_cache # Since the remainder of this function assumes that we're dealing with
if finder.find_module(name): # a package (module with a __path__), so if it's not, then bail here.
return True return False
else: for finder in sys.meta_path:
# Once a finder is found, stop the search. if finder.find_module(name, package_path):
break return True
except ImportError: for entry in package_path:
# Continue the search for a finder. try:
continue # Try the cached finder.
else: finder = sys.path_importer_cache[entry]
# No finder found. if finder is None:
# Try the implicit import machinery if searching a directory. # Implicit import machinery should be used.
if os.path.isdir(entry):
try: try:
file_, _, _ = imp.find_module(module_name, [entry]) file_, _, _ = imp.find_module(module_name, [entry])
if file_: if file_:
file_.close() file_.close()
return True return True
except ImportError: except ImportError:
pass continue
# XXX Could insert None or NullImporter # Else see if the finder knows of a loader.
else: elif finder.find_module(name):
# Exhausted the search, so the module cannot be found. return True
return False else:
continue
except KeyError:
# No cached finder, so try and make one.
for hook in sys.path_hooks:
try:
finder = hook(entry)
# XXX Could cache in sys.path_importer_cache
if finder.find_module(name):
return True
else:
# Once a finder is found, stop the search.
break
except ImportError:
# Continue the search for a finder.
continue
else:
# No finder found.
# Try the implicit import machinery if searching a directory.
if os.path.isdir(entry):
try:
file_, _, _ = imp.find_module(module_name, [entry])
if file_:
file_.close()
return True
except ImportError:
pass
# XXX Could insert None or NullImporter
else:
# Exhausted the search, so the module cannot be found.
return False