def __init__(self, *, _op=EXPR, _children=None, _negated=False, _expr=None, **kwargs):
        """
        Create a new R object.

        Query filters can be expressed through keyword arguments or using methods.

        Ex.

        .. code-block:: python

            rql = R(field='value', field2__in=('v1', 'v2'), field3__empty=True)

        All the lookups expressed as keyword arguments are combined together with a logical ``and``.

        Using the ``n`` method:

        .. code-block:: python

            rql = (
                R().n('field').eq('value')
                & R().n('field2').in_(('v1', 'v2'))
                & R().n('field3').empty(True)
            )

        The previous query can be expressed in a more concise form like:

        .. code-block:: python

            rql = R().field.eq('value') & R().field2.in_(('v1', 'v2')) & r.field3.empty(True)

        The R object support the bitwise operators ``&``, ``|`` and ``~``.

        Nested fields can be expressed using dot notation:

        .. code-block:: python

            rql = R().n('nested.field').eq('value')

        or

        .. code-block:: python

            rql = R().nested.field.eq('value')
        """
        self.op = _op
        self.children = _children or []
        self.negated = _negated
        self.expr = _expr
        self._path = []
        self._field = None
        if len(kwargs) == 1:
            self.op = self.EXPR
            self.expr = parse_kwargs(kwargs)[0]
        if len(kwargs) > 1:
            self.op = self.AND
            for token in parse_kwargs(kwargs):
                self.children.append(RQLQuery(_expr=token))
def test_simple():
    expressions = parse_kwargs({'field': 'value'})
    assert isinstance(expressions, list)
    assert len(expressions) == 1
    assert expressions[0] == 'eq(field,value)'
def test_null(expr, value, expected_op):
    expressions = parse_kwargs({f'field__{expr}': value})
    assert isinstance(expressions, list)
    assert len(expressions) == 1
    assert expressions[0] == f'{expected_op}(field,{expr}())'
def test_nested_fields():
    expressions = parse_kwargs({'field__nested': 'value'})
    assert isinstance(expressions, list)
    assert len(expressions) == 1
    assert expressions[0] == 'eq(field.nested,value)'
def test_list():
    for op in ('out', 'in'):
        expressions = parse_kwargs({f'field__{op}': ('value1', 'value2')})
        assert isinstance(expressions, list)
        assert len(expressions) == 1
        assert expressions[0] == f'{op}(field,(value1,value2))'
def test_comparison():
    for op in ('eq', 'ne', 'lt', 'le', 'gt', 'ge'):
        expressions = parse_kwargs({f'field__{op}': 'value'})
        assert isinstance(expressions, list)
        assert len(expressions) == 1
        assert expressions[0] == f'{op}(field,value)'