summaryrefslogtreecommitdiffstats
path: root/Lib/idlelib/PyShell.py
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2013-01-25 13:35:28 (GMT)
committerSerhiy Storchaka <storchaka@gmail.com>2013-01-25 13:35:28 (GMT)
commit4c9bae3d316956ffc566d4c28a2d48ec39e3cf12 (patch)
tree7a1da2d41ddd7bc9091ad5ce6becc47408b31753 /Lib/idlelib/PyShell.py
parent3f50bf652bae5e3371972eb261973238c62cc17b (diff)
parentb1b3c0dfef5fbbd6fb2247758216bb1cbc157dc5 (diff)
downloadcpython-4c9bae3d316956ffc566d4c28a2d48ec39e3cf12.zip
cpython-4c9bae3d316956ffc566d4c28a2d48ec39e3cf12.tar.gz
cpython-4c9bae3d316956ffc566d4c28a2d48ec39e3cf12.tar.bz2
Issue #9290: In IDLE the sys.std* streams now implement io.TextIOBase
interface and support all mandatory methods and properties.
Diffstat (limited to 'Lib/idlelib/PyShell.py')
-rw-r--r--Lib/idlelib/PyShell.py92
1 files changed, 68 insertions, 24 deletions
diff --git a/Lib/idlelib/PyShell.py b/Lib/idlelib/PyShell.py
index 6a9ed32..9ccb31c 100644
--- a/Lib/idlelib/PyShell.py
+++ b/Lib/idlelib/PyShell.py
@@ -417,10 +417,8 @@ class ModifiedInterpreter(InteractiveInterpreter):
except socket.timeout as err:
self.display_no_subprocess_error()
return None
- # Can't regiter self.tkconsole.stdin, since run.py wants to
- # call non-TextIO methods on it (such as getvar)
- # XXX should be renamed to "console"
- self.rpcclt.register("stdin", self.tkconsole)
+ self.rpcclt.register("console", self.tkconsole)
+ self.rpcclt.register("stdin", self.tkconsole.stdin)
self.rpcclt.register("stdout", self.tkconsole.stdout)
self.rpcclt.register("stderr", self.tkconsole.stderr)
self.rpcclt.register("flist", self.tkconsole.flist)
@@ -864,10 +862,10 @@ class PyShell(OutputWindow):
self.save_stderr = sys.stderr
self.save_stdin = sys.stdin
from idlelib import IOBinding
- self.stdin = PseudoInputFile(self)
- self.stdout = PseudoFile(self, "stdout", IOBinding.encoding)
- self.stderr = PseudoFile(self, "stderr", IOBinding.encoding)
- self.console = PseudoFile(self, "console", IOBinding.encoding)
+ self.stdin = PseudoInputFile(self, "stdin", IOBinding.encoding)
+ self.stdout = PseudoOutputFile(self, "stdout", IOBinding.encoding)
+ self.stderr = PseudoOutputFile(self, "stderr", IOBinding.encoding)
+ self.console = PseudoOutputFile(self, "console", IOBinding.encoding)
if not use_subprocess:
sys.stdout = self.stdout
sys.stderr = self.stderr
@@ -1278,36 +1276,82 @@ class PyShell(OutputWindow):
return 'disabled'
return super().rmenu_check_paste()
-class PseudoFile(object):
+class PseudoFile(io.TextIOBase):
def __init__(self, shell, tags, encoding=None):
self.shell = shell
self.tags = tags
- self.encoding = encoding
+ self._encoding = encoding
+
+ @property
+ def encoding(self):
+ return self._encoding
+
+ @property
+ def name(self):
+ return '<%s>' % self.tags
+
+ def isatty(self):
+ return True
+
+
+class PseudoOutputFile(PseudoFile):
+
+ def writable(self):
+ return True
def write(self, s):
+ if self.closed:
+ raise ValueError("write to closed file")
if not isinstance(s, str):
raise TypeError('must be str, not ' + type(s).__name__)
return self.shell.write(s, self.tags)
- def writelines(self, lines):
- for line in lines:
- self.write(line)
- def flush(self):
- pass
+class PseudoInputFile(PseudoFile):
- def isatty(self):
- return True
+ def __init__(self, shell, tags, encoding=None):
+ PseudoFile.__init__(self, shell, tags, encoding)
+ self._line_buffer = ''
-class PseudoInputFile(object):
- def __init__(self, shell):
- self.readline = shell.readline
- self.isatty = shell.isatty
+ def readable(self):
+ return True
- def write(self, s):
- raise io.UnsupportedOperation("not writable")
- writelines = write
+ def read(self, size=-1):
+ if self.closed:
+ raise ValueError("read from closed file")
+ if size is None:
+ size = -1
+ elif not isinstance(size, int):
+ raise TypeError('must be int, not ' + type(size).__name__)
+ result = self._line_buffer
+ self._line_buffer = ''
+ if size < 0:
+ while True:
+ line = self.shell.readline()
+ if not line: break
+ result += line
+ else:
+ while len(result) < size:
+ line = self.shell.readline()
+ if not line: break
+ result += line
+ self._line_buffer = result[size:]
+ result = result[:size]
+ return result
+
+ def readline(self, size=-1):
+ if self.closed:
+ raise ValueError("read from closed file")
+ if size is None:
+ size = -1
+ elif not isinstance(size, int):
+ raise TypeError('must be int, not ' + type(size).__name__)
+ line = self._line_buffer or self.shell.readline()
+ if size < 0:
+ size = len(line)
+ self._line_buffer = line[size:]
+ return line[:size]
usage_msg = """\