Пример #1
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)
Пример #2
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)
Пример #3
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)
Пример #4
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)
Пример #5
0
def cmp_terms(t1, t2, strict=False):
    '''Compares two terms in a partial order.

    This is a *partial* compare operator. A term `t1 < t2` if and only if `t1`
    is in the parent-chain of `t2`.

    If `strict` is False the comparison between expressions will be made with
    the `eq` operation; otherwise `is` will be used.

    If either `t1` or `t2` are generator tokens it's
    :attr:`~xotl.ql.interfaces.IGeneratorToken.expression` is used instead.

    Examples::

        >>> from xotl.ql.core import this, these
        >>> t1 = this('a').b.c
        >>> t2 = this('b').b.c.d
        >>> t3 = this('a').b

        >>> cmp_terms(t1, t3)
        1

        # But if equivalence is False neither t1 < t3 nor t3 < t1 holds.
        >>> cmp_terms(t1, t3, True)
        0

        # Since t1 and t2 have no comon ancestor, they are not ordered.
        >>> cmp_terms(t1, t2)
        0

        >>> query = these((child, brother)
        ...               for parent in this
        ...               for child in parent.children
        ...               for brother in parent.children
        ...               if child is not brother)

        >>> t1, t2, t3 = query.tokens

        >>> cmp_terms(t1, t2)
        -1

        >>> cmp_terms(t2, t3)
        0

    '''
    import operator
    if not strict:
        test = operator.eq
    else:
        test = operator.is_
    with context(UNPROXIFING_CONTEXT):
        if IGeneratorToken.providedBy(t1):
            t1 = t1.expression
        if IGeneratorToken.providedBy(t2):
            t2 = t2.expression
        if test(t1, t2):
            return 0
        else:
            t = t1
            while t and not test(t, t2):
                t = t.parent
            if t:
                return 1
            t = t2
            while t and not test(t, t1):
                t = t.parent
            if t:
                return -1
            else:
                return 0