##// END OF EJS Templates
Finish cleanup of setup.py and tests after dead code removal....
Fernando Perez -
Show More
@@ -1,467 +1,446 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """IPython Test Suite Runner.
2 """IPython Test Suite Runner.
3
3
4 This module provides a main entry point to a user script to test IPython
4 This module provides a main entry point to a user script to test IPython
5 itself from the command line. There are two ways of running this script:
5 itself from the command line. There are two ways of running this script:
6
6
7 1. With the syntax `iptest all`. This runs our entire test suite by
7 1. With the syntax `iptest all`. This runs our entire test suite by
8 calling this script (with different arguments) or trial recursively. This
8 calling this script (with different arguments) or trial recursively. This
9 causes modules and package to be tested in different processes, using nose
9 causes modules and package to be tested in different processes, using nose
10 or trial where appropriate.
10 or trial where appropriate.
11 2. With the regular nose syntax, like `iptest -vvs IPython`. In this form
11 2. With the regular nose syntax, like `iptest -vvs IPython`. In this form
12 the script simply calls nose, but with special command line flags and
12 the script simply calls nose, but with special command line flags and
13 plugins loaded.
13 plugins loaded.
14
14
15 For now, this script requires that both nose and twisted are installed. This
15 For now, this script requires that both nose and twisted are installed. This
16 will change in the future.
16 will change in the future.
17 """
17 """
18
18
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20 # Copyright (C) 2009 The IPython Development Team
20 # Copyright (C) 2009 The IPython Development Team
21 #
21 #
22 # Distributed under the terms of the BSD License. The full license is in
22 # Distributed under the terms of the BSD License. The full license is in
23 # the file COPYING, distributed as part of this software.
23 # the file COPYING, distributed as part of this software.
24 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
25
25
26 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
27 # Imports
27 # Imports
28 #-----------------------------------------------------------------------------
28 #-----------------------------------------------------------------------------
29
29
30 # Stdlib
30 # Stdlib
31 import os
31 import os
32 import os.path as path
32 import os.path as path
33 import signal
33 import signal
34 import sys
34 import sys
35 import subprocess
35 import subprocess
36 import tempfile
36 import tempfile
37 import time
37 import time
38 import warnings
38 import warnings
39
39
40 # Note: monkeypatch!
40 # Note: monkeypatch!
41 # We need to monkeypatch a small problem in nose itself first, before importing
41 # We need to monkeypatch a small problem in nose itself first, before importing
42 # it for actual use. This should get into nose upstream, but its release cycle
42 # it for actual use. This should get into nose upstream, but its release cycle
43 # is slow and we need it for our parametric tests to work correctly.
43 # is slow and we need it for our parametric tests to work correctly.
44 from IPython.testing import nosepatch
44 from IPython.testing import nosepatch
45 # Now, proceed to import nose itself
45 # Now, proceed to import nose itself
46 import nose.plugins.builtin
46 import nose.plugins.builtin
47 from nose.core import TestProgram
47 from nose.core import TestProgram
48
48
49 # Our own imports
49 # Our own imports
50 from IPython.utils.path import get_ipython_module_path
50 from IPython.utils.path import get_ipython_module_path
51 from IPython.utils.process import find_cmd, pycmd2argv
51 from IPython.utils.process import find_cmd, pycmd2argv
52 from IPython.utils.sysinfo import sys_info
52 from IPython.utils.sysinfo import sys_info
53
53
54 from IPython.testing import globalipapp
54 from IPython.testing import globalipapp
55 from IPython.testing.plugin.ipdoctest import IPythonDoctest
55 from IPython.testing.plugin.ipdoctest import IPythonDoctest
56
56
57 pjoin = path.join
57 pjoin = path.join
58
58
59
59
60 #-----------------------------------------------------------------------------
60 #-----------------------------------------------------------------------------
61 # Globals
61 # Globals
62 #-----------------------------------------------------------------------------
62 #-----------------------------------------------------------------------------
63
63
64
64
65 #-----------------------------------------------------------------------------
65 #-----------------------------------------------------------------------------
66 # Warnings control
66 # Warnings control
67 #-----------------------------------------------------------------------------
67 #-----------------------------------------------------------------------------
68
68
69 # Twisted generates annoying warnings with Python 2.6, as will do other code
69 # Twisted generates annoying warnings with Python 2.6, as will do other code
70 # that imports 'sets' as of today
70 # that imports 'sets' as of today
71 warnings.filterwarnings('ignore', 'the sets module is deprecated',
71 warnings.filterwarnings('ignore', 'the sets module is deprecated',
72 DeprecationWarning )
72 DeprecationWarning )
73
73
74 # This one also comes from Twisted
74 # This one also comes from Twisted
75 warnings.filterwarnings('ignore', 'the sha module is deprecated',
75 warnings.filterwarnings('ignore', 'the sha module is deprecated',
76 DeprecationWarning)
76 DeprecationWarning)
77
77
78 # Wx on Fedora11 spits these out
78 # Wx on Fedora11 spits these out
79 warnings.filterwarnings('ignore', 'wxPython/wxWidgets release number mismatch',
79 warnings.filterwarnings('ignore', 'wxPython/wxWidgets release number mismatch',
80 UserWarning)
80 UserWarning)
81
81
82 #-----------------------------------------------------------------------------
82 #-----------------------------------------------------------------------------
83 # Logic for skipping doctests
83 # Logic for skipping doctests
84 #-----------------------------------------------------------------------------
84 #-----------------------------------------------------------------------------
85
85
86 def test_for(mod):
86 def test_for(mod):
87 """Test to see if mod is importable."""
87 """Test to see if mod is importable."""
88 try:
88 try:
89 __import__(mod)
89 __import__(mod)
90 except (ImportError, RuntimeError):
90 except (ImportError, RuntimeError):
91 # GTK reports Runtime error if it can't be initialized even if it's
91 # GTK reports Runtime error if it can't be initialized even if it's
92 # importable.
92 # importable.
93 return False
93 return False
94 else:
94 else:
95 return True
95 return True
96
96
97 # Global dict where we can store information on what we have and what we don't
97 # Global dict where we can store information on what we have and what we don't
98 # have available at test run time
98 # have available at test run time
99 have = {}
99 have = {}
100
100
101 have['curses'] = test_for('_curses')
101 have['curses'] = test_for('_curses')
102 have['wx'] = test_for('wx')
102 have['wx'] = test_for('wx')
103 have['wx.aui'] = test_for('wx.aui')
103 have['wx.aui'] = test_for('wx.aui')
104 have['zope.interface'] = test_for('zope.interface')
104 have['zope.interface'] = test_for('zope.interface')
105 have['twisted'] = test_for('twisted')
105 have['twisted'] = test_for('twisted')
106 have['foolscap'] = test_for('foolscap')
106 have['foolscap'] = test_for('foolscap')
107 have['objc'] = test_for('objc')
108 have['pexpect'] = test_for('pexpect')
107 have['pexpect'] = test_for('pexpect')
109 have['gtk'] = test_for('gtk')
108 have['gtk'] = test_for('gtk')
110 have['gobject'] = test_for('gobject')
109 have['gobject'] = test_for('gobject')
111
110
112 #-----------------------------------------------------------------------------
111 #-----------------------------------------------------------------------------
113 # Functions and classes
112 # Functions and classes
114 #-----------------------------------------------------------------------------
113 #-----------------------------------------------------------------------------
115
114
116 def report():
115 def report():
117 """Return a string with a summary report of test-related variables."""
116 """Return a string with a summary report of test-related variables."""
118
117
119 out = [ sys_info() ]
118 out = [ sys_info() ]
120
119
121 avail = []
120 avail = []
122 not_avail = []
121 not_avail = []
123
122
124 for k, is_avail in have.items():
123 for k, is_avail in have.items():
125 if is_avail:
124 if is_avail:
126 avail.append(k)
125 avail.append(k)
127 else:
126 else:
128 not_avail.append(k)
127 not_avail.append(k)
129
128
130 if avail:
129 if avail:
131 out.append('\nTools and libraries available at test time:\n')
130 out.append('\nTools and libraries available at test time:\n')
132 avail.sort()
131 avail.sort()
133 out.append(' ' + ' '.join(avail)+'\n')
132 out.append(' ' + ' '.join(avail)+'\n')
134
133
135 if not_avail:
134 if not_avail:
136 out.append('\nTools and libraries NOT available at test time:\n')
135 out.append('\nTools and libraries NOT available at test time:\n')
137 not_avail.sort()
136 not_avail.sort()
138 out.append(' ' + ' '.join(not_avail)+'\n')
137 out.append(' ' + ' '.join(not_avail)+'\n')
139
138
140 return ''.join(out)
139 return ''.join(out)
141
140
142
141
143 def make_exclude():
142 def make_exclude():
144 """Make patterns of modules and packages to exclude from testing.
143 """Make patterns of modules and packages to exclude from testing.
145
144
146 For the IPythonDoctest plugin, we need to exclude certain patterns that
145 For the IPythonDoctest plugin, we need to exclude certain patterns that
147 cause testing problems. We should strive to minimize the number of
146 cause testing problems. We should strive to minimize the number of
148 skipped modules, since this means untested code.
147 skipped modules, since this means untested code.
149
148
150 These modules and packages will NOT get scanned by nose at all for tests.
149 These modules and packages will NOT get scanned by nose at all for tests.
151 """
150 """
152 # Simple utility to make IPython paths more readably, we need a lot of
151 # Simple utility to make IPython paths more readably, we need a lot of
153 # these below
152 # these below
154 ipjoin = lambda *paths: pjoin('IPython', *paths)
153 ipjoin = lambda *paths: pjoin('IPython', *paths)
155
154
156 exclusions = [ipjoin('external'),
155 exclusions = [ipjoin('external'),
157 ipjoin('frontend', 'process', 'winprocess.py'),
158 # Deprecated old Shell and iplib modules, skip to avoid
156 # Deprecated old Shell and iplib modules, skip to avoid
159 # warnings
157 # warnings
160 ipjoin('Shell'),
158 ipjoin('Shell'),
161 ipjoin('iplib'),
159 ipjoin('iplib'),
162 pjoin('IPython_doctest_plugin'),
160 pjoin('IPython_doctest_plugin'),
163 ipjoin('quarantine'),
161 ipjoin('quarantine'),
164 ipjoin('deathrow'),
162 ipjoin('deathrow'),
165 ipjoin('testing', 'attic'),
163 ipjoin('testing', 'attic'),
166 # This guy is probably attic material
164 # This guy is probably attic material
167 ipjoin('testing', 'mkdoctests'),
165 ipjoin('testing', 'mkdoctests'),
168 # Testing inputhook will need a lot of thought, to figure out
166 # Testing inputhook will need a lot of thought, to figure out
169 # how to have tests that don't lock up with the gui event
167 # how to have tests that don't lock up with the gui event
170 # loops in the picture
168 # loops in the picture
171 ipjoin('lib', 'inputhook'),
169 ipjoin('lib', 'inputhook'),
172 # Config files aren't really importable stand-alone
170 # Config files aren't really importable stand-alone
173 ipjoin('config', 'default'),
171 ipjoin('config', 'default'),
174 ipjoin('config', 'profile'),
172 ipjoin('config', 'profile'),
175 ]
173 ]
176
174
177 if not have['wx']:
175 if not have['wx']:
178 exclusions.append(ipjoin('gui'))
179 exclusions.append(ipjoin('frontend', 'wx'))
180 exclusions.append(ipjoin('lib', 'inputhookwx'))
176 exclusions.append(ipjoin('lib', 'inputhookwx'))
181
177
182 if not have['gtk'] or not have['gobject']:
178 if not have['gtk'] or not have['gobject']:
183 exclusions.append(ipjoin('lib', 'inputhookgtk'))
179 exclusions.append(ipjoin('lib', 'inputhookgtk'))
184
180
185 if not have['wx.aui']:
186 exclusions.append(ipjoin('gui', 'wx', 'wxIPython'))
187
188 if not have['objc']:
189 exclusions.append(ipjoin('frontend', 'cocoa'))
190
191 # These have to be skipped on win32 because the use echo, rm, cd, etc.
181 # These have to be skipped on win32 because the use echo, rm, cd, etc.
192 # See ticket https://bugs.launchpad.net/bugs/366982
182 # See ticket https://bugs.launchpad.net/bugs/366982
193 if sys.platform == 'win32':
183 if sys.platform == 'win32':
194 exclusions.append(ipjoin('testing', 'plugin', 'test_exampleip'))
184 exclusions.append(ipjoin('testing', 'plugin', 'test_exampleip'))
195 exclusions.append(ipjoin('testing', 'plugin', 'dtexample'))
185 exclusions.append(ipjoin('testing', 'plugin', 'dtexample'))
196
186
197 if not have['pexpect']:
187 if not have['pexpect']:
198 exclusions.extend([ipjoin('scripts', 'irunner'),
188 exclusions.extend([ipjoin('scripts', 'irunner'),
199 ipjoin('lib', 'irunner')])
189 ipjoin('lib', 'irunner')])
200
190
201 # This is scary. We still have things in frontend and testing that
191 # This is scary. We still have things in frontend and testing that
202 # are being tested by nose that use twisted. We need to rethink
192 # are being tested by nose that use twisted. We need to rethink
203 # how we are isolating dependencies in testing.
193 # how we are isolating dependencies in testing.
204 if not (have['twisted'] and have['zope.interface'] and have['foolscap']):
194 if not (have['twisted'] and have['zope.interface'] and have['foolscap']):
205 exclusions.extend(
195 exclusions.extend(
206 [ipjoin('frontend', 'asyncfrontendbase'),
196 [ipjoin('testing', 'parametric'),
207 ipjoin('frontend', 'prefilterfrontend'),
208 ipjoin('frontend', 'frontendbase'),
209 ipjoin('frontend', 'linefrontendbase'),
210 ipjoin('frontend', 'tests', 'test_linefrontend'),
211 ipjoin('frontend', 'tests', 'test_frontendbase'),
212 ipjoin('frontend', 'tests', 'test_prefilterfrontend'),
213 ipjoin('frontend', 'tests', 'test_asyncfrontendbase'),
214 ipjoin('testing', 'parametric'),
215 ipjoin('testing', 'util'),
197 ipjoin('testing', 'util'),
216 ipjoin('testing', 'tests', 'test_decorators_trial'),
198 ipjoin('testing', 'tests', 'test_decorators_trial'),
217 ] )
199 ] )
218
200
219 # This is needed for the reg-exp to match on win32 in the ipdoctest plugin.
201 # This is needed for the reg-exp to match on win32 in the ipdoctest plugin.
220 if sys.platform == 'win32':
202 if sys.platform == 'win32':
221 exclusions = [s.replace('\\','\\\\') for s in exclusions]
203 exclusions = [s.replace('\\','\\\\') for s in exclusions]
222
204
223 return exclusions
205 return exclusions
224
206
225
207
226 class IPTester(object):
208 class IPTester(object):
227 """Call that calls iptest or trial in a subprocess.
209 """Call that calls iptest or trial in a subprocess.
228 """
210 """
229 #: string, name of test runner that will be called
211 #: string, name of test runner that will be called
230 runner = None
212 runner = None
231 #: list, parameters for test runner
213 #: list, parameters for test runner
232 params = None
214 params = None
233 #: list, arguments of system call to be made to call test runner
215 #: list, arguments of system call to be made to call test runner
234 call_args = None
216 call_args = None
235 #: list, process ids of subprocesses we start (for cleanup)
217 #: list, process ids of subprocesses we start (for cleanup)
236 pids = None
218 pids = None
237
219
238 def __init__(self, runner='iptest', params=None):
220 def __init__(self, runner='iptest', params=None):
239 """Create new test runner."""
221 """Create new test runner."""
240 p = os.path
222 p = os.path
241 if runner == 'iptest':
223 if runner == 'iptest':
242 iptest_app = get_ipython_module_path('IPython.testing.iptest')
224 iptest_app = get_ipython_module_path('IPython.testing.iptest')
243 self.runner = pycmd2argv(iptest_app) + sys.argv[1:]
225 self.runner = pycmd2argv(iptest_app) + sys.argv[1:]
244 elif runner == 'trial':
226 elif runner == 'trial':
245 # For trial, it needs to be installed system-wide
227 # For trial, it needs to be installed system-wide
246 self.runner = pycmd2argv(p.abspath(find_cmd('trial')))
228 self.runner = pycmd2argv(p.abspath(find_cmd('trial')))
247 else:
229 else:
248 raise Exception('Not a valid test runner: %s' % repr(runner))
230 raise Exception('Not a valid test runner: %s' % repr(runner))
249 if params is None:
231 if params is None:
250 params = []
232 params = []
251 if isinstance(params, str):
233 if isinstance(params, str):
252 params = [params]
234 params = [params]
253 self.params = params
235 self.params = params
254
236
255 # Assemble call
237 # Assemble call
256 self.call_args = self.runner+self.params
238 self.call_args = self.runner+self.params
257
239
258 # Store pids of anything we start to clean up on deletion, if possible
240 # Store pids of anything we start to clean up on deletion, if possible
259 # (on posix only, since win32 has no os.kill)
241 # (on posix only, since win32 has no os.kill)
260 self.pids = []
242 self.pids = []
261
243
262 if sys.platform == 'win32':
244 if sys.platform == 'win32':
263 def _run_cmd(self):
245 def _run_cmd(self):
264 # On Windows, use os.system instead of subprocess.call, because I
246 # On Windows, use os.system instead of subprocess.call, because I
265 # was having problems with subprocess and I just don't know enough
247 # was having problems with subprocess and I just don't know enough
266 # about win32 to debug this reliably. Os.system may be the 'old
248 # about win32 to debug this reliably. Os.system may be the 'old
267 # fashioned' way to do it, but it works just fine. If someone
249 # fashioned' way to do it, but it works just fine. If someone
268 # later can clean this up that's fine, as long as the tests run
250 # later can clean this up that's fine, as long as the tests run
269 # reliably in win32.
251 # reliably in win32.
270 # What types of problems are you having. They may be related to
252 # What types of problems are you having. They may be related to
271 # running Python in unboffered mode. BG.
253 # running Python in unboffered mode. BG.
272 return os.system(' '.join(self.call_args))
254 return os.system(' '.join(self.call_args))
273 else:
255 else:
274 def _run_cmd(self):
256 def _run_cmd(self):
275 #print >> sys.stderr, '*** CMD:', ' '.join(self.call_args) # dbg
257 #print >> sys.stderr, '*** CMD:', ' '.join(self.call_args) # dbg
276 subp = subprocess.Popen(self.call_args)
258 subp = subprocess.Popen(self.call_args)
277 self.pids.append(subp.pid)
259 self.pids.append(subp.pid)
278 # If this fails, the pid will be left in self.pids and cleaned up
260 # If this fails, the pid will be left in self.pids and cleaned up
279 # later, but if the wait call succeeds, then we can clear the
261 # later, but if the wait call succeeds, then we can clear the
280 # stored pid.
262 # stored pid.
281 retcode = subp.wait()
263 retcode = subp.wait()
282 self.pids.pop()
264 self.pids.pop()
283 return retcode
265 return retcode
284
266
285 def run(self):
267 def run(self):
286 """Run the stored commands"""
268 """Run the stored commands"""
287 try:
269 try:
288 return self._run_cmd()
270 return self._run_cmd()
289 except:
271 except:
290 import traceback
272 import traceback
291 traceback.print_exc()
273 traceback.print_exc()
292 return 1 # signal failure
274 return 1 # signal failure
293
275
294 def __del__(self):
276 def __del__(self):
295 """Cleanup on exit by killing any leftover processes."""
277 """Cleanup on exit by killing any leftover processes."""
296
278
297 if not hasattr(os, 'kill'):
279 if not hasattr(os, 'kill'):
298 return
280 return
299
281
300 for pid in self.pids:
282 for pid in self.pids:
301 try:
283 try:
302 print 'Cleaning stale PID:', pid
284 print 'Cleaning stale PID:', pid
303 os.kill(pid, signal.SIGKILL)
285 os.kill(pid, signal.SIGKILL)
304 except OSError:
286 except OSError:
305 # This is just a best effort, if we fail or the process was
287 # This is just a best effort, if we fail or the process was
306 # really gone, ignore it.
288 # really gone, ignore it.
307 pass
289 pass
308
290
309
291
310 def make_runners():
292 def make_runners():
311 """Define the top-level packages that need to be tested.
293 """Define the top-level packages that need to be tested.
312 """
294 """
313
295
314 # Packages to be tested via nose, that only depend on the stdlib
296 # Packages to be tested via nose, that only depend on the stdlib
315 nose_pkg_names = ['config', 'core', 'extensions', 'frontend', 'lib',
297 nose_pkg_names = ['config', 'core', 'extensions', 'frontend', 'lib',
316 'scripts', 'testing', 'utils' ]
298 'scripts', 'testing', 'utils' ]
317 # The machinery in kernel needs twisted for real testing
299 # The machinery in kernel needs twisted for real testing
318 trial_pkg_names = []
300 trial_pkg_names = []
319
301
320 if have['wx']:
321 nose_pkg_names.append('gui')
322
323 # And add twisted ones if conditions are met
302 # And add twisted ones if conditions are met
324 if have['zope.interface'] and have['twisted'] and have['foolscap']:
303 if have['zope.interface'] and have['twisted'] and have['foolscap']:
325 # We only list IPython.kernel for testing using twisted.trial as
304 # We only list IPython.kernel for testing using twisted.trial as
326 # nose and twisted.trial have conflicts that make the testing system
305 # nose and twisted.trial have conflicts that make the testing system
327 # unstable.
306 # unstable.
328 trial_pkg_names.append('kernel')
307 trial_pkg_names.append('kernel')
329
308
330 # For debugging this code, only load quick stuff
309 # For debugging this code, only load quick stuff
331 #nose_pkg_names = ['core', 'extensions'] # dbg
310 #nose_pkg_names = ['core', 'extensions'] # dbg
332 #trial_pkg_names = [] # dbg
311 #trial_pkg_names = [] # dbg
333
312
334 # Make fully qualified package names prepending 'IPython.' to our name lists
313 # Make fully qualified package names prepending 'IPython.' to our name lists
335 nose_packages = ['IPython.%s' % m for m in nose_pkg_names ]
314 nose_packages = ['IPython.%s' % m for m in nose_pkg_names ]
336 trial_packages = ['IPython.%s' % m for m in trial_pkg_names ]
315 trial_packages = ['IPython.%s' % m for m in trial_pkg_names ]
337
316
338 # Make runners
317 # Make runners
339 runners = [ (v, IPTester('iptest', params=v)) for v in nose_packages ]
318 runners = [ (v, IPTester('iptest', params=v)) for v in nose_packages ]
340 runners.extend([ (v, IPTester('trial', params=v)) for v in trial_packages ])
319 runners.extend([ (v, IPTester('trial', params=v)) for v in trial_packages ])
341
320
342 return runners
321 return runners
343
322
344
323
345 def run_iptest():
324 def run_iptest():
346 """Run the IPython test suite using nose.
325 """Run the IPython test suite using nose.
347
326
348 This function is called when this script is **not** called with the form
327 This function is called when this script is **not** called with the form
349 `iptest all`. It simply calls nose with appropriate command line flags
328 `iptest all`. It simply calls nose with appropriate command line flags
350 and accepts all of the standard nose arguments.
329 and accepts all of the standard nose arguments.
351 """
330 """
352
331
353 warnings.filterwarnings('ignore',
332 warnings.filterwarnings('ignore',
354 'This will be removed soon. Use IPython.testing.util instead')
333 'This will be removed soon. Use IPython.testing.util instead')
355
334
356 argv = sys.argv + [ '--detailed-errors', # extra info in tracebacks
335 argv = sys.argv + [ '--detailed-errors', # extra info in tracebacks
357
336
358 # Loading ipdoctest causes problems with Twisted, but
337 # Loading ipdoctest causes problems with Twisted, but
359 # our test suite runner now separates things and runs
338 # our test suite runner now separates things and runs
360 # all Twisted tests with trial.
339 # all Twisted tests with trial.
361 '--with-ipdoctest',
340 '--with-ipdoctest',
362 '--ipdoctest-tests','--ipdoctest-extension=txt',
341 '--ipdoctest-tests','--ipdoctest-extension=txt',
363
342
364 # We add --exe because of setuptools' imbecility (it
343 # We add --exe because of setuptools' imbecility (it
365 # blindly does chmod +x on ALL files). Nose does the
344 # blindly does chmod +x on ALL files). Nose does the
366 # right thing and it tries to avoid executables,
345 # right thing and it tries to avoid executables,
367 # setuptools unfortunately forces our hand here. This
346 # setuptools unfortunately forces our hand here. This
368 # has been discussed on the distutils list and the
347 # has been discussed on the distutils list and the
369 # setuptools devs refuse to fix this problem!
348 # setuptools devs refuse to fix this problem!
370 '--exe',
349 '--exe',
371 ]
350 ]
372
351
373 if nose.__version__ >= '0.11':
352 if nose.__version__ >= '0.11':
374 # I don't fully understand why we need this one, but depending on what
353 # I don't fully understand why we need this one, but depending on what
375 # directory the test suite is run from, if we don't give it, 0 tests
354 # directory the test suite is run from, if we don't give it, 0 tests
376 # get run. Specifically, if the test suite is run from the source dir
355 # get run. Specifically, if the test suite is run from the source dir
377 # with an argument (like 'iptest.py IPython.core', 0 tests are run,
356 # with an argument (like 'iptest.py IPython.core', 0 tests are run,
378 # even if the same call done in this directory works fine). It appears
357 # even if the same call done in this directory works fine). It appears
379 # that if the requested package is in the current dir, nose bails early
358 # that if the requested package is in the current dir, nose bails early
380 # by default. Since it's otherwise harmless, leave it in by default
359 # by default. Since it's otherwise harmless, leave it in by default
381 # for nose >= 0.11, though unfortunately nose 0.10 doesn't support it.
360 # for nose >= 0.11, though unfortunately nose 0.10 doesn't support it.
382 argv.append('--traverse-namespace')
361 argv.append('--traverse-namespace')
383
362
384 # Construct list of plugins, omitting the existing doctest plugin, which
363 # Construct list of plugins, omitting the existing doctest plugin, which
385 # ours replaces (and extends).
364 # ours replaces (and extends).
386 plugins = [IPythonDoctest(make_exclude())]
365 plugins = [IPythonDoctest(make_exclude())]
387 for p in nose.plugins.builtin.plugins:
366 for p in nose.plugins.builtin.plugins:
388 plug = p()
367 plug = p()
389 if plug.name == 'doctest':
368 if plug.name == 'doctest':
390 continue
369 continue
391 plugins.append(plug)
370 plugins.append(plug)
392
371
393 # We need a global ipython running in this process
372 # We need a global ipython running in this process
394 globalipapp.start_ipython()
373 globalipapp.start_ipython()
395 # Now nose can run
374 # Now nose can run
396 TestProgram(argv=argv, plugins=plugins)
375 TestProgram(argv=argv, plugins=plugins)
397
376
398
377
399 def run_iptestall():
378 def run_iptestall():
400 """Run the entire IPython test suite by calling nose and trial.
379 """Run the entire IPython test suite by calling nose and trial.
401
380
402 This function constructs :class:`IPTester` instances for all IPython
381 This function constructs :class:`IPTester` instances for all IPython
403 modules and package and then runs each of them. This causes the modules
382 modules and package and then runs each of them. This causes the modules
404 and packages of IPython to be tested each in their own subprocess using
383 and packages of IPython to be tested each in their own subprocess using
405 nose or twisted.trial appropriately.
384 nose or twisted.trial appropriately.
406 """
385 """
407
386
408 runners = make_runners()
387 runners = make_runners()
409
388
410 # Run the test runners in a temporary dir so we can nuke it when finished
389 # Run the test runners in a temporary dir so we can nuke it when finished
411 # to clean up any junk files left over by accident. This also makes it
390 # to clean up any junk files left over by accident. This also makes it
412 # robust against being run in non-writeable directories by mistake, as the
391 # robust against being run in non-writeable directories by mistake, as the
413 # temp dir will always be user-writeable.
392 # temp dir will always be user-writeable.
414 curdir = os.getcwd()
393 curdir = os.getcwd()
415 testdir = tempfile.gettempdir()
394 testdir = tempfile.gettempdir()
416 os.chdir(testdir)
395 os.chdir(testdir)
417
396
418 # Run all test runners, tracking execution time
397 # Run all test runners, tracking execution time
419 failed = []
398 failed = []
420 t_start = time.time()
399 t_start = time.time()
421 try:
400 try:
422 for (name, runner) in runners:
401 for (name, runner) in runners:
423 print '*'*70
402 print '*'*70
424 print 'IPython test group:',name
403 print 'IPython test group:',name
425 res = runner.run()
404 res = runner.run()
426 if res:
405 if res:
427 failed.append( (name, runner) )
406 failed.append( (name, runner) )
428 finally:
407 finally:
429 os.chdir(curdir)
408 os.chdir(curdir)
430 t_end = time.time()
409 t_end = time.time()
431 t_tests = t_end - t_start
410 t_tests = t_end - t_start
432 nrunners = len(runners)
411 nrunners = len(runners)
433 nfail = len(failed)
412 nfail = len(failed)
434 # summarize results
413 # summarize results
435 print
414 print
436 print '*'*70
415 print '*'*70
437 print 'Test suite completed for system with the following information:'
416 print 'Test suite completed for system with the following information:'
438 print report()
417 print report()
439 print 'Ran %s test groups in %.3fs' % (nrunners, t_tests)
418 print 'Ran %s test groups in %.3fs' % (nrunners, t_tests)
440 print
419 print
441 print 'Status:'
420 print 'Status:'
442 if not failed:
421 if not failed:
443 print 'OK'
422 print 'OK'
444 else:
423 else:
445 # If anything went wrong, point out what command to rerun manually to
424 # If anything went wrong, point out what command to rerun manually to
446 # see the actual errors and individual summary
425 # see the actual errors and individual summary
447 print 'ERROR - %s out of %s test groups failed.' % (nfail, nrunners)
426 print 'ERROR - %s out of %s test groups failed.' % (nfail, nrunners)
448 for name, failed_runner in failed:
427 for name, failed_runner in failed:
449 print '-'*40
428 print '-'*40
450 print 'Runner failed:',name
429 print 'Runner failed:',name
451 print 'You may wish to rerun this one individually, with:'
430 print 'You may wish to rerun this one individually, with:'
452 print ' '.join(failed_runner.call_args)
431 print ' '.join(failed_runner.call_args)
453 print
432 print
454
433
455
434
456 def main():
435 def main():
457 for arg in sys.argv[1:]:
436 for arg in sys.argv[1:]:
458 if arg.startswith('IPython'):
437 if arg.startswith('IPython'):
459 # This is in-process
438 # This is in-process
460 run_iptest()
439 run_iptest()
461 else:
440 else:
462 # This starts subprocesses
441 # This starts subprocesses
463 run_iptestall()
442 run_iptestall()
464
443
465
444
466 if __name__ == '__main__':
445 if __name__ == '__main__':
467 main()
446 main()
@@ -1,320 +1,310 b''
1 # encoding: utf-8
1 # encoding: utf-8
2
2
3 """
3 """
4 This module defines the things that are used in setup.py for building IPython
4 This module defines the things that are used in setup.py for building IPython
5
5
6 This includes:
6 This includes:
7
7
8 * The basic arguments to setup
8 * The basic arguments to setup
9 * Functions for finding things like packages, package data, etc.
9 * Functions for finding things like packages, package data, etc.
10 * A function for checking dependencies.
10 * A function for checking dependencies.
11 """
11 """
12
12
13 __docformat__ = "restructuredtext en"
13 __docformat__ = "restructuredtext en"
14
14
15 #-------------------------------------------------------------------------------
15 #-------------------------------------------------------------------------------
16 # Copyright (C) 2008 The IPython Development Team
16 # Copyright (C) 2008 The IPython Development Team
17 #
17 #
18 # Distributed under the terms of the BSD License. The full license is in
18 # Distributed under the terms of the BSD License. The full license is in
19 # the file COPYING, distributed as part of this software.
19 # the file COPYING, distributed as part of this software.
20 #-------------------------------------------------------------------------------
20 #-------------------------------------------------------------------------------
21
21
22 #-------------------------------------------------------------------------------
22 #-------------------------------------------------------------------------------
23 # Imports
23 # Imports
24 #-------------------------------------------------------------------------------
24 #-------------------------------------------------------------------------------
25
25
26 import os, sys
26 import os, sys
27
27
28 from glob import glob
28 from glob import glob
29
29
30 from setupext import install_data_ext
30 from setupext import install_data_ext
31
31
32 #-------------------------------------------------------------------------------
32 #-------------------------------------------------------------------------------
33 # Useful globals and utility functions
33 # Useful globals and utility functions
34 #-------------------------------------------------------------------------------
34 #-------------------------------------------------------------------------------
35
35
36 # A few handy globals
36 # A few handy globals
37 isfile = os.path.isfile
37 isfile = os.path.isfile
38 pjoin = os.path.join
38 pjoin = os.path.join
39
39
40 def oscmd(s):
40 def oscmd(s):
41 print ">", s
41 print ">", s
42 os.system(s)
42 os.system(s)
43
43
44 # A little utility we'll need below, since glob() does NOT allow you to do
44 # A little utility we'll need below, since glob() does NOT allow you to do
45 # exclusion on multiple endings!
45 # exclusion on multiple endings!
46 def file_doesnt_endwith(test,endings):
46 def file_doesnt_endwith(test,endings):
47 """Return true if test is a file and its name does NOT end with any
47 """Return true if test is a file and its name does NOT end with any
48 of the strings listed in endings."""
48 of the strings listed in endings."""
49 if not isfile(test):
49 if not isfile(test):
50 return False
50 return False
51 for e in endings:
51 for e in endings:
52 if test.endswith(e):
52 if test.endswith(e):
53 return False
53 return False
54 return True
54 return True
55
55
56 #---------------------------------------------------------------------------
56 #---------------------------------------------------------------------------
57 # Basic project information
57 # Basic project information
58 #---------------------------------------------------------------------------
58 #---------------------------------------------------------------------------
59
59
60 # release.py contains version, authors, license, url, keywords, etc.
60 # release.py contains version, authors, license, url, keywords, etc.
61 execfile(pjoin('IPython','core','release.py'))
61 execfile(pjoin('IPython','core','release.py'))
62
62
63 # Create a dict with the basic information
63 # Create a dict with the basic information
64 # This dict is eventually passed to setup after additional keys are added.
64 # This dict is eventually passed to setup after additional keys are added.
65 setup_args = dict(
65 setup_args = dict(
66 name = name,
66 name = name,
67 version = version,
67 version = version,
68 description = description,
68 description = description,
69 long_description = long_description,
69 long_description = long_description,
70 author = author,
70 author = author,
71 author_email = author_email,
71 author_email = author_email,
72 url = url,
72 url = url,
73 download_url = download_url,
73 download_url = download_url,
74 license = license,
74 license = license,
75 platforms = platforms,
75 platforms = platforms,
76 keywords = keywords,
76 keywords = keywords,
77 cmdclass = {'install_data': install_data_ext},
77 cmdclass = {'install_data': install_data_ext},
78 )
78 )
79
79
80
80
81 #---------------------------------------------------------------------------
81 #---------------------------------------------------------------------------
82 # Find packages
82 # Find packages
83 #---------------------------------------------------------------------------
83 #---------------------------------------------------------------------------
84
84
85 def add_package(packages,pname,config=False,tests=False,scripts=False,
85 def add_package(packages,pname,config=False,tests=False,scripts=False,
86 others=None):
86 others=None):
87 """
87 """
88 Add a package to the list of packages, including certain subpackages.
88 Add a package to the list of packages, including certain subpackages.
89 """
89 """
90 packages.append('.'.join(['IPython',pname]))
90 packages.append('.'.join(['IPython',pname]))
91 if config:
91 if config:
92 packages.append('.'.join(['IPython',pname,'config']))
92 packages.append('.'.join(['IPython',pname,'config']))
93 if tests:
93 if tests:
94 packages.append('.'.join(['IPython',pname,'tests']))
94 packages.append('.'.join(['IPython',pname,'tests']))
95 if scripts:
95 if scripts:
96 packages.append('.'.join(['IPython',pname,'scripts']))
96 packages.append('.'.join(['IPython',pname,'scripts']))
97 if others is not None:
97 if others is not None:
98 for o in others:
98 for o in others:
99 packages.append('.'.join(['IPython',pname,o]))
99 packages.append('.'.join(['IPython',pname,o]))
100
100
101 def find_packages():
101 def find_packages():
102 """
102 """
103 Find all of IPython's packages.
103 Find all of IPython's packages.
104 """
104 """
105 packages = ['IPython']
105 packages = ['IPython']
106 add_package(packages, 'config', tests=True, others=['default','profile'])
106 add_package(packages, 'config', tests=True, others=['default','profile'])
107 add_package(packages, 'core', tests=True)
107 add_package(packages, 'core', tests=True)
108 add_package(packages, 'deathrow', tests=True)
108 add_package(packages, 'deathrow', tests=True)
109 add_package(packages , 'extensions')
109 add_package(packages , 'extensions')
110 add_package(packages, 'external')
110 add_package(packages, 'external')
111 add_package(packages, 'frontend', tests=True)
111 add_package(packages, 'frontend')
112 # Don't include the cocoa frontend for now as it is not stable
113 if sys.platform == 'darwin' and False:
114 add_package(packages, 'frontend.cocoa', tests=True, others=['plugin'])
115 add_package(packages, 'frontend.cocoa.examples')
116 add_package(packages, 'frontend.cocoa.examples.IPython1Sandbox')
117 add_package(packages, 'frontend.cocoa.examples.IPython1Sandbox.English.lproj')
118 add_package(packages, 'frontend.process')
119 add_package(packages, 'frontend.wx')
120 add_package(packages, 'gui')
121 add_package(packages, 'gui.wx')
122 add_package(packages, 'kernel', config=False, tests=True, scripts=True)
112 add_package(packages, 'kernel', config=False, tests=True, scripts=True)
123 add_package(packages, 'kernel.core', config=False, tests=True)
113 add_package(packages, 'kernel.core', config=False, tests=True)
124 add_package(packages, 'lib', tests=True)
114 add_package(packages, 'lib', tests=True)
125 add_package(packages, 'quarantine', tests=True)
115 add_package(packages, 'quarantine', tests=True)
126 add_package(packages, 'scripts')
116 add_package(packages, 'scripts')
127 add_package(packages, 'testing', tests=True)
117 add_package(packages, 'testing', tests=True)
128 add_package(packages, 'testing.plugin', tests=False)
118 add_package(packages, 'testing.plugin', tests=False)
129 add_package(packages, 'utils', tests=True)
119 add_package(packages, 'utils', tests=True)
130 return packages
120 return packages
131
121
132 #---------------------------------------------------------------------------
122 #---------------------------------------------------------------------------
133 # Find package data
123 # Find package data
134 #---------------------------------------------------------------------------
124 #---------------------------------------------------------------------------
135
125
136 def find_package_data():
126 def find_package_data():
137 """
127 """
138 Find IPython's package_data.
128 Find IPython's package_data.
139 """
129 """
140 # This is not enough for these things to appear in an sdist.
130 # This is not enough for these things to appear in an sdist.
141 # We need to muck with the MANIFEST to get this to work
131 # We need to muck with the MANIFEST to get this to work
142 package_data = {
132 package_data = {
143 'IPython.config.userconfig' : ['*'],
133 'IPython.config.userconfig' : ['*'],
144 'IPython.testing' : ['*.txt']
134 'IPython.testing' : ['*.txt']
145 }
135 }
146 return package_data
136 return package_data
147
137
148
138
149 #---------------------------------------------------------------------------
139 #---------------------------------------------------------------------------
150 # Find data files
140 # Find data files
151 #---------------------------------------------------------------------------
141 #---------------------------------------------------------------------------
152
142
153 def make_dir_struct(tag,base,out_base):
143 def make_dir_struct(tag,base,out_base):
154 """Make the directory structure of all files below a starting dir.
144 """Make the directory structure of all files below a starting dir.
155
145
156 This is just a convenience routine to help build a nested directory
146 This is just a convenience routine to help build a nested directory
157 hierarchy because distutils is too stupid to do this by itself.
147 hierarchy because distutils is too stupid to do this by itself.
158
148
159 XXX - this needs a proper docstring!
149 XXX - this needs a proper docstring!
160 """
150 """
161
151
162 # we'll use these a lot below
152 # we'll use these a lot below
163 lbase = len(base)
153 lbase = len(base)
164 pathsep = os.path.sep
154 pathsep = os.path.sep
165 lpathsep = len(pathsep)
155 lpathsep = len(pathsep)
166
156
167 out = []
157 out = []
168 for (dirpath,dirnames,filenames) in os.walk(base):
158 for (dirpath,dirnames,filenames) in os.walk(base):
169 # we need to strip out the dirpath from the base to map it to the
159 # we need to strip out the dirpath from the base to map it to the
170 # output (installation) path. This requires possibly stripping the
160 # output (installation) path. This requires possibly stripping the
171 # path separator, because otherwise pjoin will not work correctly
161 # path separator, because otherwise pjoin will not work correctly
172 # (pjoin('foo/','/bar') returns '/bar').
162 # (pjoin('foo/','/bar') returns '/bar').
173
163
174 dp_eff = dirpath[lbase:]
164 dp_eff = dirpath[lbase:]
175 if dp_eff.startswith(pathsep):
165 if dp_eff.startswith(pathsep):
176 dp_eff = dp_eff[lpathsep:]
166 dp_eff = dp_eff[lpathsep:]
177 # The output path must be anchored at the out_base marker
167 # The output path must be anchored at the out_base marker
178 out_path = pjoin(out_base,dp_eff)
168 out_path = pjoin(out_base,dp_eff)
179 # Now we can generate the final filenames. Since os.walk only produces
169 # Now we can generate the final filenames. Since os.walk only produces
180 # filenames, we must join back with the dirpath to get full valid file
170 # filenames, we must join back with the dirpath to get full valid file
181 # paths:
171 # paths:
182 pfiles = [pjoin(dirpath,f) for f in filenames]
172 pfiles = [pjoin(dirpath,f) for f in filenames]
183 # Finally, generate the entry we need, which is a triple of (tag,output
173 # Finally, generate the entry we need, which is a triple of (tag,output
184 # path, files) for use as a data_files parameter in install_data.
174 # path, files) for use as a data_files parameter in install_data.
185 out.append((tag,out_path,pfiles))
175 out.append((tag,out_path,pfiles))
186
176
187 return out
177 return out
188
178
189
179
190 def find_data_files():
180 def find_data_files():
191 """
181 """
192 Find IPython's data_files.
182 Find IPython's data_files.
193
183
194 Most of these are docs.
184 Most of these are docs.
195 """
185 """
196
186
197 docdirbase = pjoin('share', 'doc', 'ipython')
187 docdirbase = pjoin('share', 'doc', 'ipython')
198 manpagebase = pjoin('share', 'man', 'man1')
188 manpagebase = pjoin('share', 'man', 'man1')
199
189
200 # Simple file lists can be made by hand
190 # Simple file lists can be made by hand
201 manpages = filter(isfile, glob(pjoin('docs','man','*.1.gz')))
191 manpages = filter(isfile, glob(pjoin('docs','man','*.1.gz')))
202 igridhelpfiles = filter(isfile, glob(pjoin('IPython','extensions','igrid_help.*')))
192 igridhelpfiles = filter(isfile, glob(pjoin('IPython','extensions','igrid_help.*')))
203
193
204 # For nested structures, use the utility above
194 # For nested structures, use the utility above
205 example_files = make_dir_struct(
195 example_files = make_dir_struct(
206 'data',
196 'data',
207 pjoin('docs','examples'),
197 pjoin('docs','examples'),
208 pjoin(docdirbase,'examples')
198 pjoin(docdirbase,'examples')
209 )
199 )
210 manual_files = make_dir_struct(
200 manual_files = make_dir_struct(
211 'data',
201 'data',
212 pjoin('docs','dist'),
202 pjoin('docs','dist'),
213 pjoin(docdirbase,'manual')
203 pjoin(docdirbase,'manual')
214 )
204 )
215
205
216 # And assemble the entire output list
206 # And assemble the entire output list
217 data_files = [ ('data',manpagebase, manpages),
207 data_files = [ ('data',manpagebase, manpages),
218 ('data',pjoin(docdirbase,'extensions'),igridhelpfiles),
208 ('data',pjoin(docdirbase,'extensions'),igridhelpfiles),
219 ] + manual_files + example_files
209 ] + manual_files + example_files
220
210
221 ## import pprint # dbg
211 ## import pprint # dbg
222 ## print '*'*80
212 ## print '*'*80
223 ## print 'data files'
213 ## print 'data files'
224 ## pprint.pprint(data_files)
214 ## pprint.pprint(data_files)
225 ## print '*'*80
215 ## print '*'*80
226
216
227 return data_files
217 return data_files
228
218
229
219
230 def make_man_update_target(manpage):
220 def make_man_update_target(manpage):
231 """Return a target_update-compliant tuple for the given manpage.
221 """Return a target_update-compliant tuple for the given manpage.
232
222
233 Parameters
223 Parameters
234 ----------
224 ----------
235 manpage : string
225 manpage : string
236 Name of the manpage, must include the section number (trailing number).
226 Name of the manpage, must include the section number (trailing number).
237
227
238 Example
228 Example
239 -------
229 -------
240
230
241 >>> make_man_update_target('ipython.1') #doctest: +NORMALIZE_WHITESPACE
231 >>> make_man_update_target('ipython.1') #doctest: +NORMALIZE_WHITESPACE
242 ('docs/man/ipython.1.gz',
232 ('docs/man/ipython.1.gz',
243 ['docs/man/ipython.1'],
233 ['docs/man/ipython.1'],
244 'cd docs/man && gzip -9c ipython.1 > ipython.1.gz')
234 'cd docs/man && gzip -9c ipython.1 > ipython.1.gz')
245 """
235 """
246 man_dir = pjoin('docs', 'man')
236 man_dir = pjoin('docs', 'man')
247 manpage_gz = manpage + '.gz'
237 manpage_gz = manpage + '.gz'
248 manpath = pjoin(man_dir, manpage)
238 manpath = pjoin(man_dir, manpage)
249 manpath_gz = pjoin(man_dir, manpage_gz)
239 manpath_gz = pjoin(man_dir, manpage_gz)
250 gz_cmd = ( "cd %(man_dir)s && gzip -9c %(manpage)s > %(manpage_gz)s" %
240 gz_cmd = ( "cd %(man_dir)s && gzip -9c %(manpage)s > %(manpage_gz)s" %
251 locals() )
241 locals() )
252 return (manpath_gz, [manpath], gz_cmd)
242 return (manpath_gz, [manpath], gz_cmd)
253
243
254 #---------------------------------------------------------------------------
244 #---------------------------------------------------------------------------
255 # Find scripts
245 # Find scripts
256 #---------------------------------------------------------------------------
246 #---------------------------------------------------------------------------
257
247
258 def find_scripts():
248 def find_scripts():
259 """
249 """
260 Find IPython's scripts.
250 Find IPython's scripts.
261 """
251 """
262 kernel_scripts = pjoin('IPython','kernel','scripts')
252 kernel_scripts = pjoin('IPython','kernel','scripts')
263 main_scripts = pjoin('IPython','scripts')
253 main_scripts = pjoin('IPython','scripts')
264 scripts = [pjoin(kernel_scripts, 'ipengine'),
254 scripts = [pjoin(kernel_scripts, 'ipengine'),
265 pjoin(kernel_scripts, 'ipcontroller'),
255 pjoin(kernel_scripts, 'ipcontroller'),
266 pjoin(kernel_scripts, 'ipcluster'),
256 pjoin(kernel_scripts, 'ipcluster'),
267 pjoin(main_scripts, 'ipython'),
257 pjoin(main_scripts, 'ipython'),
268 pjoin(main_scripts, 'ipythonx'),
258 pjoin(main_scripts, 'ipythonx'),
269 pjoin(main_scripts, 'ipython-wx'),
259 pjoin(main_scripts, 'ipython-wx'),
270 pjoin(main_scripts, 'pycolor'),
260 pjoin(main_scripts, 'pycolor'),
271 pjoin(main_scripts, 'irunner'),
261 pjoin(main_scripts, 'irunner'),
272 pjoin(main_scripts, 'iptest')
262 pjoin(main_scripts, 'iptest')
273 ]
263 ]
274
264
275 # Script to be run by the windows binary installer after the default setup
265 # Script to be run by the windows binary installer after the default setup
276 # routine, to add shortcuts and similar windows-only things. Windows
266 # routine, to add shortcuts and similar windows-only things. Windows
277 # post-install scripts MUST reside in the scripts/ dir, otherwise distutils
267 # post-install scripts MUST reside in the scripts/ dir, otherwise distutils
278 # doesn't find them.
268 # doesn't find them.
279 if 'bdist_wininst' in sys.argv:
269 if 'bdist_wininst' in sys.argv:
280 if len(sys.argv) > 2 and ('sdist' in sys.argv or 'bdist_rpm' in sys.argv):
270 if len(sys.argv) > 2 and ('sdist' in sys.argv or 'bdist_rpm' in sys.argv):
281 print >> sys.stderr,"ERROR: bdist_wininst must be run alone. Exiting."
271 print >> sys.stderr,"ERROR: bdist_wininst must be run alone. Exiting."
282 sys.exit(1)
272 sys.exit(1)
283 scripts.append(pjoin('scripts','ipython_win_post_install.py'))
273 scripts.append(pjoin('scripts','ipython_win_post_install.py'))
284
274
285 return scripts
275 return scripts
286
276
287 #---------------------------------------------------------------------------
277 #---------------------------------------------------------------------------
288 # Verify all dependencies
278 # Verify all dependencies
289 #---------------------------------------------------------------------------
279 #---------------------------------------------------------------------------
290
280
291 def check_for_dependencies():
281 def check_for_dependencies():
292 """Check for IPython's dependencies.
282 """Check for IPython's dependencies.
293
283
294 This function should NOT be called if running under setuptools!
284 This function should NOT be called if running under setuptools!
295 """
285 """
296 from setupext.setupext import (
286 from setupext.setupext import (
297 print_line, print_raw, print_status, print_message,
287 print_line, print_raw, print_status, print_message,
298 check_for_zopeinterface, check_for_twisted,
288 check_for_zopeinterface, check_for_twisted,
299 check_for_foolscap, check_for_pyopenssl,
289 check_for_foolscap, check_for_pyopenssl,
300 check_for_sphinx, check_for_pygments,
290 check_for_sphinx, check_for_pygments,
301 check_for_nose, check_for_pexpect
291 check_for_nose, check_for_pexpect
302 )
292 )
303 print_line()
293 print_line()
304 print_raw("BUILDING IPYTHON")
294 print_raw("BUILDING IPYTHON")
305 print_status('python', sys.version)
295 print_status('python', sys.version)
306 print_status('platform', sys.platform)
296 print_status('platform', sys.platform)
307 if sys.platform == 'win32':
297 if sys.platform == 'win32':
308 print_status('Windows version', sys.getwindowsversion())
298 print_status('Windows version', sys.getwindowsversion())
309
299
310 print_raw("")
300 print_raw("")
311 print_raw("OPTIONAL DEPENDENCIES")
301 print_raw("OPTIONAL DEPENDENCIES")
312
302
313 check_for_zopeinterface()
303 check_for_zopeinterface()
314 check_for_twisted()
304 check_for_twisted()
315 check_for_foolscap()
305 check_for_foolscap()
316 check_for_pyopenssl()
306 check_for_pyopenssl()
317 check_for_sphinx()
307 check_for_sphinx()
318 check_for_pygments()
308 check_for_pygments()
319 check_for_nose()
309 check_for_nose()
320 check_for_pexpect()
310 check_for_pexpect()
General Comments 0
You need to be logged in to leave comments. Login now