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', '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