Package logilab :: Package common
[frames] | no frames]

Source Code for Package logilab.common

  1  # copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved. 
  2  # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr 
  3  # 
  4  # This file is part of logilab-common. 
  5  # 
  6  # logilab-common is free software: you can redistribute it and/or modify it under 
  7  # the terms of the GNU Lesser General Public License as published by the Free 
  8  # Software Foundation, either version 2.1 of the License, or (at your option) any 
  9  # later version. 
 10  # 
 11  # logilab-common is distributed in the hope that it will be useful, but WITHOUT 
 12  # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
 13  # FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more 
 14  # details. 
 15  # 
 16  # You should have received a copy of the GNU Lesser General Public License along 
 17  # with logilab-common.  If not, see <http://www.gnu.org/licenses/>. 
 18  """Logilab common library (aka Logilab's extension to the standard library). 
 19   
 20  :type STD_BLACKLIST: tuple 
 21  :var STD_BLACKLIST: directories ignored by default by the functions in 
 22    this package which have to recurse into directories 
 23   
 24  :type IGNORED_EXTENSIONS: tuple 
 25  :var IGNORED_EXTENSIONS: file extensions that may usually be ignored 
 26  """ 
 27  __docformat__ = "restructuredtext en" 
 28   
 29  import sys 
 30  import types 
 31  import pkg_resources 
 32   
 33  __version__ = pkg_resources.get_distribution('logilab-common').version 
 34   
 35  # deprecated, but keep compatibility with pylint < 1.4.4 
 36  __pkginfo__ = types.ModuleType('__pkginfo__') 
 37  __pkginfo__.__package__ = __name__ 
 38  __pkginfo__.version = __version__ 
 39  sys.modules['logilab.common.__pkginfo__'] = __pkginfo__ 
 40   
 41  STD_BLACKLIST = ('CVS', '.svn', '.hg', '.git', '.tox', 'debian', 'dist', 'build') 
 42   
 43  IGNORED_EXTENSIONS = ('.pyc', '.pyo', '.elc', '~', '.swp', '.orig') 
 44   
 45  # set this to False if you've mx DateTime installed but you don't want your db 
 46  # adapter to use it (should be set before you got a connection) 
 47  USE_MX_DATETIME = True 
 48   
 49   
50 -class attrdict(dict):
51 """A dictionary for which keys are also accessible as attributes."""
52 - def __getattr__(self, attr):
53 try: 54 return self[attr] 55 except KeyError: 56 raise AttributeError(attr)
57
58 -class dictattr(dict):
59 - def __init__(self, proxy):
60 self.__proxy = proxy
61
62 - def __getitem__(self, attr):
63 try: 64 return getattr(self.__proxy, attr) 65 except AttributeError: 66 raise KeyError(attr)
67
68 -class nullobject(object):
69 - def __repr__(self):
70 return '<nullobject>'
71 - def __bool__(self):
72 return False
73 __nonzero__ = __bool__
74
75 -class tempattr(object):
76 - def __init__(self, obj, attr, value):
77 self.obj = obj 78 self.attr = attr 79 self.value = value
80
81 - def __enter__(self):
82 self.oldvalue = getattr(self.obj, self.attr) 83 setattr(self.obj, self.attr, self.value) 84 return self.obj
85
86 - def __exit__(self, exctype, value, traceback):
87 setattr(self.obj, self.attr, self.oldvalue)
88 89 90 91 # flatten ----- 92 # XXX move in a specific module and use yield instead 93 # do not mix flatten and translate 94 # 95 # def iterable(obj): 96 # try: iter(obj) 97 # except: return False 98 # return True 99 # 100 # def is_string_like(obj): 101 # try: obj +'' 102 # except (TypeError, ValueError): return False 103 # return True 104 # 105 #def is_scalar(obj): 106 # return is_string_like(obj) or not iterable(obj) 107 # 108 #def flatten(seq): 109 # for item in seq: 110 # if is_scalar(item): 111 # yield item 112 # else: 113 # for subitem in flatten(item): 114 # yield subitem 115
116 -def flatten(iterable, tr_func=None, results=None):
117 """Flatten a list of list with any level. 118 119 If tr_func is not None, it should be a one argument function that'll be called 120 on each final element. 121 122 :rtype: list 123 124 >>> flatten([1, [2, 3]]) 125 [1, 2, 3] 126 """ 127 if results is None: 128 results = [] 129 for val in iterable: 130 if isinstance(val, (list, tuple)): 131 flatten(val, tr_func, results) 132 elif tr_func is None: 133 results.append(val) 134 else: 135 results.append(tr_func(val)) 136 return results
137 138 139 # XXX is function below still used ? 140
141 -def make_domains(lists):
142 """ 143 Given a list of lists, return a list of domain for each list to produce all 144 combinations of possibles values. 145 146 :rtype: list 147 148 Example: 149 150 >>> make_domains(['a', 'b'], ['c','d', 'e']) 151 [['a', 'b', 'a', 'b', 'a', 'b'], ['c', 'c', 'd', 'd', 'e', 'e']] 152 """ 153 from six.moves import range 154 domains = [] 155 for iterable in lists: 156 new_domain = iterable[:] 157 for i in range(len(domains)): 158 domains[i] = domains[i]*len(iterable) 159 if domains: 160 missing = (len(domains[0]) - len(iterable)) / len(iterable) 161 i = 0 162 for j in range(len(iterable)): 163 value = iterable[j] 164 for dummy in range(missing): 165 new_domain.insert(i, value) 166 i += 1 167 i += 1 168 domains.append(new_domain) 169 return domains
170 171 172 # private stuff ################################################################ 173
174 -def _handle_blacklist(blacklist, dirnames, filenames):
175 """remove files/directories in the black list 176 177 dirnames/filenames are usually from os.walk 178 """ 179 for norecurs in blacklist: 180 if norecurs in dirnames: 181 dirnames.remove(norecurs) 182 elif norecurs in filenames: 183 filenames.remove(norecurs)
184