Exemplo n.º 1
0
def test_data_is_an_opendict():
    c1 = object()
    with context(c1, a=1, b=1) as cc1:
        with context(c1, a=2) as cc2:
            assert cc2 is cc1
            assert cc2.a == 2
            assert cc2.b == 1   # Given by the upper enclosing level
            cc2.b = 'jaile!d'
        assert cc1.a == 1
        assert cc1['b'] == 1
Exemplo n.º 2
0
 def test_simple_contexts(self):
     with context('CONTEXT-1'):
         self.assertIsNot(None, context['CONTEXT-1'])
         with context('CONTEXT-1'):
             with context('context-2'):
                 self.assertIsNot(None, context['CONTEXT-1'])
                 self.assertIsNot(None, context['context-2'])
             self.assertEquals(False, bool(context['context-2']))
         self.assertIsNot(None, context['CONTEXT-1'])
     self.assertEquals(False, bool(context['CONTEXT-1']))
Exemplo n.º 3
0
    def test_20120822_reversed_eq_and_ne_should_compare_equal(self):
        expr = 1 == q("2")
        expr2 = q(1) == "2"
        with context(UNPROXIFING_CONTEXT):
            self.assertEqual(expr, expr2)

        # But we have not a reversing equality stuff.
        expr = 1 < q(2)
        expr2 = q(2) > 1
        with context(UNPROXIFING_CONTEXT):
            self.assertNotEqual(expr, expr2)
Exemplo n.º 4
0
    def test_20120822_reversed_eq_and_ne_should_compare_equal(self):
        expr = 1 == q("2")
        expr2 = q(1) == "2"
        with context(UNPROXIFING_CONTEXT):
            self.assertEqual(expr, expr2)

        # But we have not a reversing equality stuff.
        expr = 1 < q(2)
        expr2 = q(2) > 1
        with context(UNPROXIFING_CONTEXT):
            self.assertNotEqual(expr, expr2)
Exemplo n.º 5
0
 def test_with_objects(self):
     CONTEXT1 = object()
     CONTEXT2 = object()
     with context(CONTEXT1):
         self.assertIsNot(None, context[CONTEXT1])
         with context(CONTEXT1):
             with context(CONTEXT2):
                 self.assertIsNot(None, context[CONTEXT1])
                 self.assertIsNot(None, context[CONTEXT2])
             self.assertEquals(False, bool(context[CONTEXT2]))
         self.assertIsNot(None, context[CONTEXT1])
     self.assertEquals(False, bool(context[CONTEXT1]))
Exemplo n.º 6
0
    def __iter__(self):
        '''Yields a single instance of a :class:`bound term
        <xotl.ql.interfaces.IBoundTerm>` that is a clone of the current.

        This allows an idiomatic way to express queries::

            query_expression = ((parent, child)
                                for parent in this('parent')
                                for child in parent.children)

        See :class:`these`.

        '''
        with context(UNPROXIFING_CONTEXT):
            name = self.name
            parent = self.parent
            if not name:
                # When iterating an instance without a name (i.e the `this`
                # object), we should generate a new name (of those simple
                # mortals can't use)
                with context('_INVALID_THESE_NAME'):
                    name = self._newname()
                    bound_term = Term(name, parent=parent, binding=None)
            else:
                bound_term = Term(name, parent=parent, binding=None)
            token = GeneratorToken(expression=bound_term)
            bound_term.binding = token
            # XXX: Since bound_terms might span accross subqueries, there might
            # be several stacked bubbles around. For instance::
            #
            #    (parent
            #        for parent in this('parent')
            #        if any_(child for child in parent.children if child.age < 6))
            #
            # In this case, the enclosed parent.children emits to the top-most
            # bubble, but when the iter is invoked by `any_` to resolve its
            # argument a second bubble is in place and the hack below (XXX)
            # won't work. Furthermore, the token's expression is the bound-term
            # while the emmited part was the original one. So we keep the
            # original_term so that operations that resolver their arguments as
            # subquery may remove the escaped part.
            bound_term.original_term = self
        # XXX: When emiting a token in the context of query, if this token's
        # expression is also a part, then it was emitted without binding, so we
        # need to manually check this case here
        bubble = context[EXPRESSION_CAPTURING].get('bubble', None)
        if bubble:
            parts = bubble._parts
            if parts and self is parts[-1]:
                parts.pop(-1)
            _emit_token(token)
        yield bound_term
Exemplo n.º 7
0
 def test_regression_test_calling_terms_directly(self):
     'Tests that invoke(term, ...) is equivalent to term(...)'
     from xotl.ql.expressions import invoke
     e1 = this('parent').children.updated_since(1, threshold=0.99)
     e2 = invoke(this('parent').children.updated_since, 1, threshold=0.99)
     with context(UNPROXIFING_CONTEXT):
         self.assertEqual(e1, e2)
Exemplo n.º 8
0
 def __init__(self, **kwargs):
     with context(UNPROXIFING_CONTEXT):
         self._expression = expression = kwargs.get('expression')
         assert IExpressionCapable.providedBy(expression)
         self._token = None
         self.token = token = kwargs.get('token')
         assert IGeneratorToken.providedBy(token)
Exemplo n.º 9
0
 def test_regression_test_calling_terms_directly(self):
     'Tests that invoke(term, ...) is equivalent to term(...)'
     from xotl.ql.expressions import invoke
     e1 = this('parent').children.updated_since(1, threshold=0.99)
     e2 = invoke(this('parent').children.updated_since, 1, threshold=0.99)
     with context(UNPROXIFING_CONTEXT):
         self.assertEqual(e1, e2)
Exemplo n.º 10
0
def get_term_path(term):
    '''Returns a tuple of all the names in the path to a term.

    For example::

       >>> from xotl.ql import this
       >>> get_term_path(this('p').a.b.c)
       ('p', 'a', 'b', 'c')

    The unnamed term ``this`` is treated specially by returning None. For
    example::

        >>> get_term_path(this.a)
        (None, 'a')

    '''
    with context(UNPROXIFING_CONTEXT):
        from xotl.ql.core import this
        res = []
        current = term
        while current:
            if current is not this:
                res.insert(0, current.name)
            else:
                res.insert(0, None)
            current = current.parent
        return tuple(res)
Exemplo n.º 11
0
Arquivo: py.py Projeto: mvaled/xotl.ql
def get_term_vm_path(term):
    '''Gets the root and the "path" of a term in the VM.

    The root is actually the token to which this term is bound to.

    The path is a list of identifiers which are traversal steps from the
    root. For instance::

          these(child for parent in this
                      if parent.children & (parent.age > 33)
                      for child in parent.children
                      if child.age < 5)

    The term `child.age` in the last filter is actually encoded by the names:
    parent, children, age; but since this term is bound to `parent.children`,
    only `age` is part of the path.

    '''
    with context(UNPROXIFING_CONTEXT):
        token = term.binding
        root = token.expression
        res = []
        current = term
        while current and current is not root:
            res.insert(0, current.name)
            current = current.parent
        return (token, res)
Exemplo n.º 12
0
 def invoke(self, *args):
     from xotl.ql.expressions import invoke as f
     with context(UNPROXIFING_CONTEXT):
         instance = self.expression
         token = self.token
     result = QueryPart(expression=f(instance, *args), token=token)
     return result
Exemplo n.º 13
0
def test_cotraverse_expression():
    from xoutil.compat import zip
    from xotl.ql.expressions import is_a
    from xotl.ql.translation import cotraverse_expression

    @thesefy
    class Person(object):
        pass

    @thesefy
    class Partnership(object):
        pass

    query = these((person, partner)
                  for person, partner in zip(Person, Person)
                  for rel in Partnership
                  if (rel.subject == person) & (rel.obj == partner))
    filters = list(query.filters)
    person, partner = query.selection
    person_is_a_person = is_a(person, Person)
    partner_is_a_person = is_a(partner, Person)
    rel_token = query.tokens[-1]
    rel_subject = rel_token.expression.subject
    rel_obj = rel_token.expression.obj
    with context(UNPROXIFING_CONTEXT):
        assert person != partner
        assert person_is_a_person in filters
        assert partner_is_a_person in filters
        expected_terms_order = [person, partner, rel_token.expression, rel_subject, person, rel_obj, partner]
        assert expected_terms_order == list(cotraverse_expression(query))

    assert UNPROXIFING_CONTEXT not in context
Exemplo n.º 14
0
def test_named_terms_matches_a_token():
    '''
    Ensures that all terms are named, and they are bound to a token that is
    in the query.
    '''
    from xoutil.iterators import zip
    from xotl.ql.core import thesefy
    from xotl.ql.translation import cotraverse_expression

    @thesefy
    class Person(object):
        pass

    @thesefy
    class Partnership(object):
        pass

    query = these((person, partner)
                  for person, partner in zip(Person, Person)
                  for rel in Partnership
                  if (rel.subject == person) & (rel.obj == partner)
                  if person.age > 35)

    tokens = [tk.expression for tk in query.tokens]
    matches_token = lambda term: (term.name and (
                                  term.binding.expression in tokens or
                                  matches_token(term.parent)))
    with context(UNPROXIFING_CONTEXT):
        assert all(matches_token(term)
                   for term in cotraverse_expression(*query.filters))
Exemplo n.º 15
0
 def __init__(self, **kwargs):
     with context(UNPROXIFING_CONTEXT):
         self._expression = expression = kwargs.get('expression')
         assert IExpressionCapable.providedBy(expression)
         self._token = None
         self.token = token = kwargs.get('token')
         assert IGeneratorToken.providedBy(token)
Exemplo n.º 16
0
    def serialize(self, children, ctx=None):
        results = defaultdict(lambda: defaultdict(dict))
        more_objects_required = True

        level = 0

        while more_objects_required:
            future_children = defaultdict(lambda: {
                'children': {},
                'parameters': {
                    'ids': set(),
                    'ctx': ctx
                },
            })

            with context('carbon14', children=future_children):
                results = self._serialize(level, results, children, ctx)

            more_objects_required = False

            for collection, objs in results.items():
                ids = set(objs)
                parameters = future_children[collection]['parameters']
                parameters['ids'] = parameters['ids'].difference(ids)

            for query in future_children.values():
                if query['parameters']['ids']:
                    more_objects_required = True
                    children = future_children

            level += 1

        return results
Exemplo n.º 17
0
 def method(self):
     with context(UNPROXIFING_CONTEXT):
         instance = self.expression
         token = self.token
     result = QueryPart(expression=operation(instance),
                        token=token)
     return result
Exemplo n.º 18
0
    def capture_token(self, token):
        '''Captures an emitted token.

        When a token is emitted if the last previously created part is a term
        that *is* the same as the :attr:`IGeneratorToken.expression`, then this
        last term should be removed from the particles collection.

        This is because in a query like::

            these((parent, child)
                  for parent in this
                  for child in parent.children)

        The `parent.children` emits itself as a query part and immediately it
        is transformed to a token.

        :param token: The emitted token
        :type token: :class:`IGeneratorToken`
        '''
        tokens = self._tokens
        with context(UNPROXIFING_CONTEXT):
            assert IGeneratorToken.providedBy(token)
            parts = self._parts
            if parts:
                top = parts.pop(-1)
                if token.expression is not top:
                    parts.append(top)
        if token not in tokens:
            tokens.append(token)
            self._particles.append(token)
Exemplo n.º 19
0
    def _resolve_arguments(cls, *children, **kwargs):
        '''Resolves the first and only positional argument as a sub-query by
        calling :class:`~xotl.ql.core.these`.

        If there is more than one positional argument, or even one keyword
        argument, or the first argument is not a generator object; then it
        leaves all the arguments the same.

        '''
        import types
        first, rest = children[0], children[1:]
        if not first or (rest or kwargs):
            return children, kwargs
        else:
            if isinstance(first, types.GeneratorType):
                from xotl.ql.core import these
                first = these(first)
                # XXX: If this operation itself is enclosed in a
                # EXPRESSION_CAPTURING it might have occurred that a part
                # (actually a token's term) was emitted but then used as the
                # generator, so if the first token's binding original_term *is*
                # the last part emitted it should be removed from the bubble.
                bubble = context[EXPRESSION_CAPTURING].get('bubble', None)
                if bubble:
                    parts = bubble._parts
                    with context(UNPROXIFING_CONTEXT):
                        term = first.tokens[0].expression
                        if getattr(term, 'original_term', None) is parts[-1]:
                            parts.pop(-1)
            return (first, ), {}
Exemplo n.º 20
0
    def test_worst_case_must_have_3_filters_and_3_tokens(self):
        from itertools import izip
        query = these(person
                      for person, partner in izip(this('person'),
                                                  this('partner'))
                      for rel in this('relation')
                      if rel.type == 'partnership'
                      if rel.subject == person
                      if rel.object == partner
                      if partner.age > 32)
        filters = list(query.filters)
        tokens = list(query.tokens)
        person, partner, rel = this('person'), this('partner'), this('relation')
        expected_rel_type_filter = rel.type == 'partnership'
        expected_rel_subject_filter = rel.subject == person
        expected_rel_obj_filter = rel.object == partner
        expected_partner_age = partner.age > 32
        with context(UNPROXIFING_CONTEXT):
            self.assertIs(4, len(filters))
            self.assertIn(expected_rel_type_filter, filters)
            self.assertIn(expected_rel_subject_filter, filters)
            self.assertIn(expected_rel_obj_filter, filters)
            self.assertIn(expected_partner_age, filters)

            self.assertIn(person, tokens)
            self.assertIn(rel, tokens)
            self.assertIs(3, len(tokens))
            self.assertIn(partner, tokens)
Exemplo n.º 21
0
    def __eq__(self, other):
        '''
            >>> with context(UNPROXIFING_CONTEXT):
            ...    this('parent') == this('parent')
            True

            >>> from xotl.ql.expressions import _true
            >>> (this('parent') == this('parent')) is _true
            True
        '''
        from xotl.ql.expressions import eq
        with context(UNPROXIFING_CONTEXT):
            if isinstance(other, Term):
                res = validate_attrs(self, other, ('name', 'parent'))
            else:
                res = False
        if context[UNPROXIFING_CONTEXT]:
            return res
        else:
            if not res:
                return eq(self, other)
            else:
                # In logic A == A is always true so we don't produce nothing
                # for it.
                return _true
Exemplo n.º 22
0
    def test_named_terms_matches_a_token(self):
        '''
        Ensures that all terms are named, and they are bound to a token that is
        in the query.
        '''
        from itertools import izip
        from xotl.ql.core import thesefy
        from xotl.ql.translate import cofind_tokens

        @thesefy
        class Person(object):
            pass

        @thesefy
        class Partnership(object):
            pass

        query = these((person, partner)
                      for person, partner in izip(Person, Person)
                      for rel in Partnership
                      if (rel.subject == person) & (rel.obj == partner)
                      if person.age > 35)

        tokens = query.tokens
        matches_token = lambda term: (term.name and (
                                      term.binding.expression in tokens or
                                      matches_token(term.parent)))
        with context(UNPROXIFING_CONTEXT):
            self.assertTrue(all(matches_token(term)
                                for term in cofind_tokens(*query.filters)))
Exemplo n.º 23
0
 def __call__(self, *args, **kwargs):
     with context(UNPROXIFING_CONTEXT):
         instance = self.expression
         token = self.token
     result = QueryPart(expression=instance(*args, **kwargs),
                        token=token)
     return result
Exemplo n.º 24
0
    def test_complex_query_with_3_tokens(self):
        query = these((parent.title + parent.name,
                       child.name + child.nick, toy.name)
                      for parent in this('parent')
                      if parent.children
                      for child in parent.children
                      if child.toys
                      for toy in child.toys
                      if (parent.age > 32) & (child.age < 5) |
                         (toy.type == 'laptop'))
        p = this('parent')
        c = p.children
        t = c.toys

        filters = query.filters
        expected_filters = [((p.age > 32) & (c.age < 5) | (t.type == 'laptop')),
                            p.children, c.toys]

        tokens = query.tokens
        expected_tokens = [p, c, t]

        selection = query.selection
        expected_selection = (p.title + p.name, c.name + c.nick, t.name)
        with context(UNPROXIFING_CONTEXT):
            self.assertEqual(selection, expected_selection)

            self.assertEqual(len(expected_filters), len(filters))
            for f in expected_filters:
                self.assertIn(f, filters)

            self.assertEqual(len(expected_tokens), len(tokens))
            for t in expected_tokens:
                self.assertIn(t, tokens)
Exemplo n.º 25
0
Arquivo: py.py Projeto: mvaled/xotl.ql
    def _detect_class(self, query):
        '''Detects the class for top-level (i.e has no parent) token.

        Finds if there is any filter containing an ``is_instance(token,
        SomeClass)``. If SomeClass has an attribute `this_instances` and it
        returns an iterable, it is assumed it will yield all objects from this
        class.

        '''
        token = self.token
        term = token.expression
        with context(UNPROXIFING_CONTEXT):
            parent = term.parent
        if not parent:
            from xotl.ql.expressions import is_instance, IExpressionTree
            def matches(node):
                with context(UNPROXIFING_CONTEXT):
                    return (IExpressionTree.providedBy(node) and
                            node.operation is is_instance and
                            node.children[0] == term)

            from xotl.ql.translation import cotraverse_expression
            found = next(cotraverse_expression(*query.filters, accept=matches), None)
            if found:
                self._token_class = found.children[-1]
            else:
                self._token_class = None
        else:
            self._token_class = None
Exemplo n.º 26
0
def test_complex_query_with_3_tokens():
    query = these((parent.title + parent.name,
                   child.name + child.nick, toy.name)
                  for parent in this('parent')
                  if parent.children
                  for child in parent.children
                  if child.toys
                  for toy in child.toys
                  if (parent.age > 32) & (child.age < 5) | (toy.type == 'laptop'))
    p = this('parent')
    c = p.children
    t = c.toys

    filters = query.filters
    expected_filters = [((p.age > 32) & (c.age < 5) | (t.type == 'laptop')),
                        p.children, c.toys]

    tokens = [tk.expression for tk in query.tokens]
    expected_tokens = [p, c, t]

    selection = query.selection
    expected_selection = (p.title + p.name, c.name + c.nick, t.name)
    with context(UNPROXIFING_CONTEXT):
        assert selection == expected_selection

        assert len(expected_filters) == len(filters)
        for f in expected_filters:
            assert f in filters

        assert len(expected_tokens) == len(tokens)
        for t in expected_tokens:
            assert t in tokens
Exemplo n.º 27
0
 def test(self):
     operator = getattr(op, '_python_operator', op)
     query = these(parent for parent in this('p') if operator(parent.age, parent.check, parent.names))
     expected = operator(this('p').age, this('p').check, this('p').names)
     self.assertIs(1, len(query.filters))
     with context(UNPROXIFING_CONTEXT):
         self.assertEqual(expected, query.filters[0])
Exemplo n.º 28
0
    def test_named_terms_matches_a_token(self):
        '''
        Ensures that all terms are named, and they are bound to a token that is
        in the query.
        '''
        from itertools import izip
        from xotl.ql.core import thesefy
        from xotl.ql.translate import cofind_tokens

        @thesefy
        class Person(object):
            pass

        @thesefy
        class Partnership(object):
            pass

        query = these((person, partner)
                      for person, partner in izip(Person, Person)
                      for rel in Partnership
                      if (rel.subject == person) & (rel.obj == partner)
                      if person.age > 35)

        tokens = query.tokens
        matches_token = lambda term: (term.name and (
            term.binding.expression in tokens or matches_token(term.parent)))
        with context(UNPROXIFING_CONTEXT):
            self.assertTrue(
                all(
                    matches_token(term)
                    for term in cofind_tokens(*query.filters)))
Exemplo n.º 29
0
def test_basic_queries():
    from xotl.ql.expressions import count
    query = these((parent.title + parent.name, count(child.toys))
                    for parent in this('parent')
                    if parent.age < 40
                    for child in parent.children
                    if child.age > 5)
    assert provides_any(query, IQueryObject)

    (parent_full_name, child_toys) = query.selection
    full_name_expectation = this('parent').title + this('parent').name
    child_toys_expectation = count(this('parent').children.toys)

    parent_age_test = this('parent').age < 40
    children_age_test = this('parent').children.age > 5

    parent_token = this('parent')
    children_token = this('parent').children

    with context(UNPROXIFING_CONTEXT):
        assert parent_full_name == full_name_expectation
        assert child_toys == child_toys_expectation

        filters = query.filters
        assert len(filters) == 2
        assert parent_age_test in filters
        assert children_age_test in filters

        tokens = [tk.expression for tk in query.tokens]
        assert len(tokens) == 2
        assert parent_token in tokens
        assert children_token in tokens
Exemplo n.º 30
0
    def test_thesefy_doesnot_messup_identities(self):
        from itertools import izip
        from xotl.ql.core import thesefy
        from xotl.ql.expressions import is_a

        @thesefy
        class Person(object):
            pass

        @thesefy
        class Partnership(object):
            pass

        query = these((person, partner)
                      for person, partner in izip(Person, Person)
                      for rel in Partnership
                      if (rel.subject == person) & (rel.obj == partner))
        filters = list(query.filters)
        person, partner = query.selection
        person_is_a_person = is_a(person, Person)
        partner_is_a_person = is_a(partner, Person)
        with context(UNPROXIFING_CONTEXT):
            self.assertNotEqual(person, partner)
            self.assertIn(person_is_a_person, filters)
            self.assertIn(partner_is_a_person, filters)
            filters.remove(person_is_a_person)
            filters.remove(partner_is_a_person)
Exemplo n.º 31
0
    def test_worst_case_must_have_3_filters_and_3_tokens(self):
        from itertools import izip
        query = these(
            person for person, partner in izip(this('person'), this('partner'))
            for rel in this('relation') if rel.type == 'partnership'
            if rel.subject == person if rel.object == partner
            if partner.age > 32)
        filters = list(query.filters)
        tokens = list(query.tokens)
        person, partner, rel = this('person'), this('partner'), this(
            'relation')
        expected_rel_type_filter = rel.type == 'partnership'
        expected_rel_subject_filter = rel.subject == person
        expected_rel_obj_filter = rel.object == partner
        expected_partner_age = partner.age > 32
        with context(UNPROXIFING_CONTEXT):
            self.assertIs(4, len(filters))
            self.assertIn(expected_rel_type_filter, filters)
            self.assertIn(expected_rel_subject_filter, filters)
            self.assertIn(expected_rel_obj_filter, filters)
            self.assertIn(expected_partner_age, filters)

            self.assertIn(person, tokens)
            self.assertIn(rel, tokens)
            self.assertIs(3, len(tokens))
            self.assertIn(partner, tokens)
Exemplo n.º 32
0
    def test_complex_query_with_3_tokens(self):
        query = these(
            (parent.title + parent.name, child.name + child.nick, toy.name)
            for parent in this('parent') if parent.children
            for child in parent.children if child.toys for toy in child.toys
            if (parent.age > 32) & (child.age < 5) | (toy.type == 'laptop'))
        p = this('parent')
        c = p.children
        t = c.toys

        filters = query.filters
        expected_filters = [
            ((p.age > 32) & (c.age < 5) | (t.type == 'laptop')), p.children,
            c.toys
        ]

        tokens = query.tokens
        expected_tokens = [p, c, t]

        selection = query.selection
        expected_selection = (p.title + p.name, c.name + c.nick, t.name)
        with context(UNPROXIFING_CONTEXT):
            self.assertEqual(selection, expected_selection)

            self.assertEqual(len(expected_filters), len(filters))
            for f in expected_filters:
                self.assertIn(f, filters)

            self.assertEqual(len(expected_tokens), len(tokens))
            for t in expected_tokens:
                self.assertIn(t, tokens)
Exemplo n.º 33
0
    def __eq__(self, other):
        '''
            >>> with context(UNPROXIFING_CONTEXT):
            ...    this('parent') == this('parent')
            True

            >>> from xotl.ql.expressions import _true
            >>> (this('parent') == this('parent')) is _true
            True
        '''
        from xotl.ql.expressions import eq
        with context(UNPROXIFING_CONTEXT):
            if isinstance(other, Term):
                res = validate_attrs(self, other, ('name', 'parent'))
            else:
                res = False
        if context[UNPROXIFING_CONTEXT]:
            return res
        else:
            if not res:
                return eq(self, other)
            else:
                # In logic A == A is always true so we don't produce nothing
                # for it.
                return _true
Exemplo n.º 34
0
    def test_thesefy_doesnot_messup_identities(self):
        from itertools import izip
        from xotl.ql.core import thesefy
        from xotl.ql.expressions import is_a

        @thesefy
        class Person(object):
            pass

        @thesefy
        class Partnership(object):
            pass

        query = these((person, partner)
                      for person, partner in izip(Person, Person)
                      for rel in Partnership
                      if (rel.subject == person) & (rel.obj == partner))
        filters = list(query.filters)
        person, partner = query.selection
        person_is_a_person = is_a(person, Person)
        partner_is_a_person = is_a(partner, Person)
        with context(UNPROXIFING_CONTEXT):
            self.assertNotEqual(person, partner)
            self.assertIn(person_is_a_person, filters)
            self.assertIn(partner_is_a_person, filters)
            filters.remove(person_is_a_person)
            filters.remove(partner_is_a_person)
Exemplo n.º 35
0
    def test_basic_queries(self):
        from xotl.ql.expressions import count
        query = these((parent.title + parent.name, count(child.toys))
                      for parent in this('parent') if parent.age < 40
                      for child in parent.children if child.age > 5)
        self.assertTrue(provides_any(query, IQueryObject))

        (parent_full_name, child_toys) = query.selection
        full_name_expectation = this('parent').title + this('parent').name
        #        child_name_expectation = this('parent').children.name
        child_toys_expectation = count(this('parent').children.toys)

        parent_age_test = this('parent').age < 40
        children_age_test = this('parent').children.age > 5

        parent_token = this('parent')
        children_token = this('parent').children

        with context(UNPROXIFING_CONTEXT):
            self.assertEqual(parent_full_name, full_name_expectation)
            #            self.assertEqual(child_name, child_name_expectation)
            self.assertEqual(child_toys, child_toys_expectation)

            filters = query.filters
            self.assertEqual(2, len(filters))
            self.assertIn(parent_age_test, filters)
            self.assertIn(children_age_test, filters)

            tokens = query.tokens
            self.assertEqual(2, len(tokens))
            self.assertIn(parent_token, tokens)
            self.assertIn(children_token, tokens)
Exemplo n.º 36
0
    def capture_token(self, token):
        '''Captures an emitted token.

        When a token is emitted if the last previously created part is a term
        that *is* the same as the :attr:`IGeneratorToken.expression`, then this
        last term should be removed from the particles collection.

        This is because in a query like::

            these((parent, child)
                  for parent in this
                  for child in parent.children)

        The `parent.children` emits itself as a query part and immediately it
        is transformed to a token.

        :param token: The emitted token
        :type token: :class:`IGeneratorToken`
        '''
        tokens = self._tokens
        with context(UNPROXIFING_CONTEXT):
            assert IGeneratorToken.providedBy(token)
            parts = self._parts
            if parts:
                top = parts.pop(-1)
                if token.expression is not top:
                    parts.append(top)
        if token not in tokens:
            tokens.append(token)
            self._particles.append(token)
Exemplo n.º 37
0
def test_worst_case_must_have_3_filters_and_3_tokens():
    from xoutil.iterators import zip
    query = these(person
                  for person, partner in zip(this('person'),
                                             this('partner'))
                  for rel in this('relation')
                  if rel.type == 'partnership'
                  if rel.subject == person
                  if rel.object == partner
                  if partner.age > 32)
    filters = list(query.filters)
    tokens = [tk.expression for tk in query.tokens]
    person, partner, rel = this('person'), this('partner'), this('relation')
    expected_rel_type_filter = rel.type == 'partnership'
    expected_rel_subject_filter = rel.subject == person
    expected_rel_obj_filter = rel.object == partner
    expected_partner_age = partner.age > 32
    with context(UNPROXIFING_CONTEXT):
        assert len(filters) == 4
        assert expected_rel_type_filter in filters
        assert expected_rel_subject_filter in filters
        assert expected_rel_obj_filter in filters
        assert expected_partner_age in filters

        assert len(tokens) == 3
        assert person in tokens
        assert rel in tokens
        assert partner in tokens
Exemplo n.º 38
0
    def test_basic_queries(self):
        from xotl.ql.expressions import count
        query = these((parent.title + parent.name, count(child.toys))
                        for parent in this('parent')
                        if parent.age < 40
                        for child in parent.children
                        if child.age > 5)
        self.assertTrue(provides_any(query, IQueryObject))

        (parent_full_name, child_toys) = query.selection
        full_name_expectation = this('parent').title + this('parent').name
#        child_name_expectation = this('parent').children.name
        child_toys_expectation = count(this('parent').children.toys)

        parent_age_test = this('parent').age < 40
        children_age_test = this('parent').children.age > 5

        parent_token = this('parent')
        children_token = this('parent').children

        with context(UNPROXIFING_CONTEXT):
            self.assertEqual(parent_full_name, full_name_expectation)
#            self.assertEqual(child_name, child_name_expectation)
            self.assertEqual(child_toys, child_toys_expectation)

            filters = query.filters
            self.assertEqual(2, len(filters))
            self.assertIn(parent_age_test, filters)
            self.assertIn(children_age_test, filters)

            tokens = query.tokens
            self.assertEqual(2, len(tokens))
            self.assertIn(parent_token, tokens)
            self.assertIn(children_token, tokens)
Exemplo n.º 39
0
 def all_(self, *args):
     from xotl.ql.expressions import all_ as f
     with context(UNPROXIFING_CONTEXT):
         instance = self.expression
         token = self.token
     result = QueryPart(expression=f(instance, *args), token=token)
     _emit_part(result)
     return result
Exemplo n.º 40
0
 def __call__(self, *args, **kwargs):
     with context(UNPROXIFING_CONTEXT):
         parent = self.parent
     if parent is not None:
         from xotl.ql.expressions import invoke
         return ExpressionTree(invoke, self, *args, **kwargs)
     else:
         raise TypeError()
Exemplo n.º 41
0
 def __init__(self, name=None, **kwargs):
     with context(UNPROXIFING_CONTEXT):
         self.validate_name(name)
         self._name = name
         self._parent = kwargs.get('parent', None)
         binding = kwargs.get('binding', None)
         if binding:
             self.binding = binding
Exemplo n.º 42
0
 def __call__(self, *args, **kwargs):
     with context(UNPROXIFING_CONTEXT):
         parent = self.parent
     if parent is not None:
         from xotl.ql.expressions import invoke
         return ExpressionTree(invoke, self, *args, **kwargs)
     else:
         raise TypeError()
Exemplo n.º 43
0
 def test_named_children_equivalence(self):
     from xotl.ql.expressions import new
     expr1 = new(object, a=1, b=3)
     expr2 = new(object, b=3, a=1)
     expr3 = new(object, b=1)
     with context(UNPROXIFING_CONTEXT):
         self.assertEqual(expr1, expr2)
         self.assertNotEqual(expr1, expr3)
Exemplo n.º 44
0
 def test_named_children_equivalence(self):
     from xotl.ql.expressions import new
     expr1 = new(object, a=1, b=3)
     expr2 = new(object, b=3, a=1)
     expr3 = new(object, b=1)
     with context(UNPROXIFING_CONTEXT):
         self.assertEqual(expr1, expr2)
         self.assertNotEqual(expr1, expr3)
Exemplo n.º 45
0
def test_right_bindings():
    with bubbling() as current:
        next((parent, child)
             for parent in this('parent')
             if parent.children.updated_since(days=1)
             for child in parent.children
             if child.age < 4)
        # The query has two filters:
        #
        #    this('parent').children & (count(this('parent').children) > 4)
        #    this('parent').children.age < 5
        #
        # If we regard every term `this('parent').children` as the *token*,
        # what would be the meaning of the first condition? How do we
        # distinguish from conditions over the named-token and the expression
        # that generates the token?  i.e in `for child in parent.children`, the
        # `child` token is *not* the same as the term `parent.children`.
        #
        # Now the token of the relevant query might help, but then the machine
        # should not strip those tokens from query-parts.
        parts = current.bubble.parts
        bubble_tokens = current.bubble.tokens
    assert len(parts) == 2

    with context(UNPROXIFING_CONTEXT):
        parent_token = next((token
                             for token in bubble_tokens
                             if token.expression == this('parent')),
                            None)
        children_token = next((token
                               for token in bubble_tokens
                               if token.expression != this('parent')),
                              None)
    child_age_filter = parts.pop(-1)
    parent_children_updated_filter = parts.pop(-1)
    with pytest.raises(IndexError):
        parts.pop(-1)
    with context(UNPROXIFING_CONTEXT):
        child_age_term = child_age_filter.children[0]
        assert child_age_term.binding == children_token

        # Note that: parent.children.updated_since(days=1)
        # is equivalent to invoke(parent.children.updated_since, days=1)
        parent_children_term = parent_children_updated_filter.children[0]
        assert parent_children_term.binding == parent_token
        assert dict(days=1) == parent_children_updated_filter.named_children
Exemplo n.º 46
0
    def enter(cls):
        '''Enter the context.

        Use as ``with _bag_assign.enter()``: ...

        '''
        from xoutil.context import context
        return context(cls)
Exemplo n.º 47
0
 def test_expression(self):
     from xotl.ql.expressions import (count, ExpressionTree, or_, and_,
                                      pow_, lt, eq, add)
     expr = ((q(1) < 3) & (1 == q("1")) |
             (q("a") + q("b")**2 == q("x") + count("y")))
     expected = or_(and_(lt(1, 3), eq(1, "1")),
                    eq(add("a", pow_("b", 2)), add("x", count("y"))))
     self.assertIsInstance(expr, ExpressionTree)
     with context(UNPROXIFING_CONTEXT):
         self.assertTrue(expr == expected, "%s ---- %s" % (expected, expr))
Exemplo n.º 48
0
    def test_free_terms_are_not_captured(self):
        from xotl.ql.expressions import any_
        next(parent for parent in this('parent') if parent.name
             if any_(this.children, this.age < 6))

        parts = self.bubble.parts
        self.assertIs(1, len(parts))
        pname = this('parent').name
        with context(UNPROXIFING_CONTEXT):
            self.assertIn(pname, parts)
Exemplo n.º 49
0
 def __iter__(self):
     with context(UNPROXIFING_CONTEXT):
         expression = self.expression
         # XXX: In cases of sub-queries the part will be emitted, but the
         #      iter will be hold, so the token won't be emitted and the
         #      part won't be removed. So we're bringing this check back.
         bubble = _get_current_bubble()
         assert bubble
         if bubble._parts and expression is bubble._parts[-1]:
             bubble._parts.pop(-1)
         return iter(expression)
Exemplo n.º 50
0
 def __getattribute__(self, attr):
     get = super(QueryPart, self).__getattribute__
     if context[UNPROXIFING_CONTEXT]:
         return get(attr)
     else:
         with context(UNPROXIFING_CONTEXT):
             instance = get('expression')
             token = get('token')
         result = QueryPart(expression=getattr(instance, attr), token=token)
         _emit_part(result)
         return result
Exemplo n.º 51
0
 def test_is_a_partnership_is_not_forgotten(self):
     from itertools import izip
     query = these(
         (person, partner)
         for person, partner in izip(this('person'), this('partner'))
         for rel in this('relation') if rel.type == 'partnership'
         if (rel.subject == person) & (rel.object == partner))
     filters = list(query.filters)
     expected_rel_type = this('relation').type == 'partnership'
     with context(UNPROXIFING_CONTEXT):
         self.assertIn(expected_rel_type, filters)
         self.assertIs(2, len(filters))
Exemplo n.º 52
0
 def __str__(self):
     with context(UNPROXIFING_CONTEXT):
         name = self.name
         parent = self.parent
     if parent is None and not name:
         return 'this'
     elif parent is None and name:
         return "this('{name}')".format(name=name)
     elif parent is not None and name:
         return "{parent}.{name}".format(parent=str(parent), name=name)
     else:  # parent and not name:
         assert False
Exemplo n.º 53
0
    def test_right_bindings(self):
        next((parent, child) for parent in this('parent')
             if parent.children.updated_since(days=1)
             for child in parent.children if child.age < 4)
        # The query has two filters:
        #
        #    this('parent').children & (count(this('parent').children) > 4)
        #    this('parent').children.age < 5
        #
        # If we regard every term `this('parent').children` as the *token*,
        # what would be the meaning of the first condition? How do we
        # distinguish from conditions over the named-token and the
        # expression that generates the token?
        # i.e in `for child in parent.children`, the `child` token
        # is *not* the same as the term `parent.children`.
        #
        # Now the token of the relevant query might help, but then the
        # machine should not strip those tokens from query-parts.
        parts = self.bubble.parts
        bubble_tokens = self.bubble.tokens
        with context(UNPROXIFING_CONTEXT):
            parent_token = next((token for token in bubble_tokens
                                 if token.expression == this('parent')), None)
            children_token = next((token for token in bubble_tokens
                                   if token.expression != this('parent')),
                                  None)
        child_age_filter = parts.pop(-1)
        parent_children_updated_filter = parts.pop(-1)
        with self.assertRaises(IndexError):
            parts.pop(-1)
        with context(UNPROXIFING_CONTEXT):
            child_age_term = child_age_filter.children[0]
            self.assertEqual(child_age_term.binding, children_token)

            # Note that: parent.children.updated_since(days=1)
            # is equivalent to invoke(parent.children.updated_since, days=1)
            parent_children_term = parent_children_updated_filter.children[0]
            self.assertEqual(parent_children_term.binding, parent_token)
            self.assertEqual(dict(days=1),
                             parent_children_updated_filter.named_children)
Exemplo n.º 54
0
 def method(self, other):
     with context(UNPROXIFING_CONTEXT):
         instance = self.expression
         token = self.token
         if IQueryPart.providedBy(other):
             other = other.expression
     if not inverse:
         result = QueryPart(expression=operation(instance, other),
                            token=token)
     else:
         result = QueryPart(expression=operation(other, instance),
                            token=token)
     return result
Exemplo n.º 55
0
    def test_calling_functions(self):
        from xotl.ql.expressions import call
        expression = this.startswith('manu')
        self.assertIsInstance(expression, ExpressionTree)
        self.assertEqual("call(this.startswith, manu)",
                         str(expression))
        equiv_expr = call(this.startswith, 'manu')
        with context(UNPROXIFING_CONTEXT):
            self.assertEqual(equiv_expr, expression)

        # But the calling a these instance directly is not supported
        # (I think is not pretty)
        with self.assertRaises(TypeError):
            this('someone')('cannot', 'call', 'me')
Exemplo n.º 56
0
    def capture_part(self, part):
        '''Captures an emitted query part.

        When a given part is captured, it might replace the lastly previously
        emitted parts if either of the following conditions hold:

        - The capture part *is* the same last emitted part.

        - The captured part is a term, and the last emitted part *is* its
          parent, then the parent part is replaced by the newly captured part.

        - The captured part is an expression and the last emitted part *is* one
          of its children (named or positional).

        The previous conditions are cycled while any of them hold against the
        particle at the "end" of the :attr:`particles` collection.

        Note that in an expression like ``invoke(some, a > b, b > c,
        argument=(c > d))`` before the whole expression is formed (and thus the
        part that represents it is captured), all of the arguments emitted
        particles, so we should remove those contained parts and just keep the
        bigger one that has them all.

        .. note::

           Checks **are** done with the `is` operator and not with `==`. Doing
           otherwise may lead to undesired results::

               these(parent.name for parent in this if parent.name)

           If `==` would be used, then the filter part `parent.name` would be
           lost.

        :param part: The emitted query part
        :type part: :class:`IQueryPart`
        '''
        with context(UNPROXIFING_CONTEXT):
            if provides_all(part, IQueryPart):
                expression = part.expression
                parts = self._parts
                if parts:
                    mergable = self.mergable
                    while parts and mergable(expression):
                        top = parts.pop()
                        self._particles.remove(top)
                parts.append(expression)
                self._particles.append(expression)
            else:
                assert False
Exemplo n.º 57
0
    def test_yield_once_per_query(self):
        q = (a for c in this for b in c.bs for a in b.a)
        self.assertIsNotNone(next(q))
        with self.assertRaises(StopIteration):
            next(q)

        # TODO: Document how to obtain the queries
        qs = (a for i in range(3) for b in this('b' + str(i)) for a in b.a)
        for i in range(3):
            expected = this('b' + str(i)).a
            returned = unboxed(next(qs)).expression
            with context(UNPROXIFING_CONTEXT):
                self.assertEqual(expected, returned)
        with self.assertRaises(StopIteration):
            next(qs)
Exemplo n.º 58
0
 def test_theres_a_token_for_partnership(self):
     from itertools import izip
     query = these(
         (person, partner)
         for person, partner in izip(this('person'), this('partner'))
         for rel in this('relation') if rel.type == 'partnership'
         if (rel.subject == person) & (rel.object == partner))
     tokens = list(query.tokens)
     person, partner, rel = this('person'), this('partner'), this(
         'relation')
     with context(UNPROXIFING_CONTEXT):
         self.assertIs(3, len(tokens))
         self.assertIn(rel, tokens)
         self.assertIn(person, tokens)
         self.assertIn(partner, tokens)
Exemplo n.º 59
0
    def test_thesefy_good_meta(self):
        from xotl.ql.core import thesefy

        class Meta(type):
            def __iter__(self):
                from xoutil.objects import nameof
                return iter(this(nameof(self)))

        @thesefy("Person")
        class Person(object):
            __metaclass__ = Meta

        q = these(who for who in Person if who.age > 30)
        q1 = these(who for who in this('Person') if who.age > 30)
        with context(UNPROXIFING_CONTEXT):
            self.assertEqual(q.selection, q1.selection)
Exemplo n.º 60
0
    def test_most_basic_query(self):
        query = these(parent for parent in this('parent') if parent.age > 40)
        self.assertTrue(provides_any(query, IQueryObject))
        (p, ) = query.selection
        token_expectation = p_expected = this('parent')
        filter_expectation = this('parent').age > 40

        with context(UNPROXIFING_CONTEXT):
            self.assertEqual(p, p_expected)

            filters = query.filters
            self.assertEqual(1, len(filters))
            self.assertIn(filter_expectation, filters)

            tokens = query.tokens
            self.assertEqual(1, len(tokens))
            self.assertIn(token_expectation, tuple(tokens))