##// END OF EJS Templates
remove special case for 'python' in find_cmd
MinRK -
Show More
@@ -1,125 +1,122 b''
1 1 # encoding: utf-8
2 2 """
3 3 Utilities for working with external processes.
4 4 """
5 5
6 6 #-----------------------------------------------------------------------------
7 7 # Copyright (C) 2008-2011 The IPython Development Team
8 8 #
9 9 # Distributed under the terms of the BSD License. The full license is in
10 10 # the file COPYING, distributed as part of this software.
11 11 #-----------------------------------------------------------------------------
12 12
13 13 #-----------------------------------------------------------------------------
14 14 # Imports
15 15 #-----------------------------------------------------------------------------
16 16 from __future__ import print_function
17 17
18 18 # Stdlib
19 19 import os
20 20 import sys
21 21 import shlex
22 22
23 23 # Our own
24 24 if sys.platform == 'win32':
25 25 from ._process_win32 import _find_cmd, system, getoutput, AvoidUNCPath, arg_split
26 26 else:
27 27 from ._process_posix import _find_cmd, system, getoutput, arg_split
28 28
29 29
30 30 from ._process_common import getoutputerror
31 31
32 32 #-----------------------------------------------------------------------------
33 33 # Code
34 34 #-----------------------------------------------------------------------------
35 35
36 36
37 37 class FindCmdError(Exception):
38 38 pass
39 39
40 40
41 41 def find_cmd(cmd):
42 42 """Find absolute path to executable cmd in a cross platform manner.
43 43
44 44 This function tries to determine the full path to a command line program
45 45 using `which` on Unix/Linux/OS X and `win32api` on Windows. Most of the
46 time it will use the version that is first on the users `PATH`. If
47 cmd is `python` return `sys.executable`.
46 time it will use the version that is first on the users `PATH`.
48 47
49 48 Warning, don't use this to find IPython command line programs as there
50 49 is a risk you will find the wrong one. Instead find those using the
51 50 following code and looking for the application itself::
52 51
53 52 from IPython.utils.path import get_ipython_module_path
54 53 from IPython.utils.process import pycmd2argv
55 54 argv = pycmd2argv(get_ipython_module_path('IPython.frontend.terminal.ipapp'))
56 55
57 56 Parameters
58 57 ----------
59 58 cmd : str
60 59 The command line program to look for.
61 60 """
62 if cmd in ('python', os.path.basename(sys.executable)):
63 return os.path.abspath(sys.executable)
64 61 try:
65 62 path = _find_cmd(cmd).rstrip()
66 63 except OSError:
67 64 raise FindCmdError('command could not be found: %s' % cmd)
68 65 # which returns empty if not found
69 66 if path == '':
70 67 raise FindCmdError('command could not be found: %s' % cmd)
71 68 return os.path.abspath(path)
72 69
73 70
74 71 def is_cmd_found(cmd):
75 72 """Check whether executable `cmd` exists or not and return a bool."""
76 73 try:
77 74 find_cmd(cmd)
78 75 return True
79 76 except FindCmdError:
80 77 return False
81 78
82 79
83 80 def pycmd2argv(cmd):
84 81 r"""Take the path of a python command and return a list (argv-style).
85 82
86 83 This only works on Python based command line programs and will find the
87 84 location of the ``python`` executable using ``sys.executable`` to make
88 85 sure the right version is used.
89 86
90 87 For a given path ``cmd``, this returns [cmd] if cmd's extension is .exe,
91 88 .com or .bat, and [, cmd] otherwise.
92 89
93 90 Parameters
94 91 ----------
95 92 cmd : string
96 93 The path of the command.
97 94
98 95 Returns
99 96 -------
100 97 argv-style list.
101 98 """
102 99 ext = os.path.splitext(cmd)[1]
103 100 if ext in ['.exe', '.com', '.bat']:
104 101 return [cmd]
105 102 else:
106 103 return [sys.executable, cmd]
107 104
108 105
109 106 def abbrev_cwd():
110 107 """ Return abbreviated version of cwd, e.g. d:mydir """
111 108 cwd = os.getcwdu().replace('\\','/')
112 109 drivepart = ''
113 110 tail = cwd
114 111 if sys.platform == 'win32':
115 112 if len(cwd) < 4:
116 113 return cwd
117 114 drivepart,tail = os.path.splitdrive(cwd)
118 115
119 116
120 117 parts = tail.split('/')
121 118 if len(parts) > 2:
122 119 tail = '/'.join(parts[-2:])
123 120
124 121 return (drivepart + (
125 122 cwd == '/' and '/' or tail))
@@ -1,138 +1,134 b''
1 1 # encoding: utf-8
2 2 """
3 3 Tests for platutils.py
4 4 """
5 5
6 6 #-----------------------------------------------------------------------------
7 7 # Copyright (C) 2008-2011 The IPython Development Team
8 8 #
9 9 # Distributed under the terms of the BSD License. The full license is in
10 10 # the file COPYING, distributed as part of this software.
11 11 #-----------------------------------------------------------------------------
12 12
13 13 #-----------------------------------------------------------------------------
14 14 # Imports
15 15 #-----------------------------------------------------------------------------
16 16
17 17 import sys
18 18 import os
19 19 from unittest import TestCase
20 20
21 21 import nose.tools as nt
22 22
23 23 from IPython.utils.process import (find_cmd, FindCmdError, arg_split,
24 24 system, getoutput, getoutputerror)
25 25 from IPython.testing import decorators as dec
26 26 from IPython.testing import tools as tt
27 27
28 28 python = os.path.basename(sys.executable)
29 29
30 30 #-----------------------------------------------------------------------------
31 31 # Tests
32 32 #-----------------------------------------------------------------------------
33 33
34 def test_find_cmd_python():
35 """Make sure we find sys.exectable for python."""
36 nt.assert_equal(find_cmd(python), sys.executable)
37 34
38
39 35 @dec.skip_win32
40 36 def test_find_cmd_ls():
41 37 """Make sure we can find the full path to ls."""
42 38 path = find_cmd('ls')
43 39 nt.assert_true(path.endswith('ls'))
44 40
45 41
46 42 def has_pywin32():
47 43 try:
48 44 import win32api
49 45 except ImportError:
50 46 return False
51 47 return True
52 48
53 49
54 50 @dec.onlyif(has_pywin32, "This test requires win32api to run")
55 51 def test_find_cmd_pythonw():
56 52 """Try to find pythonw on Windows."""
57 53 path = find_cmd('pythonw')
58 54 nt.assert_true(path.endswith('pythonw.exe'))
59 55
60 56
61 57 @dec.onlyif(lambda : sys.platform != 'win32' or has_pywin32(),
62 58 "This test runs on posix or in win32 with win32api installed")
63 59 def test_find_cmd_fail():
64 60 """Make sure that FindCmdError is raised if we can't find the cmd."""
65 61 nt.assert_raises(FindCmdError,find_cmd,'asdfasdf')
66 62
67 63
68 64 @dec.skip_win32
69 65 def test_arg_split():
70 66 """Ensure that argument lines are correctly split like in a shell."""
71 67 tests = [['hi', ['hi']],
72 68 [u'hi', [u'hi']],
73 69 ['hello there', ['hello', 'there']],
74 70 # \u01ce == \N{LATIN SMALL LETTER A WITH CARON}
75 71 # Do not use \N because the tests crash with syntax error in
76 72 # some cases, for example windows python2.6.
77 73 [u'h\u01cello', [u'h\u01cello']],
78 74 ['something "with quotes"', ['something', '"with quotes"']],
79 75 ]
80 76 for argstr, argv in tests:
81 77 nt.assert_equal(arg_split(argstr), argv)
82 78
83 79 @dec.skip_if_not_win32
84 80 def test_arg_split_win32():
85 81 """Ensure that argument lines are correctly split like in a shell."""
86 82 tests = [['hi', ['hi']],
87 83 [u'hi', [u'hi']],
88 84 ['hello there', ['hello', 'there']],
89 85 [u'h\u01cello', [u'h\u01cello']],
90 86 ['something "with quotes"', ['something', 'with quotes']],
91 87 ]
92 88 for argstr, argv in tests:
93 89 nt.assert_equal(arg_split(argstr), argv)
94 90
95 91
96 92 class SubProcessTestCase(TestCase, tt.TempFileMixin):
97 93 def setUp(self):
98 94 """Make a valid python temp file."""
99 95 lines = ["from __future__ import print_function",
100 96 "import sys",
101 97 "print('on stdout', end='', file=sys.stdout)",
102 98 "print('on stderr', end='', file=sys.stderr)",
103 99 "sys.stdout.flush()",
104 100 "sys.stderr.flush()"]
105 101 self.mktmp('\n'.join(lines))
106 102
107 103 def test_system(self):
108 104 status = system('%s "%s"' % (python, self.fname))
109 105 self.assertEqual(status, 0)
110 106
111 107 def test_system_quotes(self):
112 108 status = system('%s -c "import sys"' % python)
113 109 self.assertEqual(status, 0)
114 110
115 111 def test_getoutput(self):
116 112 out = getoutput('%s "%s"' % (python, self.fname))
117 113 # we can't rely on the order the line buffered streams are flushed
118 114 try:
119 115 self.assertEqual(out, 'on stderron stdout')
120 116 except AssertionError:
121 117 self.assertEqual(out, 'on stdouton stderr')
122 118
123 119 def test_getoutput_quoted(self):
124 120 out = getoutput('%s -c "print (1)"' % python)
125 121 self.assertEqual(out.strip(), '1')
126 122
127 123 #Invalid quoting on windows
128 124 @dec.skip_win32
129 125 def test_getoutput_quoted2(self):
130 126 out = getoutput("%s -c 'print (1)'" % python)
131 127 self.assertEqual(out.strip(), '1')
132 128 out = getoutput("%s -c 'print (\"1\")'" % python)
133 129 self.assertEqual(out.strip(), '1')
134 130
135 131 def test_getoutput_error(self):
136 132 out, err = getoutputerror('%s "%s"' % (python, self.fname))
137 133 self.assertEqual(out, 'on stdout')
138 134 self.assertEqual(err, 'on stderr')
General Comments 0
You need to be logged in to leave comments. Login now