@@ -417,10 +417,8 @@ def start_subprocess(self):
417417 except socket .timeout as err :
418418 self .display_no_subprocess_error ()
419419 return None
420- # Can't regiter self.tkconsole.stdin, since run.py wants to
421- # call non-TextIO methods on it (such as getvar)
422- # XXX should be renamed to "console"
423- self .rpcclt .register ("stdin" , self .tkconsole )
420+ self .rpcclt .register ("console" , self .tkconsole )
421+ self .rpcclt .register ("stdin" , self .tkconsole .stdin )
424422 self .rpcclt .register ("stdout" , self .tkconsole .stdout )
425423 self .rpcclt .register ("stderr" , self .tkconsole .stderr )
426424 self .rpcclt .register ("flist" , self .tkconsole .flist )
@@ -864,10 +862,10 @@ def __init__(self, flist=None):
864862 self .save_stderr = sys .stderr
865863 self .save_stdin = sys .stdin
866864 from idlelib import IOBinding
867- self .stdin = PseudoInputFile (self )
868- self .stdout = PseudoFile (self , "stdout" , IOBinding .encoding )
869- self .stderr = PseudoFile (self , "stderr" , IOBinding .encoding )
870- self .console = PseudoFile (self , "console" , IOBinding .encoding )
865+ self .stdin = PseudoInputFile (self , "stdin" , IOBinding . encoding )
866+ self .stdout = PseudoOutputFile (self , "stdout" , IOBinding .encoding )
867+ self .stderr = PseudoOutputFile (self , "stderr" , IOBinding .encoding )
868+ self .console = PseudoOutputFile (self , "console" , IOBinding .encoding )
871869 if not use_subprocess :
872870 sys .stdout = self .stdout
873871 sys .stderr = self .stderr
@@ -1275,36 +1273,82 @@ def rmenu_check_paste(self):
12751273 return 'disabled'
12761274 return super ().rmenu_check_paste ()
12771275
1278- class PseudoFile (object ):
1276+ class PseudoFile (io . TextIOBase ):
12791277
12801278 def __init__ (self , shell , tags , encoding = None ):
12811279 self .shell = shell
12821280 self .tags = tags
1283- self .encoding = encoding
1281+ self ._encoding = encoding
1282+
1283+ @property
1284+ def encoding (self ):
1285+ return self ._encoding
1286+
1287+ @property
1288+ def name (self ):
1289+ return '<%s>' % self .tags
1290+
1291+ def isatty (self ):
1292+ return True
1293+
1294+
1295+ class PseudoOutputFile (PseudoFile ):
1296+
1297+ def writable (self ):
1298+ return True
12841299
12851300 def write (self , s ):
1301+ if self .closed :
1302+ raise ValueError ("write to closed file" )
12861303 if not isinstance (s , str ):
12871304 raise TypeError ('must be str, not ' + type (s ).__name__ )
12881305 return self .shell .write (s , self .tags )
12891306
1290- def writelines (self , lines ):
1291- for line in lines :
1292- self .write (line )
12931307
1294- def flush (self ):
1295- pass
1308+ class PseudoInputFile (PseudoFile ):
12961309
1297- def isatty (self ):
1298- return True
1310+ def __init__ (self , shell , tags , encoding = None ):
1311+ PseudoFile .__init__ (self , shell , tags , encoding )
1312+ self ._line_buffer = ''
12991313
1300- class PseudoInputFile (object ):
1301- def __init__ (self , shell ):
1302- self .readline = shell .readline
1303- self .isatty = shell .isatty
1314+ def readable (self ):
1315+ return True
13041316
1305- def write (self , s ):
1306- raise io .UnsupportedOperation ("not writable" )
1307- writelines = write
1317+ def read (self , size = - 1 ):
1318+ if self .closed :
1319+ raise ValueError ("read from closed file" )
1320+ if size is None :
1321+ size = - 1
1322+ elif not isinstance (size , int ):
1323+ raise TypeError ('must be int, not ' + type (size ).__name__ )
1324+ result = self ._line_buffer
1325+ self ._line_buffer = ''
1326+ if size < 0 :
1327+ while True :
1328+ line = self .shell .readline ()
1329+ if not line : break
1330+ result += line
1331+ else :
1332+ while len (result ) < size :
1333+ line = self .shell .readline ()
1334+ if not line : break
1335+ result += line
1336+ self ._line_buffer = result [size :]
1337+ result = result [:size ]
1338+ return result
1339+
1340+ def readline (self , size = - 1 ):
1341+ if self .closed :
1342+ raise ValueError ("read from closed file" )
1343+ if size is None :
1344+ size = - 1
1345+ elif not isinstance (size , int ):
1346+ raise TypeError ('must be int, not ' + type (size ).__name__ )
1347+ line = self ._line_buffer or self .shell .readline ()
1348+ if size < 0 :
1349+ size = len (line )
1350+ self ._line_buffer = line [size :]
1351+ return line [:size ]
13081352
13091353
13101354usage_msg = """\
0 commit comments