Source

Telescope / lib / telescope / sparql / expressions.py

import weakref
import operator
from rdflib import Variable

__all__ = ['Expression', 'BinaryExpression', 'ConditionalExpression',
           'VariableExpressionConstructor', 'and_', 'or_']

unary = lambda op: lambda self: Expression(self, op)
binary = lambda op: lambda self, other: BinaryExpression(op, self, other)
binary.r = lambda op: lambda self, other: BinaryExpression(op, other, self)
conditional = lambda op: lambda self, other: ConditionalExpression(op, (self, other))
conditional.r = lambda op: lambda self, other: ConditionalExpression(op, (other, self))

class Expression(object):
    def __init__(self, value, operator=None, lang=None, type=None):
        self.value = value
        self.operator = operator
        self.language = lang
        self.datatype = type
    
    def __repr__(self):
        value = self.value
        if hasattr(value, 'n3'):
            value = value.n3()
        else:
            value = repr(value)
        if self.operator:
            return "Expression(%s, %r)" % (value, self.operator)
        else:
            return "Expression(%s)" % (value,)

    def _clone(self, **kwargs):
        clone = self.__class__.__new__(self.__class__)
        clone.__dict__.update(self.__dict__)
        clone.__dict__.update(kwargs)
        return clone
    
    def _lang(self, language):
        """Emulates @lang."""
        return self._clone(language=language)
    
    def _type(self, datatype):
        """Emulates ^^type."""
        return self._clone(datatype=datatype)
    
    def compile(self, prefix_map=None):
        from telescope.sparql.compiler import ExpressionCompiler
        return ExpressionCompiler(prefix_map).compile(self)

    # Special operators.
    
    def __pow__(self, datatype):
        """Emulates ^^type."""
        return self._type(datatype)
    
    # Logical operators.
    
    __or__ = conditional(operator.or_)
    __ror__ = conditional.r(operator.or_)
    __and__ = conditional(operator.and_)
    __rand__ = conditional.r(operator.and_)
    
    # Unary operators.
    
    __pos__ = unary(operator.pos)
    __neg__ = unary(operator.neg)
    __invert__ = unary(operator.invert)
    
    # Numeric operators.
    
    __eq__ = binary(operator.eq)
    __ne__ = binary(operator.ne)
    __lt__ = binary(operator.lt)
    __gt__ = binary(operator.gt)
    __le__ = binary(operator.le)
    __ge__ = binary(operator.ge)
    
    # Additive operators.
    
    __add__ = binary(operator.add)
    __radd__ = binary.r(operator.add)
    __sub__ = binary(operator.sub)
    
    # Multiplicative operators.
    
    __mul__ = binary(operator.mul)
    __rmul__ = binary.r(operator.mul)
    __div__ = binary(operator.div)
    __rdiv__ = binary.r(operator.div)

class BinaryExpression(Expression):
    def __init__(self, operator, left, right):
        super(BinaryExpression, self).__init__(None, operator)
        self.left = left
        self.right = right

    def __repr__(self):
        return "BinaryExpression(%r, %r, %r)" % (self.operator, self.left, self.right)

class ConditionalExpression(Expression):
    def __init__(self, operator, operands):
        super(ConditionalExpression, self).__init__(None, operator)
        self.operands = operands

    def __repr__(self):
        return "ConditionalExpression(%r, %r)" % (self.operator, self.operands)

def and_(*operands):
    return ConditionalExpression(operator.and_, operands)

def or_(*operands):
    return ConditionalExpression(operator.or_, operands)

class VariableExpressionConstructor(object):
    _VARIABLES = weakref.WeakValueDictionary()
    
    def __call__(self, name):
        if isinstance(name, basestring):
            name = unicode(name)
        else:
            raise TypeError("Variable names must be strings.")
        try:
            expr = self._VARIABLES[name]
        except KeyError:
            expr = self._VARIABLES[name] = Expression(Variable(name))
        return expr
    
    def __getattr__(self, name):
        return self(name)
    
    def __getitem__(self, name):
        return self(name)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.