Changeset 109
- Timestamp:
- 11/23/07 23:00:30 (1 year ago)
- Files:
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
projects/Twisted-Goodies/trunk/twisted_goodies/pybywire/pack.py
r108 r109 121 121 def packwrap(f): 122 122 """ 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. 126 127 """ 127 128 def substituteFunction(*args): 128 129 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 re turn 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)() 134 135 135 136 substituteFunction.func_name = f.func_name projects/Twisted-Goodies/trunk/twisted_goodies/pybywire/params.py
r108 r109 30 30 31 31 32 def par allow(*instances):32 def paregister(*stringReps): 33 33 """ 34 34 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! 37 39 """ 38 for stringRep in instances:40 for stringRep in stringReps: 39 41 # Load the class for the string representation 40 42 cls = namedObject(stringRep) 41 43 # 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) 43 47 48 49 class 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 44 63 45 64 class Parameterized(jelly.Jellyable, jelly.Unjellyable, object): 46 65 """ 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. 50 70 51 71 @cvar keyAttrs: A dict of attributes on which cache keying will be … … 58 78 59 79 """ 80 __metaclass__ = ParaMeta 81 60 82 name = None 61 instances = []62 83 paramNames, keyAttrs = [], {} 63 84 … … 76 97 for name, value in kw.iteritems(): 77 98 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 can83 # accept copies of me coming back, too.84 pb.setUnjellyableForClass(stringRep, myClass)85 99 86 100 def __getattr__(self, name): projects/Twisted-Goodies/trunk/twisted_goodies/pybywire/test/test_params.py
r101 r109 23 23 """ 24 24 25 import scipy as s 25 26 from twisted.internet import reactor 26 27 from twisted.spread import pb … … 88 89 def test_local_state(self): 89 90 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()) 92 96 93 97 … … 164 168 d.addCallback(checkSubThingy) 165 169 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
