comparison DEPENDENCIES/mingw32/Python27/Lib/site-packages/numpy/distutils/exec_command.py @ 87:2a2c65a20a8b

Add Python libs and headers
author Chris Cannam
date Wed, 25 Feb 2015 14:05:22 +0000
parents
children
comparison
equal deleted inserted replaced
86:413a9d26189e 87:2a2c65a20a8b
1 #!/usr/bin/env python
2 """
3 exec_command
4
5 Implements exec_command function that is (almost) equivalent to
6 commands.getstatusoutput function but on NT, DOS systems the
7 returned status is actually correct (though, the returned status
8 values may be different by a factor). In addition, exec_command
9 takes keyword arguments for (re-)defining environment variables.
10
11 Provides functions:
12 exec_command --- execute command in a specified directory and
13 in the modified environment.
14 find_executable --- locate a command using info from environment
15 variable PATH. Equivalent to posix `which`
16 command.
17
18 Author: Pearu Peterson <pearu@cens.ioc.ee>
19 Created: 11 January 2003
20
21 Requires: Python 2.x
22
23 Succesfully tested on:
24 os.name | sys.platform | comments
25 --------+--------------+----------
26 posix | linux2 | Debian (sid) Linux, Python 2.1.3+, 2.2.3+, 2.3.3
27 PyCrust 0.9.3, Idle 1.0.2
28 posix | linux2 | Red Hat 9 Linux, Python 2.1.3, 2.2.2, 2.3.2
29 posix | sunos5 | SunOS 5.9, Python 2.2, 2.3.2
30 posix | darwin | Darwin 7.2.0, Python 2.3
31 nt | win32 | Windows Me
32 Python 2.3(EE), Idle 1.0, PyCrust 0.7.2
33 Python 2.1.1 Idle 0.8
34 nt | win32 | Windows 98, Python 2.1.1. Idle 0.8
35 nt | win32 | Cygwin 98-4.10, Python 2.1.1(MSC) - echo tests
36 fail i.e. redefining environment variables may
37 not work. FIXED: don't use cygwin echo!
38 Comment: also `cmd /c echo` will not work
39 but redefining environment variables do work.
40 posix | cygwin | Cygwin 98-4.10, Python 2.3.3(cygming special)
41 nt | win32 | Windows XP, Python 2.3.3
42
43 Known bugs:
44 - Tests, that send messages to stderr, fail when executed from MSYS prompt
45 because the messages are lost at some point.
46 """
47 from __future__ import division, absolute_import, print_function
48
49 __all__ = ['exec_command', 'find_executable']
50
51 import os
52 import sys
53 import shlex
54
55 from numpy.distutils.misc_util import is_sequence, make_temp_file
56 from numpy.distutils import log
57 from numpy.distutils.compat import get_exception
58
59 from numpy.compat import open_latin1
60
61 def temp_file_name():
62 fo, name = make_temp_file()
63 fo.close()
64 return name
65
66 def get_pythonexe():
67 pythonexe = sys.executable
68 if os.name in ['nt', 'dos']:
69 fdir, fn = os.path.split(pythonexe)
70 fn = fn.upper().replace('PYTHONW', 'PYTHON')
71 pythonexe = os.path.join(fdir, fn)
72 assert os.path.isfile(pythonexe), '%r is not a file' % (pythonexe,)
73 return pythonexe
74
75 def splitcmdline(line):
76 import warnings
77 warnings.warn('splitcmdline is deprecated; use shlex.split',
78 DeprecationWarning)
79 return shlex.split(line)
80
81 def find_executable(exe, path=None, _cache={}):
82 """Return full path of a executable or None.
83
84 Symbolic links are not followed.
85 """
86 key = exe, path
87 try:
88 return _cache[key]
89 except KeyError:
90 pass
91 log.debug('find_executable(%r)' % exe)
92 orig_exe = exe
93
94 if path is None:
95 path = os.environ.get('PATH', os.defpath)
96 if os.name=='posix':
97 realpath = os.path.realpath
98 else:
99 realpath = lambda a:a
100
101 if exe.startswith('"'):
102 exe = exe[1:-1]
103
104 suffixes = ['']
105 if os.name in ['nt', 'dos', 'os2']:
106 fn, ext = os.path.splitext(exe)
107 extra_suffixes = ['.exe', '.com', '.bat']
108 if ext.lower() not in extra_suffixes:
109 suffixes = extra_suffixes
110
111 if os.path.isabs(exe):
112 paths = ['']
113 else:
114 paths = [ os.path.abspath(p) for p in path.split(os.pathsep) ]
115
116 for path in paths:
117 fn = os.path.join(path, exe)
118 for s in suffixes:
119 f_ext = fn+s
120 if not os.path.islink(f_ext):
121 f_ext = realpath(f_ext)
122 if os.path.isfile(f_ext) and os.access(f_ext, os.X_OK):
123 log.info('Found executable %s' % f_ext)
124 _cache[key] = f_ext
125 return f_ext
126
127 log.warn('Could not locate executable %s' % orig_exe)
128 return None
129
130 ############################################################
131
132 def _preserve_environment( names ):
133 log.debug('_preserve_environment(%r)' % (names))
134 env = {}
135 for name in names:
136 env[name] = os.environ.get(name)
137 return env
138
139 def _update_environment( **env ):
140 log.debug('_update_environment(...)')
141 for name, value in env.items():
142 os.environ[name] = value or ''
143
144 def _supports_fileno(stream):
145 """
146 Returns True if 'stream' supports the file descriptor and allows fileno().
147 """
148 if hasattr(stream, 'fileno'):
149 try:
150 r = stream.fileno()
151 return True
152 except IOError:
153 return False
154 else:
155 return False
156
157 def exec_command( command,
158 execute_in='', use_shell=None, use_tee = None,
159 _with_python = 1,
160 **env ):
161 """ Return (status,output) of executed command.
162
163 command is a concatenated string of executable and arguments.
164 The output contains both stdout and stderr messages.
165 The following special keyword arguments can be used:
166 use_shell - execute `sh -c command`
167 use_tee - pipe the output of command through tee
168 execute_in - before run command `cd execute_in` and after `cd -`.
169
170 On NT, DOS systems the returned status is correct for external commands.
171 Wild cards will not work for non-posix systems or when use_shell=0.
172 """
173 log.debug('exec_command(%r,%s)' % (command,\
174 ','.join(['%s=%r'%kv for kv in env.items()])))
175
176 if use_tee is None:
177 use_tee = os.name=='posix'
178 if use_shell is None:
179 use_shell = os.name=='posix'
180 execute_in = os.path.abspath(execute_in)
181 oldcwd = os.path.abspath(os.getcwd())
182
183 if __name__[-12:] == 'exec_command':
184 exec_dir = os.path.dirname(os.path.abspath(__file__))
185 elif os.path.isfile('exec_command.py'):
186 exec_dir = os.path.abspath('.')
187 else:
188 exec_dir = os.path.abspath(sys.argv[0])
189 if os.path.isfile(exec_dir):
190 exec_dir = os.path.dirname(exec_dir)
191
192 if oldcwd!=execute_in:
193 os.chdir(execute_in)
194 log.debug('New cwd: %s' % execute_in)
195 else:
196 log.debug('Retaining cwd: %s' % oldcwd)
197
198 oldenv = _preserve_environment( list(env.keys()) )
199 _update_environment( **env )
200
201 try:
202 # _exec_command is robust but slow, it relies on
203 # usable sys.std*.fileno() descriptors. If they
204 # are bad (like in win32 Idle, PyCrust environments)
205 # then _exec_command_python (even slower)
206 # will be used as a last resort.
207 #
208 # _exec_command_posix uses os.system and is faster
209 # but not on all platforms os.system will return
210 # a correct status.
211 if (_with_python and _supports_fileno(sys.stdout) and
212 sys.stdout.fileno() == -1):
213 st = _exec_command_python(command,
214 exec_command_dir = exec_dir,
215 **env)
216 elif os.name=='posix':
217 st = _exec_command_posix(command,
218 use_shell=use_shell,
219 use_tee=use_tee,
220 **env)
221 else:
222 st = _exec_command(command, use_shell=use_shell,
223 use_tee=use_tee,**env)
224 finally:
225 if oldcwd!=execute_in:
226 os.chdir(oldcwd)
227 log.debug('Restored cwd to %s' % oldcwd)
228 _update_environment(**oldenv)
229
230 return st
231
232 def _exec_command_posix( command,
233 use_shell = None,
234 use_tee = None,
235 **env ):
236 log.debug('_exec_command_posix(...)')
237
238 if is_sequence(command):
239 command_str = ' '.join(list(command))
240 else:
241 command_str = command
242
243 tmpfile = temp_file_name()
244 stsfile = None
245 if use_tee:
246 stsfile = temp_file_name()
247 filter = ''
248 if use_tee == 2:
249 filter = r'| tr -cd "\n" | tr "\n" "."; echo'
250 command_posix = '( %s ; echo $? > %s ) 2>&1 | tee %s %s'\
251 % (command_str, stsfile, tmpfile, filter)
252 else:
253 stsfile = temp_file_name()
254 command_posix = '( %s ; echo $? > %s ) > %s 2>&1'\
255 % (command_str, stsfile, tmpfile)
256 #command_posix = '( %s ) > %s 2>&1' % (command_str,tmpfile)
257
258 log.debug('Running os.system(%r)' % (command_posix))
259 status = os.system(command_posix)
260
261 if use_tee:
262 if status:
263 # if command_tee fails then fall back to robust exec_command
264 log.warn('_exec_command_posix failed (status=%s)' % status)
265 return _exec_command(command, use_shell=use_shell, **env)
266
267 if stsfile is not None:
268 f = open_latin1(stsfile, 'r')
269 status_text = f.read()
270 status = int(status_text)
271 f.close()
272 os.remove(stsfile)
273
274 f = open_latin1(tmpfile, 'r')
275 text = f.read()
276 f.close()
277 os.remove(tmpfile)
278
279 if text[-1:]=='\n':
280 text = text[:-1]
281
282 return status, text
283
284
285 def _exec_command_python(command,
286 exec_command_dir='', **env):
287 log.debug('_exec_command_python(...)')
288
289 python_exe = get_pythonexe()
290 cmdfile = temp_file_name()
291 stsfile = temp_file_name()
292 outfile = temp_file_name()
293
294 f = open(cmdfile, 'w')
295 f.write('import os\n')
296 f.write('import sys\n')
297 f.write('sys.path.insert(0,%r)\n' % (exec_command_dir))
298 f.write('from exec_command import exec_command\n')
299 f.write('del sys.path[0]\n')
300 f.write('cmd = %r\n' % command)
301 f.write('os.environ = %r\n' % (os.environ))
302 f.write('s,o = exec_command(cmd, _with_python=0, **%r)\n' % (env))
303 f.write('f=open(%r,"w")\nf.write(str(s))\nf.close()\n' % (stsfile))
304 f.write('f=open(%r,"w")\nf.write(o)\nf.close()\n' % (outfile))
305 f.close()
306
307 cmd = '%s %s' % (python_exe, cmdfile)
308 status = os.system(cmd)
309 if status:
310 raise RuntimeError("%r failed" % (cmd,))
311 os.remove(cmdfile)
312
313 f = open_latin1(stsfile, 'r')
314 status = int(f.read())
315 f.close()
316 os.remove(stsfile)
317
318 f = open_latin1(outfile, 'r')
319 text = f.read()
320 f.close()
321 os.remove(outfile)
322
323 return status, text
324
325 def quote_arg(arg):
326 if arg[0]!='"' and ' ' in arg:
327 return '"%s"' % arg
328 return arg
329
330 def _exec_command( command, use_shell=None, use_tee = None, **env ):
331 log.debug('_exec_command(...)')
332
333 if use_shell is None:
334 use_shell = os.name=='posix'
335 if use_tee is None:
336 use_tee = os.name=='posix'
337 using_command = 0
338 if use_shell:
339 # We use shell (unless use_shell==0) so that wildcards can be
340 # used.
341 sh = os.environ.get('SHELL', '/bin/sh')
342 if is_sequence(command):
343 argv = [sh, '-c', ' '.join(list(command))]
344 else:
345 argv = [sh, '-c', command]
346 else:
347 # On NT, DOS we avoid using command.com as it's exit status is
348 # not related to the exit status of a command.
349 if is_sequence(command):
350 argv = command[:]
351 else:
352 argv = shlex.split(command)
353
354 if hasattr(os, 'spawnvpe'):
355 spawn_command = os.spawnvpe
356 else:
357 spawn_command = os.spawnve
358 argv[0] = find_executable(argv[0]) or argv[0]
359 if not os.path.isfile(argv[0]):
360 log.warn('Executable %s does not exist' % (argv[0]))
361 if os.name in ['nt', 'dos']:
362 # argv[0] might be internal command
363 argv = [os.environ['COMSPEC'], '/C'] + argv
364 using_command = 1
365
366 _so_has_fileno = _supports_fileno(sys.stdout)
367 _se_has_fileno = _supports_fileno(sys.stderr)
368 so_flush = sys.stdout.flush
369 se_flush = sys.stderr.flush
370 if _so_has_fileno:
371 so_fileno = sys.stdout.fileno()
372 so_dup = os.dup(so_fileno)
373 if _se_has_fileno:
374 se_fileno = sys.stderr.fileno()
375 se_dup = os.dup(se_fileno)
376
377 outfile = temp_file_name()
378 fout = open(outfile, 'w')
379 if using_command:
380 errfile = temp_file_name()
381 ferr = open(errfile, 'w')
382
383 log.debug('Running %s(%s,%r,%r,os.environ)' \
384 % (spawn_command.__name__, os.P_WAIT, argv[0], argv))
385
386 argv0 = argv[0]
387 if not using_command:
388 argv[0] = quote_arg(argv0)
389
390 so_flush()
391 se_flush()
392 if _so_has_fileno:
393 os.dup2(fout.fileno(), so_fileno)
394
395 if _se_has_fileno:
396 if using_command:
397 #XXX: disabled for now as it does not work from cmd under win32.
398 # Tests fail on msys
399 os.dup2(ferr.fileno(), se_fileno)
400 else:
401 os.dup2(fout.fileno(), se_fileno)
402 try:
403 status = spawn_command(os.P_WAIT, argv0, argv, os.environ)
404 except OSError:
405 errmess = str(get_exception())
406 status = 999
407 sys.stderr.write('%s: %s'%(errmess, argv[0]))
408
409 so_flush()
410 se_flush()
411 if _so_has_fileno:
412 os.dup2(so_dup, so_fileno)
413 if _se_has_fileno:
414 os.dup2(se_dup, se_fileno)
415
416 fout.close()
417 fout = open_latin1(outfile, 'r')
418 text = fout.read()
419 fout.close()
420 os.remove(outfile)
421
422 if using_command:
423 ferr.close()
424 ferr = open_latin1(errfile, 'r')
425 errmess = ferr.read()
426 ferr.close()
427 os.remove(errfile)
428 if errmess and not status:
429 # Not sure how to handle the case where errmess
430 # contains only warning messages and that should
431 # not be treated as errors.
432 #status = 998
433 if text:
434 text = text + '\n'
435 #text = '%sCOMMAND %r FAILED: %s' %(text,command,errmess)
436 text = text + errmess
437 print (errmess)
438 if text[-1:]=='\n':
439 text = text[:-1]
440 if status is None:
441 status = 0
442
443 if use_tee:
444 print (text)
445
446 return status, text
447
448
449 def test_nt(**kws):
450 pythonexe = get_pythonexe()
451 echo = find_executable('echo')
452 using_cygwin_echo = echo != 'echo'
453 if using_cygwin_echo:
454 log.warn('Using cygwin echo in win32 environment is not supported')
455
456 s, o=exec_command(pythonexe\
457 +' -c "import os;print os.environ.get(\'AAA\',\'\')"')
458 assert s==0 and o=='', (s, o)
459
460 s, o=exec_command(pythonexe\
461 +' -c "import os;print os.environ.get(\'AAA\')"',
462 AAA='Tere')
463 assert s==0 and o=='Tere', (s, o)
464
465 os.environ['BBB'] = 'Hi'
466 s, o=exec_command(pythonexe\
467 +' -c "import os;print os.environ.get(\'BBB\',\'\')"')
468 assert s==0 and o=='Hi', (s, o)
469
470 s, o=exec_command(pythonexe\
471 +' -c "import os;print os.environ.get(\'BBB\',\'\')"',
472 BBB='Hey')
473 assert s==0 and o=='Hey', (s, o)
474
475 s, o=exec_command(pythonexe\
476 +' -c "import os;print os.environ.get(\'BBB\',\'\')"')
477 assert s==0 and o=='Hi', (s, o)
478 elif 0:
479 s, o=exec_command('echo Hello')
480 assert s==0 and o=='Hello', (s, o)
481
482 s, o=exec_command('echo a%AAA%')
483 assert s==0 and o=='a', (s, o)
484
485 s, o=exec_command('echo a%AAA%', AAA='Tere')
486 assert s==0 and o=='aTere', (s, o)
487
488 os.environ['BBB'] = 'Hi'
489 s, o=exec_command('echo a%BBB%')
490 assert s==0 and o=='aHi', (s, o)
491
492 s, o=exec_command('echo a%BBB%', BBB='Hey')
493 assert s==0 and o=='aHey', (s, o)
494 s, o=exec_command('echo a%BBB%')
495 assert s==0 and o=='aHi', (s, o)
496
497 s, o=exec_command('this_is_not_a_command')
498 assert s and o!='', (s, o)
499
500 s, o=exec_command('type not_existing_file')
501 assert s and o!='', (s, o)
502
503 s, o=exec_command('echo path=%path%')
504 assert s==0 and o!='', (s, o)
505
506 s, o=exec_command('%s -c "import sys;sys.stderr.write(sys.platform)"' \
507 % pythonexe)
508 assert s==0 and o=='win32', (s, o)
509
510 s, o=exec_command('%s -c "raise \'Ignore me.\'"' % pythonexe)
511 assert s==1 and o, (s, o)
512
513 s, o=exec_command('%s -c "import sys;sys.stderr.write(\'0\');sys.stderr.write(\'1\');sys.stderr.write(\'2\')"'\
514 % pythonexe)
515 assert s==0 and o=='012', (s, o)
516
517 s, o=exec_command('%s -c "import sys;sys.exit(15)"' % pythonexe)
518 assert s==15 and o=='', (s, o)
519
520 s, o=exec_command('%s -c "print \'Heipa\'"' % pythonexe)
521 assert s==0 and o=='Heipa', (s, o)
522
523 print ('ok')
524
525 def test_posix(**kws):
526 s, o=exec_command("echo Hello",**kws)
527 assert s==0 and o=='Hello', (s, o)
528
529 s, o=exec_command('echo $AAA',**kws)
530 assert s==0 and o=='', (s, o)
531
532 s, o=exec_command('echo "$AAA"',AAA='Tere',**kws)
533 assert s==0 and o=='Tere', (s, o)
534
535
536 s, o=exec_command('echo "$AAA"',**kws)
537 assert s==0 and o=='', (s, o)
538
539 os.environ['BBB'] = 'Hi'
540 s, o=exec_command('echo "$BBB"',**kws)
541 assert s==0 and o=='Hi', (s, o)
542
543 s, o=exec_command('echo "$BBB"',BBB='Hey',**kws)
544 assert s==0 and o=='Hey', (s, o)
545
546 s, o=exec_command('echo "$BBB"',**kws)
547 assert s==0 and o=='Hi', (s, o)
548
549
550 s, o=exec_command('this_is_not_a_command',**kws)
551 assert s!=0 and o!='', (s, o)
552
553 s, o=exec_command('echo path=$PATH',**kws)
554 assert s==0 and o!='', (s, o)
555
556 s, o=exec_command('python -c "import sys,os;sys.stderr.write(os.name)"',**kws)
557 assert s==0 and o=='posix', (s, o)
558
559 s, o=exec_command('python -c "raise \'Ignore me.\'"',**kws)
560 assert s==1 and o, (s, o)
561
562 s, o=exec_command('python -c "import sys;sys.stderr.write(\'0\');sys.stderr.write(\'1\');sys.stderr.write(\'2\')"',**kws)
563 assert s==0 and o=='012', (s, o)
564
565 s, o=exec_command('python -c "import sys;sys.exit(15)"',**kws)
566 assert s==15 and o=='', (s, o)
567
568 s, o=exec_command('python -c "print \'Heipa\'"',**kws)
569 assert s==0 and o=='Heipa', (s, o)
570
571 print ('ok')
572
573 def test_execute_in(**kws):
574 pythonexe = get_pythonexe()
575 tmpfile = temp_file_name()
576 fn = os.path.basename(tmpfile)
577 tmpdir = os.path.dirname(tmpfile)
578 f = open(tmpfile, 'w')
579 f.write('Hello')
580 f.close()
581
582 s, o = exec_command('%s -c "print \'Ignore the following IOError:\','\
583 'open(%r,\'r\')"' % (pythonexe, fn),**kws)
584 assert s and o!='', (s, o)
585 s, o = exec_command('%s -c "print open(%r,\'r\').read()"' % (pythonexe, fn),
586 execute_in = tmpdir,**kws)
587 assert s==0 and o=='Hello', (s, o)
588 os.remove(tmpfile)
589 print ('ok')
590
591 def test_svn(**kws):
592 s, o = exec_command(['svn', 'status'],**kws)
593 assert s, (s, o)
594 print ('svn ok')
595
596 def test_cl(**kws):
597 if os.name=='nt':
598 s, o = exec_command(['cl', '/V'],**kws)
599 assert s, (s, o)
600 print ('cl ok')
601
602 if os.name=='posix':
603 test = test_posix
604 elif os.name in ['nt', 'dos']:
605 test = test_nt
606 else:
607 raise NotImplementedError('exec_command tests for ', os.name)
608
609 ############################################################
610
611 if __name__ == "__main__":
612
613 test(use_tee=0)
614 test(use_tee=1)
615 test_execute_in(use_tee=0)
616 test_execute_in(use_tee=1)
617 test_svn(use_tee=1)
618 test_cl(use_tee=1)