Source code for constraints.proxy

"""
proxy contains :class:`Symbol` and functions related to it.
"""

from decorator import decorator
import operator
import types

[docs]def create_cell(obj): """ Create a cell object which references `obj`. """ return (lambda: obj).func_closure[0]
[docs]def copy_func(f, code=None, globals_=None, name=None, argdefs=None, closure=None): """ Create a copy of a function, replacing any portions specified. """ return types.FunctionType( code or f.func_code, globals_ or f.func_globals, name or f.func_name, argdefs or f.func_defaults, closure or f.func_closure )
@decorator
[docs]def chainable(f, self, *args, **kwargs): """Chainable functions return Symbol objects.""" return type(self)(f(self, *args, **kwargs), self)
[docs]class Symbol(object): """ A proxy object that can be used to generatively construct functions at runtime. Most operations performed on a Symbol will return another Symbol, representing the state of the first Symbol after the operation. Notable exceptions to this include functions such as isinstance, and the built-in type/functions, such as int, float, bool, etc. """ def __init__(self, f=None, parent=None): self._f = f self.parent = parent @property def f(self): return self._f() @f.setter def f(self, func): if not isinstance(func, (types.FunctionType, Symbol)): self._f = lambda: func else: self._f = func def __evaluate__(self, f): current = self while current.parent is not None: current = current.parent current.f = f return self.f @chainable def __call__(self, *args, **kwargs): return lambda: self.f(*args, **kwargs) @chainable def __getattr__(self, attr): return lambda: getattr(self.f, attr) @chainable def __reversed__(self): return lambda: reversed(self.f) @chainable def __getitem__(self, item): return lambda: self.f[item] @chainable def __hash__(self): return lambda: hash(self.f) @chainable def __invert__(self): return lambda:~self.f @chainable def __index__(self): return lambda: operator.index(self.f) @chainable def __neg__(self): return lambda:-self.f @chainable def __pos__(self): return lambda:+self.f @chainable def __abs__(self): return lambda: abs(self.f) @chainable def __add__(self, other): return lambda: self.f + other @chainable def __sub__(self, other): return lambda: self.f - other @chainable def __mul__(self, other): return lambda: self.f * other @chainable def __floordiv__(self, other): return lambda: self.f // other @chainable def __mod__(self, other): return lambda: self.f % other @chainable def __divmod__(self, other): return lambda: divmod(self.f, other) @chainable def __pow__(self, other, modulo=None): return lambda: pow(self.f, other, modulo) @chainable def __lshift__(self, other): return lambda: self.f << other @chainable def __rshift__(self, other): return lambda: self.f >> other @chainable def __div__(self, other): return lambda: self.f / other @chainable def __truediv__(self, other): return lambda: self.f.__truediv__(other) @chainable def __radd__(self, other): return lambda: other + self.f @chainable def __rand__(self, other): return lambda: other & self.f @chainable def __rdiv__(self, other): return lambda: other / self.f @chainable def __rdivmod__(self, other): return lambda: divmod(other, self.f) @chainable def __rfloordiv__(self, other): return lambda: other // self @chainable def __rlshift__(self, other): return lambda:other << self @chainable def __rmod__(self, other): return lambda:other % self @chainable def __rmul__(self, other): return lambda: other * self @chainable def __ror__(self, other): return lambda: other | self @chainable def __rpow__(self, other): return lambda: pow(other, self) @chainable def __rrshift__(self, other): return lambda: other >> self @chainable def __rsub__(self, other): return lambda: other - self @chainable def __rtruediv__(self, other): return lambda: self.__rtruediv__(other) @chainable def __rxor__(self, other): return lambda: other ^ self @chainable def __contains__(self, item): return lambda: item in self.f @chainable def __eq__(self, other): return lambda: self.f == other @chainable def __ne__(self, other): return lambda: self.f != other @chainable def __le__(self, other): return lambda: self.f <= other @chainable def __lt__(self, other): return lambda: self.f < other @chainable def __gt__(self, other): return lambda: self.f > other @chainable def __ge__(self, other): return lambda: self.f >= other @chainable def __cmp__(self, other): return lambda: cmp(self.f, other) @chainable def __and__(self, other): return lambda: self.f & other @chainable def __xor__(self, other): return lambda: self.f ^ other @chainable def __or__(self, other): return lambda: self.f | other @chainable def __iand__(self, other): return lambda: self.f.__iand__(other) @chainable def __ixor__(self, other): return lambda: self.f.__ixor__(other) @chainable def __ior__(self, other): return lambda: self.f.__ior__(other) @chainable def __iadd__(self, other): return lambda: self.f.__iadd__(other) @chainable def __isub__(self, other): return lambda: self.f.__isub__(other) @chainable def __imul__(self, other): return lambda: self.f.__imul__(other) @chainable def __idiv__(self, other): return lambda: self.f.__idiv__(other) @chainable def __itruediv__(self, other): return lambda: self.f.__itruediv__(other) @chainable def __ifloordiv__(self, other): return lambda: self.f.__ifloordiv__(other) @chainable def __imod__(self, other): return lambda: self.f.__imod__(other) @chainable def __ipow__(self, other, modulo=None): return lambda: self.f.__ipow__(other, modulo) @chainable def __ilshift__(self, other): return lambda: self.f.__ilshift__(other) @chainable def __irshift__(self, other): return lambda: self.f.__irshift__(other)