Show More
@@ -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,21 b'' | |||||
|
1 | """ Tests for various magic functions | |||
|
2 | ||||
|
3 | Needs to be run by nose (to make ipython session available) | |||
|
4 | ||||
|
5 | """ | |||
|
6 | def test_rehashx(): | |||
|
7 | # clear up everything | |||
|
8 | _ip.IP.alias_table.clear() | |||
|
9 | del _ip.db['syscmdlist'] | |||
|
10 | ||||
|
11 | _ip.magic('rehashx') | |||
|
12 | # Practically ALL ipython development systems will have more than 10 aliases | |||
|
13 | ||||
|
14 | assert len(_ip.IP.alias_table) > 10 | |||
|
15 | for key, val in _ip.IP.alias_table.items(): | |||
|
16 | # we must strip dots from alias names | |||
|
17 | assert '.' not in key | |||
|
18 | ||||
|
19 | # rehashx must fill up syscmdlist | |||
|
20 | scoms = _ip.db['syscmdlist'] | |||
|
21 | assert len(scoms) > 10 |
@@ -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) |
@@ -335,6 +335,12 b' def cd_completer(self, event):' | |||||
335 | if not found: |
|
335 | if not found: | |
336 | if os.path.isdir(relpath): |
|
336 | if os.path.isdir(relpath): | |
337 | return [relpath] |
|
337 | return [relpath] | |
|
338 | # if no completions so far, try bookmarks | |||
|
339 | bks = self.db.get('bookmarks',{}).keys() | |||
|
340 | bkmatches = [s for s in bks if s.startswith(event.symbol)] | |||
|
341 | if bkmatches: | |||
|
342 | return bkmatches | |||
|
343 | ||||
338 | raise IPython.ipapi.TryNext |
|
344 | raise IPython.ipapi.TryNext | |
339 |
|
345 | |||
340 |
|
346 |
@@ -50,9 +50,15 b' def main():' | |||||
50 | ip.ex('import os') |
|
50 | ip.ex('import os') | |
51 | ip.ex("def up(): os.chdir('..')") |
|
51 | ip.ex("def up(): os.chdir('..')") | |
52 | ip.user_ns['LA'] = LastArgFinder() |
|
52 | ip.user_ns['LA'] = LastArgFinder() | |
53 | # Nice prompt |
|
|||
54 |
|
53 | |||
55 | o.prompt_in1= r'\C_LightBlue[\C_LightCyan\Y2\C_LightBlue]\C_Green|\#> ' |
|
54 | # You can assign to _prompt_title variable | |
|
55 | # to provide some extra information for prompt | |||
|
56 | # (e.g. the current mode, host/username...) | |||
|
57 | ||||
|
58 | ip.user_ns['_prompt_title'] = '' | |||
|
59 | ||||
|
60 | # Nice prompt | |||
|
61 | o.prompt_in1= r'\C_Green${_prompt_title}\C_LightBlue[\C_LightCyan\Y2\C_LightBlue]\C_Green|\#> ' | |||
56 | o.prompt_in2= r'\C_Green|\C_LightGreen\D\C_Green> ' |
|
62 | o.prompt_in2= r'\C_Green|\C_LightGreen\D\C_Green> ' | |
57 | o.prompt_out= '<\#> ' |
|
63 | o.prompt_out= '<\#> ' | |
58 |
|
64 | |||
@@ -98,9 +104,15 b' def main():' | |||||
98 | for cmd in syscmds: |
|
104 | for cmd in syscmds: | |
99 | # print "sys",cmd #dbg |
|
105 | # print "sys",cmd #dbg | |
100 | noext, ext = os.path.splitext(cmd) |
|
106 | noext, ext = os.path.splitext(cmd) | |
101 | key = mapper(noext) |
|
107 | if ext.lower() == '.exe': | |
|
108 | cmd = noext | |||
|
109 | ||||
|
110 | key = mapper(cmd) | |||
102 | if key not in ip.IP.alias_table: |
|
111 | if key not in ip.IP.alias_table: | |
103 | ip.defalias(key, cmd) |
|
112 | # Dots will be removed from alias names, since ipython | |
|
113 | # assumes names with dots to be python code | |||
|
114 | ||||
|
115 | ip.defalias(key.replace('.',''), cmd) | |||
104 |
|
116 | |||
105 | # mglob combines 'find', recursion, exclusion... '%mglob?' to learn more |
|
117 | # mglob combines 'find', recursion, exclusion... '%mglob?' to learn more | |
106 | ip.load("IPython.external.mglob") |
|
118 | ip.load("IPython.external.mglob") |
@@ -2329,6 +2329,12 b' Currently the magic system has the following functions:\\n"""' | |||||
2329 | print 'Editing...', |
|
2329 | print 'Editing...', | |
2330 | sys.stdout.flush() |
|
2330 | sys.stdout.flush() | |
2331 | self.shell.hooks.editor(filename,lineno) |
|
2331 | self.shell.hooks.editor(filename,lineno) | |
|
2332 | ||||
|
2333 | # XXX TODO: should this be generalized for all string vars? | |||
|
2334 | # For now, this is special-cased to blocks created by cpaste | |||
|
2335 | if args.strip() == 'pasted_block': | |||
|
2336 | self.shell.user_ns['pasted_block'] = file_read(filename) | |||
|
2337 | ||||
2332 | if opts.has_key('x'): # -x prevents actual execution |
|
2338 | if opts.has_key('x'): # -x prevents actual execution | |
2333 |
|
2339 | |||
2334 | else: |
|
2340 | else: | |
@@ -2338,6 +2344,8 b' Currently the magic system has the following functions:\\n"""' | |||||
2338 | else: |
|
2344 | else: | |
2339 | self.shell.safe_execfile(filename,self.shell.user_ns, |
|
2345 | self.shell.safe_execfile(filename,self.shell.user_ns, | |
2340 | self.shell.user_ns) |
|
2346 | self.shell.user_ns) | |
|
2347 | ||||
|
2348 | ||||
2341 | if use_temp: |
|
2349 | if use_temp: | |
2342 | try: |
|
2350 | try: | |
2343 | return open(filename).read() |
|
2351 | return open(filename).read() | |
@@ -2647,8 +2655,10 b' Defaulting color scheme to \'NoColor\'"""' | |||||
2647 | if isexec(ff) and ff not in self.shell.no_alias: |
|
2655 | if isexec(ff) and ff not in self.shell.no_alias: | |
2648 | # each entry in the alias table must be (N,name), |
|
2656 | # each entry in the alias table must be (N,name), | |
2649 | # where N is the number of positional arguments of the |
|
2657 | # where N is the number of positional arguments of the | |
2650 | # alias. |
|
2658 | # alias. | |
2651 | alias_table[ff] = (0,ff) |
|
2659 | # Dots will be removed from alias names, since ipython | |
|
2660 | # assumes names with dots to be python code | |||
|
2661 | alias_table[ff.replace('.','')] = (0,ff) | |||
2652 | syscmdlist.append(ff) |
|
2662 | syscmdlist.append(ff) | |
2653 | else: |
|
2663 | else: | |
2654 | for pdir in path: |
|
2664 | for pdir in path: | |
@@ -2658,7 +2668,7 b' Defaulting color scheme to \'NoColor\'"""' | |||||
2658 | if isexec(ff) and base.lower() not in self.shell.no_alias: |
|
2668 | if isexec(ff) and base.lower() not in self.shell.no_alias: | |
2659 | if ext.lower() == '.exe': |
|
2669 | if ext.lower() == '.exe': | |
2660 | ff = base |
|
2670 | ff = base | |
2661 | alias_table[base.lower()] = (0,ff) |
|
2671 | alias_table[base.lower().replace('.','')] = (0,ff) | |
2662 | syscmdlist.append(ff) |
|
2672 | syscmdlist.append(ff) | |
2663 | # Make sure the alias table doesn't contain keywords or builtins |
|
2673 | # Make sure the alias table doesn't contain keywords or builtins | |
2664 | self.shell.alias_table_validate() |
|
2674 | self.shell.alias_table_validate() | |
@@ -3210,14 +3220,24 b' Defaulting color scheme to \'NoColor\'"""' | |||||
3210 | This assigns the pasted block to variable 'foo' as string, without |
|
3220 | This assigns the pasted block to variable 'foo' as string, without | |
3211 | dedenting or executing it (preceding >>> and + is still stripped) |
|
3221 | dedenting or executing it (preceding >>> and + is still stripped) | |
3212 |
|
3222 | |||
|
3223 | '%cpaste -r' re-executes the block previously entered by cpaste. | |||
|
3224 | ||||
3213 | Do not be alarmed by garbled output on Windows (it's a readline bug). |
|
3225 | Do not be alarmed by garbled output on Windows (it's a readline bug). | |
3214 | Just press enter and type -- (and press enter again) and the block |
|
3226 | Just press enter and type -- (and press enter again) and the block | |
3215 | will be what was just pasted. |
|
3227 | will be what was just pasted. | |
3216 |
|
3228 | |||
3217 | IPython statements (magics, shell escapes) are not supported (yet). |
|
3229 | IPython statements (magics, shell escapes) are not supported (yet). | |
3218 | """ |
|
3230 | """ | |
3219 | opts,args = self.parse_options(parameter_s,'s:',mode='string') |
|
3231 | opts,args = self.parse_options(parameter_s,'rs:',mode='string') | |
3220 | par = args.strip() |
|
3232 | par = args.strip() | |
|
3233 | if opts.has_key('r'): | |||
|
3234 | b = self.user_ns.get('pasted_block', None) | |||
|
3235 | if b is None: | |||
|
3236 | raise UsageError('No previous pasted block available') | |||
|
3237 | print "Re-executing '%s...' (%d chars)"% (b.split('\n',1)[0], len(b)) | |||
|
3238 | exec b in self.user_ns | |||
|
3239 | return | |||
|
3240 | ||||
3221 | sentinel = opts.get('s','--') |
|
3241 | sentinel = opts.get('s','--') | |
3222 |
|
3242 | |||
3223 | # Regular expressions that declare text we strip from the input: |
|
3243 | # Regular expressions that declare text we strip from the input: | |
@@ -3245,8 +3265,8 b' Defaulting color scheme to \'NoColor\'"""' | |||||
3245 | #print "block:\n",block |
|
3265 | #print "block:\n",block | |
3246 | if not par: |
|
3266 | if not par: | |
3247 | b = textwrap.dedent(block) |
|
3267 | b = textwrap.dedent(block) | |
3248 | exec b in self.user_ns |
|
|||
3249 | self.user_ns['pasted_block'] = b |
|
3268 | self.user_ns['pasted_block'] = b | |
|
3269 | exec b in self.user_ns | |||
3250 | else: |
|
3270 | else: | |
3251 | self.user_ns[par] = SList(block.splitlines()) |
|
3271 | self.user_ns[par] = SList(block.splitlines()) | |
3252 | print "Block assigned to '%s'" % par |
|
3272 | print "Block assigned to '%s'" % par |
@@ -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 |
@@ -8,6 +8,7 b' import os' | |||||
8 |
|
8 | |||
9 | # IPython imports |
|
9 | # IPython imports | |
10 | from IPython.genutils import Term, ask_yes_no |
|
10 | from IPython.genutils import Term, ask_yes_no | |
|
11 | import IPython.ipapi | |||
11 |
|
12 | |||
12 | def magic_history(self, parameter_s = ''): |
|
13 | def magic_history(self, parameter_s = ''): | |
13 | """Print input history (_i<n> variables), with most recent last. |
|
14 | """Print input history (_i<n> variables), with most recent last. | |
@@ -222,6 +223,7 b' class ShadowHist:' | |||||
222 | # cmd => idx mapping |
|
223 | # cmd => idx mapping | |
223 | self.curidx = 0 |
|
224 | self.curidx = 0 | |
224 | self.db = db |
|
225 | self.db = db | |
|
226 | self.disabled = False | |||
225 |
|
227 | |||
226 | def inc_idx(self): |
|
228 | def inc_idx(self): | |
227 | idx = self.db.get('shadowhist_idx', 1) |
|
229 | idx = self.db.get('shadowhist_idx', 1) | |
@@ -229,12 +231,19 b' class ShadowHist:' | |||||
229 | return idx |
|
231 | return idx | |
230 |
|
232 | |||
231 | def add(self, ent): |
|
233 | def add(self, ent): | |
232 | old = self.db.hget('shadowhist', ent, _sentinel) |
|
234 | if self.disabled: | |
233 | if old is not _sentinel: |
|
|||
234 | return |
|
235 | return | |
235 | newidx = self.inc_idx() |
|
236 | try: | |
236 | #print "new",newidx # dbg |
|
237 | old = self.db.hget('shadowhist', ent, _sentinel) | |
237 | self.db.hset('shadowhist',ent, newidx) |
|
238 | if old is not _sentinel: | |
|
239 | return | |||
|
240 | newidx = self.inc_idx() | |||
|
241 | #print "new",newidx # dbg | |||
|
242 | self.db.hset('shadowhist',ent, newidx) | |||
|
243 | except: | |||
|
244 | IPython.ipapi.get().IP.showtraceback() | |||
|
245 | print "WARNING: disabling shadow history" | |||
|
246 | self.disabled = True | |||
238 |
|
247 | |||
239 | def all(self): |
|
248 | def all(self): | |
240 | d = self.db.hdict('shadowhist') |
|
249 | d = self.db.hdict('shadowhist') |
@@ -13,15 +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 | # FIXME: |
|
20 | # Our own imports | |
20 | import nose |
|
21 | from IPython.testing import decorators as dec | |
21 | import sys |
|
|||
22 | if sys.platform == 'win32': |
|
|||
23 | raise nose.SkipTest("These tests are not reliable under windows") |
|
|||
24 |
|
22 | |||
|
23 | #----------------------------------------------------------------------------- | |||
|
24 | # Test functions | |||
|
25 | ||||
|
26 | @dec.skip_win32 | |||
25 | def test_redirector(): |
|
27 | def test_redirector(): | |
26 | """ Checks that the redirector can be used to do synchronous capture. |
|
28 | """ Checks that the redirector can be used to do synchronous capture. | |
27 | """ |
|
29 | """ | |
@@ -42,6 +44,8 b' def test_redirector():' | |||||
42 | 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)) | |
43 | assert result1 == result2 |
|
45 | assert result1 == result2 | |
44 |
|
46 | |||
|
47 | ||||
|
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 |
|
@@ -91,7 +91,7 b' def start_engine():' | |||||
91 | try: |
|
91 | try: | |
92 | engine_service.execute(shell_import_statement) |
|
92 | engine_service.execute(shell_import_statement) | |
93 | except: |
|
93 | except: | |
94 | log.msg("Error running import_statement: %s" % sis) |
|
94 | log.msg("Error running import_statement: %s" % shell_import_statement) | |
95 |
|
95 | |||
96 | # Create the service hierarchy |
|
96 | # Create the service hierarchy | |
97 | main_service = service.MultiService() |
|
97 | main_service = service.MultiService() | |
@@ -169,4 +169,4 b' def main():' | |||||
169 |
|
169 | |||
170 |
|
170 | |||
171 | if __name__ == "__main__": |
|
171 | if __name__ == "__main__": | |
172 | main() No newline at end of file |
|
172 | main() |
@@ -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 |
@@ -6,20 +6,55 b" What's new" | |||||
6 |
|
6 | |||
7 | .. contents:: |
|
7 | .. contents:: | |
8 | .. |
|
8 | .. | |
9 | 1 Release 0.9 |
|
9 | 1 Release 0.9.1 | |
10 | 1.1 New features |
|
10 | 2 Release 0.9 | |
11 |
|
|
11 | 2.1 New features | |
12 | 1.3 Backwards incompatible changes |
|
12 | 2.2 Bug fixes | |
13 | 1.4 Changes merged in from IPython1 |
|
13 | 2.3 Backwards incompatible changes | |
14 | 1.4.1 New features |
|
14 | 2.4 Changes merged in from IPython1 | |
15 |
|
|
15 | 2.4.1 New features | |
16 | 1.4.3 Backwards incompatible changes |
|
16 | 2.4.2 Bug fixes | |
17 | 2 Release 0.8.4 |
|
17 | 2.4.3 Backwards incompatible changes | |
18 |
3 Release 0.8. |
|
18 | 3 Release 0.8.4 | |
19 |
4 Release 0.8. |
|
19 | 4 Release 0.8.3 | |
20 |
5 |
|
20 | 5 Release 0.8.2 | |
|
21 | 6 Older releases | |||
21 | .. |
|
22 | .. | |
22 |
|
23 | |||
|
24 | Release DEV | |||
|
25 | =========== | |||
|
26 | ||||
|
27 | * cd completer: show bookmarks if no other completions are available. | |||
|
28 | ||||
|
29 | * Remove ipy_leo.py. "easy_install ipython-extension" to get it. | |||
|
30 | (done to decouple it from ipython release cycle) | |||
|
31 | ||||
|
32 | * sh profile: easy way to give 'title' to prompt: assign to variable | |||
|
33 | '_prompt_title'. It looks like this:: | |||
|
34 | ||||
|
35 | [~]|1> _prompt_title = 'sudo!' | |||
|
36 | sudo![~]|2> | |||
|
37 | ||||
|
38 | * %rehashx: Aliases no longer contain dots. python3.0 binary | |||
|
39 | will create alias python30. Fixes: | |||
|
40 | #259716 "commands with dots in them don't work" | |||
|
41 | ||||
|
42 | * %cpaste: %cpaste -r repeats the last pasted block. | |||
|
43 | The block is assigned to pasted_block even if code | |||
|
44 | raises exception. | |||
|
45 | ||||
|
46 | * %edit: If you do '%edit pasted_block', pasted_block | |||
|
47 | variable gets updated with new data (so repeated | |||
|
48 | editing makes sense) | |||
|
49 | ||||
|
50 | ||||
|
51 | Release 0.9.1 | |||
|
52 | ============= | |||
|
53 | ||||
|
54 | This release was quickly made to restore compatibility with Python 2.4, which | |||
|
55 | version 0.9 accidentally broke. No new features were introduced, other than | |||
|
56 | some additional testing support for internal use. | |||
|
57 | ||||
23 |
|
58 | |||
24 | Release 0.9 |
|
59 | Release 0.9 | |
25 | =========== |
|
60 | =========== |
@@ -1,10 +1,8 b'' | |||||
1 | .. _development: |
|
1 | .. _development: | |
2 |
|
2 | |||
3 |
============================== |
|
3 | ============================== | |
4 | IPython development guidelines |
|
4 | IPython development guidelines | |
5 |
============================== |
|
5 | ============================== | |
6 |
|
||||
7 | .. contents:: |
|
|||
8 |
|
6 | |||
9 |
|
7 | |||
10 | Overview |
|
8 | Overview | |
@@ -380,6 +378,7 b' are interested in working on this part of IPython. The current prototype of' | |||||
380 | .. _ConfigObj: http://www.voidspace.org.uk/python/configobj.html |
|
378 | .. _ConfigObj: http://www.voidspace.org.uk/python/configobj.html | |
381 | .. _Traits: http://code.enthought.com/traits/ |
|
379 | .. _Traits: http://code.enthought.com/traits/ | |
382 |
|
380 | |||
|
381 | ||||
383 | Installation and testing scenarios |
|
382 | Installation and testing scenarios | |
384 | ================================== |
|
383 | ================================== | |
385 |
|
384 | |||
@@ -424,3 +423,24 b' Tests to run for these scenarios' | |||||
424 | installed. |
|
423 | installed. | |
425 | 5. Beat on the IPython terminal a bunch. |
|
424 | 5. Beat on the IPython terminal a bunch. | |
426 | 6. Make sure that furl files are being put in proper locations. |
|
425 | 6. Make sure that furl files are being put in proper locations. | |
|
426 | ||||
|
427 | ||||
|
428 | Release checklist | |||
|
429 | ================= | |||
|
430 | ||||
|
431 | Most of the release process is automated by the :file:`release` script in the | |||
|
432 | :file:`tools` directory. This is just a handy reminder for the release manager. | |||
|
433 | ||||
|
434 | #. Run the release script, which makes the tar.gz, eggs and Win32 .exe | |||
|
435 | installer. It posts them to the site and registers the release with PyPI. | |||
|
436 | ||||
|
437 | #. Updating the website with announcements and links to the updated changes.txt | |||
|
438 | in html form. Remember to put a short note both on the news page of the site | |||
|
439 | and on launcphad. | |||
|
440 | ||||
|
441 | #. Drafting a short release announcement with i) highlights and ii) a link to | |||
|
442 | the html changes.txt. | |||
|
443 | ||||
|
444 | #. Make sure that the released version of the docs is live on the site. | |||
|
445 | ||||
|
446 | #. Celebrate! |
@@ -4,7 +4,7 b' IPython Documentation' | |||||
4 |
|
4 | |||
5 | .. htmlonly:: |
|
5 | .. htmlonly:: | |
6 |
|
6 | |||
7 |
:Release: | |
|
7 | :Release: |release| | |
8 | :Date: |today| |
|
8 | :Date: |today| | |
9 |
|
9 | |||
10 | Contents: |
|
10 | Contents: |
@@ -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 |
@@ -12,4 +12,4 b' for f in fs:' | |||||
12 |
|
12 | |||
13 | if errs: |
|
13 | if errs: | |
14 | print "%3s" % errs, f |
|
14 | print "%3s" % errs, f | |
15 | No newline at end of file |
|
15 |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed | ||
This diff has been collapsed as it changes many lines, (660 lines changed) Show them Hide them |
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