##// END OF EJS Templates
Merge pull request #3948 from minrk/sphinx-dir...
Merge pull request #3948 from minrk/sphinx-dir Sphinx and PDF tweaks for nbconvert: - add `--interaction=batchmode` to pdflatex call to avoid waiting for interactive input. - use sphinx.package_dir to find texinputs directory regardless of on-disk location. Closes #3894.

File last commit:

r11351:84e8bb08 merge
r12057:c293fc54 merge
Show More
_process_win32.py
187 lines | 6.1 KiB | text/x-python | PythonLexer
Fernando Perez
Fully refactored subprocess handling on all platforms....
r2908 """Windows-specific implementation of process utilities.
This file is only meant to be imported by process.py, not by end-users.
"""
#-----------------------------------------------------------------------------
Matthias BUSSONNIER
update copyright to 2011/20xx-2011...
r5390 # Copyright (C) 2010-2011 The IPython Development Team
Fernando Perez
Fully refactored subprocess handling on all platforms....
r2908 #
# Distributed under the terms of the BSD License. The full license is in
# the file COPYING, distributed as part of this software.
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------
from __future__ import print_function
# stdlib
import os
import sys
Jörgen Stenarson
Moved arg_split to _process_win32.py and _process_posix.py.
r5517 import ctypes
Fernando Perez
Fully refactored subprocess handling on all platforms....
r2908
Jörgen Stenarson
Moved arg_split to _process_win32.py and _process_posix.py.
r5517 from ctypes import c_int, POINTER
from ctypes.wintypes import LPCWSTR, HLOCAL
Fernando Perez
Fully refactored subprocess handling on all platforms....
r2908 from subprocess import STDOUT
# our own imports
MinRK
add strict kwarg to win32 arg_split...
r5713 from ._process_common import read_no_interrupt, process_handler, arg_split as py_arg_split
Jörgen Stenarson
Moved arg_split to _process_win32.py and _process_posix.py.
r5517 from . import py3compat
Brandon Parsons
saner default encoding mechanism
r6716 from .encoding import DEFAULT_ENCODING
Fernando Perez
Fully refactored subprocess handling on all platforms....
r2908
#-----------------------------------------------------------------------------
# Function definitions
#-----------------------------------------------------------------------------
class AvoidUNCPath(object):
"""A context manager to protect command execution from UNC paths.
In the Win32 API, commands can't be invoked with the cwd being a UNC path.
This context manager temporarily changes directory to the 'C:' drive on
entering, and restores the original working directory on exit.
The context manager returns the starting working directory *if* it made a
change and None otherwise, so that users can apply the necessary adjustment
to their system calls in the event of a change.
Example
-------
::
cmd = 'dir'
with AvoidUNCPath() as path:
if path is not None:
cmd = '"pushd %s &&"%s' % (path, cmd)
os.system(cmd)
"""
def __enter__(self):
Jörgen Stenarson
Search of getcwd and replace with getcwdu. Ignoring core/prompts.py
r4208 self.path = os.getcwdu()
Fernando Perez
Fully refactored subprocess handling on all platforms....
r2908 self.is_unc_path = self.path.startswith(r"\\")
if self.is_unc_path:
# change to c drive (as cmd.exe cannot handle UNC addresses)
os.chdir("C:")
Fernando Perez
Fix small bug in UNC path context manager.
r2909 return self.path
else:
# We return None to signal that there was no change in the working
# directory
return None
Fernando Perez
Fully refactored subprocess handling on all platforms....
r2908
def __exit__(self, exc_type, exc_value, traceback):
if self.is_unc_path:
os.chdir(self.path)
def _find_cmd(cmd):
"""Find the full path to a .bat or .exe using the win32api module."""
try:
from win32api import SearchPath
except ImportError:
raise ImportError('you need to have pywin32 installed for this to work')
else:
PATH = os.environ['PATH']
extensions = ['.exe', '.com', '.bat', '.py']
path = None
for ext in extensions:
try:
Thomas Kluyver
Allow filename with extension in find_cmd in Windows....
r10678 path = SearchPath(PATH, cmd, ext)[0]
Fernando Perez
Fully refactored subprocess handling on all platforms....
r2908 except:
pass
if path is None:
raise OSError("command %r not found" % cmd)
else:
return path
def _system_body(p):
"""Callback for _system."""
Brandon Parsons
saner default encoding mechanism
r6716 enc = DEFAULT_ENCODING
Fernando Perez
Fully refactored subprocess handling on all platforms....
r2908 for line in read_no_interrupt(p.stdout).splitlines():
Thomas Kluyver
Improve robustness, as suggested by Min.
r3476 line = line.decode(enc, 'replace')
Fernando Perez
Fully refactored subprocess handling on all platforms....
r2908 print(line, file=sys.stdout)
for line in read_no_interrupt(p.stderr).splitlines():
Thomas Kluyver
Improve robustness, as suggested by Min.
r3476 line = line.decode(enc, 'replace')
Fernando Perez
Fully refactored subprocess handling on all platforms....
r2908 print(line, file=sys.stderr)
MinRK
store exit code in user_ns['_exit_code']...
r3910 # Wait to finish for returncode
return p.wait()
Fernando Perez
Fully refactored subprocess handling on all platforms....
r2908
def system(cmd):
"""Win32 version of os.system() that works with network shares.
Note that this implementation returns None, as meant for use in IPython.
Parameters
----------
cmd : str
A command to be executed in the system shell.
Returns
-------
None : we explicitly do NOT return the subprocess status code, as this
utility is meant to be used extensively in IPython, where any return value
would trigger :func:`sys.displayhook` calls.
"""
Mark Wiebe
Tweak out the process controller class so it works interactively better...
r6130 # The controller provides interactivity with both
# stdin and stdout
Jonathan March
Fixes gh-1632; minimal revert of gh-1424...
r7424 #import _process_win32_controller
#_process_win32_controller.system(cmd)
Fernando Perez
Fully refactored subprocess handling on all platforms....
r2908
Jonathan March
Fixes gh-1632; minimal revert of gh-1424...
r7424 with AvoidUNCPath() as path:
if path is not None:
cmd = '"pushd %s &&"%s' % (path, cmd)
return process_handler(cmd, _system_body)
Fernando Perez
Fully refactored subprocess handling on all platforms....
r2908
def getoutput(cmd):
"""Return standard output of executing cmd in a shell.
Accepts the same arguments as os.system().
Parameters
----------
cmd : str
A command to be executed in the system shell.
Returns
-------
stdout : str
"""
with AvoidUNCPath() as path:
if path is not None:
cmd = '"pushd %s &&"%s' % (path, cmd)
out = process_handler(cmd, lambda p: p.communicate()[0], STDOUT)
if out is None:
Jörgen Stenarson
Declare byte-type
r7518 out = b''
Jörgen Stenarson
cast return value to str in getoutput
r7513 return py3compat.bytes_to_str(out)
Jörgen Stenarson
Moved arg_split to _process_win32.py and _process_posix.py.
r5517
Jörgen Stenarson
Create fallback with old arg_split, incase CommandLineToArgvW is missing.
r5533 try:
CommandLineToArgvW = ctypes.windll.shell32.CommandLineToArgvW
CommandLineToArgvW.arg_types = [LPCWSTR, POINTER(c_int)]
Jörgen Stenarson
fixes #1708, failing test in arg_split on windows
r6728 CommandLineToArgvW.restype = POINTER(LPCWSTR)
Jörgen Stenarson
Create fallback with old arg_split, incase CommandLineToArgvW is missing.
r5533 LocalFree = ctypes.windll.kernel32.LocalFree
LocalFree.res_type = HLOCAL
LocalFree.arg_types = [HLOCAL]
MinRK
add strict kwarg to win32 arg_split...
r5713 def arg_split(commandline, posix=False, strict=True):
Jörgen Stenarson
Create fallback with old arg_split, incase CommandLineToArgvW is missing.
r5533 """Split a command line's arguments in a shell-like manner.
This is a special version for windows that use a ctypes call to CommandLineToArgvW
to do the argv splitting. The posix paramter is ignored.
MinRK
add strict kwarg to win32 arg_split...
r5713
If strict=False, process_common.arg_split(...strict=False) is used instead.
Jörgen Stenarson
Create fallback with old arg_split, incase CommandLineToArgvW is missing.
r5533 """
#CommandLineToArgvW returns path to executable if called with empty string.
if commandline.strip() == "":
return []
MinRK
add strict kwarg to win32 arg_split...
r5713 if not strict:
# not really a cl-arg, fallback on _process_common
return py_arg_split(commandline, posix=posix, strict=strict)
Jörgen Stenarson
Create fallback with old arg_split, incase CommandLineToArgvW is missing.
r5533 argvn = c_int()
result_pointer = CommandLineToArgvW(py3compat.cast_unicode(commandline.lstrip()), ctypes.byref(argvn))
result_array_type = LPCWSTR * argvn.value
Jörgen Stenarson
fixes #1708, failing test in arg_split on windows
r6728 result = [arg for arg in result_array_type.from_address(ctypes.addressof(result_pointer.contents))]
Jörgen Stenarson
Create fallback with old arg_split, incase CommandLineToArgvW is missing.
r5533 retval = LocalFree(result_pointer)
return result
except AttributeError:
MinRK
add strict kwarg to win32 arg_split...
r5713 arg_split = py_arg_split