12 _log = logging.getLogger(__name__)
15 # Borrow following code from stackoverflow
16 # Link: http://stackoverflow.com/questions/11461356/issubclass-returns-flase-on-the-same-class-imported-from-different-paths
17 def is_subclass(child, parent_name):
18 return inspect.isclass(child) and parent_name in [cls.__name__ for cls in inspect.getmro(child)]
21 def load_subclasses(dirname, base_class_name, base_class_file, loader):
22 filelist = [base_class_file] + [f for f in os.listdir(dirname) if f.endswith('.py') and f not in ['__init__.py', base_class_file]]
23 for filename in filelist:
24 module_name = os.path.splitext(filename)[0]
25 module = imp.load_source(module_name, os.path.join(dirname, filename))
26 for item_name in dir(module):
27 item = getattr(module, item_name)
28 if is_subclass(item, base_class_name):
32 def get_path_from_project_root(relative_path_to_project_root):
33 # Choose the directory containing current file as start point,
34 # compute relative path base on the parameter,
35 # and return an absolute path
36 return os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), relative_path_to_project_root))
39 def force_remove(path):
42 except Exception as error:
43 # Directory/file does not exist or privilege issue, just ignore it
44 _log.info("Error removing %s: %s" % (path, error))
48 # Borrow this code from
49 # 'http://stackoverflow.com/questions/2281850/timeout-function-if-it-takes-too-long-to-finish'
50 class TimeoutError(Exception):
56 def __init__(self, seconds=1, error_message='Timeout'):
57 self.seconds = seconds
58 self.error_message = error_message
60 def handle_timeout(self, signum, frame):
61 raise TimeoutError(self.error_message)
64 signal.signal(signal.SIGALRM, self.handle_timeout)
65 signal.alarm(self.seconds)
67 def __exit__(self, type, value, traceback):