[Twisted-Python] Foolscap: CopyableSlicer has no streamable attribute?

kgi iacovou at gmail.com
Thu Mar 1 10:12:27 EST 2007

Hi all.

I'm using Foolscap in a project with many disparate types and am gradually 
learning all the ins and outs of sending these all over the place.

I've got an exception occurring that is stumping me. I think it may be a bug 
in Foolscap, but I don't know enough about the inner workings to be sure.

The error is:

  'CopyableSlicer' object has no attribute 'streamable'

Which occurs here (I'm using SVN Foolscap, BTW):

> /usr/lib/python2.4/site-packages/foolscap/banana.py(312)pushSlicer()
(Pdb) l
312  ->         itr = slicer.slice(topSlicer.streamable, self)
313             next = iter(itr).next
(Pdb) whatis topSlicer
<class 'foolscap.copyable.CopyableSlicer'>
(Pdb) dir(topSlicer)
['__class__', '__delattr__', '__dict__', '__doc__', '__getattribute__', '__hash__',
'__implemented__', '__init__', '__module__', '__new__', '__providedBy__',
'__provides__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__',
'__str__', '__weakref__', 'childAborted', 'describe', 'obj', 'opentype',
'parent', 'registerReference', 'sendOpen', 'slice', 'sliceBody',
'slicerForObject', 'slices', 'trackReferences']

So the error happened when trying to access topSlicer.streamable, and indeed, 
dir() shows there is no such attribute on the object, which is of type 
CopyableSlicer. Now, CopyableSlicer is defined like this:

class CopyableSlicer(slicer.BaseSlicer):
    """I handle ICopyable objects (things which are copied by value)."""
    def slice(self, streamable, banana):
        yield 'copyable'
        copytype = self.obj.getTypeToCopy()
        assert isinstance(copytype, str)
        yield copytype
        state = self.obj.getStateToCopy()
        for k,v in state.iteritems():
            yield k
            yield v
    def describe(self):
        return "<%s>" % self.obj.getTypeToCopy()
registerAdapter(CopyableSlicer, ICopyable, tokens.ISlicer)

So it overrides slicer.BaseSlicer.slice(). Now, in slicer.BaseSlicer, we see:

class BaseSlicer:
    __metaclass__ = SlicerClass
    def slice(self, streamable, banana):
        # this is what makes us ISlicer
        self.streamable = streamable
        assert self.opentype
        for o in self.opentype:
            yield o
        for t in self.sliceBody(streamable, banana):
            yield t

Note the line following the comment, "# this is what makes us ISlicer" sets 
a 'streamable' attribute on the object in the base class, but the subclass 
doesn't preserve this behaviour.

Is this a bug, or is my exception being caused by something else?



More information about the Twisted-Python mailing list