def _sanity_check_translated_filters(self): """ Perform a few sanity checks on translated filters. Checks the following are all true: 1. 'did_type' filters use an equals operator, 2. 'name' filters use an equality operator, 3. 'length' filters are parsable as an int type, 4. wildcard expressions use an equality operator, 5. 'created_at' value adheres to one of the date formats <VALID_DATE_FORMATS>, 6. there are no duplicate key+operator criteria. :raises: ValueError, DIDFilterSyntaxError, DuplicateCriteriaInDIDFilter """ for or_group in self._filters: or_group_test_duplicates = [] for and_group in or_group: key, oper, value = and_group if key == 'did_type': # (1) if oper != operator.eq: raise ValueError("Type operator must be equals.") if key == 'name': # (2) if oper not in (operator.eq, operator.ne): raise ValueError( "Name operator must be an equality operator.") if key == 'length': # (3) try: int(value) except ValueError: raise ValueError('Length has to be an integer value.') if isinstance(value, str): # (4) if any([char in value for char in ['*', '%']]): if oper not in [operator.eq, operator.ne]: raise exception.DIDFilterSyntaxError( "Wildcards can only be used with equality operators" ) if key == 'created_at': # (5) if not isinstance(value, datetime): raise exception.DIDFilterSyntaxError( "Couldn't parse date '{}'. Valid formats are: {}". format(value, VALID_DATE_FORMATS)) or_group_test_duplicates.append((key, oper)) if len(set(or_group_test_duplicates)) != len( or_group_test_duplicates): # (6) raise exception.DuplicateCriteriaInDIDFilter()
def __init__(self, filters, model_class=None, strict_coerce=True): if isinstance(filters, str): self._filters, _ = parse_did_filter_from_string_fe(filters, omit_name=True) elif isinstance(filters, dict): self._filters = [filters] elif isinstance(filters, list): self._filters = filters else: raise exception.DIDFilterSyntaxError( "Input filters are of an unrecognised type.") self._make_input_backwards_compatible() self.mandatory_model_attributes = self._translate_filters( model_class=model_class, strict_coerce=strict_coerce) self._sanity_check_translated_filters()