Last active
December 20, 2015 01:29
-
-
Save msabramo/6049140 to your computer and use it in GitHub Desktop.
Experiment for Python issue 15805: An attempt at adding redirect_stdin, redirect_stdout, and redirect_stderr context manager functions to the `io` module
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff -r e7305517260b Lib/io.py | |
--- a/Lib/io.py Sat Jul 20 15:12:19 2013 +0200 | |
+++ b/Lib/io.py Sun Jul 21 10:14:26 2013 -0700 | |
@@ -56,6 +56,8 @@ | |
BufferedWriter, BufferedRWPair, BufferedRandom, | |
IncrementalNewlineDecoder, TextIOWrapper) | |
+from unittest.mock import patch | |
+ | |
OpenWrapper = _io.open # for compatibility with _pyio | |
# Pretend this exception was created here. | |
@@ -90,3 +92,64 @@ | |
for klass in (StringIO, TextIOWrapper): | |
TextIOBase.register(klass) | |
del klass | |
+ | |
+def redirect_stdin(replacement=None): | |
+ """Redirect stdin to come from a StringIO or str. | |
+ | |
+ 'replacement' is a StringIO or str. | |
+ | |
+ Examples: | |
+ | |
+ >>> from io import redirect_stdin, StringIO | |
+ >>> with redirect_stdin(StringIO("bleargh")) as s: | |
+ ... x = input() | |
+ ... | |
+ >>> x | |
+ 'bleargh' | |
+ | |
+ >>> with redirect_stdin("bleargh") as s: | |
+ ... x = input() | |
+ ... | |
+ >>> x | |
+ 'bleargh' | |
+ """ | |
+ if hasattr(replacement, 'readline'): # a file-like object | |
+ file_like_obj = replacement | |
+ else: | |
+ # Try to convert to a file-like object; this works for strs at least | |
+ file_like_obj = StringIO(replacement) | |
+ | |
+ return redirect_stdfile('sys.stdin', file_like_obj) | |
+ | |
+def redirect_stdout(replacement=None): | |
+ """Redirect stdout to a StringIO. | |
+ | |
+ Example: | |
+ | |
+ >>> from io import redirect_stdout | |
+ >>> with redirect_stdout() as s: | |
+ ... print('hello') | |
+ ... | |
+ >>> s.getvalue() | |
+ 'hello\n' | |
+ """ | |
+ return redirect_stdfile('sys.stdout', replacement) | |
+ | |
+def redirect_stderr(replacement=None): | |
+ """Redirect stderr to a StringIO. | |
+ | |
+ Example: | |
+ | |
+ >>> import sys | |
+ >>> from io import redirect_stderr | |
+ >>> with redirect_stderr() as s: | |
+ ... print("bleargh", file=sys.stderr) | |
+ ... | |
+ >>> s.getvalue() | |
+ 'bleargh\n' | |
+ """ | |
+ return redirect_stdfile('sys.stderr', replacement) | |
+ | |
+def redirect_stdfile(stdfilename, replacement=None): | |
+ # stdfilename is one of ('sys.stdin', 'sys.stdout', 'sys.stderr') | |
+ return patch(stdfilename, replacement if replacement is not None else StringIO()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import sys | |
from io import redirect_stdin, redirect_stdout, redirect_stderr, StringIO | |
from tempfile import TemporaryFile | |
#---------------------------------------------------------------------------- | |
# redirect_stdin with a StringIO as input | |
#---------------------------------------------------------------------------- | |
with redirect_stdin(StringIO("bleargh")) as s: | |
foo = input() | |
print("captured stdin: %s" % s.getvalue()) | |
#---------------------------------------------------------------------------- | |
# redirect_stdin with a str as input | |
#---------------------------------------------------------------------------- | |
with redirect_stdin("some text") as s: | |
foo = input() | |
print("captured stdin: %s" % s.getvalue()) | |
#---------------------------------------------------------------------------- | |
# redirect_stdin with a file as input | |
#---------------------------------------------------------------------------- | |
with TemporaryFile(mode='r+') as f: | |
f.write("one\ntwo\nthree\n") | |
f.seek(0) | |
lst = [] | |
with redirect_stdin(f): | |
for i in range(0, 3): | |
lst.append(input()) | |
print('lst = %r' % lst) | |
# lst = ['one', 'two', 'three'] | |
#---------------------------------------------------------------------------- | |
# redirect_stdout captures stdout to a StringIO | |
#---------------------------------------------------------------------------- | |
with redirect_stdout() as s: | |
sys.stdout.write("hello") | |
print("captured stdout: %s" % s.getvalue()) | |
#---------------------------------------------------------------------------- | |
# redirect_stderr captures stderr to a StringIO | |
#---------------------------------------------------------------------------- | |
with redirect_stderr() as s: | |
sys.stderr.write("hello") | |
print("captured stderr: %s" % s.getvalue()) | |
#---------------------------------------------------------------------------- | |
# Using redirect_stdout and redirect_stdin together | |
# redirect_stdout suppresses the prompt from `input` | |
# redirect_stdin with a StringIO as input | |
#---------------------------------------------------------------------------- | |
with redirect_stdout(), redirect_stdin(StringIO("bleargh")) as s: | |
foo = input("Type something> ") | |
print("captured stdin: %s" % s.getvalue()) |
marca@marca-mac:~/dev/hg-repos/cpython$ hg tip
changeset: 84735:e7305517260b
tag: tip
parent: 84733:9d93a267b8a0
parent: 84734:76bb3fe6ce8f
user: Christian Heimes <[email protected]>
date: Sat Jul 20 15:12:19 2013 +0200
files: Modules/_elementtree.c
description:
Add missing check of PyDict_Update()'s return value in _elementtree.c
CID 719637
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Example output: