Changeset 109

Show
Ignore:
Timestamp:
11/23/07 23:00:30 (1 year ago)
Author:
edsuom
Message:

Finally getting Parameterized objects passed around via PB

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • projects/Twisted-Goodies/trunk/twisted_goodies/pybywire/pack.py

    r108 r109  
    121121def packwrap(f): 
    122122    """ 
    123     Decorate a method I{f} with me and I will give you a substitute function 
    124     that you can call with a packed version of the method's args. The 
    125     substitute function return you a packed version of the method's result. 
     123    Decorate a function I{f} with me and I will give you a substitute function 
     124    that you can call with a packed version of the function's args. The 
     125    function must return one or more packable values. The substitute function 
     126    will return a packed version of that result. 
    126127    """ 
    127128    def substituteFunction(*args): 
    128129        if len(args) == 1 and isinstance(args[0], str): 
    129             result = f(*Unpacker(args[0])) 
    130             if not isinstance(result, (list, tuple)): 
    131                 result = [result] 
    132             return Packer(*result)(
    133         return f(*args
     130            args = tuple(Unpacker(args[0])) 
     131        result = f(*args) 
     132        if not isinstance(result, (list, tuple)): 
     133            result = (result,
     134        return Packer(*result)(
    134135 
    135136    substituteFunction.func_name = f.func_name 
  • projects/Twisted-Goodies/trunk/twisted_goodies/pybywire/params.py

    r108 r109  
    3030 
    3131 
    32 def parallow(*instances): 
     32def paregister(*stringReps): 
    3333    """ 
    3434    Call this function with one or more arguments containing standard string 
    35     representations of L{Parameterized} subclasses, and instances of those will 
    36     be allowed past PB security. Use judiciously! 
     35    representations of L{Parameterized} subclasses, and those subclasses will 
     36    be made self-unjellyable and allowed past PB security. 
     37 
     38    Use judiciously! 
    3739    """ 
    38     for stringRep in instances: 
     40    for stringRep in stringReps: 
    3941        # Load the class for the string representation 
    4042        cls = namedObject(stringRep) 
    4143        # Allow instances of the class, including its type and module 
    42         pb.globalSecurity.allowInstancesOf(cls) 
     44        pb.setUnjellyableForClass(stringRep, cls) 
     45        # Don't think this next line is needed after the one above has run 
     46        #pb.globalSecurity.allowInstancesOf(cls) 
    4347 
     48 
     49class ParaMeta(type): 
     50    """ 
     51    I add each imported subclass of L{Parameterized} to my I{registry} of 
     52    string class representations, which can be used in a remote call to 
     53    L{paregister} to make those subclasses self-unjellyable and allowable past 
     54    PB security. 
     55    """ 
     56    registry = [] 
     57 
     58    def __init__(cls, name, bases, dictionary): 
     59        stringRep = "%s.%s" % (cls.__module__, name) 
     60        cls.registry.append(stringRep) 
     61        pb.setUnjellyableForClass(stringRep, cls) 
     62     
    4463 
    4564class Parameterized(jelly.Jellyable, jelly.Unjellyable, object): 
    4665    """ 
    47     @cvar instances: A list of standard string representations of all instances 
    48       of me or my subclasses. Your remote PB peer should expose L{parallow} to 
    49       you so you can call it remotely with this list to allow those instances. 
     66    @cvar registry: A list of standard string representations of all my 
     67      subclasses. Your remote PB peer should expose L{paregister} to you so you 
     68      can call it remotely with those string representations to make the 
     69      subclasses self-unjellyable and allow instances of them. 
    5070     
    5171    @cvar keyAttrs: A dict of attributes on which cache keying will be 
     
    5878 
    5979    """ 
     80    __metaclass__ = ParaMeta 
     81     
    6082    name = None 
    61     instances = [] 
    6283    paramNames, keyAttrs = [], {} 
    6384 
     
    7697        for name, value in kw.iteritems(): 
    7798            object.__setattr__(self, name, value) 
    78         myClass = self.__class__ 
    79         stringRep = "%s.%s" % (myClass.__module__, myClass.__name__) 
    80         if stringRep not in self.instances: 
    81             self.instances.append(stringRep) 
    82             # Make me the unjellyable for myself, and ensure that my broker can 
    83             # accept copies of me coming back, too. 
    84             pb.setUnjellyableForClass(stringRep, myClass) 
    8599 
    86100    def __getattr__(self, name): 
  • projects/Twisted-Goodies/trunk/twisted_goodies/pybywire/test/test_params.py

    r101 r109  
    2323""" 
    2424 
     25import scipy as s 
    2526from twisted.internet import reactor 
    2627from twisted.spread import pb 
     
    8889    def test_local_state(self): 
    8990        state = self.ct.getStateFor(None) 
    90         self.failUnlessElementsEqual(state.keys(), ('a', 'b', 'c', 'd')) 
    91         self.failUnlessElementsEqual(state.values(), (1.0, 2.0, 3.0, 4.0)) 
     91        # Parameterized objects have a 'name' attribute that is automatically 
     92        # included in the state 
     93        expectedState = {'a':1.0, 'b':2.0, 'c':3.0, 'd':4.0, 'name':None} 
     94        self.failUnlessElementsEqual(state.keys(), expectedState.keys()) 
     95        self.failUnlessElementsEqual(state.values(), expectedState.values()) 
    9296 
    9397 
     
    164168        d.addCallback(checkSubThingy) 
    165169        return d 
     170 
     171    def test_remoteVersion_Array(self): 
     172        ct = Thingy(a=1.0, b=2.0, c=3.0) 
     173        ct.d = s.linspace(4,5,10) 
     174        d = self.getReferenceToRoot(self.CopyableReturner(None)) 
     175        d.addCallback(lambda _: self.ref.callRemote("takeMyCopy", ct)) 
     176        d.addCallback(lambda _: self.ref.callRemote("giveMeCopy", ct)) 
     177        d.addErrback(self._oops) 
     178        d.addCallback(self._checkCopy, ct, 'a') 
     179        return d