summaryrefslogtreecommitdiff
path: root/numpy
diff options
context:
space:
mode:
authorRalf Gommers <ralf.gommers@googlemail.com>2013-03-06 21:41:01 +0100
committerRalf Gommers <ralf.gommers@googlemail.com>2013-03-06 21:44:15 +0100
commitff01555976cbbac5cb1ee9ecabc170a9d6886641 (patch)
treec5a6afab2b07a8b59f8a4cfa388301b53cd80e6d /numpy
parentbbcfcf6ad3cbb1cbdc348161ee44f729d41c09d1 (diff)
downloadnumpy-ff01555976cbbac5cb1ee9ecabc170a9d6886641.tar.gz
BUG: fix issue with distutils.exec_command introduced in 1.7.0.
Closes gh-2999 and gh-2915. There are several packages (nose, scipy.weave.inline, Sage inline Fortran) that replace stdout, in which case it doesn't have a fileno method. This method was attempted to be used (change in gh-2766 to fix a py3k issue).
Diffstat (limited to 'numpy')
-rw-r--r--numpy/distutils/exec_command.py42
-rw-r--r--numpy/distutils/tests/test_exec_command.py29
2 files changed, 55 insertions, 16 deletions
diff --git a/numpy/distutils/exec_command.py b/numpy/distutils/exec_command.py
index f05b56429..9707f360d 100644
--- a/numpy/distutils/exec_command.py
+++ b/numpy/distutils/exec_command.py
@@ -195,7 +195,8 @@ def exec_command( command,
# _exec_command_posix uses os.system and is faster
# but not on all platforms os.system will return
# a correct status.
- if _with_python and sys.stdout.fileno() == -1:
+ if _with_python and hasattr(sys.stdout, 'fileno') and \
+ sys.stdout.fileno() == -1:
st = _exec_command_python(command,
exec_command_dir = exec_dir,
**env)
@@ -349,12 +350,17 @@ def _exec_command( command, use_shell=None, use_tee = None, **env ):
argv = [os.environ['COMSPEC'],'/C'] + argv
using_command = 1
- so_fileno = sys.stdout.fileno()
- se_fileno = sys.stderr.fileno()
- so_flush = sys.stdout.flush
- se_flush = sys.stderr.flush
- so_dup = os.dup(so_fileno)
- se_dup = os.dup(se_fileno)
+ _has_fileno = hasattr(sys.stdout, 'fileno')
+ if _has_fileno:
+ so_fileno = sys.stdout.fileno()
+ se_fileno = sys.stderr.fileno()
+ so_flush = sys.stdout.flush
+ se_flush = sys.stderr.flush
+ so_dup = os.dup(so_fileno)
+ se_dup = os.dup(se_fileno)
+ else:
+ so_flush = sys.stdout.flush
+ se_flush = sys.stderr.flush
outfile = temp_file_name()
fout = open(outfile,'w')
@@ -371,13 +377,16 @@ def _exec_command( command, use_shell=None, use_tee = None, **env ):
so_flush()
se_flush()
- os.dup2(fout.fileno(),so_fileno)
- if using_command:
- #XXX: disabled for now as it does not work from cmd under win32.
- # Tests fail on msys
- os.dup2(ferr.fileno(),se_fileno)
- else:
- os.dup2(fout.fileno(),se_fileno)
+ if _has_fileno:
+ os.dup2(fout.fileno(),so_fileno)
+
+ if _has_fileno:
+ if using_command:
+ #XXX: disabled for now as it does not work from cmd under win32.
+ # Tests fail on msys
+ os.dup2(ferr.fileno(),se_fileno)
+ else:
+ os.dup2(fout.fileno(),se_fileno)
try:
status = spawn_command(os.P_WAIT,argv0,argv,os.environ)
except OSError:
@@ -387,8 +396,9 @@ def _exec_command( command, use_shell=None, use_tee = None, **env ):
so_flush()
se_flush()
- os.dup2(so_dup,so_fileno)
- os.dup2(se_dup,se_fileno)
+ if _has_fileno:
+ os.dup2(so_dup,so_fileno)
+ os.dup2(se_dup,se_fileno)
fout.close()
fout = open_latin1(outfile,'r')
diff --git a/numpy/distutils/tests/test_exec_command.py b/numpy/distutils/tests/test_exec_command.py
new file mode 100644
index 000000000..f2c4fbd13
--- /dev/null
+++ b/numpy/distutils/tests/test_exec_command.py
@@ -0,0 +1,29 @@
+import sys
+import StringIO
+
+from numpy.distutils import exec_command
+
+
+class redirect_stdout(object):
+ """Context manager to redirect stdout for exec_command test."""
+ def __init__(self, stdout=None):
+ self._stdout = stdout or sys.stdout
+
+ def __enter__(self):
+ self.old_stdout = sys.stdout
+ sys.stdout = self._stdout
+
+ def __exit__(self, exc_type, exc_value, traceback):
+ self._stdout.flush()
+ sys.stdout = self.old_stdout
+
+
+def test_exec_command():
+ # Regression test for gh-2999 and gh-2915.
+ # There are several packages (nose, scipy.weave.inline, Sage inline
+ # Fortran) that replace stdout, in which case it doesn't have a fileno
+ # method. This is tested here, with a do-nothing command that fails if the
+ # presence of fileno() is assumed in exec_command.
+ with redirect_stdout(StringIO.StringIO()):
+ exec_command.exec_command("cd '.'")
+