home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2011 February / maximum-cd-2011-02.iso / DiscContents / digsby_setup85.exe / lib / peak / context.pyo (.txt) < prev   
Encoding:
Python Compiled Bytecode  |  2010-11-24  |  27.6 KB  |  889 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.6)
  3.  
  4. import contextlib
  5. import sys
  6. from thread import get_ident
  7. from peak.util.decorators import cache_source, classy
  8. __all__ = [
  9.     'Service',
  10.     'replaces',
  11.     'setting',
  12.     'InputConflict',
  13.     'DynamicRuleError',
  14.     'State',
  15.     'Action',
  16.     'resource',
  17.     'registry',
  18.     'new',
  19.     'empty',
  20.     'lookup',
  21.     'manager',
  22.     'reraise',
  23.     'with_',
  24.     'call_with',
  25.     'ScopeError',
  26.     'resource_registry']
  27. _in_place = '__iadd__ __isub__ __imul__ __idiv__ __itruediv__ __ifloordiv__\n__imod__ __ipow__ __ilshift__ __irshift__ __iand__ __ixor__ __ior__'.split()
  28. _ignore = dict.fromkeys('\n    __name__ __module__ __return__ __slots__ get __init__ __metaclass__ __doc__\n    __call__ __new__'.split() + _in_place).__contains__
  29.  
  30. def _no_in_place(self, *args):
  31.     raise TypeError('In-place operators (other than <<=) cannot be performed on a service class')
  32.  
  33.  
  34. def _ilshift(cls, factory):
  35.     State[cls] = factory
  36.     return cls
  37.  
  38.  
  39. def _mod(cls, expr):
  40.     return 'lambda: ' + expr
  41.  
  42. _std_attrs = []([ (k, _no_in_place) for k in _in_place ], __ilshift__ = _ilshift, __mod__ = _mod)
  43.  
  44. def redirect_attribute(cls, name, payload):
  45.     setattr(type(cls), name, (property,)(((lambda s: getattr(s.get(), name)),), ((lambda s, v: setattr(s.get(), name, v)),), (lambda s: delattr(s.get(), name))))
  46.  
  47.  
  48. class _ClassDelegate(classy):
  49.     __slots__ = ()
  50.     get = None
  51.     
  52.     def __class_init__(cls, name, bases, cdict, supr):
  53.         meta = type(cls)
  54.         if getattr(meta, '__for_class__', None) is not cls:
  55.             cls.__class__ = meta = type(meta)(cls.__name__ + 'Class', (meta,), dict(_std_attrs, __module__ = cls.__module__, __for_class__ = cls))
  56.         
  57.         supr()(cls, name, bases, cdict, supr)
  58.         if 'get' not in cdict:
  59.             cls.get = staticmethod(classmethod(lookup).__get__(None, cls))
  60.         
  61.         for k, v in cdict.items():
  62.             if not isinstance(k, basestring):
  63.                 continue
  64.             
  65.             if not isinstance(v, (classmethod, staticmethod)) and not _ignore(k):
  66.                 redirect_attribute(cls, k, v)
  67.                 continue
  68.         
  69.  
  70.     __class_init__ = classmethod(__class_init__)
  71.  
  72.  
  73. class State(_ClassDelegate):
  74.     
  75.     def __new__(cls, *rules, **attrs):
  76.         if not attrs or object.__new__(cls):
  77.             pass
  78.         return empty()
  79.  
  80.     
  81.     def __init__(self, **attrs):
  82.         self.__dict__.update(attrs)
  83.  
  84.     
  85.     def __getitem__(self, key):
  86.         return self.getRule(key)
  87.  
  88.     
  89.     def __setitem__(self, key, rule):
  90.         return self.setRule(key, rule)
  91.  
  92.     
  93.     def swap(self):
  94.         raise NotImplementedError("Can't switch to the root state")
  95.  
  96.     
  97.     def child(self, *rules):
  98.         raise NotImplementedError
  99.  
  100.     
  101.     def __enter__(self):
  102.         raise NotImplementedError("Can't enter the root state")
  103.  
  104.     
  105.     def __exit__(self, typ, val, tb):
  106.         raise NotImplementedError("Can't exit the root state")
  107.  
  108.     
  109.     def on_exit(self, callback):
  110.         raise NotImplementedError
  111.  
  112.     
  113.     def get(key = None):
  114.         raise NotImplementedError
  115.  
  116.     get = staticmethod(get)
  117.     parent = None
  118.  
  119.  
  120. class InputConflict(Exception):
  121.     pass
  122.  
  123.  
  124. class DynamicRuleError(Exception):
  125.     pass
  126.  
  127.  
  128. class ScopeError(Exception):
  129.     pass
  130.  
  131. _exc_info = { }
  132. nones = (None, None, None)
  133.  
  134. def _swap_exc_info(data):
  135.     this_thread = get_ident()
  136.     old = _exc_info.get(this_thread, nones)
  137.     _exc_info[this_thread] = data
  138.     return old
  139.  
  140.  
  141. def new():
  142.     return State.child()
  143.  
  144.  
  145. def _let_there_be_state():
  146.     states = { }
  147.     
  148.     def _swap(what):
  149.         this_thread = get_ident()
  150.         old = states.setdefault(this_thread, what)
  151.         states[this_thread] = what
  152.         return old
  153.  
  154.     
  155.     def lookup(key):
  156.         
  157.         try:
  158.             (state, getRule, lookup, child) = states[get_ident()]
  159.         except KeyError:
  160.             empty().swap()
  161.             (state, getRule, lookup, child) = states[get_ident()]
  162.  
  163.         return lookup(key)
  164.  
  165.     
  166.     def get(key = ((None, (None,)), None)):
  167.         
  168.         try:
  169.             (state, getRule, lookup, child) = states[get_ident()]
  170.         except KeyError:
  171.             empty().swap()
  172.             (state, getRule, lookup, child) = states[get_ident()]
  173.  
  174.         if key is None:
  175.             return state
  176.         return getRule(key)
  177.  
  178.     
  179.     def disallow(key):
  180.         raise DynamicRuleError('default rule or exit function tried to read dynamic state', key)
  181.  
  182.     
  183.     def empty():
  184.         state = new_state(root_getrule)
  185.         state.parent = root
  186.         return state
  187.  
  188.     
  189.     def new_state(inherit = None, inheritedDistances = None, propagate = (None, (None, None, None), None, None, None)):
  190.         buffer = { }
  191.         rules = { }
  192.         values = { }
  193.         distances = { }
  194.         computing = { }
  195.         get_stack = computing.get
  196.         set_stack = computing.setdefault
  197.         
  198.         def getRule(key):
  199.             
  200.             try:
  201.                 rule = rules[key]
  202.             except KeyError:
  203.                 
  204.                 try:
  205.                     rule = buffer[key]
  206.                 except KeyError:
  207.                     rule = buffer.setdefault(key, __fallback(key))
  208.  
  209.                 rule = rules.setdefault(key, rule)
  210.                 if key not in distances:
  211.                     if inheritedDistances is not None and inherit(key) == rule:
  212.                         distances.setdefault(key, inheritedDistances[key] + 1)
  213.                     else:
  214.                         distances[key] = 0
  215.                 
  216.             except:
  217.                 key not in distances
  218.  
  219.             if computing:
  220.                 stack = get_stack(get_ident())
  221.                 if stack:
  222.                     stack[-1] = min(stack[-1], distances[key])
  223.                 
  224.             
  225.             return rule
  226.  
  227.         
  228.         def setRule(key, rule):
  229.             buffer[key] = rule
  230.             old = rules.get(key, rule)
  231.             if old is not rule and old != rule:
  232.                 raise InputConflict(key, old, rule)
  233.             old != rule
  234.  
  235.         
  236.         def getValue(key):
  237.             
  238.             try:
  239.                 value = values[key]
  240.             except KeyError:
  241.                 this_thread = get_ident()
  242.                 rule = getRule(key)
  243.                 stack = set_stack(this_thread, [])
  244.                 stack.append(distances[key])
  245.                 
  246.                 try:
  247.                     value = key.__apply__(key, rule)
  248.                 finally:
  249.                     distance = stack.pop()
  250.                     if not stack:
  251.                         del computing[this_thread]
  252.                     else:
  253.                         stack[-1] = min(stack[-1], distance)
  254.  
  255.                 value = publish(distance, key, value)
  256.  
  257.             if computing:
  258.                 stack = get_stack(get_ident())
  259.                 if stack:
  260.                     stack[-1] = min(stack[-1], distances[key])
  261.                 
  262.             
  263.             return value
  264.  
  265.         
  266.         def publish(distance, key, value):
  267.             distances[key] = distance
  268.             if distance and propagate:
  269.                 value = propagate(distance - 1, key, value)
  270.             
  271.             return values.setdefault(key, value)
  272.  
  273.         
  274.         def child():
  275.             s = new_state(getRule, distances, publish)
  276.             s.parent = this
  277.             return s
  278.  
  279.         
  280.         def __fallback(key):
  281.             old = _swap(disabled)
  282.             
  283.             try:
  284.                 return key.__fallback__(inherit, key)
  285.             finally:
  286.                 _swap(old)
  287.  
  288.  
  289.         
  290.         def swap():
  291.             if exited:
  292.                 raise ScopeError("Can't switch to an exited state")
  293.             exited
  294.             (state, get, lookup, old_child) = old = _swap(enabled)
  295.             if lookup is disallow:
  296.                 _swap(old)
  297.                 raise DynamicRuleError('default rule or exit function tried to change states')
  298.             lookup is disallow
  299.             return state
  300.  
  301.         
  302.         def __enter__():
  303.             if my_parent or exited:
  304.                 raise ScopeError("Can't re-enter a previously-entered state")
  305.             exited
  306.             if active_child:
  307.                 raise ScopeError('State already has an active child')
  308.             active_child
  309.             if get() is this:
  310.                 raise ScopeError('State is already current')
  311.             get() is this
  312.             (parent, xx, xx, parents_child) = old = states[get_ident()]
  313.             if parents_child:
  314.                 raise ScopeError('Current state already has an active child')
  315.             parents_child
  316.             swap()
  317.             my_parent.append(old)
  318.             parents_child.append(this)
  319.             return this
  320.  
  321.         
  322.         def __exit__(typ, val, tb):
  323.             if exited:
  324.                 raise ScopeError('State already exited')
  325.             exited
  326.             if not my_parent:
  327.                 raise ScopeError("State hasn't been entered yet")
  328.             my_parent
  329.             if active_child:
  330.                 raise ScopeError("Nested state(s) haven't exited yet")
  331.             active_child
  332.             if get() is not this:
  333.                 raise ScopeError("Can't exit a non-current state")
  334.             get() is not this
  335.             parents_child = my_parent[0][-1]
  336.             _swap(my_parent.pop())
  337.             parents_child.pop()
  338.             exited.append(1)
  339.             values.clear()
  340.             return call_exitfuncs(typ, val, tb)
  341.  
  342.         active_child = []
  343.         my_parent = []
  344.         exited = []
  345.         exit_functions = []
  346.         
  347.         def call_exitfuncs(typ, val, tb):
  348.             old = _swap(disabled)
  349.             
  350.             try:
  351.                 for func in exit_functions:
  352.                     
  353.                     try:
  354.                         func(typ, val, tb)
  355.                     continue
  356.                     (typ, val, tb) = sys.exc_info()
  357.                     continue
  358.  
  359.             finally:
  360.                 _swap(old)
  361.                 del typ
  362.                 del val
  363.                 del tb
  364.  
  365.  
  366.         
  367.         def on_exit(callback):
  368.             if exited:
  369.                 raise ScopeError('State already exited')
  370.             exited
  371.             if not my_parent:
  372.                 raise ScopeError("State hasn't been entered yet")
  373.             my_parent
  374.             if callback not in exit_functions:
  375.                 exit_functions.append(callback)
  376.             
  377.  
  378.         this = State(getRule = getRule, setRule = setRule, swap = swap, child = child, __enter__ = __enter__, __exit__ = __exit__, on_exit = on_exit)
  379.         enabled = (this, getRule, getValue, active_child)
  380.         disabled = (None, getRule, disallow, active_child)
  381.         return this
  382.  
  383.     State.get = staticmethod(get)
  384.     State.root = root = new_state()
  385.     root.child = empty
  386.     root_getrule = root.getRule
  387.     del root.swap
  388.     del root.__enter__
  389.     del root.__exit__
  390.     return (lookup, empty)
  391.  
  392. (lookup, empty) = _let_there_be_state()
  393. del _let_there_be_state
  394.  
  395. class _GeneratorContextManager(object):
  396.     
  397.     def __init__(self, gen):
  398.         self.gen = gen
  399.  
  400.     
  401.     def __enter__(self):
  402.         for value in self.gen:
  403.             return value
  404.         else:
  405.             raise RuntimeError("generator didn't yield")
  406.  
  407.     
  408.     def __exit__(self, typ, value, traceback):
  409.         if typ is None:
  410.             for value in self.gen:
  411.                 raise RuntimeError("generator didn't stop")
  412.             
  413.         else:
  414.             
  415.             try:
  416.                 old = _swap_exc_info((typ, value, traceback))
  417.                 
  418.                 try:
  419.                     self.gen.next()
  420.                 finally:
  421.                     _swap_exc_info(old)
  422.  
  423.                 raise RuntimeError("generator didn't stop after throw()")
  424.             except StopIteration:
  425.                 exc = None
  426.                 return exc is not value
  427.                 if sys.exc_info()[1] is not value:
  428.                     raise 
  429.                 sys.exc_info()[1] is not value
  430.  
  431.  
  432.  
  433. manager = contextlib.contextmanager
  434.  
  435. def with_(ctx, func):
  436.     inp = ctx.__enter__()
  437.     
  438.     try:
  439.         retval = func(inp)
  440.     except:
  441.         if not ctx.__exit__(*sys.exc_info()):
  442.             raise 
  443.         ctx.__exit__(*sys.exc_info())
  444.  
  445.     ctx.__exit__(None, None, None)
  446.     return retval
  447.  
  448.  
  449. def reraise():
  450.     (typ, val, tb) = _exc_info.get(get_ident(), nones)
  451.     if typ:
  452.         
  453.         try:
  454.             raise typ, val, tb
  455.         finally:
  456.             del typ
  457.             del val
  458.             del tb
  459.  
  460.     
  461.  
  462.  
  463. def call_with(ctxmgr):
  464.     return with_.__get__(ctxmgr, type(ctxmgr))
  465.  
  466.  
  467. noop = lambda key, rule: rule
  468.  
  469. mngr = lambda key, rule: Action.manage(rule())
  470.  
  471. call = lambda key, rule: rule()
  472.  
  473. class Service(_ClassDelegate):
  474.     __slots__ = ()
  475.     
  476.     def __default__(cls):
  477.         return cls()
  478.  
  479.     __default__ = classmethod(__default__)
  480.     
  481.     def __fallback__(cls, inherit, key):
  482.         if inherit:
  483.             return inherit(key)
  484.         return cls.__default__
  485.  
  486.     __fallback__ = classmethod(__fallback__)
  487.     __apply__ = staticmethod(call)
  488.     
  489.     def new(cls, factory = None):
  490.         if not factory:
  491.             pass
  492.         factory = cls
  493.         state = State.child().__enter__()
  494.         
  495.         try:
  496.             
  497.             state[cls.get.im_self] = lambda : factory()
  498.             yield cls.get()
  499.             (None,)
  500.             reraise()
  501.         except:
  502.             state.__exit__(*sys.exc_info())
  503.             raise 
  504.  
  505.         state.__exit__(None, None, None)
  506.  
  507.     new = classmethod(manager(new))
  508.  
  509.  
  510. class Scope(Service):
  511.     
  512.     def __init__(self):
  513.         self.state = State.get()
  514.         self.cache = { }
  515.  
  516.     
  517.     def __compute__(cls, key, func, input):
  518.         self = cls.get()
  519.         cache = self.cache
  520.         if cache is None:
  521.             raise ScopeError(self.__class__.__name__ + ' is already exited')
  522.         cache is None
  523.         if input is not self.state[key]:
  524.             raise ScopeError('Redefined rule in sub-state')
  525.         input is not self.state[key]
  526.         if key in cache:
  527.             return cache[key]
  528.         old = self.state.swap()
  529.         
  530.         try:
  531.             self.state.on_exit(self.atexit)
  532.             return value
  533.         finally:
  534.             old.swap()
  535.  
  536.  
  537.     __compute__ = classmethod(__compute__)
  538.     
  539.     def manage(self, ob):
  540.         return ob
  541.  
  542.     
  543.     def atexit(self, *exc):
  544.         self.cache = None
  545.  
  546.     
  547.     def __default__(cls):
  548.         raise RuntimeError('No %s is currently active' % cls.__name__)
  549.  
  550.     __default__ = classmethod(__default__)
  551.     
  552.     def resource(cls, func):
  553.         return setting(func, wrap = cls.__compute__)
  554.  
  555.     resource = classmethod(resource)
  556.     
  557.     def resource_registry(cls, func):
  558.         return registry(func, wrap = cls.__compute__)
  559.  
  560.     resource_registry = classmethod(resource_registry)
  561.  
  562.  
  563. class Action(Scope):
  564.     
  565.     def __init__(self):
  566.         self.managers = []
  567.         super(Action, self).__init__()
  568.  
  569.     
  570.     def atexit(self, *exc):
  571.         super(Action, self).atexit(*exc)
  572.         managers = self.managers
  573.         self.managers = None
  574.         while managers:
  575.             managers.pop().__exit__(*exc)
  576.  
  577.     
  578.     def manage(self, ob):
  579.         enter = getattr(ob, '__enter__', None)
  580.         if enter is None:
  581.             return ob
  582.         ctx = ob
  583.         ob = ctx.__enter__()
  584.         self.managers.append(ctx)
  585.         return ob
  586.  
  587.  
  588. resource = Action.resource
  589. resource_registry = Action.resource_registry
  590.  
  591. def nop():
  592.     pass
  593.  
  594.  
  595. class setting(object):
  596.     __class__ = type(nop)
  597.     func_code = nop.func_code
  598.     func_defaults = ()
  599.     __argnames__ = (('value', 'expr'),)
  600.     
  601.     def __init__(self, func, wrap = None):
  602.         if func.func_code.co_argcount != len(self.__argnames__):
  603.             raise TypeError(type(self).__name__ + ' function must have exactly %d argument(s)' % len(self.__argnames__))
  604.         func.func_code.co_argcount != len(self.__argnames__)
  605.         for var, names in enumerate(zip(func.func_code.co_varnames, self.__argnames__)):
  606.             if var not in names:
  607.                 raise TypeError(type(self).__name__ + " function argument %d must be named '%s'" % (num + 1, "' or '".join(names)))
  608.             var not in names
  609.         
  610.         if self.__argnames__:
  611.             if not (func.func_defaults) or len(func.func_defaults) != 1:
  612.                 raise TypeError(type(self).__name__ + ' function must have a default value for last argument')
  613.         len(func.func_defaults) != 1
  614.         self.__function__ = func
  615.         self.__module__ = func.__module__
  616.         self.__name__ = func.__name__
  617.         self.__doc__ = func.__doc__
  618.         if wrap:
  619.             self.__wrap__ = wrap
  620.         
  621.  
  622.     __call__ = lookup
  623.     
  624.     def __apply__(self, key, input):
  625.         return self.__wrap__(key, self.__function__, input)
  626.  
  627.     
  628.     def __wrap__(self, key, func, input):
  629.         return func(input)
  630.  
  631.     
  632.     def __fallback__(self, inherit, key):
  633.         if inherit is None:
  634.             return self.__function__.func_defaults[0]
  635.         return inherit(key)
  636.  
  637.     
  638.     def __ilshift__(self, value):
  639.         State[self] = value
  640.         return self
  641.  
  642.     
  643.     def __repr__(self):
  644.         if self.__module__:
  645.             return self.__module__ + '.' + self.__name__
  646.         return self.__name__
  647.  
  648.     
  649.     def __mod__(self, other):
  650.         if self.__function__.func_code.co_varnames[len(type(self).__argnames__) - 1] == 'expr':
  651.             return 'lambda: ' + other
  652.         return other
  653.  
  654.  
  655.  
  656. def _with_prefix(.0, suffix):
  657.     (pre, func) = .0
  658.     return func(pre + suffix)
  659.  
  660.  
  661. def _prefixer(prefix, func):
  662.     return _with_prefix.__get__((prefix, func), tuple)
  663.  
  664.  
  665. class wildcard(setting):
  666.     
  667.     def __init__(self, registry):
  668.         self.__module__ = registry.__module__
  669.         self.__name__ = registry.__name__ + '.*'
  670.         self.__function__ = registry.__function__
  671.         self.__namespace__ = registry
  672.  
  673.     
  674.     def __mod__(self, other):
  675.         return 'lambda suffix: ' + other
  676.  
  677.     
  678.     def __apply__(self, key, input):
  679.         return input
  680.  
  681.     
  682.     def __fallback__(self, inherit, key):
  683.         parent = self.__namespace__
  684.         if parent.__namespace__:
  685.             func = State.get(parent.__namespace__['*'])
  686.             if func is not None:
  687.                 prefix = self.__name__.split('.')[-2] + '.'
  688.                 return _prefixer(prefix, func)
  689.         
  690.  
  691.  
  692.  
  693. class registry(setting):
  694.     __argnames__ = (('suffix',), ('value', 'expr'))
  695.     func_code = (lambda key, default: pass).func_code
  696.     func_defaults = (None,)
  697.     
  698.     def __init__(self, func, ns = None, name = '', wrap = None):
  699.         setting.__init__(self, func, wrap)
  700.         if not name:
  701.             pass
  702.         self.__name__ = self.__name__
  703.         self.__namespace__ = ns
  704.         self.__contents__ = {
  705.             '*': wildcard(self) }
  706.  
  707.     
  708.     def __getitem__(self, key):
  709.         if '.' in key:
  710.             for key in key.split('.'):
  711.                 self = self[key]
  712.             
  713.             return self
  714.         
  715.         try:
  716.             return self.__contents__[key]
  717.         except KeyError:
  718.             '.' in key
  719.             '.' in key
  720.             s = self.__dict__[key] = self.__contents__[key] = registry(self.__function__, self, self.__name__ + '.' + key, self.__dict__.get('__wrap__'))
  721.             return s
  722.  
  723.  
  724.     
  725.     def __getattr__(self, key):
  726.         if key.startswith('__') and key.endswith('__'):
  727.             raise AttributeError(key)
  728.         key.endswith('__')
  729.         return self[key]
  730.  
  731.     
  732.     def __contains__(self, key):
  733.         if '.' in key:
  734.             for key in key.split('.'):
  735.                 if key not in self.__contents__:
  736.                     return False
  737.                 self = self[key]
  738.             else:
  739.                 return True
  740.         key not in self.__contents__
  741.         return key in self.__contents__
  742.  
  743.     
  744.     def __iter__(self):
  745.         return [](_[1])
  746.  
  747.     
  748.     def __call__(self, key, default = None):
  749.         if key not in self:
  750.             return default
  751.         return lookup(self[key])
  752.  
  753.     
  754.     def __apply__(self, key, input):
  755.         return self.__wrap__(key, self.__function__.__get__(''), input)
  756.  
  757.     
  758.     def __fallback__(self, inherit, key):
  759.         if self.__namespace__:
  760.             suffix = key.__name__[len(self.__namespace__.__name__) + 1:]
  761.             finder = State.get(self.__namespace__['*'])
  762.             if finder is not None:
  763.                 return finder(suffix)
  764.         
  765.         if inherit is not None:
  766.             return inherit(key)
  767.         while self.__namespace__:
  768.             self = self.__namespace__
  769.             continue
  770.             inherit is not None
  771.         suffix = key.__name__[len(self.__name__) + 1:]
  772.         return self.__function__(suffix)
  773.  
  774.     
  775.     def __setitem__(self, key, value):
  776.         if value is not self[key]:
  777.             raise TypeError('Registries are read-only')
  778.         value is not self[key]
  779.  
  780.     
  781.     def __setattr__(self, key, value):
  782.         if key.startswith('__') and key.endswith('__'):
  783.             return object.__setattr__(self, key, value)
  784.         self[key] = value
  785.  
  786.  
  787.  
  788. class Source(object):
  789.     __slots__ = ('filename', '__weakref__')
  790.     
  791.     def __init__(self, filename, source = None):
  792.         global linecache
  793.         import linecache
  794.         self.filename = filename
  795.         if source is not None:
  796.             cache_source(filename, source, self)
  797.         
  798.  
  799.     
  800.     def compile(self, *args, **kw):
  801.         return Line(''.join(self), self, 1).compile(*args, **kw)
  802.  
  803.     
  804.     def __getitem__(self, key):
  805.         return Line(linecache.getlines(self.filename)[key], self, key + 1)
  806.  
  807.     
  808.     def __repr__(self):
  809.         return 'Source(%r)' % self.filename
  810.  
  811.     
  812.     def recode(self, code, offset = 0):
  813.         import new
  814.         if not isinstance(code, new.code):
  815.             return code
  816.         return code.co_nlocals(code.co_stacksize, code.co_flags, code.co_code, tuple, [], []([ self.recode(c, offset) for c in code.co_consts ] + [
  817.             self]), code.co_names, code.co_varnames, code.co_filename, code.co_name, code.co_firstlineno + offset, code.co_lnotab, code.co_freevars, code.co_cellvars)
  818.  
  819.  
  820.  
  821. class Line(str):
  822.     
  823.     def __new__(cls, text, source, line):
  824.         return str.__new__(cls, text)
  825.  
  826.     
  827.     def __init__(self, text, source, line):
  828.         self.source = source
  829.         self.line = line
  830.  
  831.     
  832.     def compile(self, *args, **kw):
  833.         code = compile(self, self.source.filename, *args, **kw)
  834.         return self.source.recode(code, self.line - 1)
  835.  
  836.     
  837.     def eval(self, *args):
  838.         return eval(self.compile('eval'), *args)
  839.  
  840.     
  841.     def splitlines(self, *args, **kw):
  842.         return [ Line(line, self.source, self.line + offset) for offset, line in enumerate(str.splitlines(self, *args, **kw)) ]
  843.  
  844.     for m in [
  845.         'capitalize',
  846.         'center',
  847.         'expandtabs',
  848.         'ljust',
  849.         'lower',
  850.         'lstrip',
  851.         'replace',
  852.         'rjust',
  853.         'rstrip',
  854.         'strip',
  855.         'swapcase',
  856.         'title',
  857.         'translate',
  858.         'upper',
  859.         'zfill',
  860.         '__add__',
  861.         '__radd__',
  862.         '__getslice__',
  863.         '__mod__',
  864.         '__rmod__']:
  865.         if hasattr(str, m):
  866.             locals()[m] = (lambda f: (lambda self: Line(f(self, *args, **kw), self.source, self.line))
  867. )(getattr(str, m))
  868.             continue
  869.     
  870.  
  871.  
  872. def replaces(target):
  873.     
  874.     def decorator(cls):
  875.         if not issubclass(cls, Service):
  876.             raise TypeError('context.replaces() can only be used in a context.Service subclass')
  877.         issubclass(cls, Service)
  878.         cls.get = staticmethod(target.get)
  879.         return cls
  880.  
  881.     decorate_class = decorate_class
  882.     import peak.util.decorators
  883.     decorate_class(decorator)
  884.     cdict = sys._getframe(1).f_locals
  885.     if cdict.setdefault('get', target.get) is not target.get:
  886.         raise ValueError('replaces() must be used only once per class; there is already a value for ``get``: %r' % (cdict['get'],))
  887.     cdict.setdefault('get', target.get) is not target.get
  888.  
  889.