Skip to content

Commit

Permalink
Properly support std* redirection when using pythonw on Windows.
Browse files Browse the repository at this point in the history
  • Loading branch information
Evan Patterson committed May 9, 2011
1 parent 9832ac6 commit 2b87755
Showing 1 changed file with 27 additions and 10 deletions.
37 changes: 27 additions & 10 deletions IPython/zmq/entry_point.py
Expand Up @@ -52,6 +52,10 @@ def make_argument_parser():
help='set the REQ channel port [default: random]')
parser.add_argument('--hb', type=int, metavar='PORT', default=0,
help='set the heartbeat port [default: random]')
parser.add_argument('--no-stdout', action='store_true',
help='redirect stdout to the null device')
parser.add_argument('--no-stderr', action='store_true',
help='redirect stderr to the null device')

if sys.platform == 'win32':
parser.add_argument('--interrupt', type=int, metavar='HANDLE',
Expand All @@ -72,13 +76,13 @@ def make_kernel(namespace, kernel_factory,
""" Creates a kernel, redirects stdout/stderr, and installs a display hook
and exception handler.
"""
# If running under pythonw.exe, the interpreter will crash if more than 4KB
# of data is written to stdout or stderr. This is a bug that has been with
# Python for a very long time; see http://bugs.python.org/issue706263.
if sys.executable.endswith('pythonw.exe'):
# Re-direct stdout/stderr, if necessary.
if namespace.no_stdout or namespace.no_stderr:
blackhole = file(os.devnull, 'w')
sys.stdout = sys.stderr = blackhole
sys.__stdout__ = sys.__stderr__ = blackhole
if namespace.no_stdout:
sys.stdout = sys.__stdout__ = blackhole
if namespace.no_stderr:
sys.stderr = sys.__stderr__ = blackhole

# Install minimal exception handling
sys.excepthook = FormattedTB(mode='Verbose', color_scheme='NoColor',
Expand Down Expand Up @@ -233,10 +237,10 @@ def base_launch_kernel(code, xrep_port=0, pub_port=0, req_port=0, hb_port=0,
interrupt_event = ParentPollerWindows.create_interrupt_event()
arguments += [ '--interrupt', str(int(interrupt_event)) ]

# If using pythonw, stdin, stdout, and stderr are invalid. Popen will
# fail unless they are suitably redirected. We don't read from the
# pipes, but they must exist.
if executable.endswith('pythonw.exe'):
# If this process in running on pythonw, stdin, stdout, and stderr are
# invalid. Popen will fail unless they are suitably redirected. We don't
# read from the pipes, but they must exist.
if sys.executable.endswith('pythonw.exe'):
redirect = True
_stdin = PIPE if stdin is None else stdin
_stdout = PIPE if stdout is None else stdout
Expand All @@ -245,6 +249,19 @@ def base_launch_kernel(code, xrep_port=0, pub_port=0, req_port=0, hb_port=0,
redirect = False
_stdin, _stdout, _stderr = stdin, stdout, stderr

# If the kernel is running on pythonw and stdout/stderr are not been
# re-directed, it will crash when more than 4KB of data is written to
# stdout or stderr. This is a bug that has been with Python for a very
# long time; see http://bugs.python.org/issue706263.
# A cleaner solution to this problem would be to pass os.devnull to
# Popen directly. Unfortunately, that does not work.
if executable.endswith('pythonw.exe'):
if stdout is None:
arguments.append('--no-stdout')
if stderr is None:
arguments.append('--no-stderr')

# Launch the kernel process.
if independent:
proc = Popen(arguments,
creationflags=512, # CREATE_NEW_PROCESS_GROUP
Expand Down

0 comments on commit 2b87755

Please sign in to comment.