1import itertools 2 3def as_unicode(s, encoding='utf-8'): 4 typ = type(s) 5 if typ is unicode: 6 pass 7 elif issubclass(typ, unicode): 8 s = unicode(s) 9 elif issubclass(typ, str): 10 s = unicode(s, encoding, 'replace') 11 else: 12 raise TypeError, 'expecting basestring, not %s' % (typ.__name__,) 13 return s 14 15 16def as_str(s, encoding='utf-8'): 17 typ = type(s) 18 if typ is str: 19 pass 20 elif issubclass(typ, str): 21 s = str(s) 22 elif issubclass(typ, unicode): 23 s = s.encode(encoding) 24 else: 25 raise TypeError, 'expecting basestring, not %s' % (typ.__name__,) 26 return s 27 28 29class RemotePipe(object): 30 def __init__(self, runcode, clientfile, netReprCenter, namespace, pool): 31 self.runcode = runcode 32 self.pool = pool 33 self.clientfile = clientfile 34 self.namespace = namespace 35 self.result = self.namespace['__result__'] = {} 36 self.netReprCenter = netReprCenter 37 self.netrepr_list = netReprCenter.netrepr_list 38 self.sequence = itertools.count() 39 self.stdin = RemoteFileLike(self, 'stdin') 40 self.stdout = RemoteFileLike(self, 'stdout') 41 self.stderr = RemoteFileLike(self, 'stderr') 42 43 def send(self, *args): 44 self.clientfile.write(self.netrepr_list(args) + '\n') 45 self.clientfile.flush() 46 47 def respond(self, *args): 48 self.send('respond', *args) 49 50 def expect(self, *args): 51 self.pool.push() 52 try: 53 return self._expect(*args) 54 finally: 55 self.pool.pop() 56 57 def _expect(self, *args): 58 ident = self.sequence.next() 59 self.send('expect', ident, *args) 60 while ident not in self.result: 61 self.runcode(self.clientfile, self.namespace) 62 return self.result.pop(ident) 63 64 65class RemoteFileLike(object): 66 softspace = 0 67 closed = False 68 encoding = 'utf-8' 69 70 def __init__(self, pipe, ident): 71 self.pipe = pipe 72 self.ident = ident 73 74 def __iter__(self): 75 while True: 76 rval = self.readline() 77 if not rval: 78 break 79 yield rval 80 81 def write(self, s): 82 s = as_unicode(s, self.encoding) 83 self.pipe.expect('RemoteFileLike.write', self.ident, s) 84 85 def writelines(self, lines): 86 for line in lines: 87 self.write(line) 88 89 def close(self): 90 self.closed = True 91 92 def flush(self): 93 pass 94 95 def isatty(self): 96 return True 97 98 def read(self, size=-1): 99 return as_str( 100 self.pipe.expect('RemoteFileLike.read', self.ident, size), 101 self.encoding, 102 ) 103 104 def readline(self, size=-1): 105 return as_str( 106 self.pipe.expect('RemoteFileLike.readline', self.ident, size), 107 self.encoding, 108 ) 109 110 def readlines(self): 111 return list(self) 112