~ubuntu-branches/ubuntu/feisty/python-numpy/feisty

« back to all changes in this revision

Viewing changes to numpy/distutils/exec_command.py

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2006-07-12 10:00:24 UTC
  • Revision ID: james.westby@ubuntu.com-20060712100024-5lw9q2yczlisqcrt
Tags: upstream-0.9.8
ImportĀ upstreamĀ versionĀ 0.9.8

Show diffs side-by-side

added added

removed removed

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