[Twisted-Python] foolscap copyable and constraint
ciao! i'm playing a bit with foolscap and i try to use RemoteInterface to describe my constraint but i cannot understand how to use it with pass-by-copy. this is a small example: from foolscap import RemoteInterface, registerCopier, \ registerRemoteCopyFactory class Label: def __init__(self, text): self.text = text def copyLabel(label): return ('_Label', {'text': label.text}) registerCopier(Label, copyLabel) def makeLabel(state): label = Label(state['text']) return label registerRemoteCopyFactory('_Label', makeLabel) class RITest(RemoteInterface): def getLabel(): return Label but what i get is: foolscap.tokens.UnknownSchemaType: can't make constraint from '__main__.Label' (<type 'classobj'>) which is the correct way to define a constraint for a third party-class?
ciao! i'm playing a bit with foolscap and i try to use RemoteInterface to describe my constraint but i cannot understand how to use it with pass-by-copy. this is a small example:
My memory is a bit fuzzy, but I think Copyables aren't as mature as they ought to be, and we don't yet have a way to express a constraint that allows a Copyable as an argument. When I hit a need for this in Tahoe, I punted and used an Any() (which just allows anything through). There's a foolscap.copyable.AttributeDictConstraint, which can be used to control what gets to go into the Copyable (store an instance of it in the .stateSchema attribute of your RemoteCopy class, or provide it as the stateSchema= argument to registerRemoteCopyFactory.. see foolscap/test/test_copyable.py MyRemoteCopy4 for an example). It might be used something like this (untested): label_constraint = copyable.AttributeDictConstraint( ("text", str) ) registerRemoteCopyFactory("_Label", makeLabel, label_constraint) But that doesn't get you the next-higher-level part.
class RITest(RemoteInterface): def getLabel(): return Label
That's the desired syntax for this sort of constraint, but it doesn't work yet. We could fix that.. the approach would be: 1: create a CopyableConstraint class, inheriting from constraint.Constraint, and created with a Copyable subclass (or maybe a RemoteCopy subclass) 1a: implement CopyableConstraint.checkObject(), somehow. If inbound=False then it should probably assert an isinstance(obj, myCopyableClass). If inbound=True, it should probably check against myRemoteCopyClass instead. checkObject() is used outbound before serialization, and inbound post-deserialization; i.e. it examines fully-formed objects rather than individual tokens. 2: add code to schema.adapt_obj_to_iconstraint() (or register an adapter) that knows how to create a CopyableConstraint from a Copyable or RemoteCopy class. There is a small design issue.. should the constraint reference the Copyable, or the RemoteCopy? I.e. should your getLabel() interface method say "return Label" or "return RemoteLabel"? It depends upon how you want to read the RemoteInterface.. from the point of view of the sender, or that of the receiver. My casual thought is to use the Copyable. This makes more difference in constraints that specify pass-by-proxy objects: class RIRow(RemoteInterface): def get_value(): return int class RIDatabase(RemoteInterface) def get_row(rownum=int): return RIRow where the question is: does the get_row() method return a Referenceable (which gets turned into a RemoteReference by the time it gets to the remote caller), or are we saying that it has to return a RemoteReference that is hosted on the caller's side (such that it gets turned back into a local Referenceable byt the time it gets to that caller). The former is a lot more useful, but there might be situations where you want to express the latter, so it would be nice if there were a syntax for it. I don't remember if there is such a syntax right now, but my point is that this sort of distinction doesn't show up with pass-by-copy objects like Copyable. The caller always receives a RemoteCopy of some sort. hope that helps, -Brian
participants (2)
-
Brian Warner
-
Marco Giusti