Source code for fiql_parser.constraint
# -*- coding: utf-8 -*-
"""
The FIQL ``Constraint`` is the building block of the FIQL ``Expression``. A
FIQL ``Constraint`` is, on its own, a very simple ``Expression``.
The ``constraint`` module includes the code used for managing comparison
acceptance and representation of the FIQL ``Constraint``.
Attributes:
REV_COMPARISON_MAP (dict): Reverse mappings for common FIQL comparisons.
"""
from __future__ import unicode_literals
from __future__ import absolute_import
try:
#pylint: disable=no-name-in-module
from urllib import quote_plus
except ImportError:
#pylint: disable=import-error,no-name-in-module
from urllib.parse import quote_plus
from .exceptions import FiqlObjectException
from .constants import COMPARISON_COMP, COMPARISON_MAP
from .expression import BaseExpression, Expression
# Reversed Common FIQL comparisons.
REV_COMPARISON_MAP = {v: k for k, v in COMPARISON_MAP.items()}
[docs]class Constraint(BaseExpression):
"""
The ``Constraint`` is the smallest logical unit for a FIQL ``Expression``.
It itself must evaluate to ``True`` or ``False`` and contains no smaller
unit which itself can evaluate to ``True`` or ``False``.
Attributes:
selector (string): Constraint ``selector``.
comparison (string): Constraint ``comparison`` operator.
argument (string): Constraint ``argument``.
"""
def __init__(self, selector, comparison=None, argument=None):
"""Initialize instance of ``Constraint``.
Args:
selector (string): URL decoded constraint ``selector``.
comparison (string, optional): Parsed/mapped ``comparison``
operator. Defaults to ``None``.
argument (string, optional): URL decoded constraint ``argument``.
Defaults to ``None``.
Raises:
FiqlObjectException: Not a valid FIQL comparison.
"""
super(Constraint, self).__init__()
self.selector = selector
# Validate comparison format.
if comparison and COMPARISON_COMP.match(comparison) is None:
# Check for >, <, >=, or <=.
if not REV_COMPARISON_MAP.get(comparison):
raise FiqlObjectException(
"'%s' is not a valid FIQL comparison" % comparison)
comparison = REV_COMPARISON_MAP.get(comparison)
self.comparison = comparison
self.argument = argument
[docs] def op_and(self, *elements):
"""Create an ``Expression`` using this ``Constraint`` and the specified
additional ``elements`` joined using an "AND" ``Operator``
Args:
*elements (BaseExpression): The ``Expression`` and/or
``Constraint`` elements which the "AND" ``Operator`` applies
to in addition to this ``Constraint``.
Returns:
Expression: Newly created ``Expression`` including this
``Constraint``, the elements passed in, and the "AND"
``Operator``.
"""
return Expression().op_and(self, *elements)
[docs] def op_or(self, *elements):
"""Create an ``Expression`` using this ``Constraint`` and the specified
additional ``elements`` joined using an "OR" ``Operator``
Args:
*elements (BaseExpression): The ``Expression`` and/or
``Constraint`` elements which the "OR" ``Operator`` applies
to in addition to this ``Constraint``.
Returns:
Expression: Newly created ``Expression`` including this
``Constraint``, the elements passed in, and the "OR"
``Operator``.
"""
return Expression().op_or(self, *elements)
[docs] def to_python(self):
"""Deconstruct the ``Constraint`` instance to a tuple.
Returns:
tuple: The deconstructed ``Constraint``.
"""
return (
self.selector,
COMPARISON_MAP.get(self.comparison, self.comparison),
self.argument
)
def __str__(self):
"""Represent the ``Constraint`` instance as a string.
Returns:
string: The represented ``Constraint``.
"""
if self.argument:
return "{0}{1}{2}".format(quote_plus(self.selector),
self.comparison,
quote_plus(self.argument))
return self.selector