nutools/lib/nulib/python/deploydb/expr.py

108 lines
3.3 KiB
Python

# -*- coding: utf-8 mode: python -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
__all__ = (
'ANY', 'ALL', 'NONE', 'EXISTS',
)
from .utils import *
class Expr(object):
_terms, terms = None, property(lambda self: self._terms)
def __init__(self, *terms):
self._terms = listof(terms or None, None)
@staticmethod
def match_dict(dict, object):
for name, value in dict.items():
one_match = False
attr_values = object.get(name, ())
for value in listof(value):
if value in attr_values:
one_match = True
break
if not one_match: return False
return True
@staticmethod
def match_term(term, object):
"""tester le terme par rapport à l'objet.
* si c'est None, retourner vrai
* si c'est un dictionnaire, tous les attributs cités doivent avoir au
moins une des valeurs fournies
* si c'est une fonction (plus exactement un objet appelable), elle doit
prendre l'unique argument (object) et retourner True si l'objet
correspond
* si c'est une liste, la traiter comme ANY(*term)
* si c'est une instance de Expr, déléguer le traitement à sa méthode
match()
* sinon, lancer une exception.
"""
if term is None:
return True
elif isinstance(term, dict):
return Expr.match_dict(term, object)
elif callable(term):
return term(object)
elif isseq(term):
term = ANY(*term)
if isinstance(term, Expr):
return term.match(object)
else:
raise ValueError("Argument invalide %r" % term)
def match(self, object):
return False
class ANY(Expr):
"""construire l'objet avec une liste de termes. au moins un des termes doit
correspondre
"""
def match(self, object, lazy=True):
result = False
if self.terms is None: return result
for term in self.terms:
if self.match_term(term, object):
result = True
if lazy: break
return result
class ALL(Expr):
"""construire l'objet avec une liste de termes. tous les termes doivent
correspondrent
"""
def match(self, object, lazy=True):
result = True
if self.terms is None: return result
for term in self.terms:
if not self.match_term(term, object):
result = False
if lazy: break
return result
class NONE(Expr):
"""construire l'objet avec une liste de termes. aucun des termes ne doit
correspondre
"""
def match(self, object, lazy=False):
result = True
if self.terms is None: return result
for term in self.terms:
if self.match_term(term, object):
result = False
if lazy: break
return result
class EXISTS(Expr):
"""construire l'objet avec une liste d'attributs. tous les attributs doivent
exister
"""
def match(self, object, lazy=True):
result = True
if self.terms is None: return result
for term in self.terms:
if not object.has_key(term):
result = False
if lazy: break
return result