From d7f1f316bcb21853597515a25e6e43639b9ed021 Mon Sep 17 00:00:00 2001 From: Aymeric Augustin Date: Sat, 7 Jun 2014 21:55:16 +0200 Subject: [PATCH] Simplified module_has_submodule on Python >= 3.3. Stopped using the imp module on Python >= 3.3. Refs #21628. --- django/utils/module_loading.py | 134 +++++++++++++++++++-------------- 1 file changed, 77 insertions(+), 57 deletions(-) diff --git a/django/utils/module_loading.py b/django/utils/module_loading.py index bd546ac405..826aed8c00 100644 --- a/django/utils/module_loading.py +++ b/django/utils/module_loading.py @@ -1,7 +1,6 @@ from __future__ import absolute_import # Avoid importing `importlib` from this package. import copy -import imp from importlib import import_module import os import sys @@ -87,67 +86,88 @@ def autodiscover_modules(*args, **kwargs): raise -def module_has_submodule(package, module_name): - """See if 'module' is in 'package'.""" - name = ".".join([package.__name__, module_name]) - try: - # None indicates a cached miss; see mark_miss() in Python/import.c. - return sys.modules[name] is not None - except KeyError: - pass - 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: +if sys.version_info[:2] >= (3, 3): + if sys.version_info[:2] >= (3, 4): + from importlib.util import find_spec as importlib_find + else: + from importlib import find_loader as importlib_find + + def module_has_submodule(package, module_name): + """See if 'module' is in 'package'.""" try: - # Try the cached finder. - finder = sys.path_importer_cache[entry] - if finder is None: - # Implicit import machinery should be used. - try: - file_, _, _ = imp.find_module(module_name, [entry]) - if file_: - file_.close() - return True - except ImportError: - continue - # Else see if the finder knows of a loader. - elif finder.find_module(name): - return True - else: - continue + package_name = package.__name__ + package_path = package.__path__ + except AttributeError: + # package isn't a package. + return False + + full_module_name = package_name + '.' + module_name + return importlib_find(full_module_name, package_path) is not None + +else: + import imp + + def module_has_submodule(package, module_name): + """See if 'module' is in 'package'.""" + name = ".".join([package.__name__, module_name]) + try: + # None indicates a cached miss; see mark_miss() in Python/import.c. + return sys.modules[name] is not None 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): + pass + 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 the cached finder. + finder = sys.path_importer_cache[entry] + if finder is None: + # Implicit import machinery should be used. 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 + continue + # Else see if the finder knows of a loader. + elif finder.find_module(name): + return True + 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