import py class remotefile(object): """ remotely control a file pointer using py.execnet """ code = py.code.Source('''\ fp = file(%r, %r, %r) try: while True: data = channel.receive() if data == 'close': break elif isinstance(data, tuple): callable = getattr(fp, data[0]) channel.send(callable(*data[1], **data[2])) else: channel.send(getattr(fp, data)) finally: fp.close() channel.close() ''') initcmd = 'import os; os.__fp = file(%r, %r, %r)' attrcmd = 'import os; channel.send(os.__fp.%s)' callablecmd = 'import os; channel.send(os.__fp.%s(%s))' closecmd = 'import os; os.__fp.close()' def __init__(self, address, mode='r', buffering=0, gatewayclass=py.execnet.SshGateway): self.address = address self.mode = mode self.buffering = buffering self.gatewayclass = gatewayclass self._gateway = None self._channel = None def __getattr__(self, name): attr = getattr(file, name) c = self._initialize() if callable(attr): def handler(*args, **kwargs): c.send((name, args, kwargs)) return c.receive() return handler c.send(name) return c.receive() def _initialize(self): c = self._channel if c is None: address, path = self.address.split(':', 1) self._gateway = gw = self.gatewayclass(address) self._channel = c = gw.remote_exec( str(self.code) % (path, self.mode, self.buffering)) return c if __name__ == '__main__': fp = remotefile('localhost:/tmp/foo') try: print fp.read() finally: fp.close()