summaryrefslogtreecommitdiffstats
path: root/ignore_import_errors.py
diff options
context:
space:
mode:
authorJan Cholasta <jcholast@redhat.com>2016-08-24 13:36:12 +0200
committerDavid Kupka <dkupka@redhat.com>2016-10-24 14:11:08 +0200
commit9b534238157e003d2d7c3e1a7fd27531ab1dfd25 (patch)
treee51358355aa0ff725d939e55a54dd33befef2a25 /ignore_import_errors.py
parent0b91735c79a0ba577f9540e946180760a97913a4 (diff)
downloadfreeipa-9b534238157e003d2d7c3e1a7fd27531ab1dfd25.tar.gz
freeipa-9b534238157e003d2d7c3e1a7fd27531ab1dfd25.tar.xz
freeipa-9b534238157e003d2d7c3e1a7fd27531ab1dfd25.zip
makeapi, makeaci: do not fail on missing imports
Add import hook to makeapi and makeaci which makes them ignore import errors in modules in our source tree and instead print a warning. This makes it possible to build IPA without having to have most of our runtime dependencies installed. https://fedorahosted.org/freeipa/ticket/6418 Reviewed-By: Petr Spacek <pspacek@redhat.com> Reviewed-By: Martin Basti <mbasti@redhat.com>
Diffstat (limited to 'ignore_import_errors.py')
-rw-r--r--ignore_import_errors.py87
1 files changed, 87 insertions, 0 deletions
diff --git a/ignore_import_errors.py b/ignore_import_errors.py
new file mode 100644
index 000000000..4ee6ee98b
--- /dev/null
+++ b/ignore_import_errors.py
@@ -0,0 +1,87 @@
+#
+# Copyright (C) 2016 FreeIPA Contributors see COPYING for license
+#
+
+"""
+ImportError ignoring import hook.
+"""
+
+from __future__ import print_function
+
+import imp
+import inspect
+import os.path
+import sys
+
+DIRNAME = os.path.dirname(os.path.abspath(__file__))
+
+
+class FailedImport(object):
+ def __init__(self, loader, name):
+ self.__file__ = __file__
+ self.__name__ = name
+ self.__path__ = []
+ self.__loader__ = loader
+ self.__package__ = name
+
+ def __repr__(self):
+ return '<failed import {!r}>'.format(self.__name__)
+
+
+class IgnoringImporter(object):
+ def find_module(self, fullname, path=None):
+ parentname, dot, name = fullname.rpartition('.')
+ assert (not dot and path is None) or (dot and path is not None)
+
+ # check if the module can be found
+ try:
+ file, _filename, _description = imp.find_module(name, path)
+ except ImportError:
+ pass
+ else:
+ if file is not None:
+ file.close()
+ # it can be found, do normal import
+ return None
+
+ # check if the parent module import failed
+ if dot and isinstance(sys.modules[parentname], FailedImport):
+ # it did fail, so this import will fail as well
+ return self
+
+ # find out from where are we importing
+ if path is None:
+ path = sys.path
+ for pathname in path:
+ pathname = os.path.abspath(pathname)
+ if not pathname.startswith(DIRNAME):
+ break
+ else:
+ # importing from our source tree, do normal import
+ return None
+
+ # find out into what .py file are we importing
+ frame = inspect.currentframe().f_back
+ filename = frame.f_code.co_filename
+ if filename.startswith('<'):
+ # not a file, do normal import
+ return None
+ filename = os.path.abspath(filename)
+ if not filename.startswith(DIRNAME):
+ # not a file in our source tree, do normal import
+ return None
+
+ return self
+
+ def load_module(self, fullname):
+ frame = inspect.currentframe().f_back
+ print("{}: {}:{}: ignoring ImportError: No module named {}".format(
+ sys.argv[0],
+ os.path.relpath(frame.f_code.co_filename),
+ frame.f_lineno,
+ fullname))
+
+ return sys.modules.setdefault(fullname, FailedImport(self, fullname))
+
+
+sys.meta_path.insert(0, IgnoringImporter())