| 1 | # Copyright (c) 2003-2006 LOGILAB S.A. (Paris, FRANCE). |
|---|
| 2 | # http://www.logilab.fr/ -- mailto:contact@logilab.fr |
|---|
| 3 | # |
|---|
| 4 | # This program is free software; you can redistribute it and/or modify it under |
|---|
| 5 | # the terms of the GNU General Public License as published by the Free Software |
|---|
| 6 | # Foundation; either version 2 of the License, or (at your option) any later |
|---|
| 7 | # version. |
|---|
| 8 | # |
|---|
| 9 | # This program is distributed in the hope that it will be useful, but WITHOUT |
|---|
| 10 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
|---|
| 11 | # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. |
|---|
| 12 | # |
|---|
| 13 | # You should have received a copy of the GNU General Public License along with |
|---|
| 14 | # this program; if not, write to the Free Software Foundation, Inc., |
|---|
| 15 | # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
|---|
| 16 | """Logilab common libraries: |
|---|
| 17 | |
|---|
| 18 | a set of common functionnalities shared among logilab projects |
|---|
| 19 | |
|---|
| 20 | |
|---|
| 21 | :type STD_BLACKLIST: tuple |
|---|
| 22 | :var STD_BLACKLIST: |
|---|
| 23 | directories ignored by default by the functions in this package which have |
|---|
| 24 | to recurse into directories |
|---|
| 25 | |
|---|
| 26 | :type IGNORED_EXTENSIONS: tuple |
|---|
| 27 | :var IGNORED_EXTENSIONS: |
|---|
| 28 | file extensions that may usually be ignored |
|---|
| 29 | """ |
|---|
| 30 | |
|---|
| 31 | STD_BLACKLIST = ('CVS', '.svn', '.hg', 'debian', 'dist', 'build') |
|---|
| 32 | |
|---|
| 33 | IGNORED_EXTENSIONS = ('.pyc', '.pyo', '.elc', '~') |
|---|
| 34 | |
|---|
| 35 | |
|---|
| 36 | |
|---|
| 37 | from logilab.common.deprecation import moved |
|---|
| 38 | |
|---|
| 39 | get_cycles = moved('logilab.common.graph', 'get_cycles') |
|---|
| 40 | cached = moved('logilab.common.decorators', 'cached') |
|---|
| 41 | ProgressBar = moved('logilab.common.shellutils', 'ProgressBar') |
|---|
| 42 | Execute = moved('logilab.common.shellutils', 'Execute') |
|---|
| 43 | acquire_lock = moved('logilab.common.shellutils', 'acquire_lock') |
|---|
| 44 | release_lock = moved('logilab.common.shellutils', 'release_lock') |
|---|
| 45 | deprecated_function = moved('logilab.common.deprecation', 'deprecated_function') |
|---|
| 46 | class_renamed = moved('logilab.common.deprecation', 'class_renamed') |
|---|
| 47 | |
|---|
| 48 | def intersection(list1, list2): |
|---|
| 49 | """return the intersection of list1 and list2""" |
|---|
| 50 | warn('this function is deprecated, use a set instead', DeprecationWarning, |
|---|
| 51 | stacklevel=2) |
|---|
| 52 | intersect_dict, result = {}, [] |
|---|
| 53 | for item in list1: |
|---|
| 54 | intersect_dict[item] = 1 |
|---|
| 55 | for item in list2: |
|---|
| 56 | if intersect_dict.has_key(item): |
|---|
| 57 | result.append(item) |
|---|
| 58 | return result |
|---|
| 59 | |
|---|
| 60 | def difference(list1, list2): |
|---|
| 61 | """return elements of list1 not in list2""" |
|---|
| 62 | warn('this function is deprecated, use a set instead', DeprecationWarning, |
|---|
| 63 | stacklevel=2) |
|---|
| 64 | tmp, result = {}, [] |
|---|
| 65 | for i in list2: |
|---|
| 66 | tmp[i] = 1 |
|---|
| 67 | for i in list1: |
|---|
| 68 | if not tmp.has_key(i): |
|---|
| 69 | result.append(i) |
|---|
| 70 | return result |
|---|
| 71 | |
|---|
| 72 | def union(list1, list2): |
|---|
| 73 | """return list1 union list2""" |
|---|
| 74 | warn('this function is deprecated, use a set instead', DeprecationWarning, |
|---|
| 75 | stacklevel=2) |
|---|
| 76 | tmp = {} |
|---|
| 77 | for i in list1: |
|---|
| 78 | tmp[i] = 1 |
|---|
| 79 | for i in list2: |
|---|
| 80 | tmp[i] = 1 |
|---|
| 81 | return tmp.keys() |
|---|
| 82 | |
|---|
| 83 | |
|---|
| 84 | class attrdict(dict): |
|---|
| 85 | """a dictionary whose keys are also accessible as attributes""" |
|---|
| 86 | def __getattr__(self, attr): |
|---|
| 87 | try: |
|---|
| 88 | return self[attr] |
|---|
| 89 | except KeyError: |
|---|
| 90 | raise AttributeError(attr) |
|---|
| 91 | |
|---|
| 92 | class nullobject(object): |
|---|
| 93 | def __nonzero__(self): |
|---|
| 94 | return False |
|---|
| 95 | |
|---|
| 96 | # XXX move in a specific module |
|---|
| 97 | |
|---|
| 98 | def flatten(iterable, tr_func=None, results=None): |
|---|
| 99 | """flatten a list of list with any level |
|---|
| 100 | |
|---|
| 101 | if tr_func is not None, it should be a one argument function that'll be called |
|---|
| 102 | on each final element |
|---|
| 103 | """ |
|---|
| 104 | if results is None: |
|---|
| 105 | results = [] |
|---|
| 106 | for val in iterable: |
|---|
| 107 | if isinstance(val, (list, tuple)): |
|---|
| 108 | flatten(val, tr_func, results) |
|---|
| 109 | elif tr_func is None: |
|---|
| 110 | results.append(val) |
|---|
| 111 | else: |
|---|
| 112 | results.append(tr_func(val)) |
|---|
| 113 | return results |
|---|
| 114 | |
|---|
| 115 | |
|---|
| 116 | # XXX is function below still used ? |
|---|
| 117 | |
|---|
| 118 | def make_domains(lists): |
|---|
| 119 | """ |
|---|
| 120 | given a list of lists, return a list of domain for each list to produce all |
|---|
| 121 | combinaisons of possibles values |
|---|
| 122 | |
|---|
| 123 | ex: (['a', 'b'], ['c','d', 'e']) |
|---|
| 124 | -> (['a', 'b', 'a', 'b', 'a', 'b'], |
|---|
| 125 | ['c', 'c', 'd', 'd', 'e', 'e']) |
|---|
| 126 | """ |
|---|
| 127 | domains = [] |
|---|
| 128 | for iterable in lists: |
|---|
| 129 | new_domain = iterable[:] |
|---|
| 130 | for i in range(len(domains)): |
|---|
| 131 | domains[i] = domains[i]*len(iterable) |
|---|
| 132 | if domains: |
|---|
| 133 | missing = (len(domains[0]) - len(iterable)) / len(iterable) |
|---|
| 134 | i = 0 |
|---|
| 135 | for j in range(len(iterable)): |
|---|
| 136 | value = iterable[j] |
|---|
| 137 | for dummy in range(missing): |
|---|
| 138 | new_domain.insert(i, value) |
|---|
| 139 | i += 1 |
|---|
| 140 | i += 1 |
|---|
| 141 | domains.append(new_domain) |
|---|
| 142 | return domains |
|---|