[Twisted-Python] foolscap copyable and constraint

Brian Warner warner at lothar.com
Mon Aug 11 19:52:11 EDT 2008

> 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,

More information about the Twisted-Python mailing list