[jhbuild/pre-3-cleanup: 1/6] Improve dynamic import error handling



commit 5e31ea839b6beea8aa379db9552068c5971a8c21
Author: Christoph Reiter <reiter christoph gmail com>
Date:   Sat Sep 21 19:33:27 2019 +0200

    Improve dynamic import error handling
    
    Replace all code trying to import a module and skipping the import if
    the module isn't there with try_import_module(). This allows us to only
    skip the module-not-there case and raise with all other errors.
    
    This is mainly helpful with Python 3 porting where invalid imports/syntax
    make the imports fail but those errors getting ignored and things failing
    later on without context.
    
    This also removes all other __import__() calls with importlib.import_module()
    because it's an easier API.

 jhbuild/commands/__init__.py       | 11 +++--------
 jhbuild/commands/gui.py            |  9 ++++-----
 jhbuild/frontends/__init__.py      |  3 ++-
 jhbuild/modtypes/__init__.py       | 10 ++++------
 jhbuild/utils/__init__.py          |  2 +-
 jhbuild/utils/misc.py              | 12 +++++++++++-
 jhbuild/versioncontrol/__init__.py |  6 ++----
 7 files changed, 27 insertions(+), 26 deletions(-)
---
diff --git a/jhbuild/commands/__init__.py b/jhbuild/commands/__init__.py
index 56db2eba..a911aa7e 100644
--- a/jhbuild/commands/__init__.py
+++ b/jhbuild/commands/__init__.py
@@ -31,6 +31,7 @@ import sys
 import os
 
 from jhbuild.errors import UsageError, FatalError
+from jhbuild.utils import try_import_module
 
 
 class OptionParser(optparse.OptionParser):
@@ -136,10 +137,7 @@ def print_help():
         name, ext = os.path.splitext(fname)
         if not ext == '.py':
             continue
-        try:
-            __import__('jhbuild.commands.%s' % name)
-        except ImportError:
-            pass
+        try_import_module('jhbuild.commands.%s' % name)
 
     uprint(_('JHBuild commands are:'))
     commands = [(x.name, x.doc) for x in get_commands().values()]
@@ -174,10 +172,7 @@ def get_commands():
 def run(command, config, args, help):
     # if the command hasn't been registered, load a module by the same name
     if command not in _commands:
-        try:
-            __import__('jhbuild.commands.%s' % command)
-        except ImportError:
-            pass
+        try_import_module('jhbuild.commands.%s' % command)
     if command not in _commands:
         import jhbuild.moduleset
         module_set = jhbuild.moduleset.load(config)
diff --git a/jhbuild/commands/gui.py b/jhbuild/commands/gui.py
index 82654766..543c1b43 100644
--- a/jhbuild/commands/gui.py
+++ b/jhbuild/commands/gui.py
@@ -18,14 +18,9 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
-import pygtk
-pygtk.require('2.0')
-import gtk
-
 from jhbuild.commands import Command, register_command
 import jhbuild.frontends
 
-
 class cmd_gui(Command):
     doc = N_('Build targets from a GUI app')
 
@@ -33,6 +28,10 @@ class cmd_gui(Command):
     usage_args = ''
 
     def run(self, config, options, args, help=None):
+        import pygtk
+        pygtk.require('2.0')
+        import gtk
+
         # request GTK build script.
         config.buildscript = 'gtkui'
 
diff --git a/jhbuild/frontends/__init__.py b/jhbuild/frontends/__init__.py
index f74e5b47..f0974945 100644
--- a/jhbuild/frontends/__init__.py
+++ b/jhbuild/frontends/__init__.py
@@ -18,9 +18,10 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
 import sys
+import importlib
 
 def get_buildscript(config, module_list=None, module_set=None):
     modname = 'jhbuild.frontends.%s' % config.buildscript
-    __import__(modname)
+    importlib.import_module(modname)
     BuildScript = sys.modules[modname].BUILD_SCRIPT
     return BuildScript(config, module_list, module_set=module_set)
diff --git a/jhbuild/modtypes/__init__.py b/jhbuild/modtypes/__init__.py
index 7612c071..9137efc1 100644
--- a/jhbuild/modtypes/__init__.py
+++ b/jhbuild/modtypes/__init__.py
@@ -31,11 +31,12 @@ import os
 import re
 import shutil
 import logging
+import importlib
 
 from jhbuild.errors import FatalError, CommandError, BuildStateError, \
              SkipToEnd, UndefinedRepositoryError
 from jhbuild.utils.sxml import sxml
-from jhbuild.utils import inpath
+from jhbuild.utils import inpath, try_import_module
 import jhbuild.utils.fileutils as fileutils
 
 _module_types = {}
@@ -45,7 +46,7 @@ def register_module_type(name, parse_func):
 def register_lazy_module_type(name, module):
     def parse_func(node, config, uri, repositories, default_repo):
         old_func = _module_types[name]
-        __import__(module)
+        importlib.import_module(module)
         assert _module_types[name] != old_func, (
             'module did not register new parser_func for %s' % name)
         return _module_types[name](node, config, uri, repositories, default_repo)
@@ -53,10 +54,7 @@ def register_lazy_module_type(name, module):
 
 def parse_xml_node(node, config, uri, repositories, default_repo):
     if node.nodeName not in _module_types:
-        try:
-            __import__('jhbuild.modtypes.%s' % node.nodeName)
-        except ImportError:
-            pass
+        try_import_module('jhbuild.modtypes.%s' % node.nodeName)
     if node.nodeName not in _module_types:
         raise FatalError(_('unknown module type %s') % node.nodeName)
 
diff --git a/jhbuild/utils/__init__.py b/jhbuild/utils/__init__.py
index 8fd78b70..56596733 100644
--- a/jhbuild/utils/__init__.py
+++ b/jhbuild/utils/__init__.py
@@ -17,4 +17,4 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
-from .misc import inpath
\ No newline at end of file
+from .misc import inpath, try_import_module
\ No newline at end of file
diff --git a/jhbuild/utils/misc.py b/jhbuild/utils/misc.py
index 9d33aa85..dfca0014 100644
--- a/jhbuild/utils/misc.py
+++ b/jhbuild/utils/misc.py
@@ -14,6 +14,8 @@
 
 import os
 import sys
+import importlib
+import pkgutil
 
 
 def inpath(filename, path):
@@ -23,4 +25,12 @@ def inpath(filename, path):
         # also check for filename.exe on Windows
         if sys.platform.startswith('win') and os.path.isfile(os.path.join(dir, filename + '.exe')):
             return True
-    return False
\ No newline at end of file
+    return False
+
+
+def try_import_module(module_name):
+    """Like importlib.import_module() but doesn't raise if the module doesn't exist"""
+
+    if pkgutil.get_loader(module_name) is None:
+        return
+    return importlib.import_module(module_name)
\ No newline at end of file
diff --git a/jhbuild/versioncontrol/__init__.py b/jhbuild/versioncontrol/__init__.py
index 5b10f7dd..48bccd27 100644
--- a/jhbuild/versioncontrol/__init__.py
+++ b/jhbuild/versioncontrol/__init__.py
@@ -27,6 +27,7 @@ __all__ = [
 __metaclass__ = type
 
 from jhbuild.errors import FatalError, BuildStateError
+from jhbuild.utils import try_import_module
 import os
 
 class Repository:
@@ -191,10 +192,7 @@ def register_repo_type(name, repo_class):
 
 def get_repo_type(name):
     if name not in _repo_types:
-        try:
-            __import__('jhbuild.versioncontrol.%s' % name)
-        except ImportError:
-            pass
+        try_import_module('jhbuild.versioncontrol.%s' % name)
     if name not in _repo_types:
         raise FatalError(_('unknown repository type %s') % name)
     return _repo_types[name]


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]