151 lines
4.6 KiB
Python
151 lines
4.6 KiB
Python
|
# -*- coding: utf-8 mode: python -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
|
||
|
|
||
|
"""Fonctions utilitaires diverses
|
||
|
"""
|
||
|
|
||
|
__all__ = (
|
||
|
'isnum',
|
||
|
'istrue', 'isfalse',
|
||
|
'isseq', 'seqof', 'listof', 'ulistof',
|
||
|
'flattenstr', 'flattenseq',
|
||
|
'qshell',
|
||
|
'withpath', 'cwithpath', 'find_in_path', 'relpath',
|
||
|
)
|
||
|
|
||
|
from os import path
|
||
|
|
||
|
def isnum(v):
|
||
|
return isinstance(v, int) or isinstance(v, long)
|
||
|
|
||
|
def istrue(b):
|
||
|
s = str(b).lower()
|
||
|
if s in ('true', 'vrai', 'yes', 'oui', '1'):
|
||
|
return True
|
||
|
elif s in ('false', 'faux', 'no', 'non', '0'):
|
||
|
return False
|
||
|
else:
|
||
|
return bool(b) # laisser python décider de la valeur
|
||
|
|
||
|
def isfalse(b):
|
||
|
s = str(b).lower()
|
||
|
if s in ('true', 'vrai', 'yes', 'oui', '1'):
|
||
|
return False
|
||
|
elif s in ('false', 'faux', 'no', 'non', '0'):
|
||
|
return True
|
||
|
else:
|
||
|
return not bool(b) # laisser python décider de la valeur
|
||
|
|
||
|
def isseq(t):
|
||
|
"""Tester si t est une séquence
|
||
|
"""
|
||
|
return isinstance(t, list) or isinstance(t, tuple) or isinstance(t, set)
|
||
|
|
||
|
_SEQOF_UNDEF = object()
|
||
|
def seqof(o, noneValue=_SEQOF_UNDEF):
|
||
|
"""Retourner un tuple à parti de o
|
||
|
* si o est une séquence, retourner tuple(o)
|
||
|
* si noneValue est défini, et que o is noneValue, retourner noneValue
|
||
|
* sinon, retourner le tuple (o,)
|
||
|
"""
|
||
|
if isseq(o): return tuple(o)
|
||
|
elif o is noneValue and noneValue is not _SEQOF_UNDEF: return noneValue
|
||
|
else: return (o,)
|
||
|
|
||
|
_LISTOF_UNDEF = object()
|
||
|
def listof(o, noneValue=_LISTOF_UNDEF):
|
||
|
"""Retourner une nouvelle liste à parti de o
|
||
|
* si o est une séquence, retourner list(o)
|
||
|
* si noneValue est défini, et que o is noneValue, retourner noneValue
|
||
|
* sinon, retourner la liste [o]
|
||
|
"""
|
||
|
if isseq(o): return list(o)
|
||
|
elif o is noneValue and noneValue is not _LISTOF_UNDEF: return noneValue
|
||
|
else: return [o]
|
||
|
|
||
|
def ulistof(o, noneValue=_LISTOF_UNDEF):
|
||
|
"""Retourner une nouvelle liste à parti de o
|
||
|
* si o est une séquence, retourner list(o)
|
||
|
* si noneValue est défini, et que o is noneValue, retourner noneValue
|
||
|
* sinon, retourner la liste [o]
|
||
|
|
||
|
La différence avec listof(), c'est que les doublons sont supprimés de la
|
||
|
liste, tout en préservant l'ordre original, ce qui n'est pas le cas avec
|
||
|
set()
|
||
|
"""
|
||
|
if isseq(o): tmplist = list(o)
|
||
|
elif o is noneValue and noneValue is not _LISTOF_UNDEF: return noneValue
|
||
|
else: return [o]
|
||
|
ulist = []
|
||
|
for item in tmplist:
|
||
|
if item not in ulist: ulist.append(item)
|
||
|
return ulist
|
||
|
|
||
|
def flattenstr(src, unique=True, clean=True, sep=','):
|
||
|
"""découper chaque élément du tableau src selon sep et les aplatir dans une
|
||
|
seule liste.
|
||
|
|
||
|
Si unique==True, supprimer les doublons.
|
||
|
Si clean==True, supprimer les valeurs vides et les espaces périphériques
|
||
|
|
||
|
e.g flattenstr(['a , b', 'c,']) --> ['a', 'b', 'c']
|
||
|
"""
|
||
|
if src is None: return None
|
||
|
dest = []
|
||
|
for items in seqof(src):
|
||
|
items = items.split(sep)
|
||
|
if clean: items = filter(None, map(lambda item: item.strip(), items))
|
||
|
if unique:
|
||
|
for item in items:
|
||
|
if item not in dest: dest.append(item)
|
||
|
else:
|
||
|
dest.extend(items)
|
||
|
return dest
|
||
|
|
||
|
def flattenseq(seq):
|
||
|
"""aplatir les éléments de seq en une seule liste
|
||
|
|
||
|
e.g flattenlist([(1, 2), (3, 4), 5]) --> [1, 2, 3, 4, 5]
|
||
|
"""
|
||
|
if seq is None: return None
|
||
|
if not isseq(seq): return [seq]
|
||
|
items = []
|
||
|
for item in seq:
|
||
|
if isseq(item): items.extend(item)
|
||
|
else: items.append(item)
|
||
|
return items
|
||
|
|
||
|
def qshell(values):
|
||
|
if isseq(values): return map(qshell, values)
|
||
|
elif not values: return ''
|
||
|
else: return "'%s'" % values.replace("'", "'\\''")
|
||
|
|
||
|
def withpath(p): return p is not None and '/' in p
|
||
|
def cwithpath(p): return p is not None and ('/' in p or p in ('.', '..'))
|
||
|
|
||
|
def find_in_path(filename, dirs, allow_path=False):
|
||
|
"""chercher le fichier nommé filename dans les répertoires dirs
|
||
|
|
||
|
si filename est un chemin (contient le caractère '/' ou path.sep) alors la
|
||
|
valeur est retournée telle quelle, sauf si allow_path=True
|
||
|
|
||
|
retourner le chemin complet dir/filename si le fichier est trouvé, ou None
|
||
|
si le fichier ne figure dans aucun des répertoires
|
||
|
|
||
|
"""
|
||
|
is_path = '/' in filename or path.sep in filename
|
||
|
if is_path and not allow_path: return filename
|
||
|
|
||
|
for dir in dirs:
|
||
|
pf = path.join(dir, filename)
|
||
|
if path.isfile(pf): return pf
|
||
|
return None
|
||
|
|
||
|
def relpath(filep, refp, abspath=True):
|
||
|
"""exprimer filep par rapport au répertoire de refp
|
||
|
|
||
|
si abspath==True, rendre le chemin absolu
|
||
|
"""
|
||
|
pf = path.join(dirname(refp), filep)
|
||
|
if abspath: pf = path.abspath(pf)
|
||
|
return pf
|