Show More
@@ -26,32 +26,16 b' IPython.external.decorators, we import either numpy.testing.decorators if numpy ' | |||||
26 | available, OR use equivalent code in IPython.external._decorators, which |
|
26 | available, OR use equivalent code in IPython.external._decorators, which | |
27 | we've copied verbatim from numpy. |
|
27 | we've copied verbatim from numpy. | |
28 |
|
28 | |||
29 | Authors |
|
|||
30 | ------- |
|
|||
31 |
|
||||
32 | - Fernando Perez <Fernando.Perez@berkeley.edu> |
|
|||
33 | """ |
|
29 | """ | |
34 |
|
30 | |||
35 | #----------------------------------------------------------------------------- |
|
31 | # Copyright (c) IPython Development Team. | |
36 | # Copyright (C) 2009-2011 The IPython Development Team |
|
32 | # Distributed under the terms of the Modified BSD License. | |
37 | # |
|
|||
38 | # Distributed under the terms of the BSD License. The full license is in |
|
|||
39 | # the file COPYING, distributed as part of this software. |
|
|||
40 | #----------------------------------------------------------------------------- |
|
|||
41 |
|
33 | |||
42 | #----------------------------------------------------------------------------- |
|
|||
43 | # Imports |
|
|||
44 | #----------------------------------------------------------------------------- |
|
|||
45 |
|
||||
46 | # Stdlib imports |
|
|||
47 | import sys |
|
34 | import sys | |
48 | import os |
|
35 | import os | |
49 | import tempfile |
|
36 | import tempfile | |
50 | import unittest |
|
37 | import unittest | |
51 |
|
38 | |||
52 | # Third-party imports |
|
|||
53 |
|
||||
54 | # This is Michele Simionato's decorator module, kept verbatim. |
|
|||
55 | from decorator import decorator |
|
39 | from decorator import decorator | |
56 |
|
40 | |||
57 | # Expose the unittest-driven decorators |
|
41 | # Expose the unittest-driven decorators | |
@@ -63,8 +47,7 b' from .ipunittest import ipdoctest, ipdocstring' | |||||
63 | from IPython.external.decorators import * |
|
47 | from IPython.external.decorators import * | |
64 |
|
48 | |||
65 | # For onlyif_cmd_exists decorator |
|
49 | # For onlyif_cmd_exists decorator | |
66 |
from IPython.utils.p |
|
50 | from IPython.utils.py3compat import string_types, which | |
67 | from IPython.utils.py3compat import string_types |
|
|||
68 |
|
51 | |||
69 | #----------------------------------------------------------------------------- |
|
52 | #----------------------------------------------------------------------------- | |
70 | # Classes and functions |
|
53 | # Classes and functions | |
@@ -370,16 +353,9 b' def onlyif_cmds_exist(*commands):' | |||||
370 | Decorator to skip test when at least one of `commands` is not found. |
|
353 | Decorator to skip test when at least one of `commands` is not found. | |
371 | """ |
|
354 | """ | |
372 | for cmd in commands: |
|
355 | for cmd in commands: | |
373 | try: |
|
356 | if not which(cmd): | |
374 | if not is_cmd_found(cmd): |
|
357 | return skip("This test runs only if command '{0}' " | |
375 | return skip("This test runs only if command '{0}' " |
|
358 | "is installed".format(cmd)) | |
376 | "is installed".format(cmd)) |
|
|||
377 | except ImportError as e: |
|
|||
378 | # is_cmd_found uses pywin32 on windows, which might not be available |
|
|||
379 | if sys.platform == 'win32' and 'pywin32' in str(e): |
|
|||
380 | return skip("This test runs only if pywin32 and command '{0}' " |
|
|||
381 | "is installed".format(cmd)) |
|
|||
382 | raise e |
|
|||
383 | return null_deco |
|
359 | return null_deco | |
384 |
|
360 | |||
385 | def onlyif_any_cmd_exists(*commands): |
|
361 | def onlyif_any_cmd_exists(*commands): | |
@@ -387,14 +363,7 b' def onlyif_any_cmd_exists(*commands):' | |||||
387 | Decorator to skip test unless at least one of `commands` is found. |
|
363 | Decorator to skip test unless at least one of `commands` is found. | |
388 | """ |
|
364 | """ | |
389 | for cmd in commands: |
|
365 | for cmd in commands: | |
390 | try: |
|
366 | if which(cmd): | |
391 | if is_cmd_found(cmd): |
|
367 | return null_deco | |
392 | return null_deco |
|
|||
393 | except ImportError as e: |
|
|||
394 | # is_cmd_found uses pywin32 on windows, which might not be available |
|
|||
395 | if sys.platform == 'win32' and 'pywin32' in str(e): |
|
|||
396 | return skip("This test runs only if pywin32 and commands '{0}' " |
|
|||
397 | "are installed".format(commands)) |
|
|||
398 | raise e |
|
|||
399 | return skip("This test runs only if one of the commands {0} " |
|
368 | return skip("This test runs only if one of the commands {0} " | |
400 | "is installed".format(commands)) |
|
369 | "is installed".format(commands)) |
@@ -3,37 +3,24 b'' | |||||
3 | Utilities for working with external processes. |
|
3 | Utilities for working with external processes. | |
4 | """ |
|
4 | """ | |
5 |
|
5 | |||
6 | #----------------------------------------------------------------------------- |
|
6 | # Copyright (c) IPython Development Team. | |
7 | # Copyright (C) 2008-2011 The IPython Development Team |
|
7 | # Distributed under the terms of the Modified BSD License. | |
8 | # |
|
8 | ||
9 | # Distributed under the terms of the BSD License. The full license is in |
|
|||
10 | # the file COPYING, distributed as part of this software. |
|
|||
11 | #----------------------------------------------------------------------------- |
|
|||
12 |
|
||||
13 | #----------------------------------------------------------------------------- |
|
|||
14 | # Imports |
|
|||
15 | #----------------------------------------------------------------------------- |
|
|||
16 | from __future__ import print_function |
|
9 | from __future__ import print_function | |
17 |
|
10 | |||
18 | # Stdlib |
|
|||
19 | import os |
|
11 | import os | |
20 | import sys |
|
12 | import sys | |
21 |
|
13 | |||
22 | # Our own |
|
|||
23 | if sys.platform == 'win32': |
|
14 | if sys.platform == 'win32': | |
24 |
from ._process_win32 import |
|
15 | from ._process_win32 import system, getoutput, arg_split, check_pid | |
25 | elif sys.platform == 'cli': |
|
16 | elif sys.platform == 'cli': | |
26 |
from ._process_cli import |
|
17 | from ._process_cli import system, getoutput, arg_split, check_pid | |
27 | else: |
|
18 | else: | |
28 |
from ._process_posix import |
|
19 | from ._process_posix import system, getoutput, arg_split, check_pid | |
29 |
|
20 | |||
30 | from ._process_common import getoutputerror, get_output_error_code, process_handler |
|
21 | from ._process_common import getoutputerror, get_output_error_code, process_handler | |
31 | from . import py3compat |
|
22 | from . import py3compat | |
32 |
|
23 | |||
33 | #----------------------------------------------------------------------------- |
|
|||
34 | # Code |
|
|||
35 | #----------------------------------------------------------------------------- |
|
|||
36 |
|
||||
37 |
|
24 | |||
38 | class FindCmdError(Exception): |
|
25 | class FindCmdError(Exception): | |
39 | pass |
|
26 | pass | |
@@ -59,14 +46,10 b' def find_cmd(cmd):' | |||||
59 | cmd : str |
|
46 | cmd : str | |
60 | The command line program to look for. |
|
47 | The command line program to look for. | |
61 | """ |
|
48 | """ | |
62 | try: |
|
49 | path = py3compat.which(cmd) | |
63 | path = _find_cmd(cmd).rstrip() |
|
50 | if path is None: | |
64 | except OSError: |
|
|||
65 | raise FindCmdError('command could not be found: %s' % cmd) |
|
|||
66 | # which returns empty if not found |
|
|||
67 | if path == '': |
|
|||
68 | raise FindCmdError('command could not be found: %s' % cmd) |
|
51 | raise FindCmdError('command could not be found: %s' % cmd) | |
69 |
return |
|
52 | return path | |
70 |
|
53 | |||
71 |
|
54 | |||
72 | def is_cmd_found(cmd): |
|
55 | def is_cmd_found(cmd): |
@@ -4,6 +4,7 b' import functools' | |||||
4 | import os |
|
4 | import os | |
5 | import sys |
|
5 | import sys | |
6 | import re |
|
6 | import re | |
|
7 | import shutil | |||
7 | import types |
|
8 | import types | |
8 |
|
9 | |||
9 | from .encoding import DEFAULT_ENCODING |
|
10 | from .encoding import DEFAULT_ENCODING | |
@@ -75,6 +76,70 b' def safe_unicode(e):' | |||||
75 |
|
76 | |||
76 | return u'Unrecoverably corrupt evalue' |
|
77 | return u'Unrecoverably corrupt evalue' | |
77 |
|
78 | |||
|
79 | # shutil.which from Python 3.4 | |||
|
80 | def _shutil_which(cmd, mode=os.F_OK | os.X_OK, path=None): | |||
|
81 | """Given a command, mode, and a PATH string, return the path which | |||
|
82 | conforms to the given mode on the PATH, or None if there is no such | |||
|
83 | file. | |||
|
84 | ||||
|
85 | `mode` defaults to os.F_OK | os.X_OK. `path` defaults to the result | |||
|
86 | of os.environ.get("PATH"), or can be overridden with a custom search | |||
|
87 | path. | |||
|
88 | ||||
|
89 | This is a backport of shutil.which from Python 3.4 | |||
|
90 | """ | |||
|
91 | # Check that a given file can be accessed with the correct mode. | |||
|
92 | # Additionally check that `file` is not a directory, as on Windows | |||
|
93 | # directories pass the os.access check. | |||
|
94 | def _access_check(fn, mode): | |||
|
95 | return (os.path.exists(fn) and os.access(fn, mode) | |||
|
96 | and not os.path.isdir(fn)) | |||
|
97 | ||||
|
98 | # If we're given a path with a directory part, look it up directly rather | |||
|
99 | # than referring to PATH directories. This includes checking relative to the | |||
|
100 | # current directory, e.g. ./script | |||
|
101 | if os.path.dirname(cmd): | |||
|
102 | if _access_check(cmd, mode): | |||
|
103 | return cmd | |||
|
104 | return None | |||
|
105 | ||||
|
106 | if path is None: | |||
|
107 | path = os.environ.get("PATH", os.defpath) | |||
|
108 | if not path: | |||
|
109 | return None | |||
|
110 | path = path.split(os.pathsep) | |||
|
111 | ||||
|
112 | if sys.platform == "win32": | |||
|
113 | # The current directory takes precedence on Windows. | |||
|
114 | if not os.curdir in path: | |||
|
115 | path.insert(0, os.curdir) | |||
|
116 | ||||
|
117 | # PATHEXT is necessary to check on Windows. | |||
|
118 | pathext = os.environ.get("PATHEXT", "").split(os.pathsep) | |||
|
119 | # See if the given file matches any of the expected path extensions. | |||
|
120 | # This will allow us to short circuit when given "python.exe". | |||
|
121 | # If it does match, only test that one, otherwise we have to try | |||
|
122 | # others. | |||
|
123 | if any(cmd.lower().endswith(ext.lower()) for ext in pathext): | |||
|
124 | files = [cmd] | |||
|
125 | else: | |||
|
126 | files = [cmd + ext for ext in pathext] | |||
|
127 | else: | |||
|
128 | # On other platforms you don't have things like PATHEXT to tell you | |||
|
129 | # what file suffixes are executable, so just pass on cmd as-is. | |||
|
130 | files = [cmd] | |||
|
131 | ||||
|
132 | seen = set() | |||
|
133 | for dir in path: | |||
|
134 | normdir = os.path.normcase(dir) | |||
|
135 | if not normdir in seen: | |||
|
136 | seen.add(normdir) | |||
|
137 | for thefile in files: | |||
|
138 | name = os.path.join(dir, thefile) | |||
|
139 | if _access_check(name, mode): | |||
|
140 | return name | |||
|
141 | return None | |||
|
142 | ||||
78 | if sys.version_info[0] >= 3: |
|
143 | if sys.version_info[0] >= 3: | |
79 | PY3 = True |
|
144 | PY3 = True | |
80 |
|
145 | |||
@@ -97,6 +162,8 b' if sys.version_info[0] >= 3:' | |||||
97 | string_types = (str,) |
|
162 | string_types = (str,) | |
98 | unicode_type = str |
|
163 | unicode_type = str | |
99 |
|
164 | |||
|
165 | which = shutil.which | |||
|
166 | ||||
100 | def isidentifier(s, dotted=False): |
|
167 | def isidentifier(s, dotted=False): | |
101 | if dotted: |
|
168 | if dotted: | |
102 | return all(isidentifier(a) for a in s.split(".")) |
|
169 | return all(isidentifier(a) for a in s.split(".")) | |
@@ -184,6 +251,8 b' else:' | |||||
184 | def get_closure(f): |
|
251 | def get_closure(f): | |
185 | """Get a function's closure attribute""" |
|
252 | """Get a function's closure attribute""" | |
186 | return f.func_closure |
|
253 | return f.func_closure | |
|
254 | ||||
|
255 | which = _shutil_which | |||
187 |
|
256 | |||
188 | # Abstract u'abc' syntax: |
|
257 | # Abstract u'abc' syntax: | |
189 | @_modify_str_or_docstring |
|
258 | @_modify_str_or_docstring |
@@ -52,7 +52,7 b' def has_pywin32():' | |||||
52 | def test_find_cmd_pythonw(): |
|
52 | def test_find_cmd_pythonw(): | |
53 | """Try to find pythonw on Windows.""" |
|
53 | """Try to find pythonw on Windows.""" | |
54 | path = find_cmd('pythonw') |
|
54 | path = find_cmd('pythonw') | |
55 |
|
|
55 | assert path.lower().endswith('pythonw.exe'), path | |
56 |
|
56 | |||
57 |
|
57 | |||
58 | @dec.onlyif(lambda : sys.platform != 'win32' or has_pywin32(), |
|
58 | @dec.onlyif(lambda : sys.platform != 'win32' or has_pywin32(), |
@@ -7,7 +7,7 b' import subprocess' | |||||
7 | import os |
|
7 | import os | |
8 | import sys |
|
8 | import sys | |
9 |
|
9 | |||
10 |
from IPython.utils.p |
|
10 | from IPython.utils.py3compat import which | |
11 | from IPython.utils.traitlets import Integer, List, Bool, Instance |
|
11 | from IPython.utils.traitlets import Integer, List, Bool, Instance | |
12 | from IPython.utils.tempdir import TemporaryWorkingDirectory |
|
12 | from IPython.utils.tempdir import TemporaryWorkingDirectory | |
13 | from .latex import LatexExporter |
|
13 | from .latex import LatexExporter | |
@@ -65,10 +65,12 b' class PDFExporter(LatexExporter):' | |||||
65 | #We must use cp1252 encoding for calling subprocess.Popen |
|
65 | #We must use cp1252 encoding for calling subprocess.Popen | |
66 | #Note that sys.stdin.encoding and encoding.DEFAULT_ENCODING |
|
66 | #Note that sys.stdin.encoding and encoding.DEFAULT_ENCODING | |
67 | # could be different (cp437 in case of dos console) |
|
67 | # could be different (cp437 in case of dos console) | |
68 |
command = [c.encode('cp1252') for c in command] |
|
68 | command = [c.encode('cp1252') for c in command] | |
69 |
|
69 | |||
70 | # This will throw a clearer error if the command is not found |
|
70 | # This will throw a clearer error if the command is not found | |
71 |
|
|
71 | cmd = which(command_list[0]) | |
|
72 | if cmd is None: | |||
|
73 | raise OSError("%s not found on PATH" % command_list[0]) | |||
72 |
|
74 | |||
73 | times = 'time' if count == 1 else 'times' |
|
75 | times = 'time' if count == 1 else 'times' | |
74 | self.log.info("Running %s %i %s: %s", command_list[0], count, times, command) |
|
76 | self.log.info("Running %s %i %s: %s", command_list[0], count, times, command) |
General Comments 0
You need to be logged in to leave comments.
Login now