[Twisted-Python] Bloody Twisted VFS

Andy Gayton andy at thecablelounge.com
Wed Jul 9 22:24:38 EDT 2008

On Wed, Jul 9, 2008 at 7:34 PM, Andrew Bennetts
<andrew-twisted at puzzling.org> wrote:
> Andy Gayton wrote:
> [...]
>> Its a general solution for re-decorating the return result of methods
>> on decorated objects, which return new instances of themselves.  Which
>> is particularly handy for decorating tree node like objects, which can
>> return new child instances.
>> For example:
>> root = FilePathNode(FilePath('/tmp'))
>> root = ReadOnly(root)
>> root = ForceUser(root, 'nobody')
>> root.child('foo') # should return a read only node for /tmp/foo, which
>> creates new files as user nobody.
>> It'd be awesome to provide support for this in a simpler way.
> For what it's worth, bzrlib.transport.decorator provides a similar facility
> for bzrlib.transport.  It's used to implement e.g. ReadonlyTransportDecorator.
> There's also a ChrootTransport, which is essentially a decorator too (although
> it doesn't use bzrlib.transport.decorator because the generic decorator facility
> didn't provide a sane way to track what the root of the chroot should be).

I'm likely over looking a few things.  Just hacked this together after
reading over TransportDecorator for a couple of minutes.  It's
possible that TransportDecorator could be implemented with vfs's
Decorator helper, with something along the lines of:

class TransportDecorator(twisted.vfs._decorator.Decorator):
    def __init__(self, url, _decorated=None):
        prefix = self._get_url_prefix()
        if not url.startswith(prefix):
            raise ValueError(
                "url %r doesn't start with decorator prefix %r" % \
                (url, prefix))
        decorated_url = url[len(prefix):]
        if _decorated is None:
             _decorated = get_transport(decorated_url)
        super(TransportDecorator, self).__init__(
            _decorated, factoryMethods=['clone'])

    def abspath(self, relpath):
        return self._get_url_prefix() + self.target.abspath(relpath)

    def external_url(self):
        return self._get_url_prefix() + self.target.external_url()

    def _get_url_prefix(self):
        raise NotImplementedError(self._get_url_prefix)

A key difference to this compared to the verbose approach in bzrlib,
is that the above object isn't an instance of Transport.  So far I've
handled this with zope.interface's.  The above decorator could say
that it implements(ITransport).

More information about the Twisted-Python mailing list