home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2012 January / maximum-cd-2012-01.iso / DiscContents / digsby_setup.exe / lib / peak / events / trellis.pyo (.txt) < prev   
Encoding:
Python Compiled Bytecode  |  2011-10-05  |  44.2 KB  |  1,448 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.6)
  3.  
  4. from thread import get_ident
  5. from weakref import ref
  6. from peak.util import addons, decorators
  7. import sys
  8. import UserDict
  9. import UserList
  10. import sets
  11. import stm
  12. import types
  13. import new
  14. import weakref
  15. import copy
  16. from peak.util.extremes import Max
  17. from peak.util.symbols import Symbol, NOT_GIVEN
  18. __all__ = [
  19.     'Cell',
  20.     'Constant',
  21.     'make',
  22.     'todo',
  23.     'todos',
  24.     'modifier',
  25.     'Component',
  26.     'repeat',
  27.     'poll',
  28.     'InputConflict',
  29.     'Dict',
  30.     'List',
  31.     'Set',
  32.     'mark_dirty',
  33.     'ctrl',
  34.     'ConstantMixin',
  35.     'Sensor',
  36.     'AbstractConnector',
  37.     'Connector',
  38.     'Effector',
  39.     'init_attrs',
  40.     'attr',
  41.     'attrs',
  42.     'compute',
  43.     'maintain',
  44.     'perform',
  45.     'Performer',
  46.     'Pipe']
  47. NO_VALUE = Symbol('NO_VALUE', __name__)
  48. _sentinel = NO_VALUE
  49.  
  50. class InputConflict(Exception):
  51.     pass
  52.  
  53.  
  54. def init_attrs(self, **kw):
  55.     if kw:
  56.         cls = type(self)
  57.         for k, v in kw.iteritems():
  58.             if not hasattr(cls, k):
  59.                 raise TypeError('%s() has no keyword argument %r' % (cls.__name__, k))
  60.             hasattr(cls, k)
  61.             setattr(self, k, v)
  62.         
  63.     
  64.  
  65.  
  66. def named_lambda(func, name):
  67.     if getattr(func, '__name__', None) == '<lambda>':
  68.         
  69.         try:
  70.             func.__name__ = name
  71.         except TypeError:
  72.             pass
  73.         except:
  74.             None<EXCEPTION MATCH>TypeError
  75.         
  76.  
  77.     None<EXCEPTION MATCH>TypeError
  78.     return func
  79.  
  80.  
  81. try:
  82.     set = set
  83. except NameError:
  84.     set = sets.Set
  85.     frozenset = sets.ImmutableSet
  86.     set_like = sets.BaseSet
  87.     dictlike = (dict, sets.BaseSet)
  88.  
  89. set_like = (set, frozenset, sets.BaseSet)
  90. dictlike = (dict,) + set_like
  91.  
  92. class AbstractCell(object):
  93.     __slots__ = ()
  94.     rule = None
  95.     value = None
  96.     _value = None
  97.     _needs_init = None
  98.     writer = None
  99.     connector = None
  100.     was_set = False
  101.     _uninit_repr = ' [uninitialized]'
  102.     
  103.     def get_value(self):
  104.         return self.value
  105.  
  106.     
  107.     def __repr__(self):
  108.         rule = reset = ni = ''
  109.         if getattr(self, 'rule', None) is not None:
  110.             rule = repr(self.rule) + ', '
  111.         
  112.         if self._needs_init:
  113.             ni = self._uninit_repr
  114.         
  115.         if getattr(self, '_reset', _sentinel) is not _sentinel:
  116.             reset = ', discrete[' + repr(self._reset) + ']'
  117.         
  118.         return '%s(%s%r%s%s)' % (self.__class__.__name__, rule, self._value, ni, reset)
  119.  
  120.  
  121.  
  122. class _ReadValue(stm.AbstractSubject, AbstractCell):
  123.     __slots__ = ('_value', 'next_listener', '_set_by', '_reset')
  124.     
  125.     def __init__(self, value = None, discrete = False):
  126.         self._value = value
  127.         self._set_by = _sentinel
  128.         stm.AbstractSubject.__init__(self)
  129.         self._reset = (_sentinel, value)[bool(discrete)]
  130.         if ctrl.newcells is not None:
  131.             ctrl.new_cell(self)
  132.         
  133.  
  134.     
  135.     def get_value(self):
  136.         if ctrl.active:
  137.             used(self)
  138.         
  139.         return self._value
  140.  
  141.     value = property(get_value)
  142.     
  143.     def _finish(self):
  144.         if self._set_by is not _sentinel:
  145.             change_attr(self, '_set_by', _sentinel)
  146.         
  147.         if self._reset is not _sentinel and self._value != self._reset:
  148.             change_attr(self, '_value', self._reset)
  149.             changed(self)
  150.         
  151.  
  152.     
  153.     def was_set(self):
  154.         if ctrl.current_listener is None:
  155.             raise RuntimeError('was_set can only be accessed by a rule')
  156.         ctrl.current_listener is None
  157.         used(self)
  158.         who = self._set_by
  159.         if who is not _sentinel:
  160.             pass
  161.         return who is not self
  162.  
  163.     was_set = property(was_set)
  164.  
  165.  
  166. class Value(_ReadValue):
  167.     __slots__ = '__weakref__'
  168.     
  169.     def set_value(self, value):
  170.         if not ctrl.active:
  171.             return atomically(self.set_value, value)
  172.         lock(self)
  173.         if self._set_by is _sentinel:
  174.             change_attr(self, '_set_by', ctrl.current_listener)
  175.             on_commit(self._finish)
  176.         
  177.         if value is self._value:
  178.             return None
  179.         if value != self._value:
  180.             if self._set_by not in (ctrl.current_listener, self):
  181.                 raise InputConflict(self._value, value)
  182.             self._set_by not in (ctrl.current_listener, self)
  183.             changed(self)
  184.         
  185.         change_attr(self, '_value', value)
  186.  
  187.     value = property(_ReadValue.get_value.im_func, set_value)
  188.  
  189.  
  190. def install_controller(controller):
  191.     global ctrl
  192.     stm.ctrl = ctrl = controller
  193.     for name in [
  194.         'on_commit',
  195.         'on_undo',
  196.         'atomically',
  197.         'manage',
  198.         'savepoint',
  199.         'rollback_to',
  200.         'schedule',
  201.         'cancel',
  202.         'lock',
  203.         'used',
  204.         'changed',
  205.         'initialize',
  206.         'change_attr']:
  207.         globals()[name] = getattr(ctrl, name)
  208.         if name not in __all__:
  209.             __all__.append(name)
  210.             continue
  211.     
  212.  
  213. install_controller(stm.LocalController())
  214.  
  215. class ReadOnlyCell(_ReadValue, stm.AbstractListener):
  216.     __slots__ = ('rule', '_needs_init', 'next_subject', '__weakref__', 'layer')
  217.     
  218.     def __init__(self, rule, value = None, discrete = False):
  219.         super(ReadOnlyCell, self).__init__(value, discrete)
  220.         stm.AbstractListener.__init__(self)
  221.         self._needs_init = True
  222.         self.rule = rule
  223.         self.layer = 0
  224.  
  225.     
  226.     def get_value(self):
  227.         if self._needs_init:
  228.             if not ctrl.active:
  229.                 atomically(schedule, self)
  230.                 return self._value
  231.             cancel(self)
  232.             initialize(self)
  233.         
  234.         if ctrl.current_listener is not None:
  235.             used(self)
  236.         
  237.         return self._value
  238.  
  239.     value = property(get_value)
  240.     
  241.     def run(self):
  242.         if self._needs_init:
  243.             change_attr(self, '_needs_init', False)
  244.             change_attr(self, '_set_by', self)
  245.             change_attr(self, '_value', self.rule())
  246.             on_commit(self._finish)
  247.         else:
  248.             value = self.rule()
  249.             if value != self._value:
  250.                 if self._set_by is _sentinel:
  251.                     change_attr(self, '_set_by', self)
  252.                     on_commit(self._finish)
  253.                 
  254.                 change_attr(self, '_value', value)
  255.                 changed(self)
  256.             
  257.         if not ctrl.reads:
  258.             on_commit(self._check_const)
  259.         
  260.  
  261.     
  262.     def _check_const(self):
  263.         if self.next_subject is None:
  264.             if self._reset is _sentinel or self._value == self._reset:
  265.                 change_attr(self, '_set_by', _sentinel)
  266.                 change_attr(self, 'rule', None)
  267.                 change_attr(self, 'next_listener', None)
  268.                 change_attr(self, '__class__', self._const_class())
  269.             
  270.  
  271.     
  272.     def _const_class(self):
  273.         return ConstantRule
  274.  
  275.  
  276.  
  277. class ConstantMixin(AbstractCell):
  278.     __slots__ = ()
  279.     
  280.     def __setattr__(self, name, value):
  281.         if name == '__class__':
  282.             object.__setattr__(self, name, value)
  283.         else:
  284.             raise AttributeError("Constants can't be changed")
  285.         return name == '__class__'
  286.  
  287.     
  288.     def __repr__(self):
  289.         return 'Constant(%r)' % (self.value,)
  290.  
  291.  
  292.  
  293. class Constant(ConstantMixin):
  294.     __slots__ = 'value'
  295.     
  296.     def __init__(self, value):
  297.         Constant.value.__set__(self, value)
  298.  
  299.     
  300.     def from_attr(cls, rule, value, discrete):
  301.         return cls(value)
  302.  
  303.     from_attr = classmethod(from_attr)
  304.  
  305.  
  306. class ConstantRule(ConstantMixin, ReadOnlyCell):
  307.     __slots__ = ()
  308.     value = ReadOnlyCell._value
  309.     
  310.     def dirty(self):
  311.         return False
  312.  
  313.     
  314.     def run(self):
  315.         pass
  316.  
  317.  
  318.  
  319. class Performer(stm.AbstractListener, AbstractCell):
  320.     __slots__ = ('run', 'next_subject', '__weakref__')
  321.     layer = Max
  322.     
  323.     def __init__(self, rule):
  324.         self.run = rule
  325.         super(Performer, self).__init__()
  326.         atomically(schedule, self)
  327.  
  328.     
  329.     def from_attr(cls, rule, value, discrete):
  330.         return cls(rule)
  331.  
  332.     from_attr = classmethod(from_attr)
  333.  
  334. Performer.rule = Performer.run
  335.  
  336. def modifier(func):
  337.     
  338.     def wrap(__func, __module):
  339.         return '\n        if not __module.ctrl.active:\n            return __module.atomically(__func, $args)\n        elif __module.ctrl.current_listener is None:\n            return __func($args)\n        else:\n            # Prevent any reads from counting against the current rule\n            old_reads, __module.ctrl.reads = __module.ctrl.reads, {}\n            try:\n                return __func($args)\n            finally:\n                __module.ctrl.reads = old_reads\n        '
  340.  
  341.     return decorators.template_function(wrap)(func, sys.modules[__name__])
  342.  
  343. set_next_listener = ReadOnlyCell.next_listener.__set__
  344. get_next_listener = ReadOnlyCell.next_listener.__get__
  345.  
  346. class SensorBase(ReadOnlyCell):
  347.     __slots__ = ()
  348.     
  349.     def __init__(self, rule, value = None, discrete = False):
  350.         if isinstance(rule, AbstractConnector):
  351.             self.connector = rule
  352.             rule = rule.read
  353.         else:
  354.             self.connector = None
  355.         self.listening = NOT_GIVEN
  356.         set_next_listener(self, None)
  357.         super(SensorBase, self).__init__(rule, value, discrete)
  358.  
  359.     
  360.     def _set_listener(self, listener):
  361.         was_seen = get_next_listener(self) is not None
  362.         set_next_listener(self, listener)
  363.         if was_seen != (listener is not None) and self.connector is not None:
  364.             atomically(on_commit, schedule, self.update_connection)
  365.         
  366.  
  367.     next_listener = property(get_next_listener, _set_listener)
  368.     _set_value = Value.set_value.im_func
  369.     
  370.     def receive(self, value):
  371.         if not ctrl.active:
  372.             return atomically(self.receive, value)
  373.         lock(self)
  374.         self._set_value(value)
  375.         change_attr(self, '_set_by', self)
  376.  
  377.     receive = modifier(receive)
  378.     
  379.     def _check_const(self):
  380.         pass
  381.  
  382.     
  383.     def update_connection():
  384.         old_listener = ctrl.current_listener
  385.         ctrl.current_listener = None
  386.         
  387.         try:
  388.             self = old_listener.im_self
  389.             descr = type(self).listening
  390.             listening = descr.__get__(self)
  391.             if self.next_listener is not None:
  392.                 if listening is NOT_GIVEN:
  393.                     descr.__set__(self, self.connector.connect(self))
  394.                 
  395.             elif listening is not NOT_GIVEN:
  396.                 self.connector.disconnect(self, listening)
  397.                 descr.__set__(self, NOT_GIVEN)
  398.         finally:
  399.             ctrl.current_listener = old_listener
  400.  
  401.  
  402.     update_connection.run = update_connection
  403.     update_connection.next_subject = None
  404.     update_connection.next_listener = None
  405.     update_connection.layer = -1
  406.  
  407.  
  408. class Sensor(SensorBase):
  409.     __slots__ = ('connector', 'listening')
  410.  
  411.  
  412. class AbstractConnector(object):
  413.     __slots__ = ()
  414.     
  415.     def read(self):
  416.         return ctrl.current_listener._value
  417.  
  418.     
  419.     def connect(self, sensor):
  420.         pass
  421.  
  422.     
  423.     def disconnect(self, sensor, key):
  424.         pass
  425.  
  426.  
  427.  
  428. class Connector(AbstractConnector):
  429.     __slots__ = ('read', 'connect', 'disconnect')
  430.     
  431.     def __init__(self, connect, disconnect, read = None):
  432.         if read is None:
  433.             read = noop
  434.         
  435.         self.read = read
  436.         self.connect = connect
  437.         self.disconnect = disconnect
  438.  
  439.  
  440.  
  441. def noop():
  442.     return ctrl.current_listener._value
  443.  
  444.  
  445. class LazyConnector(AbstractConnector):
  446.     
  447.     def connect(sensor):
  448.         pass
  449.  
  450.     connect = staticmethod(connect)
  451.     
  452.     def disconnect(sensor, key):
  453.         link = sensor.next_subject
  454.         if link is not None:
  455.             change_attr(sensor, '_needs_init', True)
  456.         
  457.         while link is not None:
  458.             nxt = link.next_subject
  459.             on_undo(stm.Link, link.subject, sensor)
  460.             link.unlink()
  461.             link = nxt
  462.  
  463.     disconnect = staticmethod(disconnect)
  464.  
  465.  
  466. class LazyCell(Sensor):
  467.     __slots__ = ()
  468.     _uninit_repr = ' [inactive]'
  469.     
  470.     def __init__(self, rule, value = None, discrete = False):
  471.         super(LazyCell, self).__init__(rule, value, discrete)
  472.         self.connector = LazyConnector
  473.  
  474.     _check_const = ReadOnlyCell._check_const
  475.     
  476.     def run(self):
  477.         run = super(LazyCell, self).run
  478.         if not ctrl.readonly:
  479.             ctrl.with_readonly(run)
  480.         else:
  481.             run()
  482.         if self.listening is NOT_GIVEN:
  483.             self.listening = None
  484.             on_commit(schedule, self.update_connection)
  485.         
  486.  
  487.     
  488.     def _const_class(self):
  489.         return LazyConstant
  490.  
  491.     
  492.     def get_value(self):
  493.         if ctrl.current_listener is self:
  494.             raise RuntimeError('@compute rules cannot use their own value')
  495.         ctrl.current_listener is self
  496.         return super(LazyCell, self).get_value()
  497.  
  498.     value = property(get_value)
  499.  
  500.  
  501. class LazyConstant(ConstantRule, LazyCell):
  502.     __slots__ = ()
  503.  
  504.  
  505. class Cell(ReadOnlyCell, Value):
  506.     __slots__ = ()
  507.     
  508.     def __new__(cls, rule = None, value = _sentinel, discrete = False):
  509.         v = [
  510.             value,
  511.             None][value is _sentinel]
  512.         return ReadOnlyCell.__new__(cls, rule, value, discrete)
  513.  
  514.     
  515.     def _check_const(self):
  516.         pass
  517.  
  518.     
  519.     def get_value(self):
  520.         if self._needs_init:
  521.             if not ctrl.active:
  522.                 atomically(schedule, self)
  523.                 return self._value
  524.             if self._set_by is _sentinel:
  525.                 cancel(self)
  526.                 initialize(self)
  527.             
  528.         
  529.         if ctrl.current_listener is not None:
  530.             used(self)
  531.         
  532.         return self._value
  533.  
  534.     
  535.     def set_value(self, value):
  536.         if not ctrl.active:
  537.             return atomically(self.set_value, value)
  538.         super(Cell, self).set_value(value)
  539.         if self._needs_init:
  540.             schedule(self)
  541.         else:
  542.             cancel(self)
  543.  
  544.     value = property(get_value, set_value)
  545.     
  546.     def dirty(self):
  547.         who = self._set_by
  548.         if not who is _sentinel:
  549.             pass
  550.         return who is self
  551.  
  552.     
  553.     def run(self):
  554.         if self.dirty():
  555.             super(Cell, self).run()
  556.         elif self._needs_init:
  557.             change_attr(self, '_needs_init', False)
  558.             self.rule()
  559.         else:
  560.             raise AssertionError('This should never happen!')
  561.         return self.dirty()
  562.  
  563.  
  564.  
  565. class Effector(SensorBase, Cell):
  566.     __slots__ = ('connector', 'listening')
  567.  
  568.  
  569. class _Defaulting(addons.Registry):
  570.     
  571.     def __init__(self, subject):
  572.         self.defaults = { }
  573.         return super(_Defaulting, self).__init__(subject)
  574.  
  575.     
  576.     def created_for(self, cls):
  577.         for k, v in self.defaults.items():
  578.             self.setdefault(k, v)
  579.         
  580.         return super(_Defaulting, self).created_for(cls)
  581.  
  582.  
  583.  
  584. class CellFactories(_Defaulting):
  585.     pass
  586.  
  587.  
  588. class IsOptional(_Defaulting):
  589.     pass
  590.  
  591.  
  592. class Cells(addons.AddOn):
  593.     __slots__ = ()
  594.     addon_key = classmethod((lambda cls: '__cells__'))
  595.     
  596.     def __new__(cls, subject):
  597.         return { }
  598.  
  599.  
  600.  
  601. class Component(decorators.classy):
  602.     __slots__ = ()
  603.     
  604.     def __class_call__(cls, *args, **kw):
  605.         if ctrl.readonly and ctrl.newcells is None:
  606.             return ctrl.with_new(Component.__class_call__.im_func, cls, *args, **kw)
  607.         optional = IsOptional(cls)
  608.         rv = super(Component, cls).__class_call__(*args, **kw)
  609.         if isinstance(rv, cls):
  610.             cells = Cells(rv)
  611.             for k, v in optional.iteritems():
  612.                 if not v and k not in cells:
  613.                     c = cells.setdefault(k, CellFactories(cls)[k](cls, rv, k))
  614.                     c.value
  615.                     continue
  616.                 ctrl.newcells is None
  617.             
  618.         
  619.         return rv
  620.  
  621.     __class_call__ = classmethod(modifier(__class_call__))
  622.     __init__ = init_attrs
  623.     
  624.     def __sa_instrumentation_manager__(cls):
  625.         SAInstrument = SAInstrument
  626.         import peak.events.sa_support
  627.         return SAInstrument(cls)
  628.  
  629.     __sa_instrumentation_manager__ = staticmethod(__sa_instrumentation_manager__)
  630.     
  631.     def __class_init__(cls, name, bases, cdict, supr):
  632.         supr()(cls, name, bases, cdict, supr)
  633.         
  634.         try:
  635.             Component
  636.         except NameError:
  637.             return None
  638.  
  639.         optional = IsOptional(cls)
  640.         factories = CellFactories(cls)
  641.         for k, descr in cdict.items():
  642.             if isinstance(descr, CellAttribute):
  643.                 if descr.__name__ is None:
  644.                     descr.__name__ = k
  645.                 
  646.                 optional[k] = descr.optional
  647.                 factories[k] = descr.make_cell
  648.                 continue
  649.             if k in optional:
  650.                 optional[k] = True
  651.                 continue
  652.         
  653.  
  654.  
  655.  
  656. def repeat():
  657.     if ctrl.current_listener is not None:
  658.         on_commit(schedule, ctrl.current_listener)
  659.     else:
  660.         raise RuntimeError('repeat() must be called from a rule')
  661.     return ctrl.current_listener is not None
  662.  
  663.  
  664. def poll():
  665.     listener = ctrl.current_listener
  666.     if listener is None or not hasattr(listener, '_needs_init'):
  667.         raise RuntimeError('poll() must be called from a rule')
  668.     not hasattr(listener, '_needs_init')
  669.     return ctrl.pulse.value
  670.  
  671.  
  672. def mark_dirty():
  673.     changed(ctrl.current_listener)
  674.  
  675.  
  676. def bind(rule, ob, typ = None):
  677.     if hasattr(rule, '__get__'):
  678.         return rule.__get__(ob, typ)
  679.     return rule
  680.  
  681.  
  682. class CellAttribute(object):
  683.     value = NO_VALUE
  684.     rule = None
  685.     connect = None
  686.     disconnect = None
  687.     make = None
  688.     factory = Cell
  689.     discrete = False
  690.     optional = False
  691.     __name__ = None
  692.     __init__ = init_attrs
  693.     
  694.     def initial_value(self, ob):
  695.         return self.value
  696.  
  697.     
  698.     def make_cell(self, typ, ob, name):
  699.         rule = bind(self.rule, ob, typ)
  700.         if self.connect is not None or self.disconnect is not None:
  701.             connect = bind(self.connect, ob, typ)
  702.             disconnect = bind(self.disconnect, ob, typ)
  703.             missing = 'disconnect'
  704.             if connect is None:
  705.                 missing = 'connect'
  706.             
  707.             if connect is None or disconnect is None:
  708.                 raise TypeError('%r is missing a .%sor' % (self, missing))
  709.             disconnect is None
  710.             rule = Connector(connect, disconnect, rule)
  711.         
  712.         return self.factory(rule, self.initial_value(ob), self.discrete)
  713.  
  714.     
  715.     def connector(self, func = None):
  716.         return self._hook_method('connect', func)
  717.  
  718.     
  719.     def disconnector(self, func = None):
  720.         return self._hook_method('disconnect', func)
  721.  
  722.     
  723.     def __get__(self, ob, typ = None):
  724.         if ob is None:
  725.             return self
  726.         
  727.         try:
  728.             cells = ob.__cells__
  729.         except AttributeError:
  730.             ob is None
  731.             ob is None
  732.             cells = Cells(ob)
  733.         except:
  734.             ob is None
  735.  
  736.         
  737.         try:
  738.             cell = cells[self.__name__]
  739.         except KeyError:
  740.             ob is None
  741.             ob is None
  742.             name = self.__name__
  743.             cell = cells.setdefault(name, self.make_cell(typ, ob, name))
  744.         except:
  745.             ob is None
  746.  
  747.         return cell.value
  748.  
  749.     
  750.     def __repr__(self):
  751.         return '%s(%r)' % (self.__class__.__name__, self.__name__)
  752.  
  753.     
  754.     def __set__(self, ob, value):
  755.         
  756.         try:
  757.             cells = ob.__cells__
  758.         except AttributeError:
  759.             cells = Cells(ob)
  760.  
  761.  
  762.     
  763.     def mkattr(cls, initially = NO_VALUE, resetting_to = NO_VALUE, **kw):
  764.         if initially is not NO_VALUE and resetting_to is not NO_VALUE:
  765.             raise TypeError("Can't specify both 'initially' and 'resetting_to'")
  766.         resetting_to is not NO_VALUE
  767.         value = initially
  768.         discrete = False
  769.         if resetting_to is not NO_VALUE:
  770.             value = resetting_to
  771.             discrete = True
  772.         
  773.         if value is not NO_VALUE and kw.get('make') is not None:
  774.             raise TypeError("Can't specify both a value and 'make'")
  775.         kw.get('make') is not None
  776.         return cls(value = value, discrete = discrete, **kw)
  777.  
  778.     mkattr = classmethod(mkattr)
  779.     
  780.     def can_connect(self):
  781.         if self.factory is LazyCell:
  782.             self.factory = Sensor
  783.         elif not self.factory is Cell:
  784.             pass
  785.         return self.factory is Sensor
  786.         return True
  787.  
  788.     
  789.     def _hook_method(self, methodname, func = None, frame = None):
  790.         if not self.can_connect():
  791.             raise TypeError('%r cannot have a .%sor' % (self, methodname))
  792.         self.can_connect()
  793.         if isinstance(self.rule, AbstractConnector):
  794.             raise TypeError('The rule for %r is itself a Connector' % (self,))
  795.         isinstance(self.rule, AbstractConnector)
  796.         if getattr(self, methodname) is not None:
  797.             raise TypeError('%r already has a .%sor' % (self, methodname))
  798.         getattr(self, methodname) is not None
  799.         if func is not None:
  800.             setattr(self, methodname, func)
  801.             if getattr(func, '__name__', None) == self.__name__:
  802.                 if not frame:
  803.                     pass
  804.                 frame = sys._getframe(2)
  805.                 if frame.f_locals.get(self.__name__) is self:
  806.                     return self
  807.             
  808.             return func
  809.         if not frame:
  810.             pass
  811.         frame = sys._getframe(2)
  812.         
  813.         def callback(frame, name, func, locals):
  814.             setattr(self, methodname, func)
  815.             if name == self.__name__ and locals.get(name) is self:
  816.                 return self
  817.             return func
  818.  
  819.         return decorators.decorate_assignment(callback, frame = frame)
  820.  
  821.  
  822.  
  823. def attr(initially = NO_VALUE, resetting_to = NO_VALUE):
  824.     return CellAttribute.mkattr(initially, resetting_to)
  825.  
  826.  
  827. def compute(rule = None, resetting_to = NO_VALUE, name = None):
  828.     return _build_descriptor(rule = rule, resetting_to = resetting_to, factory = LazyCell, optional = True, __name = name)
  829.  
  830.  
  831. def maintain(rule = None, make = None, initially = NO_VALUE, resetting_to = NO_VALUE, optional = False, name = None):
  832.     return _build_descriptor(rule = rule, initially = initially, resetting_to = resetting_to, make = make, optional = optional, __name = name)
  833.  
  834.  
  835. def perform(rule = None, optional = False, name = None):
  836.     return _build_descriptor(rule = rule, factory = Performer.from_attr, optional = optional, __name = name)
  837.  
  838.  
  839. def compute_attrs(**attrs):
  840.     _make_multi(sys._getframe(1), attrs, factory = LazyCell, optional = True)
  841.  
  842. compute.attrs = compute_attrs
  843.  
  844. def maintain_attrs(**attrs):
  845.     _make_multi(sys._getframe(1), attrs)
  846.  
  847. maintain.attrs = maintain_attrs
  848.  
  849. def attrs(**attrs):
  850.     _make_multi(sys._getframe(1), attrs, arg = 'initially')
  851.  
  852.  
  853. def attrs_resetting_to(**attrs):
  854.     _make_multi(sys._getframe(1), attrs, arg = 'resetting_to')
  855.  
  856. attrs.resetting_to = attrs_resetting_to
  857.  
  858. def _make_multi(frame, kw, wrap = CellAttribute.mkattr, arg = 'rule', **opts):
  859.     for k, v in kw.items():
  860.         if k in frame.f_locals:
  861.             raise TypeError('%s is already defined in this class' % (k,))
  862.         k in frame.f_locals
  863.         opts[arg] = named_lambda(v, k)
  864.         frame.f_locals[k] = wrap(__name__ = k, **opts)
  865.     
  866.  
  867.  
  868. def _build_descriptor(rule = None, __frame = None, __name = None, __proptype = CellAttribute.mkattr, __ruleattr = 'rule', **kw):
  869.     if not __frame:
  870.         pass
  871.     frame = sys._getframe(2)
  872.     name = __name
  873.     if isinstance(rule, types.FunctionType):
  874.         if frame.f_locals.get(rule.__name__) is rule:
  875.             if not name:
  876.                 pass
  877.             name = rule.__name__
  878.         
  879.     
  880.     
  881.     def callback(frame, name, rule, locals):
  882.         kw[__ruleattr] = named_lambda(rule, name)
  883.         return __proptype(__name__ = name, **kw)
  884.  
  885.     if name:
  886.         return callback(frame, name, rule, None)
  887.     if rule is not None:
  888.         
  889.         try:
  890.             name = rule.__name__
  891.             if name == '<lambda>':
  892.                 decorators.decorate_assignment(callback, frame = frame)
  893.                 return rule
  894.         except:
  895.             name
  896.             (None, None, None)
  897.             decorators.decorate_assignment(callback, frame = frame)
  898.  
  899.         return callback(frame, name, rule, None)
  900.     return rule is not None
  901.     name
  902.     return decorators.decorate_assignment(callback, frame = frame)
  903.  
  904.  
  905. def todos(**attrs):
  906.     _make_multi(sys._getframe(1), attrs, TodoProperty.mkattr)
  907.  
  908.  
  909. def todo(rule = None, name = None):
  910.     return _build_descriptor(rule = rule, __proptype = TodoProperty.mkattr, __name = name)
  911.  
  912.  
  913. class TodoProperty(CellAttribute):
  914.     
  915.     def future(self):
  916.         name = self.__name__
  917.         
  918.         def get(ob):
  919.             
  920.             try:
  921.                 cells = ob.__cells__
  922.             except AttributeError:
  923.                 cells = Cells(ob)
  924.  
  925.             
  926.             try:
  927.                 cell = cells[name]
  928.             except KeyError:
  929.                 typ = type(ob)
  930.                 cell = cells.setdefault(name, self.make_cell(typ, ob, name))
  931.  
  932.             return cell.get_future()
  933.  
  934.         return property(get, doc = 'The future value of the %r attribute' % name)
  935.  
  936.     future = property(future)
  937.     
  938.     def factory(self, rule, value, discrete):
  939.         return TodoValue(rule)
  940.  
  941.  
  942.  
  943. def build_value(make, ob, name):
  944.     if hasattr(make, '__get__'):
  945.         make = make.__get__(ob, type(ob))
  946.     
  947.     return make()
  948.  
  949.  
  950. def make(rule = None, writable = False, optional = True, name = None):
  951.     return _build_descriptor(rule, optional = optional, __ruleattr = 'make', factory = [
  952.         Constant.from_attr,
  953.         Cell][bool(writable)], __name = name)
  954.  
  955.  
  956. def make_attrs(**attrs):
  957.     _make_multi(sys._getframe(1), attrs, factory = Constant.from_attr, arg = 'make', optional = True)
  958.  
  959. make.attrs = make_attrs
  960.  
  961. class TodoValue(Value):
  962.     __slots__ = ('rule', '_copy', '_last_reader')
  963.     
  964.     def __new__(cls, rule, copy = copy.copy):
  965.         return Value.__new__(cls)
  966.  
  967.     
  968.     def __init__(self, rule, copy = copy.copy):
  969.         self.rule = rule
  970.         self._copy = copy
  971.         self._last_reader = NOT_GIVEN
  972.         Value.__init__(self, rule(), True)
  973.  
  974.     
  975.     def get_future(self):
  976.         if not ctrl.active:
  977.             raise RuntimeError('future can only be accessed from a @modifier')
  978.         ctrl.active
  979.         lock(self)
  980.         if ctrl.current_listener is not self._last_reader:
  981.             if self._last_reader is NOT_GIVEN:
  982.                 self.value = value = self.rule()
  983.                 changed(self)
  984.             else:
  985.                 value = self._copy(self._value)
  986.                 change_attr(self, '_value', value)
  987.             change_attr(self, '_last_reader', ctrl.current_listener)
  988.         
  989.         return self._value
  990.  
  991.     
  992.     def _finish(self):
  993.         change_attr(self, '_last_reader', NOT_GIVEN)
  994.         super(TodoValue, self)._finish()
  995.  
  996.  
  997.  
  998. class Pipe(Component):
  999.     output = todo(list, name = 'output')
  1000.     input = output.future
  1001.     
  1002.     def append(self, value):
  1003.         self.input.append(value)
  1004.  
  1005.     append = modifier(append)
  1006.     
  1007.     def extend(self, sequence):
  1008.         self.input.extend(sequence)
  1009.  
  1010.     extend = modifier(extend)
  1011.     
  1012.     def __iter__(self):
  1013.         return iter(self.output)
  1014.  
  1015.     
  1016.     def __contains__(self, value):
  1017.         return value in self.output
  1018.  
  1019.     
  1020.     def __len__(self):
  1021.         return len(self.output)
  1022.  
  1023.     
  1024.     def __repr__(self):
  1025.         return repr(self.output)
  1026.  
  1027.  
  1028.  
  1029. class WeakDefaultDict(weakref.WeakValueDictionary):
  1030.     
  1031.     def __init__(self, missing):
  1032.         weakref.WeakValueDictionary.__init__(self)
  1033.         self.__missing__ = missing
  1034.  
  1035.     
  1036.     def __getitem__(self, key):
  1037.         
  1038.         try:
  1039.             return weakref.WeakValueDictionary.__getitem__(self, key)
  1040.         except KeyError:
  1041.             value = self.__missing__(key)
  1042.             self[key] = value
  1043.             return value
  1044.  
  1045.  
  1046.  
  1047.  
  1048. class CacheAttr(CellAttribute):
  1049.     optional = True
  1050.     
  1051.     def can_connect(self):
  1052.         return True
  1053.  
  1054.     
  1055.     def factory(self, rule, value, discrete):
  1056.         conn = rule.connect
  1057.         disc = rule.disconnect
  1058.         rule = rule.read
  1059.         
  1060.         def make_cell(key):
  1061.             r = new.instancemethod(rule, key, type(key))
  1062.             return None(None(((Sensor, Connector), (lambda s: conn(key))), (lambda s, m: disc(key)), r), value, discrete)
  1063.  
  1064.         return Constant(WeakDefaultDict(make_cell))
  1065.  
  1066.  
  1067.  
  1068. def cellcache(rule = None, make = None, initially = NO_VALUE, resetting_to = NO_VALUE, name = None):
  1069.     return _build_descriptor(rule = rule, initially = initially, resetting_to = resetting_to, make = make, __proptype = CacheAttr.mkattr, __name = name)
  1070.  
  1071.  
  1072. class Dict(UserDict.IterableUserDict, Component):
  1073.     added = todo(dict, name = 'added')
  1074.     deleted = todo(dict, name = 'deleted')
  1075.     changed = todo(dict, name = 'changed')
  1076.     to_add = added.future
  1077.     to_change = changed.future
  1078.     to_delete = deleted.future
  1079.     
  1080.     def __init__(self, other = (), **kw):
  1081.         Component.__init__(self)
  1082.         if other:
  1083.             self.data.update(other)
  1084.         
  1085.         if kw:
  1086.             self.data.update(kw)
  1087.         
  1088.  
  1089.     
  1090.     def copy(self):
  1091.         return self.__class__(self.data)
  1092.  
  1093.     
  1094.     def get(self, key, failobj = None):
  1095.         return self.data.get(key, failobj)
  1096.  
  1097.     
  1098.     def __hash__(self):
  1099.         raise TypeError
  1100.  
  1101.     
  1102.     def data(self):
  1103.         data = self.data
  1104.         pop = data.pop
  1105.         if self.added:
  1106.             for key in self.added:
  1107.                 on_undo(pop, key, None)
  1108.             
  1109.             mark_dirty()
  1110.             data.update(self.added)
  1111.         
  1112.         if self.changed:
  1113.             mark_dirty()
  1114.             data.update(self.changed)
  1115.         
  1116.         return data
  1117.  
  1118.     data = maintain(data, make = dict, name = 'data')
  1119.     
  1120.     def __setitem__(self, key, item):
  1121.         if key in self.to_delete:
  1122.             del self.to_delete[key]
  1123.         
  1124.         if key in self.data:
  1125.             self.to_change[key] = item
  1126.         else:
  1127.             self.to_add[key] = item
  1128.  
  1129.     __setitem__ = modifier(__setitem__)
  1130.     
  1131.     def __delitem__(self, key):
  1132.         if key in self.to_add:
  1133.             del self.to_add[key]
  1134.         elif key in self.data and key not in self.to_delete:
  1135.             self.to_delete[key] = self.data[key]
  1136.             if key in self.to_change:
  1137.                 del self.to_change[key]
  1138.             
  1139.         else:
  1140.             raise KeyError, key
  1141.         return key not in self.to_delete
  1142.  
  1143.     __delitem__ = modifier(__delitem__)
  1144.     
  1145.     def clear(self):
  1146.         self.to_add.clear()
  1147.         self.to_change.clear()
  1148.         self.to_delete.update(self.data)
  1149.  
  1150.     clear = modifier(clear)
  1151.     
  1152.     def update(self, d = (), **kw):
  1153.         if d:
  1154.             if kw:
  1155.                 d = dict(d)
  1156.                 d.update(kw)
  1157.             elif not hasattr(d, 'iteritems'):
  1158.                 d = dict(d)
  1159.             
  1160.         else:
  1161.             d = kw
  1162.         to_change = self.to_change
  1163.         to_add = self.to_add
  1164.         to_delete = self.to_delete
  1165.         data = self.data
  1166.         for k, v in d.iteritems():
  1167.             if k in to_delete:
  1168.                 del to_delete[k]
  1169.             
  1170.             if k in data:
  1171.                 to_change[k] = d[k]
  1172.                 continue
  1173.             to_add[k] = d[k]
  1174.         
  1175.  
  1176.     update = modifier(update)
  1177.     
  1178.     def setdefault(self, key, failobj = None):
  1179.         raise InputConflict("Can't read and write in the same operation")
  1180.  
  1181.     
  1182.     def pop(self, key, *args):
  1183.         raise InputConflict("Can't read and write in the same operation")
  1184.  
  1185.     
  1186.     def popitem(self):
  1187.         raise InputConflict("Can't read and write in the same operation")
  1188.  
  1189.  
  1190.  
  1191. class List(UserList.UserList, Component):
  1192.     updated = todo((lambda self: self.data[:]), name = 'updated')
  1193.     future = updated.future
  1194.     changed = todo(bool, name = 'changed')
  1195.     
  1196.     def __init__(self, other = (), **kw):
  1197.         Component.__init__(self, **kw)
  1198.         self.data[:] = other
  1199.  
  1200.     
  1201.     def data(self):
  1202.         if self.changed:
  1203.             mark_dirty()
  1204.             return self.updated
  1205.         return self.data
  1206.  
  1207.     data = maintain(data, make = list, name = 'data')
  1208.     
  1209.     def __setitem__(self, i, item):
  1210.         self.changed = True
  1211.         self.future[i] = item
  1212.  
  1213.     __setitem__ = modifier(__setitem__)
  1214.     
  1215.     def __delitem__(self, i):
  1216.         self.changed = True
  1217.         del self.future[i]
  1218.  
  1219.     __delitem__ = modifier(__delitem__)
  1220.     
  1221.     def __setslice__(self, i, j, other):
  1222.         self.changed = True
  1223.         self.future[i:j] = other
  1224.  
  1225.     __setslice__ = modifier(__setslice__)
  1226.     
  1227.     def __delslice__(self, i, j):
  1228.         self.changed = True
  1229.         del self.future[i:j]
  1230.  
  1231.     __delslice__ = modifier(__delslice__)
  1232.     
  1233.     def __iadd__(self, other):
  1234.         self.changed = True
  1235.         self.future.extend(other)
  1236.         return self
  1237.  
  1238.     __iadd__ = modifier(__iadd__)
  1239.     
  1240.     def append(self, item):
  1241.         self.changed = True
  1242.         self.future.append(item)
  1243.  
  1244.     append = modifier(append)
  1245.     
  1246.     def insert(self, i, item):
  1247.         self.changed = True
  1248.         self.future.insert(i, item)
  1249.  
  1250.     insert = modifier(insert)
  1251.     
  1252.     def extend(self, other):
  1253.         self.changed = True
  1254.         self.future.extend(other)
  1255.  
  1256.     extend = modifier(extend)
  1257.     
  1258.     def __imul__(self, n):
  1259.         self.changed = True
  1260.         self.future[:] = self.future * n
  1261.         return self
  1262.  
  1263.     __imul__ = modifier(__imul__)
  1264.     
  1265.     def remove(self, item):
  1266.         self.changed = True
  1267.         self.future.remove(item)
  1268.  
  1269.     remove = modifier(remove)
  1270.     
  1271.     def reverse(self):
  1272.         self.changed = True
  1273.         self.future.reverse()
  1274.  
  1275.     reverse = modifier(reverse)
  1276.     
  1277.     def sort(self, *args, **kw):
  1278.         self.changed = True
  1279.         self.future.sort(*args, **kw)
  1280.  
  1281.     sort = modifier(sort)
  1282.     
  1283.     def pop(self, i = -1):
  1284.         raise InputConflict("Can't read and write in the same operation")
  1285.  
  1286.     
  1287.     def __hash__(self):
  1288.         raise TypeError
  1289.  
  1290.  
  1291.  
  1292. class Set(sets.Set, Component):
  1293.     _added = todo(set, name = '_added')
  1294.     _removed = todo(set, name = '_removed')
  1295.     added = _added
  1296.     removed = _removed
  1297.     to_add = _added.future
  1298.     to_remove = _removed.future
  1299.     
  1300.     def __init__(self, iterable = None, **kw):
  1301.         Component.__init__(self, **kw)
  1302.         if iterable is not None:
  1303.             sets.Set._update(self, iterable)
  1304.         
  1305.  
  1306.     
  1307.     def _data(self):
  1308.         data = self._data
  1309.         pop = data.pop
  1310.         if self.removed:
  1311.             mark_dirty()
  1312.             for item in self.removed:
  1313.                 pop(item, None)
  1314.             
  1315.             on_undo(data.update, dict.fromkeys(self.removed, True))
  1316.         
  1317.         if self.added:
  1318.             mark_dirty()
  1319.             data.update(dict.fromkeys(self.added, True))
  1320.             for item in self.added:
  1321.                 on_undo(pop, item, None)
  1322.             
  1323.         
  1324.         return data
  1325.  
  1326.     _data = maintain(_data, make = dict, name = '_data')
  1327.     
  1328.     def __setstate__(self, data):
  1329.         self.__init__(data[0])
  1330.  
  1331.     
  1332.     def _binary_sanity_check(self, other):
  1333.         if not isinstance(other, set_like):
  1334.             raise TypeError, 'Binary operation only permitted between sets'
  1335.         isinstance(other, set_like)
  1336.  
  1337.     
  1338.     def pop(self):
  1339.         raise InputConflict("Can't read and write in the same operation")
  1340.  
  1341.     
  1342.     def _update(self, iterable):
  1343.         to_remove = self.to_remove
  1344.         add = self.to_add.add
  1345.         for item in iterable:
  1346.             if item in to_remove:
  1347.                 to_remove.remove(item)
  1348.                 continue
  1349.             add(item)
  1350.         
  1351.  
  1352.     _update = modifier(_update)
  1353.     
  1354.     def add(self, item):
  1355.         if item in self.to_remove:
  1356.             self.to_remove.remove(item)
  1357.         elif item not in self._data:
  1358.             self.to_add.add(item)
  1359.         
  1360.  
  1361.     add = modifier(add)
  1362.     
  1363.     def remove(self, item):
  1364.         if item in self.to_add:
  1365.             self.to_add.remove(item)
  1366.         elif item in self._data and item not in self.to_remove:
  1367.             self.to_remove.add(item)
  1368.         else:
  1369.             raise KeyError(item)
  1370.         return item not in self.to_remove
  1371.  
  1372.     remove = modifier(remove)
  1373.     
  1374.     def clear(self):
  1375.         self.to_remove.update(self)
  1376.         self.to_add.clear()
  1377.  
  1378.     clear = modifier(clear)
  1379.     
  1380.     def __ior__(self, other):
  1381.         self._binary_sanity_check(other)
  1382.         self._update(other)
  1383.         return self
  1384.  
  1385.     
  1386.     def __iand__(self, other):
  1387.         self._binary_sanity_check(other)
  1388.         self.intersection_update(other)
  1389.         return self
  1390.  
  1391.     
  1392.     def difference_update(self, other):
  1393.         data = self._data
  1394.         to_add = self.to_add
  1395.         to_remove = self.to_remove
  1396.         for item in other:
  1397.             if item in to_add:
  1398.                 to_add.remove(item)
  1399.                 continue
  1400.             if item in data:
  1401.                 to_remove.add(item)
  1402.                 continue
  1403.         
  1404.  
  1405.     difference_update = modifier(difference_update)
  1406.     
  1407.     def intersection_update(self, other):
  1408.         to_remove = self.to_remove
  1409.         to_add = self.to_add
  1410.         self.to_add.intersection_update(other)
  1411.         other = to_dict_or_set(other)
  1412.         for item in self._data:
  1413.             if item not in other:
  1414.                 to_remove.add(item)
  1415.                 continue
  1416.         
  1417.         return self
  1418.  
  1419.     intersection_update = modifier(intersection_update)
  1420.     
  1421.     def symmetric_difference_update(self, other):
  1422.         data = self._data
  1423.         to_add = self.to_add
  1424.         to_remove = self.to_remove
  1425.         for elt in to_dict_or_set(other):
  1426.             if elt in to_add:
  1427.                 to_add.remove(elt)
  1428.                 continue
  1429.             if elt in to_remove:
  1430.                 to_remove.remove(elt)
  1431.                 continue
  1432.             if elt in data:
  1433.                 to_remove.add(elt)
  1434.                 continue
  1435.             to_add.add(elt)
  1436.         
  1437.  
  1438.     symmetric_difference_update = modifier(symmetric_difference_update)
  1439.  
  1440.  
  1441. def to_dict_or_set(ob):
  1442.     if isinstance(ob, sets.BaseSet):
  1443.         return ob._data
  1444.     if not isinstance(ob, dictlike):
  1445.         return dict.fromkeys(ob)
  1446.     return ob
  1447.  
  1448.