提交 a4ca0cba authored 作者: Michael Osthege's avatar Michael Osthege 提交者: Brandon T. Willard

Move subprocess helper functions to theano.utils

These helper functions where in `theano.misc.windows`, but they're not actually specific to Windows and they're clearly generic "utils" style functions.
上级 aaf82d6a
...@@ -23,8 +23,11 @@ from theano.configparser import ( ...@@ -23,8 +23,11 @@ from theano.configparser import (
IntParam, IntParam,
StrParam, StrParam,
) )
from theano.misc.windows import call_subprocess_Popen, output_subprocess_Popen from theano.utils import (
from theano.utils import maybe_add_to_os_environ_pathlist call_subprocess_Popen,
maybe_add_to_os_environ_pathlist,
output_subprocess_Popen,
)
_logger = logging.getLogger("theano.configdefaults") _logger = logging.getLogger("theano.configdefaults")
......
...@@ -28,8 +28,7 @@ from theano.configdefaults import gcc_version_str, local_bitwidth ...@@ -28,8 +28,7 @@ from theano.configdefaults import gcc_version_str, local_bitwidth
# we will abuse the lockfile mechanism when reading and writing the registry # we will abuse the lockfile mechanism when reading and writing the registry
from theano.gof import compilelock from theano.gof import compilelock
from theano.gof.utils import flatten, hash_from_code from theano.gof.utils import flatten, hash_from_code
from theano.misc.windows import output_subprocess_Popen, subprocess_Popen from theano.utils import decode, decode_iter, output_subprocess_Popen, subprocess_Popen
from theano.utils import decode, decode_iter
importlib = None importlib = None
......
import os
import subprocess
def subprocess_Popen(command, **params):
"""
Utility function to work around windows behavior that open windows.
:see: call_subprocess_Popen and output_subprocess_Popen
"""
startupinfo = None
if os.name == "nt":
startupinfo = subprocess.STARTUPINFO()
try:
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
except AttributeError:
startupinfo.dwFlags |= subprocess._subprocess.STARTF_USESHOWWINDOW
# Anaconda for Windows does not always provide .exe files
# in the PATH, they also have .bat files that call the corresponding
# executable. For instance, "g++.bat" is in the PATH, not "g++.exe"
# Unless "shell=True", "g++.bat" is not executed when trying to
# execute "g++" without extensions.
# (Executing "g++.bat" explicitly would also work.)
params["shell"] = True
# "If shell is True, it is recommended to pass args as a string rather than as a sequence." (cite taken from https://docs.python.org/2/library/subprocess.html#frequently-used-arguments)
# In case when command arguments have spaces, passing a command as a list will result in incorrect arguments break down, and consequently
# in "The filename, directory name, or volume label syntax is incorrect" error message.
# Passing the command as a single string solves this problem.
if isinstance(command, list):
command = " ".join(command)
# Using the dummy file descriptors below is a workaround for a
# crash experienced in an unusual Python 2.4.4 Windows environment
# with the default None values.
stdin = None
if "stdin" not in params:
stdin = open(os.devnull)
params["stdin"] = stdin.fileno()
try:
proc = subprocess.Popen(command, startupinfo=startupinfo, **params)
finally:
if stdin is not None:
stdin.close()
return proc
def call_subprocess_Popen(command, **params):
"""
Calls subprocess_Popen and discards the output, returning only the
exit code.
"""
if "stdout" in params or "stderr" in params:
raise TypeError("don't use stderr or stdout with call_subprocess_Popen")
with open(os.devnull, "wb") as null:
# stdin to devnull is a workaround for a crash in a weird Windows
# environment where sys.stdin was None
params.setdefault("stdin", null)
params["stdout"] = null
params["stderr"] = null
p = subprocess_Popen(command, **params)
returncode = p.wait()
return returncode
def output_subprocess_Popen(command, **params):
"""
Calls subprocess_Popen, returning the output, error and exit code
in a tuple.
"""
if "stdout" in params or "stderr" in params:
raise TypeError("don't use stderr or stdout with output_subprocess_Popen")
params["stdout"] = subprocess.PIPE
params["stderr"] = subprocess.PIPE
p = subprocess_Popen(command, **params)
# we need to use communicate to make sure we don't deadlock around
# the stdout/stderr pipe.
out = p.communicate()
return out + (p.returncode,)
"""Utility functions for Theano.""" """Utility functions that only depend on the standard library."""
import inspect import inspect
import os
import subprocess
import traceback import traceback
import warnings import warnings
from collections import OrderedDict from collections import OrderedDict
...@@ -146,3 +148,81 @@ def deprecated(message: str = ""): ...@@ -146,3 +148,81 @@ def deprecated(message: str = ""):
return function_wrapper return function_wrapper
return decorator_wrapper return decorator_wrapper
def subprocess_Popen(command, **params):
"""
Utility function to work around windows behavior that open windows.
:see: call_subprocess_Popen and output_subprocess_Popen
"""
startupinfo = None
if os.name == "nt":
startupinfo = subprocess.STARTUPINFO()
try:
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
except AttributeError:
startupinfo.dwFlags |= subprocess._subprocess.STARTF_USESHOWWINDOW
# Anaconda for Windows does not always provide .exe files
# in the PATH, they also have .bat files that call the corresponding
# executable. For instance, "g++.bat" is in the PATH, not "g++.exe"
# Unless "shell=True", "g++.bat" is not executed when trying to
# execute "g++" without extensions.
# (Executing "g++.bat" explicitly would also work.)
params["shell"] = True
# "If shell is True, it is recommended to pass args as a string rather than as a sequence." (cite taken from https://docs.python.org/2/library/subprocess.html#frequently-used-arguments)
# In case when command arguments have spaces, passing a command as a list will result in incorrect arguments break down, and consequently
# in "The filename, directory name, or volume label syntax is incorrect" error message.
# Passing the command as a single string solves this problem.
if isinstance(command, list):
command = " ".join(command)
# Using the dummy file descriptors below is a workaround for a
# crash experienced in an unusual Python 2.4.4 Windows environment
# with the default None values.
stdin = None
if "stdin" not in params:
stdin = open(os.devnull)
params["stdin"] = stdin.fileno()
try:
proc = subprocess.Popen(command, startupinfo=startupinfo, **params)
finally:
if stdin is not None:
stdin.close()
return proc
def call_subprocess_Popen(command, **params):
"""
Calls subprocess_Popen and discards the output, returning only the
exit code.
"""
if "stdout" in params or "stderr" in params:
raise TypeError("don't use stderr or stdout with call_subprocess_Popen")
with open(os.devnull, "wb") as null:
# stdin to devnull is a workaround for a crash in a weird Windows
# environment where sys.stdin was None
params.setdefault("stdin", null)
params["stdout"] = null
params["stderr"] = null
p = subprocess_Popen(command, **params)
returncode = p.wait()
return returncode
def output_subprocess_Popen(command, **params):
"""
Calls subprocess_Popen, returning the output, error and exit code
in a tuple.
"""
if "stdout" in params or "stderr" in params:
raise TypeError("don't use stderr or stdout with output_subprocess_Popen")
params["stdout"] = subprocess.PIPE
params["stderr"] = subprocess.PIPE
p = subprocess_Popen(command, **params)
# we need to use communicate to make sure we don't deadlock around
# the stdout/stderr pipe.
out = p.communicate()
return out + (p.returncode,)
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论