# -*- 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