import importlib import inspect import pkgutil import sys from core.tokenizer import TokenKind def sysarg_to_string(argv): """ Transform a list of strings into a single string Add quotes if needed :return: """ if argv is None or not argv: return "" result = "" first = True for s in argv: if not first: result += " " result += '"' + s + '"' if " " in s else s first = False if result[0] in ('"', "'"): result = result[1:-1] # strip quotes return result def get_class(qname): """ Loads a class from its full qualified name :param qname: :return: """ parts = qname.split('.') module = ".".join(parts[:-1]) m = __import__(module) for comp in parts[1:]: m = getattr(m, comp) return m def get_module(qname): """ Loads a module from its full qualified name :param qname: :return: """ parts = qname.split('.') m = __import__(qname) for comp in parts[1:]: m = getattr(m, comp) return m def new_object(kls, *args, **kwargs): """ New instance of an object :param kls: :param args: :param kwargs: :return: """ obj_type = get_class(kls) return obj_type(*args, **kwargs) def get_full_qualified_name(obj): """ Returns the full qualified name of a class (including its module name ) :param obj: :return: """ if obj.__class__ == type: module = obj.__module__ if module is None or module == str.__class__.__module__: return obj.__name__ # Avoid reporting __builtin__ else: return module + '.' + obj.__name__ else: module = obj.__class__.__module__ if module is None or module == str.__class__.__module__: return obj.__class__.__name__ # Avoid reporting __builtin__ else: return module + '.' + obj.__class__.__name__ def get_classes(module_name): """ Gets all classes, for a given module_name :param module_name: name of the module :return: """ mod = get_module(module_name) for name in dir(mod): obj = getattr(mod, name) if inspect.isclass(obj): yield obj def get_classes_from_package(package_name): """ Gets all classes, for a given package :param package_name: name of the package :return: """ pkg = __import__(package_name) prefix = pkg.__name__ + "." for importer, modname, ispkg in pkgutil.iter_modules(pkg.__path__, prefix): for c in get_classes(modname): yield c def get_sub_classes(package_name, base_class): pkg = __import__(package_name) prefix = pkg.__name__ + "." for (module_loader, name, ispkg) in pkgutil.iter_modules(pkg.__path__, prefix): importlib.import_module(name) base_class = get_class(base_class) if isinstance(base_class, str) else base_class return set(base_class.__subclasses__()).union( [s for c in base_class.__subclasses__() for s in get_sub_classes(package_name, c)]) def remove_from_list(lst, to_remove_predicate): """ Removes elements from a list if they exist :param lst: :param to_remove_predicate: :return: """ flagged = [] for item in lst: if to_remove_predicate(item): flagged.append(item) for item in flagged: lst.remove(item) return lst def product(a, b): """ Kind of cartesian product between lists a and b knowing that a is also a list So it's a cartesian product between a list of list and a list """ if a is None or len(a) == 0: return b if b is None or len(b) == 0: return a res = [] for item_b in b: for item_a in a: items = item_a + [item_b] res.append(items) return res def strip_quotes(text): if not isinstance(text, str): return text if text == "": return "" if text[0] == "'" or text[0] == '"': return text[1:-1] return text def strip_tokens(tokens, strip_eof=False): """ Remove the starting and trailing spaces and newline """ if tokens is None: return None start = 0 length = len(tokens) while start < length and tokens[start].type in (TokenKind.WHITESPACE, TokenKind.NEWLINE): start += 1 if start == length: return [] end_tokens = (TokenKind.WHITESPACE, TokenKind.NEWLINE, TokenKind.EOF) \ if strip_eof \ else (TokenKind.WHITESPACE, TokenKind.NEWLINE) end = length - 1 while end > 0 and tokens[end].type in end_tokens: end -= 1 return tokens[start: end + 1] def pp(items): if not hasattr(items, "__iter__"): return str(items) if len(items) == 0: return str(items) return " \n" + " \n".join(str(item) for item in items)