Show More
@@ -0,0 +1,155 b'' | |||
|
1 | # encoding: utf-8 | |
|
2 | ||
|
3 | """This file contains unittests for the frontendbase module.""" | |
|
4 | ||
|
5 | __docformat__ = "restructuredtext en" | |
|
6 | ||
|
7 | #--------------------------------------------------------------------------- | |
|
8 | # Copyright (C) 2008 The IPython Development Team | |
|
9 | # | |
|
10 | # Distributed under the terms of the BSD License. The full license is in | |
|
11 | # the file COPYING, distributed as part of this software. | |
|
12 | #--------------------------------------------------------------------------- | |
|
13 | ||
|
14 | #--------------------------------------------------------------------------- | |
|
15 | # Imports | |
|
16 | #--------------------------------------------------------------------------- | |
|
17 | ||
|
18 | import unittest | |
|
19 | ||
|
20 | try: | |
|
21 | from IPython.frontend.asyncfrontendbase import AsyncFrontEndBase | |
|
22 | from IPython.frontend import frontendbase | |
|
23 | from IPython.kernel.engineservice import EngineService | |
|
24 | except ImportError: | |
|
25 | import nose | |
|
26 | raise nose.SkipTest("This test requires zope.interface, Twisted and Foolscap") | |
|
27 | ||
|
28 | from IPython.testing.decorators import skip | |
|
29 | ||
|
30 | class FrontEndCallbackChecker(AsyncFrontEndBase): | |
|
31 | """FrontEndBase subclass for checking callbacks""" | |
|
32 | def __init__(self, engine=None, history=None): | |
|
33 | super(FrontEndCallbackChecker, self).__init__(engine=engine, | |
|
34 | history=history) | |
|
35 | self.updateCalled = False | |
|
36 | self.renderResultCalled = False | |
|
37 | self.renderErrorCalled = False | |
|
38 | ||
|
39 | def update_cell_prompt(self, result, blockID=None): | |
|
40 | self.updateCalled = True | |
|
41 | return result | |
|
42 | ||
|
43 | def render_result(self, result): | |
|
44 | self.renderResultCalled = True | |
|
45 | return result | |
|
46 | ||
|
47 | ||
|
48 | def render_error(self, failure): | |
|
49 | self.renderErrorCalled = True | |
|
50 | return failure | |
|
51 | ||
|
52 | ||
|
53 | ||
|
54 | ||
|
55 | class TestAsyncFrontendBase(unittest.TestCase): | |
|
56 | def setUp(self): | |
|
57 | """Setup the EngineService and FrontEndBase""" | |
|
58 | ||
|
59 | self.fb = FrontEndCallbackChecker(engine=EngineService()) | |
|
60 | ||
|
61 | def test_implements_IFrontEnd(self): | |
|
62 | assert(frontendbase.IFrontEnd.implementedBy( | |
|
63 | AsyncFrontEndBase)) | |
|
64 | ||
|
65 | def test_is_complete_returns_False_for_incomplete_block(self): | |
|
66 | """""" | |
|
67 | ||
|
68 | block = """def test(a):""" | |
|
69 | ||
|
70 | assert(self.fb.is_complete(block) == False) | |
|
71 | ||
|
72 | def test_is_complete_returns_True_for_complete_block(self): | |
|
73 | """""" | |
|
74 | ||
|
75 | block = """def test(a): pass""" | |
|
76 | ||
|
77 | assert(self.fb.is_complete(block)) | |
|
78 | ||
|
79 | block = """a=3""" | |
|
80 | ||
|
81 | assert(self.fb.is_complete(block)) | |
|
82 | ||
|
83 | def test_blockID_added_to_result(self): | |
|
84 | block = """3+3""" | |
|
85 | ||
|
86 | d = self.fb.execute(block, blockID='TEST_ID') | |
|
87 | ||
|
88 | d.addCallback(self.checkBlockID, expected='TEST_ID') | |
|
89 | ||
|
90 | def test_blockID_added_to_failure(self): | |
|
91 | block = "raise Exception()" | |
|
92 | ||
|
93 | d = self.fb.execute(block,blockID='TEST_ID') | |
|
94 | d.addErrback(self.checkFailureID, expected='TEST_ID') | |
|
95 | ||
|
96 | def checkBlockID(self, result, expected=""): | |
|
97 | assert(result['blockID'] == expected) | |
|
98 | ||
|
99 | ||
|
100 | def checkFailureID(self, failure, expected=""): | |
|
101 | assert(failure.blockID == expected) | |
|
102 | ||
|
103 | ||
|
104 | def test_callbacks_added_to_execute(self): | |
|
105 | """test that | |
|
106 | update_cell_prompt | |
|
107 | render_result | |
|
108 | ||
|
109 | are added to execute request | |
|
110 | """ | |
|
111 | ||
|
112 | d = self.fb.execute("10+10") | |
|
113 | d.addCallback(self.checkCallbacks) | |
|
114 | ||
|
115 | def checkCallbacks(self, result): | |
|
116 | assert(self.fb.updateCalled) | |
|
117 | assert(self.fb.renderResultCalled) | |
|
118 | ||
|
119 | @skip("This test fails and lead to an unhandled error in a Deferred.") | |
|
120 | def test_error_callback_added_to_execute(self): | |
|
121 | """test that render_error called on execution error""" | |
|
122 | ||
|
123 | d = self.fb.execute("raise Exception()") | |
|
124 | d.addCallback(self.checkRenderError) | |
|
125 | ||
|
126 | def checkRenderError(self, result): | |
|
127 | assert(self.fb.renderErrorCalled) | |
|
128 | ||
|
129 | def test_history_returns_expected_block(self): | |
|
130 | """Make sure history browsing doesn't fail""" | |
|
131 | ||
|
132 | blocks = ["a=1","a=2","a=3"] | |
|
133 | for b in blocks: | |
|
134 | d = self.fb.execute(b) | |
|
135 | ||
|
136 | # d is now the deferred for the last executed block | |
|
137 | d.addCallback(self.historyTests, blocks) | |
|
138 | ||
|
139 | ||
|
140 | def historyTests(self, result, blocks): | |
|
141 | """historyTests""" | |
|
142 | ||
|
143 | assert(len(blocks) >= 3) | |
|
144 | assert(self.fb.get_history_previous("") == blocks[-2]) | |
|
145 | assert(self.fb.get_history_previous("") == blocks[-3]) | |
|
146 | assert(self.fb.get_history_next() == blocks[-2]) | |
|
147 | ||
|
148 | ||
|
149 | def test_history_returns_none_at_startup(self): | |
|
150 | """test_history_returns_none_at_startup""" | |
|
151 | ||
|
152 | assert(self.fb.get_history_previous("")==None) | |
|
153 | assert(self.fb.get_history_next()==None) | |
|
154 | ||
|
155 |
@@ -0,0 +1,161 b'' | |||
|
1 | """Tests for the decorators we've created for IPython. | |
|
2 | """ | |
|
3 | ||
|
4 | # Module imports | |
|
5 | # Std lib | |
|
6 | import inspect | |
|
7 | import sys | |
|
8 | ||
|
9 | # Third party | |
|
10 | import nose.tools as nt | |
|
11 | ||
|
12 | # Our own | |
|
13 | from IPython.testing import decorators as dec | |
|
14 | ||
|
15 | ||
|
16 | #----------------------------------------------------------------------------- | |
|
17 | # Utilities | |
|
18 | ||
|
19 | # Note: copied from OInspect, kept here so the testing stuff doesn't create | |
|
20 | # circular dependencies and is easier to reuse. | |
|
21 | def getargspec(obj): | |
|
22 | """Get the names and default values of a function's arguments. | |
|
23 | ||
|
24 | A tuple of four things is returned: (args, varargs, varkw, defaults). | |
|
25 | 'args' is a list of the argument names (it may contain nested lists). | |
|
26 | 'varargs' and 'varkw' are the names of the * and ** arguments or None. | |
|
27 | 'defaults' is an n-tuple of the default values of the last n arguments. | |
|
28 | ||
|
29 | Modified version of inspect.getargspec from the Python Standard | |
|
30 | Library.""" | |
|
31 | ||
|
32 | if inspect.isfunction(obj): | |
|
33 | func_obj = obj | |
|
34 | elif inspect.ismethod(obj): | |
|
35 | func_obj = obj.im_func | |
|
36 | else: | |
|
37 | raise TypeError, 'arg is not a Python function' | |
|
38 | args, varargs, varkw = inspect.getargs(func_obj.func_code) | |
|
39 | return args, varargs, varkw, func_obj.func_defaults | |
|
40 | ||
|
41 | #----------------------------------------------------------------------------- | |
|
42 | # Testing functions | |
|
43 | ||
|
44 | @dec.skip | |
|
45 | def test_deliberately_broken(): | |
|
46 | """A deliberately broken test - we want to skip this one.""" | |
|
47 | 1/0 | |
|
48 | ||
|
49 | @dec.skip('foo') | |
|
50 | def test_deliberately_broken2(): | |
|
51 | """Another deliberately broken test - we want to skip this one.""" | |
|
52 | 1/0 | |
|
53 | ||
|
54 | ||
|
55 | # Verify that we can correctly skip the doctest for a function at will, but | |
|
56 | # that the docstring itself is NOT destroyed by the decorator. | |
|
57 | @dec.skip_doctest | |
|
58 | def doctest_bad(x,y=1,**k): | |
|
59 | """A function whose doctest we need to skip. | |
|
60 | ||
|
61 | >>> 1+1 | |
|
62 | 3 | |
|
63 | """ | |
|
64 | print 'x:',x | |
|
65 | print 'y:',y | |
|
66 | print 'k:',k | |
|
67 | ||
|
68 | ||
|
69 | def call_doctest_bad(): | |
|
70 | """Check that we can still call the decorated functions. | |
|
71 | ||
|
72 | >>> doctest_bad(3,y=4) | |
|
73 | x: 3 | |
|
74 | y: 4 | |
|
75 | k: {} | |
|
76 | """ | |
|
77 | pass | |
|
78 | ||
|
79 | ||
|
80 | def test_skip_dt_decorator(): | |
|
81 | """Doctest-skipping decorator should preserve the docstring. | |
|
82 | """ | |
|
83 | # Careful: 'check' must be a *verbatim* copy of the doctest_bad docstring! | |
|
84 | check = """A function whose doctest we need to skip. | |
|
85 | ||
|
86 | >>> 1+1 | |
|
87 | 3 | |
|
88 | """ | |
|
89 | # Fetch the docstring from doctest_bad after decoration. | |
|
90 | val = doctest_bad.__doc__ | |
|
91 | ||
|
92 | assert check==val,"doctest_bad docstrings don't match" | |
|
93 | ||
|
94 | # Doctest skipping should work for class methods too | |
|
95 | class foo(object): | |
|
96 | """Foo | |
|
97 | ||
|
98 | Example: | |
|
99 | ||
|
100 | >>> 1+1 | |
|
101 | 2 | |
|
102 | """ | |
|
103 | ||
|
104 | @dec.skip_doctest | |
|
105 | def __init__(self,x): | |
|
106 | """Make a foo. | |
|
107 | ||
|
108 | Example: | |
|
109 | ||
|
110 | >>> f = foo(3) | |
|
111 | junk | |
|
112 | """ | |
|
113 | print 'Making a foo.' | |
|
114 | self.x = x | |
|
115 | ||
|
116 | @dec.skip_doctest | |
|
117 | def bar(self,y): | |
|
118 | """Example: | |
|
119 | ||
|
120 | >>> f = foo(3) | |
|
121 | >>> f.bar(0) | |
|
122 | boom! | |
|
123 | >>> 1/0 | |
|
124 | bam! | |
|
125 | """ | |
|
126 | return 1/y | |
|
127 | ||
|
128 | def baz(self,y): | |
|
129 | """Example: | |
|
130 | ||
|
131 | >>> f = foo(3) | |
|
132 | Making a foo. | |
|
133 | >>> f.baz(3) | |
|
134 | True | |
|
135 | """ | |
|
136 | return self.x==y | |
|
137 | ||
|
138 | ||
|
139 | ||
|
140 | def test_skip_dt_decorator2(): | |
|
141 | """Doctest-skipping decorator should preserve function signature. | |
|
142 | """ | |
|
143 | # Hardcoded correct answer | |
|
144 | dtargs = (['x', 'y'], None, 'k', (1,)) | |
|
145 | # Introspect out the value | |
|
146 | dtargsr = getargspec(doctest_bad) | |
|
147 | assert dtargsr==dtargs, \ | |
|
148 | "Incorrectly reconstructed args for doctest_bad: %s" % (dtargsr,) | |
|
149 | ||
|
150 | ||
|
151 | @dec.skip_linux | |
|
152 | def test_linux(): | |
|
153 | nt.assert_not_equals(sys.platform,'linux2',"This test can't run under linux") | |
|
154 | ||
|
155 | @dec.skip_win32 | |
|
156 | def test_win32(): | |
|
157 | nt.assert_not_equals(sys.platform,'win32',"This test can't run under windows") | |
|
158 | ||
|
159 | @dec.skip_osx | |
|
160 | def test_osx(): | |
|
161 | nt.assert_not_equals(sys.platform,'darwin',"This test can't run under osx") |
@@ -0,0 +1,20 b'' | |||
|
1 | #!/usr/bin/env python | |
|
2 | """Call the compile script to check that all code we ship compiles correctly. | |
|
3 | """ | |
|
4 | ||
|
5 | import os | |
|
6 | import sys | |
|
7 | ||
|
8 | ||
|
9 | vstr = '.'.join(map(str,sys.version_info[:2])) | |
|
10 | ||
|
11 | stat = os.system('python %s/lib/python%s/compileall.py .' % (sys.prefix,vstr)) | |
|
12 | ||
|
13 | ||
|
14 | if stat: | |
|
15 | print '*** THERE WAS AN ERROR! ***' | |
|
16 | print 'See messages above for the actual file that produced it.' | |
|
17 | else: | |
|
18 | print 'OK' | |
|
19 | ||
|
20 | sys.exit(stat) |
@@ -21,7 +21,7 b" name = 'ipython'" | |||
|
21 | 21 | # bdist_deb does not accept underscores (a Debian convention). |
|
22 | 22 | |
|
23 | 23 | development = False # change this to False to do a release |
|
24 | version_base = '0.9' | |
|
24 | version_base = '0.9.1' | |
|
25 | 25 | branch = 'ipython' |
|
26 | 26 | revision = '1143' |
|
27 | 27 | |
@@ -34,14 +34,19 b' else:' | |||
|
34 | 34 | version = version_base |
|
35 | 35 | |
|
36 | 36 | |
|
37 |
description = " |
|
|
37 | description = "An interactive computing environment for Python" | |
|
38 | 38 | |
|
39 | 39 | long_description = \ |
|
40 | 40 | """ |
|
41 | IPython provides a replacement for the interactive Python interpreter with | |
|
42 | extra functionality. | |
|
41 | The goal of IPython is to create a comprehensive environment for | |
|
42 | interactive and exploratory computing. To support this goal, IPython | |
|
43 | has two main components: | |
|
43 | 44 | |
|
44 | Main features: | |
|
45 | * An enhanced interactive Python shell. | |
|
46 | ||
|
47 | * An architecture for interactive parallel computing. | |
|
48 | ||
|
49 | The enhanced interactive Python shell has the following main features: | |
|
45 | 50 | |
|
46 | 51 |
|
|
47 | 52 | |
@@ -64,14 +69,33 b' Main features:' | |||
|
64 | 69 | |
|
65 | 70 |
|
|
66 | 71 | |
|
67 |
|
|
|
72 | * Easily embeddable in other Python programs and wxPython GUIs. | |
|
68 | 73 | |
|
69 | 74 |
|
|
70 | 75 | |
|
71 | The latest development version is always available at the IPython subversion | |
|
72 | repository_. | |
|
76 | The parallel computing architecture has the following main features: | |
|
77 | ||
|
78 | * Quickly parallelize Python code from an interactive Python/IPython session. | |
|
79 | ||
|
80 | * A flexible and dynamic process model that be deployed on anything from | |
|
81 | multicore workstations to supercomputers. | |
|
82 | ||
|
83 | * An architecture that supports many different styles of parallelism, from | |
|
84 | message passing to task farming. | |
|
85 | ||
|
86 | * Both blocking and fully asynchronous interfaces. | |
|
87 | ||
|
88 | * High level APIs that enable many things to be parallelized in a few lines | |
|
89 | of code. | |
|
90 | ||
|
91 | * Share live parallel jobs with other users securely. | |
|
92 | ||
|
93 | * Dynamically load balanced task farming system. | |
|
94 | ||
|
95 | * Robust error handling in parallel code. | |
|
73 | 96 | |
|
74 | .. _repository: http://ipython.scipy.org/svn/ipython/ipython/trunk#egg=ipython-dev | |
|
97 | The latest development version is always available from IPython's `Launchpad | |
|
98 | site <http://launchpad.net/ipython>`_. | |
|
75 | 99 |
|
|
76 | 100 | |
|
77 | 101 | license = 'BSD' |
@@ -21,10 +21,6 b' from os.path import join as pjoin' | |||
|
21 | 21 | from IPython.genutils import get_home_dir, get_ipython_dir |
|
22 | 22 | from IPython.external.configobj import ConfigObj |
|
23 | 23 | |
|
24 | # Traitlets config imports | |
|
25 | from IPython.config import traitlets | |
|
26 | from IPython.config.config import * | |
|
27 | from traitlets import * | |
|
28 | 24 | |
|
29 | 25 | class ConfigObjManager(object): |
|
30 | 26 |
@@ -14,7 +14,7 b' __docformat__ = "restructuredtext en"' | |||
|
14 | 14 | #------------------------------------------------------------------------------- |
|
15 | 15 | # Imports |
|
16 | 16 | #------------------------------------------------------------------------------- |
|
17 | import uuid | |
|
17 | from IPython.external import guid | |
|
18 | 18 | |
|
19 | 19 | |
|
20 | 20 | from zope.interface import Interface, Attribute, implements, classProvides |
@@ -59,7 +59,7 b' class AsyncFrontEndBase(FrontEndBase):' | |||
|
59 | 59 | return Failure(Exception("Block is not compilable")) |
|
60 | 60 | |
|
61 | 61 | if(blockID == None): |
|
62 |
blockID = |
|
|
62 | blockID = guid.generate() | |
|
63 | 63 | |
|
64 | 64 | d = self.engine.execute(block) |
|
65 | 65 | d.addCallback(self._add_history, block=block) |
@@ -26,7 +26,7 b' __docformat__ = "restructuredtext en"' | |||
|
26 | 26 | |
|
27 | 27 | import sys |
|
28 | 28 | import objc |
|
29 | import uuid | |
|
29 | from IPython.external import guid | |
|
30 | 30 | |
|
31 | 31 | from Foundation import NSObject, NSMutableArray, NSMutableDictionary,\ |
|
32 | 32 | NSLog, NSNotificationCenter, NSMakeRange,\ |
@@ -361,7 +361,7 b' class IPythonCocoaController(NSObject, AsyncFrontEndBase):' | |||
|
361 | 361 | |
|
362 | 362 | def next_block_ID(self): |
|
363 | 363 | |
|
364 |
return |
|
|
364 | return guid.generate() | |
|
365 | 365 | |
|
366 | 366 | def new_cell_block(self): |
|
367 | 367 | """A new CellBlock at the end of self.textView.textStorage()""" |
@@ -21,14 +21,13 b' __docformat__ = "restructuredtext en"' | |||
|
21 | 21 | # Imports |
|
22 | 22 | #------------------------------------------------------------------------------- |
|
23 | 23 | import string |
|
24 |
import |
|
|
25 | import _ast | |
|
24 | import codeop | |
|
25 | from IPython.external import guid | |
|
26 | ||
|
26 | 27 | |
|
27 | 28 | from IPython.frontend.zopeinterface import ( |
|
28 | 29 | Interface, |
|
29 | 30 | Attribute, |
|
30 | implements, | |
|
31 | classProvides | |
|
32 | 31 | ) |
|
33 | 32 | from IPython.kernel.core.history import FrontEndHistory |
|
34 | 33 | from IPython.kernel.core.util import Bunch |
@@ -134,10 +133,6 b' class IFrontEnd(Interface):' | |||
|
134 | 133 | |
|
135 | 134 | pass |
|
136 | 135 | |
|
137 | def compile_ast(block): | |
|
138 | """Compiles block to an _ast.AST""" | |
|
139 | ||
|
140 | pass | |
|
141 | 136 |
|
|
142 | 137 | def get_history_previous(current_block): |
|
143 | 138 | """Returns the block previous in the history. Saves currentBlock if |
@@ -220,28 +215,14 b' class FrontEndBase(object):' | |||
|
220 | 215 | """ |
|
221 | 216 | |
|
222 | 217 | try: |
|
223 |
|
|
|
218 | is_complete = codeop.compile_command(block.rstrip() + '\n\n', | |
|
219 | "<string>", "exec") | |
|
224 | 220 | except: |
|
225 | 221 | return False |
|
226 | 222 | |
|
227 | 223 | lines = block.split('\n') |
|
228 | return (len(lines)==1 or str(lines[-1])=='') | |
|
229 | ||
|
230 | ||
|
231 | def compile_ast(self, block): | |
|
232 | """Compile block to an AST | |
|
233 | ||
|
234 | Parameters: | |
|
235 | block : str | |
|
236 | ||
|
237 | Result: | |
|
238 | AST | |
|
239 | ||
|
240 | Throws: | |
|
241 | Exception if block cannot be compiled | |
|
242 | """ | |
|
243 | ||
|
244 | return compile(block, "<string>", "exec", _ast.PyCF_ONLY_AST) | |
|
224 | return ((is_complete is not None) | |
|
225 | and (len(lines)==1 or str(lines[-1])=='')) | |
|
245 | 226 | |
|
246 | 227 | |
|
247 | 228 | def execute(self, block, blockID=None): |
@@ -261,7 +242,7 b' class FrontEndBase(object):' | |||
|
261 | 242 | raise Exception("Block is not compilable") |
|
262 | 243 | |
|
263 | 244 | if(blockID == None): |
|
264 |
blockID = |
|
|
245 | blockID = guid.generate() | |
|
265 | 246 | |
|
266 | 247 | try: |
|
267 | 248 | result = self.shell.execute(block) |
@@ -182,6 +182,18 b' class LineFrontEndBase(FrontEndBase):' | |||
|
182 | 182 | raw_string = python_string |
|
183 | 183 | # Create a false result, in case there is an exception |
|
184 | 184 | self.last_result = dict(number=self.prompt_number) |
|
185 | ||
|
186 | ## try: | |
|
187 | ## self.history.input_cache[-1] = raw_string.rstrip() | |
|
188 | ## result = self.shell.execute(python_string) | |
|
189 | ## self.last_result = result | |
|
190 | ## self.render_result(result) | |
|
191 | ## except: | |
|
192 | ## self.show_traceback() | |
|
193 | ## finally: | |
|
194 | ## self.after_execute() | |
|
195 | ||
|
196 | try: | |
|
185 | 197 | try: |
|
186 | 198 | self.history.input_cache[-1] = raw_string.rstrip() |
|
187 | 199 | result = self.shell.execute(python_string) |
@@ -192,6 +204,7 b' class LineFrontEndBase(FrontEndBase):' | |||
|
192 | 204 | finally: |
|
193 | 205 | self.after_execute() |
|
194 | 206 | |
|
207 | ||
|
195 | 208 | #-------------------------------------------------------------------------- |
|
196 | 209 | # LineFrontEndBase interface |
|
197 | 210 | #-------------------------------------------------------------------------- |
@@ -196,6 +196,20 b' This is the wx frontend, by Gael Varoquaux. This is EXPERIMENTAL code."""' | |||
|
196 | 196 | # capture it. |
|
197 | 197 | self.capture_output() |
|
198 | 198 | self.last_result = dict(number=self.prompt_number) |
|
199 | ||
|
200 | ## try: | |
|
201 | ## for line in input_string.split('\n'): | |
|
202 | ## filtered_lines.append( | |
|
203 | ## self.ipython0.prefilter(line, False).rstrip()) | |
|
204 | ## except: | |
|
205 | ## # XXX: probably not the right thing to do. | |
|
206 | ## self.ipython0.showsyntaxerror() | |
|
207 | ## self.after_execute() | |
|
208 | ## finally: | |
|
209 | ## self.release_output() | |
|
210 | ||
|
211 | ||
|
212 | try: | |
|
199 | 213 | try: |
|
200 | 214 | for line in input_string.split('\n'): |
|
201 | 215 | filtered_lines.append( |
@@ -207,6 +221,8 b' This is the wx frontend, by Gael Varoquaux. This is EXPERIMENTAL code."""' | |||
|
207 | 221 | finally: |
|
208 | 222 | self.release_output() |
|
209 | 223 | |
|
224 | ||
|
225 | ||
|
210 | 226 | # Clean up the trailing whitespace, to avoid indentation errors |
|
211 | 227 | filtered_string = '\n'.join(filtered_lines) |
|
212 | 228 | return filtered_string |
@@ -1,155 +1,32 b'' | |||
|
1 | 1 | # encoding: utf-8 |
|
2 | ||
|
3 | """This file contains unittests for the frontendbase module.""" | |
|
2 | """ | |
|
3 | Test the basic functionality of frontendbase. | |
|
4 | """ | |
|
4 | 5 | |
|
5 | 6 | __docformat__ = "restructuredtext en" |
|
6 | 7 | |
|
7 | #--------------------------------------------------------------------------- | |
|
8 | #------------------------------------------------------------------------------- | |
|
8 | 9 |
# Copyright (C) 2008 The IPython Development Team |
|
9 | 10 | # |
|
10 |
# Distributed under the terms of the BSD License. The full license is |
|
|
11 |
# the file COPYING, distributed as part of this software. |
|
|
12 | #--------------------------------------------------------------------------- | |
|
13 | ||
|
14 | #--------------------------------------------------------------------------- | |
|
15 | # Imports | |
|
16 | #--------------------------------------------------------------------------- | |
|
17 | ||
|
18 | import unittest | |
|
19 | ||
|
20 | try: | |
|
21 | from IPython.frontend.asyncfrontendbase import AsyncFrontEndBase | |
|
22 | from IPython.frontend import frontendbase | |
|
23 | from IPython.kernel.engineservice import EngineService | |
|
24 | except ImportError: | |
|
25 | import nose | |
|
26 | raise nose.SkipTest("This test requires zope.interface, Twisted and Foolscap") | |
|
27 | ||
|
28 | from IPython.testing.decorators import skip | |
|
29 | ||
|
30 | class FrontEndCallbackChecker(AsyncFrontEndBase): | |
|
31 | """FrontEndBase subclass for checking callbacks""" | |
|
32 | def __init__(self, engine=None, history=None): | |
|
33 | super(FrontEndCallbackChecker, self).__init__(engine=engine, | |
|
34 | history=history) | |
|
35 | self.updateCalled = False | |
|
36 | self.renderResultCalled = False | |
|
37 | self.renderErrorCalled = False | |
|
38 | ||
|
39 | def update_cell_prompt(self, result, blockID=None): | |
|
40 | self.updateCalled = True | |
|
41 | return result | |
|
42 | ||
|
43 | def render_result(self, result): | |
|
44 | self.renderResultCalled = True | |
|
45 | return result | |
|
46 | ||
|
47 | ||
|
48 | def render_error(self, failure): | |
|
49 | self.renderErrorCalled = True | |
|
50 | return failure | |
|
51 | ||
|
52 | ||
|
53 | ||
|
54 | ||
|
55 | class TestAsyncFrontendBase(unittest.TestCase): | |
|
56 | def setUp(self): | |
|
57 | """Setup the EngineService and FrontEndBase""" | |
|
58 | ||
|
59 | self.fb = FrontEndCallbackChecker(engine=EngineService()) | |
|
60 | ||
|
61 | def test_implements_IFrontEnd(self): | |
|
62 | assert(frontendbase.IFrontEnd.implementedBy( | |
|
63 | AsyncFrontEndBase)) | |
|
64 | ||
|
65 | def test_is_complete_returns_False_for_incomplete_block(self): | |
|
66 | """""" | |
|
67 | ||
|
68 | block = """def test(a):""" | |
|
69 | ||
|
70 | assert(self.fb.is_complete(block) == False) | |
|
71 | ||
|
72 | def test_is_complete_returns_True_for_complete_block(self): | |
|
73 | """""" | |
|
74 | ||
|
75 | block = """def test(a): pass""" | |
|
76 | ||
|
77 | assert(self.fb.is_complete(block)) | |
|
78 | ||
|
79 | block = """a=3""" | |
|
11 | # Distributed under the terms of the BSD License. The full license is | |
|
12 | # in the file COPYING, distributed as part of this software. | |
|
13 | #------------------------------------------------------------------------------- | |
|
80 | 14 | |
|
81 | assert(self.fb.is_complete(block)) | |
|
15 | from IPython.frontend.frontendbase import FrontEndBase | |
|
82 | 16 | |
|
83 | def test_blockID_added_to_result(self): | |
|
84 | block = """3+3""" | |
|
85 | ||
|
86 | d = self.fb.execute(block, blockID='TEST_ID') | |
|
87 | ||
|
88 | d.addCallback(self.checkBlockID, expected='TEST_ID') | |
|
89 | ||
|
90 | def test_blockID_added_to_failure(self): | |
|
91 | block = "raise Exception()" | |
|
92 | ||
|
93 | d = self.fb.execute(block,blockID='TEST_ID') | |
|
94 | d.addErrback(self.checkFailureID, expected='TEST_ID') | |
|
95 | ||
|
96 | def checkBlockID(self, result, expected=""): | |
|
97 | assert(result['blockID'] == expected) | |
|
98 | ||
|
99 | ||
|
100 | def checkFailureID(self, failure, expected=""): | |
|
101 | assert(failure.blockID == expected) | |
|
102 | ||
|
103 | ||
|
104 | def test_callbacks_added_to_execute(self): | |
|
105 | """test that | |
|
106 | update_cell_prompt | |
|
107 | render_result | |
|
108 | ||
|
109 | are added to execute request | |
|
17 | def test_iscomplete(): | |
|
18 | """ Check that is_complete works. | |
|
110 | 19 |
|
|
111 | ||
|
112 | d = self.fb.execute("10+10") | |
|
113 | d.addCallback(self.checkCallbacks) | |
|
114 | ||
|
115 | def checkCallbacks(self, result): | |
|
116 | assert(self.fb.updateCalled) | |
|
117 | assert(self.fb.renderResultCalled) | |
|
118 | ||
|
119 | @skip("This test fails and lead to an unhandled error in a Deferred.") | |
|
120 | def test_error_callback_added_to_execute(self): | |
|
121 | """test that render_error called on execution error""" | |
|
122 | ||
|
123 | d = self.fb.execute("raise Exception()") | |
|
124 | d.addCallback(self.checkRenderError) | |
|
125 | ||
|
126 | def checkRenderError(self, result): | |
|
127 | assert(self.fb.renderErrorCalled) | |
|
128 | ||
|
129 | def test_history_returns_expected_block(self): | |
|
130 | """Make sure history browsing doesn't fail""" | |
|
131 | ||
|
132 | blocks = ["a=1","a=2","a=3"] | |
|
133 | for b in blocks: | |
|
134 | d = self.fb.execute(b) | |
|
135 | ||
|
136 | # d is now the deferred for the last executed block | |
|
137 | d.addCallback(self.historyTests, blocks) | |
|
138 | ||
|
139 | ||
|
140 | def historyTests(self, result, blocks): | |
|
141 | """historyTests""" | |
|
142 | ||
|
143 | assert(len(blocks) >= 3) | |
|
144 | assert(self.fb.get_history_previous("") == blocks[-2]) | |
|
145 | assert(self.fb.get_history_previous("") == blocks[-3]) | |
|
146 | assert(self.fb.get_history_next() == blocks[-2]) | |
|
147 | ||
|
148 | ||
|
149 | def test_history_returns_none_at_startup(self): | |
|
150 | """test_history_returns_none_at_startup""" | |
|
151 | ||
|
152 | assert(self.fb.get_history_previous("")==None) | |
|
153 | assert(self.fb.get_history_next()==None) | |
|
154 | ||
|
20 | f = FrontEndBase() | |
|
21 | assert f.is_complete('(a + a)') | |
|
22 | assert not f.is_complete('(a + a') | |
|
23 | assert f.is_complete('1') | |
|
24 | assert not f.is_complete('1 + ') | |
|
25 | assert not f.is_complete('1 + \n\n') | |
|
26 | assert f.is_complete('if True:\n print 1\n') | |
|
27 | assert not f.is_complete('if True:\n print 1') | |
|
28 | assert f.is_complete('def f():\n print 1\n') | |
|
29 | ||
|
30 | if __name__ == '__main__': | |
|
31 | test_iscomplete() | |
|
155 | 32 |
@@ -16,13 +16,6 b' __docformat__ = "restructuredtext en"' | |||
|
16 | 16 | # the file COPYING, distributed as part of this software. |
|
17 | 17 | #------------------------------------------------------------------------------- |
|
18 | 18 | |
|
19 | #------------------------------------------------------------------------------- | |
|
20 | # Imports | |
|
21 | #------------------------------------------------------------------------------- | |
|
22 | import string | |
|
23 | import uuid | |
|
24 | import _ast | |
|
25 | ||
|
26 | 19 | try: |
|
27 | 20 | from zope.interface import Interface, Attribute, implements, classProvides |
|
28 | 21 | except ImportError: |
@@ -8,8 +8,6 b' which can also be useful as templates for writing new, application-specific' | |||
|
8 | 8 | managers. |
|
9 | 9 | """ |
|
10 | 10 | |
|
11 | from __future__ import with_statement | |
|
12 | ||
|
13 | 11 | __docformat__ = "restructuredtext en" |
|
14 | 12 | |
|
15 | 13 | #------------------------------------------------------------------------------- |
@@ -13,13 +13,17 b' __docformat__ = "restructuredtext en"' | |||
|
13 | 13 | #------------------------------------------------------------------------------- |
|
14 | 14 | |
|
15 | 15 | |
|
16 | # Stdlib imports | |
|
16 | 17 | import os |
|
17 | 18 | from cStringIO import StringIO |
|
18 | 19 | |
|
19 | from IPython.testing import decorators as testdec | |
|
20 | # Our own imports | |
|
21 | from IPython.testing import decorators as dec | |
|
20 | 22 | |
|
21 | # FIXME | |
|
22 | @testdec.skip("This doesn't work under Windows") | |
|
23 | #----------------------------------------------------------------------------- | |
|
24 | # Test functions | |
|
25 | ||
|
26 | @dec.skip_win32 | |
|
23 | 27 | def test_redirector(): |
|
24 | 28 | """ Checks that the redirector can be used to do synchronous capture. |
|
25 | 29 | """ |
@@ -40,8 +44,8 b' def test_redirector():' | |||
|
40 | 44 | result2 = "".join("%ic\n%i\n" %(i, i) for i in range(10)) |
|
41 | 45 | assert result1 == result2 |
|
42 | 46 | |
|
43 | # FIXME | |
|
44 | @testdec.skip("This doesn't work under Windows") | |
|
47 | ||
|
48 | @dec.skip_win32 | |
|
45 | 49 | def test_redirector_output_trap(): |
|
46 | 50 | """ This test check not only that the redirector_output_trap does |
|
47 | 51 | trap the output, but also that it does it in a gready way, that |
@@ -64,5 +68,3 b' def test_redirector_output_trap():' | |||
|
64 | 68 | result2 = "".join("%ic\n%ip\n%i\n" %(i, i, i) for i in range(10)) |
|
65 | 69 | assert result1 == result2 |
|
66 | 70 | |
|
67 | ||
|
68 |
@@ -1,4 +1,6 b'' | |||
|
1 | from __future__ import with_statement | |
|
1 | #from __future__ import with_statement | |
|
2 | ||
|
3 | # XXX This file is currently disabled to preserve 2.4 compatibility. | |
|
2 | 4 | |
|
3 | 5 | #def test_simple(): |
|
4 | 6 | if 0: |
@@ -25,17 +27,17 b' if 0:' | |||
|
25 | 27 | |
|
26 | 28 | mec.pushAll() |
|
27 | 29 | |
|
28 | with parallel as pr: | |
|
29 | # A comment | |
|
30 | remote() # this means the code below only runs remotely | |
|
31 | print 'Hello remote world' | |
|
32 | x = range(10) | |
|
33 | # Comments are OK | |
|
34 | # Even misindented. | |
|
35 | y = x+1 | |
|
30 | ## with parallel as pr: | |
|
31 | ## # A comment | |
|
32 | ## remote() # this means the code below only runs remotely | |
|
33 | ## print 'Hello remote world' | |
|
34 | ## x = range(10) | |
|
35 | ## # Comments are OK | |
|
36 | ## # Even misindented. | |
|
37 | ## y = x+1 | |
|
36 | 38 | |
|
37 | 39 | |
|
38 | with pfor('i',sequence) as pr: | |
|
39 | print x[i] | |
|
40 | ## with pfor('i',sequence) as pr: | |
|
41 | ## print x[i] | |
|
40 | 42 | |
|
41 | 43 | print pr.x + pr.y |
@@ -8,6 +8,10 b' the decorator, in order to preserve metadata such as function name,' | |||
|
8 | 8 | setup and teardown functions and so on - see nose.tools for more |
|
9 | 9 | information. |
|
10 | 10 | |
|
11 | This module provides a set of useful decorators meant to be ready to use in | |
|
12 | your own tests. See the bottom of the file for the ready-made ones, and if you | |
|
13 | find yourself writing a new one that may be of generic use, add it here. | |
|
14 | ||
|
11 | 15 | NOTE: This file contains IPython-specific decorators and imports the |
|
12 | 16 | numpy.testing.decorators file, which we've copied verbatim. Any of our own |
|
13 | 17 | code will be added at the bottom if we end up extending this. |
@@ -15,6 +19,7 b' code will be added at the bottom if we end up extending this.' | |||
|
15 | 19 | |
|
16 | 20 | # Stdlib imports |
|
17 | 21 | import inspect |
|
22 | import sys | |
|
18 | 23 | |
|
19 | 24 | # Third-party imports |
|
20 | 25 | |
@@ -123,6 +128,9 b" skip_doctest = make_label_dec('skip_doctest'," | |||
|
123 | 128 | def skip(msg=''): |
|
124 | 129 | """Decorator - mark a test function for skipping from test suite. |
|
125 | 130 | |
|
131 | This function *is* already a decorator, it is not a factory like | |
|
132 | make_label_dec or some of those in decorators_numpy. | |
|
133 | ||
|
126 | 134 | :Parameters: |
|
127 | 135 | |
|
128 | 136 | func : function |
@@ -145,3 +153,8 b" def skip(msg=''):" | |||
|
145 | 153 | return apply_wrapper(wrapper,func) |
|
146 | 154 | |
|
147 | 155 | return inner |
|
156 | ||
|
157 | # Decorators to skip certain tests on specific platforms. | |
|
158 | skip_win32 = skipif(sys.platform=='win32',"This test does not run under Windows") | |
|
159 | skip_linux = skipif(sys.platform=='linux2',"This test does not run under Linux") | |
|
160 | skip_osx = skipif(sys.platform=='darwin',"This test does not run under OSX") |
@@ -1,152 +1,19 b'' | |||
|
1 | """Some simple tests for the plugin while running scripts. | |
|
2 | """ | |
|
1 | 3 | # Module imports |
|
2 | 4 | # Std lib |
|
3 | 5 | import inspect |
|
4 | 6 | |
|
5 | # Third party | |
|
6 | ||
|
7 | 7 | # Our own |
|
8 | 8 | from IPython.testing import decorators as dec |
|
9 | 9 | |
|
10 | 10 | #----------------------------------------------------------------------------- |
|
11 | # Utilities | |
|
12 | ||
|
13 | # Note: copied from OInspect, kept here so the testing stuff doesn't create | |
|
14 | # circular dependencies and is easier to reuse. | |
|
15 | def getargspec(obj): | |
|
16 | """Get the names and default values of a function's arguments. | |
|
17 | ||
|
18 | A tuple of four things is returned: (args, varargs, varkw, defaults). | |
|
19 | 'args' is a list of the argument names (it may contain nested lists). | |
|
20 | 'varargs' and 'varkw' are the names of the * and ** arguments or None. | |
|
21 | 'defaults' is an n-tuple of the default values of the last n arguments. | |
|
22 | ||
|
23 | Modified version of inspect.getargspec from the Python Standard | |
|
24 | Library.""" | |
|
25 | ||
|
26 | if inspect.isfunction(obj): | |
|
27 | func_obj = obj | |
|
28 | elif inspect.ismethod(obj): | |
|
29 | func_obj = obj.im_func | |
|
30 | else: | |
|
31 | raise TypeError, 'arg is not a Python function' | |
|
32 | args, varargs, varkw = inspect.getargs(func_obj.func_code) | |
|
33 | return args, varargs, varkw, func_obj.func_defaults | |
|
34 | ||
|
35 | #----------------------------------------------------------------------------- | |
|
36 | 11 | # Testing functions |
|
37 | 12 | |
|
38 | 13 | def test_trivial(): |
|
39 | 14 | """A trivial passing test.""" |
|
40 | 15 | pass |
|
41 | 16 | |
|
42 | ||
|
43 | @dec.skip | |
|
44 | def test_deliberately_broken(): | |
|
45 | """A deliberately broken test - we want to skip this one.""" | |
|
46 | 1/0 | |
|
47 | ||
|
48 | @dec.skip('foo') | |
|
49 | def test_deliberately_broken2(): | |
|
50 | """Another deliberately broken test - we want to skip this one.""" | |
|
51 | 1/0 | |
|
52 | ||
|
53 | ||
|
54 | # Verify that we can correctly skip the doctest for a function at will, but | |
|
55 | # that the docstring itself is NOT destroyed by the decorator. | |
|
56 | @dec.skip_doctest | |
|
57 | def doctest_bad(x,y=1,**k): | |
|
58 | """A function whose doctest we need to skip. | |
|
59 | ||
|
60 | >>> 1+1 | |
|
61 | 3 | |
|
62 | """ | |
|
63 | print 'x:',x | |
|
64 | print 'y:',y | |
|
65 | print 'k:',k | |
|
66 | ||
|
67 | ||
|
68 | def call_doctest_bad(): | |
|
69 | """Check that we can still call the decorated functions. | |
|
70 | ||
|
71 | >>> doctest_bad(3,y=4) | |
|
72 | x: 3 | |
|
73 | y: 4 | |
|
74 | k: {} | |
|
75 | """ | |
|
76 | pass | |
|
77 | ||
|
78 | ||
|
79 | # Doctest skipping should work for class methods too | |
|
80 | class foo(object): | |
|
81 | """Foo | |
|
82 | ||
|
83 | Example: | |
|
84 | ||
|
85 | >>> 1+1 | |
|
86 | 2 | |
|
87 | """ | |
|
88 | ||
|
89 | @dec.skip_doctest | |
|
90 | def __init__(self,x): | |
|
91 | """Make a foo. | |
|
92 | ||
|
93 | Example: | |
|
94 | ||
|
95 | >>> f = foo(3) | |
|
96 | junk | |
|
97 | """ | |
|
98 | print 'Making a foo.' | |
|
99 | self.x = x | |
|
100 | ||
|
101 | @dec.skip_doctest | |
|
102 | def bar(self,y): | |
|
103 | """Example: | |
|
104 | ||
|
105 | >>> f = foo(3) | |
|
106 | >>> f.bar(0) | |
|
107 | boom! | |
|
108 | >>> 1/0 | |
|
109 | bam! | |
|
110 | """ | |
|
111 | return 1/y | |
|
112 | ||
|
113 | def baz(self,y): | |
|
114 | """Example: | |
|
115 | ||
|
116 | >>> f = foo(3) | |
|
117 | Making a foo. | |
|
118 | >>> f.baz(3) | |
|
119 | True | |
|
120 | """ | |
|
121 | return self.x==y | |
|
122 | ||
|
123 | ||
|
124 | def test_skip_dt_decorator(): | |
|
125 | """Doctest-skipping decorator should preserve the docstring. | |
|
126 | """ | |
|
127 | # Careful: 'check' must be a *verbatim* copy of the doctest_bad docstring! | |
|
128 | check = """A function whose doctest we need to skip. | |
|
129 | ||
|
130 | >>> 1+1 | |
|
131 | 3 | |
|
132 | """ | |
|
133 | # Fetch the docstring from doctest_bad after decoration. | |
|
134 | val = doctest_bad.__doc__ | |
|
135 | ||
|
136 | assert check==val,"doctest_bad docstrings don't match" | |
|
137 | ||
|
138 | ||
|
139 | def test_skip_dt_decorator2(): | |
|
140 | """Doctest-skipping decorator should preserve function signature. | |
|
141 | """ | |
|
142 | # Hardcoded correct answer | |
|
143 | dtargs = (['x', 'y'], None, 'k', (1,)) | |
|
144 | # Introspect out the value | |
|
145 | dtargsr = getargspec(doctest_bad) | |
|
146 | assert dtargsr==dtargs, \ | |
|
147 | "Incorrectly reconstructed args for doctest_bad: %s" % (dtargsr,) | |
|
148 | ||
|
149 | ||
|
150 | 17 | def doctest_run(): |
|
151 | 18 | """Test running a trivial script. |
|
152 | 19 | |
@@ -154,7 +21,6 b' def doctest_run():' | |||
|
154 | 21 | x is: 1 |
|
155 | 22 | """ |
|
156 | 23 | |
|
157 | #@dec.skip_doctest | |
|
158 | 24 | def doctest_runvars(): |
|
159 | 25 | """Test that variables defined in scripts get loaded correcly via %run. |
|
160 | 26 |
@@ -1,11 +1,11 b'' | |||
|
1 |
============== |
|
|
2 |
IPython |
|
|
3 |
============== |
|
|
4 | ||
|
5 | .. contents:: | |
|
1 | ============== | |
|
2 | IPython README | |
|
3 | ============== | |
|
6 | 4 | |
|
7 | 5 | Overview |
|
8 | 6 | ======== |
|
9 | 7 | |
|
10 |
Welcome to IPython. |
|
|
11 | in the docs/source subdirectory. | |
|
8 | Welcome to IPython. Our documentation can be found in the docs/source | |
|
9 | subdirectory. We also have ``.html`` and ``.pdf`` versions of this | |
|
10 | documentation available on the IPython `website <http://ipython.scipy.org>`_. | |
|
11 |
@@ -45,7 +45,10 b' def mergesort(list_of_lists, key=None):' | |||
|
45 | 45 | for i, itr in enumerate(iter(pl) for pl in list_of_lists): |
|
46 | 46 | try: |
|
47 | 47 | item = itr.next() |
|
48 | toadd = (key(item), i, item, itr) if key else (item, i, itr) | |
|
48 | if key: | |
|
49 | toadd = (key(item), i, item, itr) | |
|
50 | else: | |
|
51 | toadd = (item, i, itr) | |
|
49 | 52 | heap.append(toadd) |
|
50 | 53 | except StopIteration: |
|
51 | 54 | pass |
@@ -14,7 +14,7 b' However, the interpreter supplied with the standard Python distribution' | |||
|
14 | 14 | is somewhat limited for extended interactive use. |
|
15 | 15 | |
|
16 | 16 | The goal of IPython is to create a comprehensive environment for |
|
17 |
interactive and exploratory computing. To support |
|
|
17 | interactive and exploratory computing. To support this goal, IPython | |
|
18 | 18 | has two main components: |
|
19 | 19 | |
|
20 | 20 | * An enhanced interactive Python shell. |
|
1 | NO CONTENT: file renamed from IPython/config/config.py to sandbox/config.py |
|
1 | NO CONTENT: file renamed from IPython/config/tests/sample_config.py to sandbox/sample_config.py |
|
1 | NO CONTENT: file renamed from IPython/config/tests/test_config.py to sandbox/test_config.py |
|
1 | NO CONTENT: file renamed from IPython/config/traitlets.py to sandbox/traitlets.py |
@@ -15,8 +15,8 b' cd $ipdir' | |||
|
15 | 15 | ./setup.py sdist --formats=gztar |
|
16 | 16 | |
|
17 | 17 | # Build rpms |
|
18 |
|
|
|
19 |
|
|
|
18 | python2.4 ./setup.py bdist_rpm --binary-only --release=py24 --python=/usr/bin/python2.4 | |
|
19 | python2.5 ./setup.py bdist_rpm --binary-only --release=py25 --python=/usr/bin/python2.5 | |
|
20 | 20 | |
|
21 | 21 | # Build eggs |
|
22 | 22 | python2.4 ./setup_bdist_egg.py |
|
1 | NO CONTENT: file was removed |
General Comments 0
You need to be logged in to leave comments.
Login now