@@ -269,28 +269,45 @@ def __init__(self, rpc):
269269
270270 def __getattribute__ (self , name ):
271271 # When accessing the 'rpc' attribute, or 'write', use ours
272- if name in ('rpc' , 'write' ):
272+ if name in ('rpc' , 'write' , 'writelines' ):
273273 return io .TextIOBase .__getattribute__ (self , name )
274274 # Else only look into the remote object only
275275 return getattr (self .rpc , name )
276276
277277 def __setattr__ (self , name , value ):
278278 return setattr (self .rpc , name , value )
279279
280+ @staticmethod
281+ def _ensure_string (func ):
282+ def f (self , s ):
283+ if not isinstance (s , str ):
284+ raise TypeError ('must be str, not ' + type (s ).__name__ )
285+ return func (self , s )
286+ return f
287+
288+ class _RPCOutputFile (_RPCFile ):
289+ @_RPCFile ._ensure_string
280290 def write (self , s ):
281291 if not isinstance (s , str ):
282292 raise TypeError ('must be str, not ' + type (s ).__name__ )
283293 return self .rpc .write (s )
284294
295+ class _RPCInputFile (_RPCFile ):
296+ @_RPCFile ._ensure_string
297+ def write (self , s ):
298+ raise io .UnsupportedOperation ("not writable" )
299+ writelines = write
300+
285301class MyHandler (rpc .RPCHandler ):
286302
287303 def handle (self ):
288304 """Override base method"""
289305 executive = Executive (self )
290306 self .register ("exec" , executive )
291- sys .stdin = self .console = self .get_remote_proxy ("stdin" )
292- sys .stdout = _RPCFile (self .get_remote_proxy ("stdout" ))
293- sys .stderr = _RPCFile (self .get_remote_proxy ("stderr" ))
307+ self .console = self .get_remote_proxy ("stdin" )
308+ sys .stdin = _RPCInputFile (self .console )
309+ sys .stdout = _RPCOutputFile (self .get_remote_proxy ("stdout" ))
310+ sys .stderr = _RPCOutputFile (self .get_remote_proxy ("stderr" ))
294311 sys .displayhook = rpc .displayhook
295312 # page help() text to shell.
296313 import pydoc # import must be done here to capture i/o binding
0 commit comments