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 | # bdist_deb does not accept underscores (a Debian convention). |
|
21 | # bdist_deb does not accept underscores (a Debian convention). | |
22 |
|
22 | |||
23 | development = False # change this to False to do a release |
|
23 | development = False # change this to False to do a release | |
24 | version_base = '0.9' |
|
24 | version_base = '0.9.1' | |
25 | branch = 'ipython' |
|
25 | branch = 'ipython' | |
26 | revision = '1143' |
|
26 | revision = '1143' | |
27 |
|
27 | |||
@@ -34,45 +34,69 b' else:' | |||||
34 | version = version_base |
|
34 | version = version_base | |
35 |
|
35 | |||
36 |
|
36 | |||
37 |
description = " |
|
37 | description = "An interactive computing environment for Python" | |
38 |
|
38 | |||
39 | long_description = \ |
|
39 | long_description = \ | |
40 | """ |
|
40 | """ | |
41 | IPython provides a replacement for the interactive Python interpreter with |
|
41 | The goal of IPython is to create a comprehensive environment for | |
42 | extra functionality. |
|
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. | |
45 |
|
46 | |||
46 | * Comprehensive object introspection. |
|
47 | * An architecture for interactive parallel computing. | |
47 |
|
48 | |||
48 | * Input history, persistent across sessions. |
|
49 | The enhanced interactive Python shell has the following main features: | |
49 |
|
50 | |||
50 | * Caching of output results during a session with automatically generated |
|
51 | * Comprehensive object introspection. | |
51 | references. |
|
|||
52 |
|
52 | |||
53 | * Readline based name completion. |
|
53 | * Input history, persistent across sessions. | |
54 |
|
54 | |||
55 | * Extensible system of 'magic' commands for controlling the environment and |
|
55 | * Caching of output results during a session with automatically generated | |
56 | performing many tasks related either to IPython or the operating system. |
|
56 | references. | |
57 |
|
57 | |||
58 | * Configuration system with easy switching between different setups (simpler |
|
58 | * Readline based name completion. | |
59 | than changing $PYTHONSTARTUP environment variables every time). |
|
|||
60 |
|
59 | |||
61 | * Session logging and reloading. |
|
60 | * Extensible system of 'magic' commands for controlling the environment and | |
|
61 | performing many tasks related either to IPython or the operating system. | |||
62 |
|
62 | |||
63 | * Extensible syntax processing for special purpose situations. |
|
63 | * Configuration system with easy switching between different setups (simpler | |
|
64 | than changing $PYTHONSTARTUP environment variables every time). | |||
64 |
|
65 | |||
65 | * Access to the system shell with user-extensible alias system. |
|
66 | * Session logging and reloading. | |
66 |
|
67 | |||
67 | * Easily embeddable in other Python programs. |
|
68 | * Extensible syntax processing for special purpose situations. | |
68 |
|
69 | |||
69 | * Integrated access to the pdb debugger and the Python profiler. |
|
70 | * Access to the system shell with user-extensible alias system. | |
70 |
|
71 | |||
71 | The latest development version is always available at the IPython subversion |
|
72 | * Easily embeddable in other Python programs and wxPython GUIs. | |
72 | repository_. |
|
|||
73 |
|
73 | |||
74 | .. _repository: http://ipython.scipy.org/svn/ipython/ipython/trunk#egg=ipython-dev |
|
74 | * Integrated access to the pdb debugger and the Python profiler. | |
75 | """ |
|
75 | ||
|
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. | |||
|
96 | ||||
|
97 | The latest development version is always available from IPython's `Launchpad | |||
|
98 | site <http://launchpad.net/ipython>`_. | |||
|
99 | """ | |||
76 |
|
100 | |||
77 | license = 'BSD' |
|
101 | license = 'BSD' | |
78 |
|
102 |
@@ -21,10 +21,6 b' from os.path import join as pjoin' | |||||
21 | from IPython.genutils import get_home_dir, get_ipython_dir |
|
21 | from IPython.genutils import get_home_dir, get_ipython_dir | |
22 | from IPython.external.configobj import ConfigObj |
|
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 | class ConfigObjManager(object): |
|
25 | class ConfigObjManager(object): | |
30 |
|
26 |
@@ -14,7 +14,7 b' __docformat__ = "restructuredtext en"' | |||||
14 | #------------------------------------------------------------------------------- |
|
14 | #------------------------------------------------------------------------------- | |
15 | # Imports |
|
15 | # Imports | |
16 | #------------------------------------------------------------------------------- |
|
16 | #------------------------------------------------------------------------------- | |
17 | import uuid |
|
17 | from IPython.external import guid | |
18 |
|
18 | |||
19 |
|
19 | |||
20 | from zope.interface import Interface, Attribute, implements, classProvides |
|
20 | from zope.interface import Interface, Attribute, implements, classProvides | |
@@ -59,7 +59,7 b' class AsyncFrontEndBase(FrontEndBase):' | |||||
59 | return Failure(Exception("Block is not compilable")) |
|
59 | return Failure(Exception("Block is not compilable")) | |
60 |
|
60 | |||
61 | if(blockID == None): |
|
61 | if(blockID == None): | |
62 |
blockID = |
|
62 | blockID = guid.generate() | |
63 |
|
63 | |||
64 | d = self.engine.execute(block) |
|
64 | d = self.engine.execute(block) | |
65 | d.addCallback(self._add_history, block=block) |
|
65 | d.addCallback(self._add_history, block=block) |
@@ -26,7 +26,7 b' __docformat__ = "restructuredtext en"' | |||||
26 |
|
26 | |||
27 | import sys |
|
27 | import sys | |
28 | import objc |
|
28 | import objc | |
29 | import uuid |
|
29 | from IPython.external import guid | |
30 |
|
30 | |||
31 | from Foundation import NSObject, NSMutableArray, NSMutableDictionary,\ |
|
31 | from Foundation import NSObject, NSMutableArray, NSMutableDictionary,\ | |
32 | NSLog, NSNotificationCenter, NSMakeRange,\ |
|
32 | NSLog, NSNotificationCenter, NSMakeRange,\ | |
@@ -361,7 +361,7 b' class IPythonCocoaController(NSObject, AsyncFrontEndBase):' | |||||
361 |
|
361 | |||
362 | def next_block_ID(self): |
|
362 | def next_block_ID(self): | |
363 |
|
363 | |||
364 |
return |
|
364 | return guid.generate() | |
365 |
|
365 | |||
366 | def new_cell_block(self): |
|
366 | def new_cell_block(self): | |
367 | """A new CellBlock at the end of self.textView.textStorage()""" |
|
367 | """A new CellBlock at the end of self.textView.textStorage()""" |
@@ -21,14 +21,13 b' __docformat__ = "restructuredtext en"' | |||||
21 | # Imports |
|
21 | # Imports | |
22 | #------------------------------------------------------------------------------- |
|
22 | #------------------------------------------------------------------------------- | |
23 | import string |
|
23 | import string | |
24 |
import |
|
24 | import codeop | |
25 | import _ast |
|
25 | from IPython.external import guid | |
|
26 | ||||
26 |
|
27 | |||
27 | from IPython.frontend.zopeinterface import ( |
|
28 | from IPython.frontend.zopeinterface import ( | |
28 | Interface, |
|
29 | Interface, | |
29 | Attribute, |
|
30 | Attribute, | |
30 | implements, |
|
|||
31 | classProvides |
|
|||
32 | ) |
|
31 | ) | |
33 | from IPython.kernel.core.history import FrontEndHistory |
|
32 | from IPython.kernel.core.history import FrontEndHistory | |
34 | from IPython.kernel.core.util import Bunch |
|
33 | from IPython.kernel.core.util import Bunch | |
@@ -134,11 +133,7 b' class IFrontEnd(Interface):' | |||||
134 |
|
133 | |||
135 | pass |
|
134 | pass | |
136 |
|
135 | |||
137 | def compile_ast(block): |
|
136 | ||
138 | """Compiles block to an _ast.AST""" |
|
|||
139 |
|
||||
140 | pass |
|
|||
141 |
|
||||
142 | def get_history_previous(current_block): |
|
137 | def get_history_previous(current_block): | |
143 | """Returns the block previous in the history. Saves currentBlock if |
|
138 | """Returns the block previous in the history. Saves currentBlock if | |
144 | the history_cursor is currently at the end of the input history""" |
|
139 | the history_cursor is currently at the end of the input history""" | |
@@ -220,28 +215,14 b' class FrontEndBase(object):' | |||||
220 | """ |
|
215 | """ | |
221 |
|
216 | |||
222 | try: |
|
217 | try: | |
223 |
|
|
218 | is_complete = codeop.compile_command(block.rstrip() + '\n\n', | |
|
219 | "<string>", "exec") | |||
224 | except: |
|
220 | except: | |
225 | return False |
|
221 | return False | |
226 |
|
222 | |||
227 | lines = block.split('\n') |
|
223 | lines = block.split('\n') | |
228 | return (len(lines)==1 or str(lines[-1])=='') |
|
224 | return ((is_complete is not None) | |
229 |
|
225 | and (len(lines)==1 or str(lines[-1])=='')) | ||
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) |
|
|||
245 |
|
226 | |||
246 |
|
227 | |||
247 | def execute(self, block, blockID=None): |
|
228 | def execute(self, block, blockID=None): | |
@@ -261,7 +242,7 b' class FrontEndBase(object):' | |||||
261 | raise Exception("Block is not compilable") |
|
242 | raise Exception("Block is not compilable") | |
262 |
|
243 | |||
263 | if(blockID == None): |
|
244 | if(blockID == None): | |
264 |
blockID = |
|
245 | blockID = guid.generate() | |
265 |
|
246 | |||
266 | try: |
|
247 | try: | |
267 | result = self.shell.execute(block) |
|
248 | result = self.shell.execute(block) |
@@ -182,16 +182,29 b' class LineFrontEndBase(FrontEndBase):' | |||||
182 | raw_string = python_string |
|
182 | raw_string = python_string | |
183 | # Create a false result, in case there is an exception |
|
183 | # Create a false result, in case there is an exception | |
184 | self.last_result = dict(number=self.prompt_number) |
|
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 | ||||
185 | try: |
|
196 | try: | |
186 | self.history.input_cache[-1] = raw_string.rstrip() |
|
197 | try: | |
187 | result = self.shell.execute(python_string) |
|
198 | self.history.input_cache[-1] = raw_string.rstrip() | |
188 | self.last_result = result |
|
199 | result = self.shell.execute(python_string) | |
189 |
self. |
|
200 | self.last_result = result | |
190 | except: |
|
201 | self.render_result(result) | |
191 | self.show_traceback() |
|
202 | except: | |
|
203 | self.show_traceback() | |||
192 | finally: |
|
204 | finally: | |
193 | self.after_execute() |
|
205 | self.after_execute() | |
194 |
|
206 | |||
|
207 | ||||
195 | #-------------------------------------------------------------------------- |
|
208 | #-------------------------------------------------------------------------- | |
196 | # LineFrontEndBase interface |
|
209 | # LineFrontEndBase interface | |
197 | #-------------------------------------------------------------------------- |
|
210 | #-------------------------------------------------------------------------- |
@@ -196,17 +196,33 b' This is the wx frontend, by Gael Varoquaux. This is EXPERIMENTAL code."""' | |||||
196 | # capture it. |
|
196 | # capture it. | |
197 | self.capture_output() |
|
197 | self.capture_output() | |
198 | self.last_result = dict(number=self.prompt_number) |
|
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 | ||||
199 | try: |
|
212 | try: | |
200 | for line in input_string.split('\n'): |
|
213 | try: | |
201 | filtered_lines.append( |
|
214 | for line in input_string.split('\n'): | |
202 | self.ipython0.prefilter(line, False).rstrip()) |
|
215 | filtered_lines.append( | |
203 | except: |
|
216 | self.ipython0.prefilter(line, False).rstrip()) | |
204 | # XXX: probably not the right thing to do. |
|
217 | except: | |
205 | self.ipython0.showsyntaxerror() |
|
218 | # XXX: probably not the right thing to do. | |
206 | self.after_execute() |
|
219 | self.ipython0.showsyntaxerror() | |
|
220 | self.after_execute() | |||
207 | finally: |
|
221 | finally: | |
208 | self.release_output() |
|
222 | self.release_output() | |
209 |
|
223 | |||
|
224 | ||||
|
225 | ||||
210 | # Clean up the trailing whitespace, to avoid indentation errors |
|
226 | # Clean up the trailing whitespace, to avoid indentation errors | |
211 | filtered_string = '\n'.join(filtered_lines) |
|
227 | filtered_string = '\n'.join(filtered_lines) | |
212 | return filtered_string |
|
228 | return filtered_string |
@@ -1,155 +1,32 b'' | |||||
1 | # encoding: utf-8 |
|
1 | # encoding: utf-8 | |
2 |
|
2 | """ | ||
3 | """This file contains unittests for the frontendbase module.""" |
|
3 | Test the basic functionality of frontendbase. | |
|
4 | """ | |||
4 |
|
5 | |||
5 | __docformat__ = "restructuredtext en" |
|
6 | __docformat__ = "restructuredtext en" | |
6 |
|
7 | |||
7 | #--------------------------------------------------------------------------- |
|
8 | #------------------------------------------------------------------------------- | |
8 |
# Copyright (C) 2008 The IPython Development Team |
|
9 | # Copyright (C) 2008 The IPython Development Team | |
9 | # |
|
10 | # | |
10 |
# Distributed under the terms of the BSD License. The full license is |
|
11 | # Distributed under the terms of the BSD License. The full license is | |
11 |
# the file COPYING, distributed as part of this software. |
|
12 | # in the file COPYING, distributed as part of this software. | |
12 | #--------------------------------------------------------------------------- |
|
13 | #------------------------------------------------------------------------------- | |
13 |
|
14 | |||
14 | #--------------------------------------------------------------------------- |
|
15 | from IPython.frontend.frontendbase import FrontEndBase | |
15 | # Imports |
|
16 | ||
16 | #--------------------------------------------------------------------------- |
|
17 | def test_iscomplete(): | |
17 |
|
18 | """ Check that is_complete works. | ||
18 | import unittest |
|
19 | """ | |
19 |
|
20 | f = FrontEndBase() | ||
20 | try: |
|
21 | assert f.is_complete('(a + a)') | |
21 | from IPython.frontend.asyncfrontendbase import AsyncFrontEndBase |
|
22 | assert not f.is_complete('(a + a') | |
22 | from IPython.frontend import frontendbase |
|
23 | assert f.is_complete('1') | |
23 | from IPython.kernel.engineservice import EngineService |
|
24 | assert not f.is_complete('1 + ') | |
24 | except ImportError: |
|
25 | assert not f.is_complete('1 + \n\n') | |
25 | import nose |
|
26 | assert f.is_complete('if True:\n print 1\n') | |
26 | raise nose.SkipTest("This test requires zope.interface, Twisted and Foolscap") |
|
27 | assert not f.is_complete('if True:\n print 1') | |
27 |
|
28 | assert f.is_complete('def f():\n print 1\n') | ||
28 | from IPython.testing.decorators import skip |
|
29 | ||
29 |
|
30 | if __name__ == '__main__': | ||
30 | class FrontEndCallbackChecker(AsyncFrontEndBase): |
|
31 | test_iscomplete() | |
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 |
|
32 | |||
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 |
|
@@ -16,13 +16,6 b' __docformat__ = "restructuredtext en"' | |||||
16 | # the file COPYING, distributed as part of this software. |
|
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 | try: |
|
19 | try: | |
27 | from zope.interface import Interface, Attribute, implements, classProvides |
|
20 | from zope.interface import Interface, Attribute, implements, classProvides | |
28 | except ImportError: |
|
21 | except ImportError: |
@@ -8,8 +8,6 b' which can also be useful as templates for writing new, application-specific' | |||||
8 | managers. |
|
8 | managers. | |
9 | """ |
|
9 | """ | |
10 |
|
10 | |||
11 | from __future__ import with_statement |
|
|||
12 |
|
||||
13 | __docformat__ = "restructuredtext en" |
|
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 | import os |
|
17 | import os | |
17 | from cStringIO import StringIO |
|
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 |
|
23 | #----------------------------------------------------------------------------- | |
22 | @testdec.skip("This doesn't work under Windows") |
|
24 | # Test functions | |
|
25 | ||||
|
26 | @dec.skip_win32 | |||
23 | def test_redirector(): |
|
27 | def test_redirector(): | |
24 | """ Checks that the redirector can be used to do synchronous capture. |
|
28 | """ Checks that the redirector can be used to do synchronous capture. | |
25 | """ |
|
29 | """ | |
@@ -40,8 +44,8 b' def test_redirector():' | |||||
40 | result2 = "".join("%ic\n%i\n" %(i, i) for i in range(10)) |
|
44 | result2 = "".join("%ic\n%i\n" %(i, i) for i in range(10)) | |
41 | assert result1 == result2 |
|
45 | assert result1 == result2 | |
42 |
|
46 | |||
43 | # FIXME |
|
47 | ||
44 | @testdec.skip("This doesn't work under Windows") |
|
48 | @dec.skip_win32 | |
45 | def test_redirector_output_trap(): |
|
49 | def test_redirector_output_trap(): | |
46 | """ This test check not only that the redirector_output_trap does |
|
50 | """ This test check not only that the redirector_output_trap does | |
47 | trap the output, but also that it does it in a gready way, that |
|
51 | trap the output, but also that it does it in a gready way, that | |
@@ -63,6 +67,4 b' def test_redirector_output_trap():' | |||||
63 | result1 = out.getvalue() |
|
67 | result1 = out.getvalue() | |
64 | result2 = "".join("%ic\n%ip\n%i\n" %(i, i, i) for i in range(10)) |
|
68 | result2 = "".join("%ic\n%ip\n%i\n" %(i, i, i) for i in range(10)) | |
65 | assert result1 == result2 |
|
69 | assert result1 == result2 | |
66 |
|
||||
67 |
|
70 | |||
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 | #def test_simple(): |
|
5 | #def test_simple(): | |
4 | if 0: |
|
6 | if 0: | |
@@ -25,17 +27,17 b' if 0:' | |||||
25 |
|
27 | |||
26 | mec.pushAll() |
|
28 | mec.pushAll() | |
27 |
|
29 | |||
28 | with parallel as pr: |
|
30 | ## with parallel as pr: | |
29 | # A comment |
|
31 | ## # A comment | |
30 | remote() # this means the code below only runs remotely |
|
32 | ## remote() # this means the code below only runs remotely | |
31 | print 'Hello remote world' |
|
33 | ## print 'Hello remote world' | |
32 | x = range(10) |
|
34 | ## x = range(10) | |
33 | # Comments are OK |
|
35 | ## # Comments are OK | |
34 | # Even misindented. |
|
36 | ## # Even misindented. | |
35 | y = x+1 |
|
37 | ## y = x+1 | |
36 |
|
38 | |||
37 |
|
39 | |||
38 | with pfor('i',sequence) as pr: |
|
40 | ## with pfor('i',sequence) as pr: | |
39 | print x[i] |
|
41 | ## print x[i] | |
40 |
|
42 | |||
41 | print pr.x + pr.y |
|
43 | print pr.x + pr.y |
@@ -8,6 +8,10 b' the decorator, in order to preserve metadata such as function name,' | |||||
8 | setup and teardown functions and so on - see nose.tools for more |
|
8 | setup and teardown functions and so on - see nose.tools for more | |
9 | information. |
|
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 | NOTE: This file contains IPython-specific decorators and imports the |
|
15 | NOTE: This file contains IPython-specific decorators and imports the | |
12 | numpy.testing.decorators file, which we've copied verbatim. Any of our own |
|
16 | numpy.testing.decorators file, which we've copied verbatim. Any of our own | |
13 | code will be added at the bottom if we end up extending this. |
|
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 | # Stdlib imports |
|
20 | # Stdlib imports | |
17 | import inspect |
|
21 | import inspect | |
|
22 | import sys | |||
18 |
|
23 | |||
19 | # Third-party imports |
|
24 | # Third-party imports | |
20 |
|
25 | |||
@@ -123,6 +128,9 b" skip_doctest = make_label_dec('skip_doctest'," | |||||
123 | def skip(msg=''): |
|
128 | def skip(msg=''): | |
124 | """Decorator - mark a test function for skipping from test suite. |
|
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 | :Parameters: |
|
134 | :Parameters: | |
127 |
|
135 | |||
128 | func : function |
|
136 | func : function | |
@@ -145,3 +153,8 b" def skip(msg=''):" | |||||
145 | return apply_wrapper(wrapper,func) |
|
153 | return apply_wrapper(wrapper,func) | |
146 |
|
154 | |||
147 | return inner |
|
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 | # Module imports |
|
3 | # Module imports | |
2 | # Std lib |
|
4 | # Std lib | |
3 | import inspect |
|
5 | import inspect | |
4 |
|
6 | |||
5 | # Third party |
|
|||
6 |
|
||||
7 | # Our own |
|
7 | # Our own | |
8 | from IPython.testing import decorators as dec |
|
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 | # Testing functions |
|
11 | # Testing functions | |
37 |
|
12 | |||
38 | def test_trivial(): |
|
13 | def test_trivial(): | |
39 | """A trivial passing test.""" |
|
14 | """A trivial passing test.""" | |
40 | pass |
|
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 | def doctest_run(): |
|
17 | def doctest_run(): | |
151 | """Test running a trivial script. |
|
18 | """Test running a trivial script. | |
152 |
|
19 | |||
@@ -154,7 +21,6 b' def doctest_run():' | |||||
154 | x is: 1 |
|
21 | x is: 1 | |
155 | """ |
|
22 | """ | |
156 |
|
23 | |||
157 | #@dec.skip_doctest |
|
|||
158 | def doctest_runvars(): |
|
24 | def doctest_runvars(): | |
159 | """Test that variables defined in scripts get loaded correcly via %run. |
|
25 | """Test that variables defined in scripts get loaded correcly via %run. | |
160 |
|
26 |
@@ -1,11 +1,11 b'' | |||||
1 |
============== |
|
1 | ============== | |
2 |
IPython |
|
2 | IPython README | |
3 |
============== |
|
3 | ============== | |
4 |
|
||||
5 | .. contents:: |
|
|||
6 |
|
4 | |||
7 | Overview |
|
5 | Overview | |
8 | ======== |
|
6 | ======== | |
9 |
|
7 | |||
10 |
Welcome to IPython. |
|
8 | Welcome to IPython. Our documentation can be found in the docs/source | |
11 | in the docs/source subdirectory. |
|
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 | for i, itr in enumerate(iter(pl) for pl in list_of_lists): |
|
45 | for i, itr in enumerate(iter(pl) for pl in list_of_lists): | |
46 | try: |
|
46 | try: | |
47 | item = itr.next() |
|
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 | heap.append(toadd) |
|
52 | heap.append(toadd) | |
50 | except StopIteration: |
|
53 | except StopIteration: | |
51 | pass |
|
54 | pass |
@@ -14,7 +14,7 b' However, the interpreter supplied with the standard Python distribution' | |||||
14 | is somewhat limited for extended interactive use. |
|
14 | is somewhat limited for extended interactive use. | |
15 |
|
15 | |||
16 | The goal of IPython is to create a comprehensive environment for |
|
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 | has two main components: |
|
18 | has two main components: | |
19 |
|
19 | |||
20 | * An enhanced interactive Python shell. |
|
20 | * An enhanced interactive Python shell. |
1 | NO CONTENT: file renamed from IPython/config/config.py to sandbox/config.py |
|
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 |
|
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 |
|
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 |
|
NO CONTENT: file renamed from IPython/config/traitlets.py to sandbox/traitlets.py |
@@ -15,8 +15,8 b' cd $ipdir' | |||||
15 | ./setup.py sdist --formats=gztar |
|
15 | ./setup.py sdist --formats=gztar | |
16 |
|
16 | |||
17 | # Build rpms |
|
17 | # Build rpms | |
18 |
|
|
18 | python2.4 ./setup.py bdist_rpm --binary-only --release=py24 --python=/usr/bin/python2.4 | |
19 |
|
|
19 | python2.5 ./setup.py bdist_rpm --binary-only --release=py25 --python=/usr/bin/python2.5 | |
20 |
|
20 | |||
21 | # Build eggs |
|
21 | # Build eggs | |
22 | python2.4 ./setup_bdist_egg.py |
|
22 | python2.4 ./setup_bdist_egg.py |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
General Comments 0
You need to be logged in to leave comments.
Login now