# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved. # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr # # This file is part of logilab-common. # # logilab-common is free software: you can redistribute it and/or modify it under # the terms of the GNU Lesser General Public License as published by the Free # Software Foundation, either version 2.1 of the License, or (at your option) any # later version. # # logilab-common is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. # # You should have received a copy of the GNU Lesser General Public License along # with logilab-common. If not, see . """Logilab common library (aka Logilab's extension to the standard library). :type STD_BLACKLIST: tuple :var STD_BLACKLIST: directories ignored by default by the functions in this package which have to recurse into directories :type IGNORED_EXTENSIONS: tuple :var IGNORED_EXTENSIONS: file extensions that may usually be ignored """ __docformat__ = "restructuredtext en" from logilab.common.__pkginfo__ import version as __version__ STD_BLACKLIST = ('CVS', '.svn', '.hg', 'debian', 'dist', 'build') IGNORED_EXTENSIONS = ('.pyc', '.pyo', '.elc', '~', '.swp', '.orig') # set this to False if you've mx DateTime installed but you don't want your db # adapter to use it (should be set before you got a connection) USE_MX_DATETIME = True class attrdict(dict): """A dictionary for which keys are also accessible as attributes.""" def __getattr__(self, attr): try: return self[attr] except KeyError: raise AttributeError(attr) class dictattr(dict): def __init__(self, proxy): self.__proxy = proxy def __getitem__(self, attr): try: return getattr(self.__proxy, attr) except AttributeError: raise KeyError(attr) class nullobject(object): def __repr__(self): return '' def __nonzero__(self): return False class tempattr(object): def __init__(self, obj, attr, value): self.obj = obj self.attr = attr self.value = value def __enter__(self): self.oldvalue = getattr(self.obj, self.attr) setattr(self.obj, self.attr, self.value) return self.obj def __exit__(self, exctype, value, traceback): setattr(self.obj, self.attr, self.oldvalue) # flatten ----- # XXX move in a specific module and use yield instead # do not mix flatten and translate # # def iterable(obj): # try: iter(obj) # except: return False # return True # # def is_string_like(obj): # try: obj +'' # except (TypeError, ValueError): return False # return True # #def is_scalar(obj): # return is_string_like(obj) or not iterable(obj) # #def flatten(seq): # for item in seq: # if is_scalar(item): # yield item # else: # for subitem in flatten(item): # yield subitem def flatten(iterable, tr_func=None, results=None): """Flatten a list of list with any level. If tr_func is not None, it should be a one argument function that'll be called on each final element. :rtype: list >>> flatten([1, [2, 3]]) [1, 2, 3] """ if results is None: results = [] for val in iterable: if isinstance(val, (list, tuple)): flatten(val, tr_func, results) elif tr_func is None: results.append(val) else: results.append(tr_func(val)) return results # XXX is function below still used ? def make_domains(lists): """ Given a list of lists, return a list of domain for each list to produce all combinations of possibles values. :rtype: list Example: >>> make_domains(['a', 'b'], ['c','d', 'e']) [['a', 'b', 'a', 'b', 'a', 'b'], ['c', 'c', 'd', 'd', 'e', 'e']] """ domains = [] for iterable in lists: new_domain = iterable[:] for i in range(len(domains)): domains[i] = domains[i]*len(iterable) if domains: missing = (len(domains[0]) - len(iterable)) / len(iterable) i = 0 for j in range(len(iterable)): value = iterable[j] for dummy in range(missing): new_domain.insert(i, value) i += 1 i += 1 domains.append(new_domain) return domains # private stuff ################################################################ def _handle_blacklist(blacklist, dirnames, filenames): """remove files/directories in the black list dirnames/filenames are usually from os.walk """ for norecurs in blacklist: if norecurs in dirnames: dirnames.remove(norecurs) elif norecurs in filenames: filenames.remove(norecurs)