Show More
@@ -0,0 +1,56 b'' | |||
|
1 | """ Utilities for accessing the platform's clipboard. | |
|
2 | """ | |
|
3 | ||
|
4 | import subprocess | |
|
5 | import sys | |
|
6 | ||
|
7 | from IPython.core.ipapi import TryNext | |
|
8 | ||
|
9 | ||
|
10 | def win32_clipboard_get(): | |
|
11 | """ Get the current clipboard's text on Windows. | |
|
12 | ||
|
13 | Requires Mark Hammond's pywin32 extensions. | |
|
14 | """ | |
|
15 | try: | |
|
16 | import win32clipboard | |
|
17 | except ImportError: | |
|
18 | message = ("Getting text from the clipboard requires the pywin32 " | |
|
19 | "extensions: http://sourceforge.net/projects/pywin32/") | |
|
20 | raise TryNext(message) | |
|
21 | win32clipboard.OpenClipboard() | |
|
22 | text = win32clipboard.GetClipboardData(win32clipboard.CF_TEXT) | |
|
23 | # FIXME: convert \r\n to \n? | |
|
24 | win32clipboard.CloseClipboard() | |
|
25 | return text | |
|
26 | ||
|
27 | def osx_clipboard_get(): | |
|
28 | """ Get the clipboard's text on OS X. | |
|
29 | """ | |
|
30 | p = subprocess.Popen(['pbpaste', '-Prefer', 'ascii'], | |
|
31 | stdout=subprocess.PIPE) | |
|
32 | text, stderr = p.communicate() | |
|
33 | # Text comes in with old Mac \r line endings. Change them to \n. | |
|
34 | text = text.replace('\r', '\n') | |
|
35 | return text | |
|
36 | ||
|
37 | def tkinter_clipboard_get(): | |
|
38 | """ Get the clipboard's text using Tkinter. | |
|
39 | ||
|
40 | This is the default on systems that are not Windows or OS X. It may | |
|
41 | interfere with other UI toolkits and should be replaced with an | |
|
42 | implementation that uses that toolkit. | |
|
43 | """ | |
|
44 | try: | |
|
45 | import Tkinter | |
|
46 | except ImportError: | |
|
47 | message = ("Getting text from the clipboard on this platform " | |
|
48 | "requires Tkinter.") | |
|
49 | raise TryNext(message) | |
|
50 | root = Tkinter.Tk() | |
|
51 | root.withdraw() | |
|
52 | text = root.clipboard_get() | |
|
53 | root.destroy() | |
|
54 | return text | |
|
55 | ||
|
56 |
@@ -0,0 +1,85 b'' | |||
|
1 | """This is meant to be run from the IPython prompt: | |
|
2 | ||
|
3 | %run demo-exercizer.py | |
|
4 | ||
|
5 | It will create demo objects of the example that is embedded in demo.py in a | |
|
6 | number of ways and allow you to see how they work, just follow the printed | |
|
7 | directions.""" | |
|
8 | ||
|
9 | #----------------------------------------------------------------------------- | |
|
10 | # Imports | |
|
11 | #----------------------------------------------------------------------------- | |
|
12 | ||
|
13 | # From std lib | |
|
14 | import StringIO | |
|
15 | import os | |
|
16 | import shutil | |
|
17 | import tempfile | |
|
18 | ||
|
19 | # From IPython | |
|
20 | from IPython.demo import (Demo, IPythonDemo, LineDemo, IPythonLineDemo, | |
|
21 | ClearDemo, ClearIPDemo) | |
|
22 | ||
|
23 | #----------------------------------------------------------------------------- | |
|
24 | # Demo code | |
|
25 | #----------------------------------------------------------------------------- | |
|
26 | ||
|
27 | example1 = """ | |
|
28 | '''A simple interactive demo to illustrate the use of IPython's Demo class.''' | |
|
29 | ||
|
30 | print 'Hello, welcome to an interactive IPython demo.' | |
|
31 | ||
|
32 | # The mark below defines a block boundary, which is a point where IPython will | |
|
33 | # stop execution and return to the interactive prompt. The dashes are actually | |
|
34 | # optional and used only as a visual aid to clearly separate blocks while | |
|
35 | # editing the demo code. | |
|
36 | # <demo> stop | |
|
37 | ||
|
38 | x = 1 | |
|
39 | y = 2 | |
|
40 | ||
|
41 | # <demo> stop | |
|
42 | ||
|
43 | # the mark below makes this block as silent | |
|
44 | # <demo> silent | |
|
45 | ||
|
46 | print 'This is a silent block, which gets executed but not printed.' | |
|
47 | ||
|
48 | # <demo> stop | |
|
49 | # <demo> auto | |
|
50 | print 'This is an automatic block.' | |
|
51 | print 'It is executed without asking for confirmation, but printed.' | |
|
52 | z = x+y | |
|
53 | ||
|
54 | print 'z=',x | |
|
55 | ||
|
56 | # <demo> stop | |
|
57 | # This is just another normal block. | |
|
58 | print 'z is now:', z | |
|
59 | ||
|
60 | print 'bye!' | |
|
61 | """ | |
|
62 | fp = tempfile.mkdtemp(prefix = 'DemoTmp') | |
|
63 | fd, filename = tempfile.mkstemp(prefix = 'demoExample1File', suffix = '.py', | |
|
64 | dir = fp) | |
|
65 | f = os.fdopen(fd, 'wt') | |
|
66 | ||
|
67 | f.write(example1) | |
|
68 | f.close() | |
|
69 | ||
|
70 | my_d = Demo(filename) | |
|
71 | my_cd = ClearDemo(filename) | |
|
72 | ||
|
73 | fobj = StringIO.StringIO(example1) | |
|
74 | str_d = Demo(fobj, title='via stringio') | |
|
75 | ||
|
76 | print ''' | |
|
77 | The example that is embeded in demo.py file has been used to create | |
|
78 | the following 3 demos, and should now be available to use: | |
|
79 | my_d() -- created from a file | |
|
80 | my_cd() -- created from a file, a ClearDemo | |
|
81 | str_d() -- same as above, but created via a StringIO object | |
|
82 | Call by typing their name, (with parentheses), at the | |
|
83 | ipython prompt, interact with the block, then call again | |
|
84 | to run the next block. | |
|
85 | ''' |
@@ -0,0 +1,48 b'' | |||
|
1 | .TH IPCLUSTER 1 "October 28, 2008" "" "" | |
|
2 | .SH NAME | |
|
3 | \fBipcluster \- IPython parallel computing cluster control tool | |
|
4 | .SH SYNOPSIS | |
|
5 | .nf | |
|
6 | .fam C | |
|
7 | \fBipcluster\fP {\fmpiexec,local,mpirun,pbs,ssh\fP} [\fIoptions\fP] | |
|
8 | .fam T | |
|
9 | .fi | |
|
10 | .SH DESCRIPTION | |
|
11 | ipcluster is a control tool for IPython's parallel computing functions. | |
|
12 | ||
|
13 | IPython cluster startup. This starts a controller and engines using various | |
|
14 | approaches. Use the IPYTHONDIR environment variable to change your IPython | |
|
15 | directory from the default of .ipython or _ipython. The log and security | |
|
16 | subdirectories of your IPython directory will be used by this script for log | |
|
17 | files and security files. | |
|
18 | .SH POSITIONAL ARGUMENTS | |
|
19 | ||
|
20 | The first positional argument should be one of: {mpiexec, local, mpirun, pbs, | |
|
21 | ssh}, which are the available cluster types. | |
|
22 | ||
|
23 | For detailed help on each, type "ipcluster TYPE --help". Briefly: | |
|
24 | ||
|
25 | local run a local cluster | |
|
26 | mpirun run a cluster using mpirun (mpiexec also works) | |
|
27 | mpiexec run a cluster using mpiexec (mpirun also works) | |
|
28 | pbs run a pbs cluster | |
|
29 | ssh run a cluster using ssh, should have ssh-keys setup | |
|
30 | .SH OPTIONS | |
|
31 | .TP | |
|
32 | .B | |
|
33 | \-h, \-\-help | |
|
34 | show help message and exit | |
|
35 | .SH EXAMPLE | |
|
36 | ipcluster local -n 4 | |
|
37 | ||
|
38 | This command will start 4 IPython engines on the local computer. | |
|
39 | .SH SEE ALSO | |
|
40 | .BR ipython(1), ipcontroller(1), ipengine(1) | |
|
41 | .br | |
|
42 | .SH AUTHOR | |
|
43 | \fBipcluster\fP is a tool that ships with IPython, created by | |
|
44 | the IPython Development Team. | |
|
45 | .PP | |
|
46 | This manual page was written by Stephan Peijnik <debian@sp.or.at>, | |
|
47 | for the Debian project (but may be used by others). Modified by Fernando Perez | |
|
48 | <Fernando.Perez@berkeley.edu> for inclusion in IPython. |
@@ -0,0 +1,87 b'' | |||
|
1 | .TH IPCONTROLLER 1 "October 29, 2008" "" "" | |
|
2 | .SH NAME | |
|
3 | \fBipcontroller \- IPython parallel computing controller control tool | |
|
4 | .SH SYNOPSIS | |
|
5 | .nf | |
|
6 | .fam C | |
|
7 | \fBipengine\fP [\fIoptions\fP] | |
|
8 | .fam T | |
|
9 | .fi | |
|
10 | .SH DESCRIPTION | |
|
11 | ipcontroller is a control tool for IPython's parallel computing functions. | |
|
12 | .SH OPTIONS | |
|
13 | .TP | |
|
14 | .B | |
|
15 | \-h, \-\-help | |
|
16 | show this help message and exit | |
|
17 | .TP | |
|
18 | .B | |
|
19 | \-\-client\-ip=CLIENT_IP | |
|
20 | the IP address or hostname the controller will listen on for | |
|
21 | client connections | |
|
22 | .TP | |
|
23 | .B | |
|
24 | \-\-client\-port=CLIENT_PORT | |
|
25 | the port the controller will listen on for client connections | |
|
26 | .TP | |
|
27 | .B | |
|
28 | \-\-client\-location=CLIENT_LOCATION | |
|
29 | hostname or ip for clients to connect to | |
|
30 | .TP | |
|
31 | .B | |
|
32 | \-x | |
|
33 | turn off all client security | |
|
34 | .TP | |
|
35 | .B | |
|
36 | \-\-client\-cert\-file=CLIENT_CERT_FILE | |
|
37 | file to store the client SSL certificate | |
|
38 | .TP | |
|
39 | .B | |
|
40 | \-\-task\-furl\-file=TASK_FURL_FILE | |
|
41 | file to store the FURL for task clients to connect with | |
|
42 | .TP | |
|
43 | .B | |
|
44 | \-\-multiengine\-furl\-file=MULTIENGINE_FURL_FILE | |
|
45 | file to store the FURL for multiengine clients to connect with | |
|
46 | .TP | |
|
47 | .B | |
|
48 | \-\-engine\-ip=ENGINE_IP | |
|
49 | the IP address or hostname the controller will listen on for engine connections | |
|
50 | .TP | |
|
51 | .B | |
|
52 | \-\-engine\-port=ENGINE_PORT | |
|
53 | the port the controller will listen on for engine connections | |
|
54 | .TP | |
|
55 | .B | |
|
56 | \-\-engine\-location=ENGINE_LOCATION | |
|
57 | the IP address or hostname for engine to connect to | |
|
58 | .TP | |
|
59 | .B | |
|
60 | \-y | |
|
61 | turn off all engine security | |
|
62 | .TP | |
|
63 | .B | |
|
64 | \-\-engine\-cert\-file=ENGINE_CERT_FILE | |
|
65 | file to store the engine SSL certificate | |
|
66 | .TP | |
|
67 | .B | |
|
68 | \-\-engine\-furl\-file=ENGINE_FURL_FILE | |
|
69 | file to store the FURL for engines to connect with | |
|
70 | .TP | |
|
71 | .B | |
|
72 | \-l LOGFILE, \-\-logfile=LOGFILE | |
|
73 | log file name (default is stdout) | |
|
74 | .TP | |
|
75 | .B | |
|
76 | \-r | |
|
77 | try to reuse all furl files | |
|
78 | .SH SEE ALSO | |
|
79 | .BR ipython(1), ipcluster(1), ipengine(1) | |
|
80 | .br | |
|
81 | .SH AUTHOR | |
|
82 | \fBipcontroller\fP is a tool that ships with IPython, created by | |
|
83 | the IPython Development Team. | |
|
84 | .PP | |
|
85 | This manual page was written by Stephan Peijnik <debian@sp.or.at>, | |
|
86 | for the Debian project (but may be used by others). Modified by Fernando Perez | |
|
87 | <Fernando.Perez@berkeley.edu> for inclusion in IPython. |
@@ -0,0 +1,38 b'' | |||
|
1 | .TH IPENGINE 1 "October 28, 2008" "" "" | |
|
2 | .SH NAME | |
|
3 | \fBipengine \- IPython parallel computing engine control tool | |
|
4 | .SH SYNOPSIS | |
|
5 | .nf | |
|
6 | .fam C | |
|
7 | \fBipengine\fP [\fIoptions\fP] | |
|
8 | .fam T | |
|
9 | .fi | |
|
10 | .SH DESCRIPTION | |
|
11 | ipengine is a control tool for IPython's parallel computing functions. | |
|
12 | .SH OPTIONS | |
|
13 | .TP | |
|
14 | .B | |
|
15 | \-h, \-\-help | |
|
16 | show this help message and exit | |
|
17 | .TP | |
|
18 | .B | |
|
19 | \-\-furl\-file=FURL_FILE | |
|
20 | The filename containing the FURL of the controller | |
|
21 | .TP | |
|
22 | .B | |
|
23 | \-\-mpi=MPI | |
|
24 | How to enable MPI (mpi4py, pytrilions, or empty string to disable) | |
|
25 | .TP | |
|
26 | .B | |
|
27 | \-l LOGFILE, \-\-logfile=LOGFILE | |
|
28 | log file name (defaults to stdout) | |
|
29 | .SH SEE ALSO | |
|
30 | .BR ipython(1), ipcluster(1), ipcontroller(1) | |
|
31 | .br | |
|
32 | .SH AUTHOR | |
|
33 | \fBipengine\fP is a tool that ships with IPython, created by | |
|
34 | the IPython Development Team. | |
|
35 | .PP | |
|
36 | This manual page was written by Stephan Peijnik <debian@sp.or.at>, | |
|
37 | for the Debian project (but may be used by others). Modified by Fernando Perez | |
|
38 | <Fernando.Perez@berkeley.edu> for inclusion in IPython. |
@@ -0,0 +1,25 b'' | |||
|
1 | .TH IPYTHON-WX 1 "October 29, 2008" "" "" | |
|
2 | .SH NAME | |
|
3 | \fBipython-wx \- Graphical frontend that embeds a multithreaded IPython Shell | |
|
4 | .SH SYNOPSIS | |
|
5 | .nf | |
|
6 | .fam C | |
|
7 | \fBipython-wx\fP | |
|
8 | .fam T | |
|
9 | .fi | |
|
10 | .SH DESCRIPTION | |
|
11 | ipython-wx is, compared to ipythonx, a more advanced graphical frontend | |
|
12 | to IPython. It is implemented using WxWidgets. | |
|
13 | .SH OPTIONS | |
|
14 | .TP | |
|
15 | .B | |
|
16 | ipython-wx does not accept any command line options. | |
|
17 | .SH SEE ALSO | |
|
18 | .BR ipython(1), ipythonx(1) | |
|
19 | .br | |
|
20 | .SH AUTHOR | |
|
21 | \fBipython-wx\fP is a tool that ships with IPython, created by | |
|
22 | the IPython Development Team. | |
|
23 | .PP | |
|
24 | This manual page was written by Stephan Peijnik <debian@sp.or.at>, | |
|
25 | for the Debian project (but may be used by others). |
@@ -0,0 +1,30 b'' | |||
|
1 | .TH IPYTHONX 1 "October 29, 2008" "" "" | |
|
2 | .SH NAME | |
|
3 | \fBipythonx \- Simple graphical frontend to IPython, using WxWidgets. | |
|
4 | .SH SYNOPSIS | |
|
5 | .nf | |
|
6 | .fam C | |
|
7 | \fBipengine\fP [\fIoptions\fP] | |
|
8 | .fam T | |
|
9 | .fi | |
|
10 | .SH DESCRIPTION | |
|
11 | ipythonx is a simple graphical frontend to IPython, using WxWidgets. | |
|
12 | .SH OPTIONS | |
|
13 | .TP | |
|
14 | .B | |
|
15 | \-h, \-\-help | |
|
16 | show this help message and exit | |
|
17 | .TP | |
|
18 | .B | |
|
19 | \-d, \-\-debug | |
|
20 | Enable debug messages for the wx frontend. | |
|
21 | look for config files and profiles in this directory | |
|
22 | .SH SEE ALSO | |
|
23 | .BR ipython(1), ipython-wx(1) | |
|
24 | .br | |
|
25 | .SH AUTHOR | |
|
26 | \fBipythonx\fP is a tool that ships with IPython, created by | |
|
27 | the IPython Development Team. | |
|
28 | .PP | |
|
29 | This manual page was written by Stephan Peijnik <debian@sp.or.at>, | |
|
30 | for the Debian project (but may be used by others). |
@@ -0,0 +1,49 b'' | |||
|
1 | .TH IRUNNER 1 "April 24, 2007" "" "" | |
|
2 | .SH NAME | |
|
3 | \fBirunner \- interactive runner interface | |
|
4 | .SH SYNOPSIS | |
|
5 | .nf | |
|
6 | .fam C | |
|
7 | \fBirunner\fP [\fIoptions\fP] \fIfile_to_run\fP | |
|
8 | .fam T | |
|
9 | .fi | |
|
10 | .SH DESCRIPTION | |
|
11 | irunner is an interface to the various interactive runners | |
|
12 | available in IPython's \fBirunner\fP module. | |
|
13 | .PP | |
|
14 | The already implemented runners are listed below; adding | |
|
15 | one for a new program is a trivial task, see the source | |
|
16 | for examples. | |
|
17 | .SH OPTIONS | |
|
18 | .TP | |
|
19 | .B | |
|
20 | \-h, \-\-help | |
|
21 | show this help message and exit | |
|
22 | .TP | |
|
23 | .B | |
|
24 | \-\-ipython | |
|
25 | IPython interactive runner (default). | |
|
26 | .TP | |
|
27 | .B | |
|
28 | \-\-python | |
|
29 | Python interactive runner. | |
|
30 | .TP | |
|
31 | .B | |
|
32 | \-\-sage | |
|
33 | SAGE interactive runner. | |
|
34 | .SH EXAMPLE | |
|
35 | irunner.py \-\-python \-\- \-\-help | |
|
36 | will pass \-\-help to the python runner. | |
|
37 | Similarly, | |
|
38 | irunner.py \-\-ipython \-\- \-\-interact script.ipy | |
|
39 | .SH SEE ALSO | |
|
40 | .BR ipython(1) | |
|
41 | .br | |
|
42 | .SH AUTHOR | |
|
43 | \fBirunner\fP is an extension of Ken Schutte <kschutte-AT-csail.mit.edu>'s | |
|
44 | script contributed on the ipython-user list: | |
|
45 | http://scipy.net/pipermail/ipython-user/2006-May/001705.html | |
|
46 | .PP | |
|
47 | This manual page was written by Bernd Zeimetz <bernd@bzed.de>, for the Debian | |
|
48 | project (but may be used by others). Modified by Fernando Perez | |
|
49 | <Fernando.Perez@berkeley.edu> for inclusion in IPython. |
@@ -0,0 +1,42 b'' | |||
|
1 | #!/usr/bin/env python | |
|
2 | """IPython release build script. | |
|
3 | """ | |
|
4 | from toollib import * | |
|
5 | ||
|
6 | # Get main ipython dir, this will raise if it doesn't pass some checks | |
|
7 | ipdir = get_ipdir() | |
|
8 | cd(ipdir) | |
|
9 | ||
|
10 | # Load release info | |
|
11 | execfile(pjoin('IPython','core','release.py')) | |
|
12 | ||
|
13 | # Check that everything compiles | |
|
14 | compile_tree() | |
|
15 | ||
|
16 | # Cleanup | |
|
17 | for d in ['build','dist',pjoin('docs','build'),pjoin('docs','dist')]: | |
|
18 | if os.path.isdir(d): | |
|
19 | remove_tree(d) | |
|
20 | ||
|
21 | # Build source and binary distros | |
|
22 | c('./setup.py sdist --formats=gztar') | |
|
23 | ||
|
24 | # Build version-specific RPMs, where we must use the --python option to ensure | |
|
25 | # that the resulting RPM is really built with the requested python version (so | |
|
26 | # things go to lib/python2.X/...) | |
|
27 | c("python2.5 ./setup.py bdist_rpm --binary-only --release=py25 " | |
|
28 | "--python=/usr/bin/python2.5") | |
|
29 | c("python2.6 ./setup.py bdist_rpm --binary-only --release=py26 " | |
|
30 | "--python=/usr/bin/python2.6") | |
|
31 | ||
|
32 | # Build eggs | |
|
33 | c('python2.5 ./setupegg.py bdist_egg') | |
|
34 | c('python2.6 ./setupegg.py bdist_egg') | |
|
35 | ||
|
36 | # Call the windows build separately, so that the extra Windows scripts don't | |
|
37 | # get pulled into Unix builds (setup.py has code which checks for | |
|
38 | # bdist_wininst) | |
|
39 | c("python setup.py bdist_wininst --install-script=ipython_win_post_install.py") | |
|
40 | ||
|
41 | # Change name so retarded Vista runs the installer correctly | |
|
42 | c("rename 's/linux-i686/win32-setup/' dist/*.exe") |
@@ -0,0 +1,55 b'' | |||
|
1 | """Various utilities common to IPython release and maintenance tools. | |
|
2 | """ | |
|
3 | # Library imports | |
|
4 | import os | |
|
5 | import sys | |
|
6 | ||
|
7 | from distutils.dir_util import remove_tree | |
|
8 | ||
|
9 | # Useful shorthands | |
|
10 | pjoin = os.path.join | |
|
11 | cd = os.chdir | |
|
12 | ||
|
13 | # Utility functions | |
|
14 | def c(cmd): | |
|
15 | """Run system command, raise SystemExit if it returns an error.""" | |
|
16 | print "$",cmd | |
|
17 | stat = os.system(cmd) | |
|
18 | #stat = 0 # Uncomment this and comment previous to run in debug mode | |
|
19 | if stat: | |
|
20 | raise SystemExit("Command %s failed with code: %s" % (cmd, stat)) | |
|
21 | ||
|
22 | ||
|
23 | def get_ipdir(): | |
|
24 | """Get IPython directory from command line, or assume it's the one above.""" | |
|
25 | ||
|
26 | # Initialize arguments and check location | |
|
27 | try: | |
|
28 | ipdir = sys.argv[1] | |
|
29 | except IndexError: | |
|
30 | ipdir = '..' | |
|
31 | ||
|
32 | ipdir = os.path.abspath(ipdir) | |
|
33 | ||
|
34 | cd(ipdir) | |
|
35 | if not os.path.isdir('IPython') and os.path.isfile('setup.py'): | |
|
36 | raise SystemExit('Invalid ipython directory: %s' % ipdir) | |
|
37 | return ipdir | |
|
38 | ||
|
39 | ||
|
40 | def compile_tree(): | |
|
41 | """Compile all Python files below current directory.""" | |
|
42 | vstr = '.'.join(map(str,sys.version_info[:2])) | |
|
43 | stat = os.system('python %s/lib/python%s/compileall.py .' % | |
|
44 | (sys.prefix,vstr)) | |
|
45 | if stat: | |
|
46 | msg = '*** ERROR: Some Python files in tree do NOT compile! ***\n' | |
|
47 | msg += 'See messages above for the actual file that produced it.\n' | |
|
48 | raise SystemExit(msg) | |
|
49 | ||
|
50 | ||
|
51 | def version_info(): | |
|
52 | """Return bzr version info as a dict.""" | |
|
53 | out = os.popen('bzr version-info') | |
|
54 | pairs = (l.split(':',1) for l in out) | |
|
55 | return dict(((k,v.strip()) for (k,v) in pairs)) |
@@ -190,7 +190,7 b' class IPythonCrashHandler(CrashHandler):' | |||
|
190 | 190 | def __init__(self,IP): |
|
191 | 191 | |
|
192 | 192 | # Set here which of the IPython authors should be listed as contact |
|
193 |
AUTHOR_CONTACT = ' |
|
|
193 | AUTHOR_CONTACT = 'Fernando' | |
|
194 | 194 | |
|
195 | 195 | # Set argument defaults |
|
196 | 196 | app_name = 'IPython' |
@@ -43,8 +43,9 b' somewhere in your configuration files or ipython command line.' | |||
|
43 | 43 | |
|
44 | 44 | from IPython.core import ipapi |
|
45 | 45 | |
|
46 | import os,bisect | |
|
47 | from IPython.utils.genutils import Term,shell | |
|
46 | import os, bisect | |
|
47 | import sys | |
|
48 | from IPython.utils.genutils import Term, shell | |
|
48 | 49 | from pprint import PrettyPrinter |
|
49 | 50 | |
|
50 | 51 | # List here all the default hooks. For now it's just the editor functions |
@@ -53,7 +54,8 b' from pprint import PrettyPrinter' | |||
|
53 | 54 | __all__ = ['editor', 'fix_error_editor', 'synchronize_with_editor', 'result_display', |
|
54 | 55 | 'input_prefilter', 'shutdown_hook', 'late_startup_hook', |
|
55 | 56 | 'generate_prompt', 'generate_output_prompt','shell_hook', |
|
56 |
'show_in_pager','pre_prompt_hook', 'pre_runcode_hook' |
|
|
57 | 'show_in_pager','pre_prompt_hook', 'pre_runcode_hook', | |
|
58 | 'clipboard_get'] | |
|
57 | 59 | # vds: << |
|
58 | 60 | |
|
59 | 61 | pformat = PrettyPrinter().pformat |
@@ -109,7 +111,7 b' def fix_error_editor(self,filename,linenum,column,msg):' | |||
|
109 | 111 | |
|
110 | 112 | # vds: >> |
|
111 | 113 | def synchronize_with_editor(self, filename, linenum, column): |
|
112 | pass | |
|
114 | pass | |
|
113 | 115 | # vds: << |
|
114 | 116 | |
|
115 | 117 | class CommandChainDispatcher: |
@@ -243,5 +245,22 b' def pre_prompt_hook(self):' | |||
|
243 | 245 | def pre_runcode_hook(self): |
|
244 | 246 | """ Executed before running the (prefiltered) code in IPython """ |
|
245 | 247 | return None |
|
246 | ||
|
247 | 248 | |
|
249 | def clipboard_get(self): | |
|
250 | """ Get text from the clipboard. | |
|
251 | """ | |
|
252 | from IPython.lib.clipboard import ( | |
|
253 | osx_clipboard_get, tkinter_clipboard_get, | |
|
254 | win32_clipboard_get | |
|
255 | ) | |
|
256 | if sys.platform == 'win32': | |
|
257 | chain = [win32_clipboard_get, tkinter_clipboard_get] | |
|
258 | elif sys.platform == 'darwin': | |
|
259 | chain = [osx_clipboard_get, tkinter_clipboard_get] | |
|
260 | else: | |
|
261 | chain = [tkinter_clipboard_get] | |
|
262 | dispatcher = CommandChainDispatcher() | |
|
263 | for func in chain: | |
|
264 | dispatcher.add(func) | |
|
265 | text = dispatcher() | |
|
266 | return text |
@@ -927,8 +927,8 b' class InteractiveShell(object,Magic):' | |||
|
927 | 927 | Certain history lists are also initialized here, as they effectively |
|
928 | 928 | act as user namespaces. |
|
929 | 929 | |
|
930 | Note | |
|
931 | ---- | |
|
930 | Notes | |
|
931 | ----- | |
|
932 | 932 | All data structures here are only filled in, they are NOT reset by this |
|
933 | 933 | method. If they were not empty before, data will simply be added to |
|
934 | 934 | therm. |
@@ -1315,8 +1315,8 b' class InteractiveShell(object,Magic):' | |||
|
1315 | 1315 | def user_setup(self,ipythondir,rc_suffix,mode='install'): |
|
1316 | 1316 | """Install the user configuration directory. |
|
1317 | 1317 | |
|
1318 | Note | |
|
1319 | ---- | |
|
1318 | Notes | |
|
1319 | ----- | |
|
1320 | 1320 | DEPRECATED: use the top-level user_setup() function instead. |
|
1321 | 1321 | """ |
|
1322 | 1322 | return user_setup(ipythondir,rc_suffix,mode) |
@@ -1707,7 +1707,12 b' Currently the magic system has the following functions:\\n"""' | |||
|
1707 | 1707 | # (leaving dangling references). |
|
1708 | 1708 | self.shell.cache_main_mod(prog_ns,filename) |
|
1709 | 1709 | # update IPython interactive namespace |
|
1710 | del prog_ns['__name__'] | |
|
1710 | ||
|
1711 | # Some forms of read errors on the file may mean the | |
|
1712 | # __name__ key was never set; using pop we don't have to | |
|
1713 | # worry about a possible KeyError. | |
|
1714 | prog_ns.pop('__name__', None) | |
|
1715 | ||
|
1711 | 1716 | self.shell.user_ns.update(prog_ns) |
|
1712 | 1717 | finally: |
|
1713 | 1718 | # It's a bit of a mystery why, but __builtins__ can change from |
@@ -3262,6 +3267,61 b' Defaulting color scheme to \'NoColor\'"""' | |||
|
3262 | 3267 | page(self.shell.pycolorize(cont), |
|
3263 | 3268 | screen_lines=self.shell.rc.screen_length) |
|
3264 | 3269 | |
|
3270 | def _rerun_pasted(self): | |
|
3271 | """ Rerun a previously pasted command. | |
|
3272 | """ | |
|
3273 | b = self.user_ns.get('pasted_block', None) | |
|
3274 | if b is None: | |
|
3275 | raise UsageError('No previous pasted block available') | |
|
3276 | print "Re-executing '%s...' (%d chars)"% (b.split('\n',1)[0], len(b)) | |
|
3277 | exec b in self.user_ns | |
|
3278 | ||
|
3279 | def _get_pasted_lines(self, sentinel): | |
|
3280 | """ Yield pasted lines until the user enters the given sentinel value. | |
|
3281 | """ | |
|
3282 | from IPython.core import iplib | |
|
3283 | print "Pasting code; enter '%s' alone on the line to stop." % sentinel | |
|
3284 | while True: | |
|
3285 | l = iplib.raw_input_original(':') | |
|
3286 | if l == sentinel: | |
|
3287 | return | |
|
3288 | else: | |
|
3289 | yield l | |
|
3290 | ||
|
3291 | def _strip_pasted_lines_for_code(self, raw_lines): | |
|
3292 | """ Strip non-code parts of a sequence of lines to return a block of | |
|
3293 | code. | |
|
3294 | """ | |
|
3295 | # Regular expressions that declare text we strip from the input: | |
|
3296 | strip_re = [r'^\s*In \[\d+\]:', # IPython input prompt | |
|
3297 | r'^\s*(\s?>)+', # Python input prompt | |
|
3298 | r'^\s*\.{3,}', # Continuation prompts | |
|
3299 | r'^\++', | |
|
3300 | ] | |
|
3301 | ||
|
3302 | strip_from_start = map(re.compile,strip_re) | |
|
3303 | ||
|
3304 | lines = [] | |
|
3305 | for l in raw_lines: | |
|
3306 | for pat in strip_from_start: | |
|
3307 | l = pat.sub('',l) | |
|
3308 | lines.append(l) | |
|
3309 | ||
|
3310 | block = "\n".join(lines) + '\n' | |
|
3311 | #print "block:\n",block | |
|
3312 | return block | |
|
3313 | ||
|
3314 | def _execute_block(self, block, par): | |
|
3315 | """ Execute a block, or store it in a variable, per the user's request. | |
|
3316 | """ | |
|
3317 | if not par: | |
|
3318 | b = textwrap.dedent(block) | |
|
3319 | self.user_ns['pasted_block'] = b | |
|
3320 | exec b in self.user_ns | |
|
3321 | else: | |
|
3322 | self.user_ns[par] = SList(block.splitlines()) | |
|
3323 | print "Block assigned to '%s'" % par | |
|
3324 | ||
|
3265 | 3325 | def magic_cpaste(self, parameter_s=''): |
|
3266 | 3326 | """Allows you to paste & execute a pre-formatted code block from clipboard. |
|
3267 | 3327 | |
@@ -3287,50 +3347,60 b' Defaulting color scheme to \'NoColor\'"""' | |||
|
3287 | 3347 | will be what was just pasted. |
|
3288 | 3348 | |
|
3289 | 3349 | IPython statements (magics, shell escapes) are not supported (yet). |
|
3350 | ||
|
3351 | See also | |
|
3352 | -------- | |
|
3353 | paste: automatically pull code from clipboard. | |
|
3290 | 3354 | """ |
|
3355 | ||
|
3291 | 3356 | opts,args = self.parse_options(parameter_s,'rs:',mode='string') |
|
3292 | 3357 | par = args.strip() |
|
3293 | 3358 | if opts.has_key('r'): |
|
3294 |
|
|
|
3295 | if b is None: | |
|
3296 | raise UsageError('No previous pasted block available') | |
|
3297 | print "Re-executing '%s...' (%d chars)"% (b.split('\n',1)[0], len(b)) | |
|
3298 | exec b in self.user_ns | |
|
3359 | self._rerun_pasted() | |
|
3299 | 3360 | return |
|
3300 | 3361 | |
|
3301 | 3362 | sentinel = opts.get('s','--') |
|
3302 | 3363 | |
|
3303 | # Regular expressions that declare text we strip from the input: | |
|
3304 | strip_re = [r'^\s*In \[\d+\]:', # IPython input prompt | |
|
3305 | r'^\s*(\s?>)+', # Python input prompt | |
|
3306 | r'^\s*\.{3,}', # Continuation prompts | |
|
3307 | r'^\++', | |
|
3308 | ] | |
|
3364 | block = self._strip_pasted_lines_for_code( | |
|
3365 | self._get_pasted_lines(sentinel)) | |
|
3309 | 3366 | |
|
3310 | strip_from_start = map(re.compile,strip_re) | |
|
3367 | self._execute_block(block, par) | |
|
3368 | ||
|
3369 | def magic_paste(self, parameter_s=''): | |
|
3370 | """Allows you to paste & execute a pre-formatted code block from clipboard. | |
|
3311 | 3371 |
|
|
3312 | from IPython.core import iplib | |
|
3313 | lines = [] | |
|
3314 | print "Pasting code; enter '%s' alone on the line to stop." % sentinel | |
|
3315 | while 1: | |
|
3316 | l = iplib.raw_input_original(':') | |
|
3317 | if l ==sentinel: | |
|
3318 | break | |
|
3319 | ||
|
3320 | for pat in strip_from_start: | |
|
3321 | l = pat.sub('',l) | |
|
3322 | lines.append(l) | |
|
3323 | ||
|
3324 | block = "\n".join(lines) + '\n' | |
|
3325 | #print "block:\n",block | |
|
3326 | if not par: | |
|
3327 | b = textwrap.dedent(block) | |
|
3328 | self.user_ns['pasted_block'] = b | |
|
3329 | exec b in self.user_ns | |
|
3330 |
|
|
|
3331 | self.user_ns[par] = SList(block.splitlines()) | |
|
3332 | print "Block assigned to '%s'" % par | |
|
3333 |
|
|
|
3372 | The text is pulled directly from the clipboard without user | |
|
3373 | intervention. | |
|
3374 | ||
|
3375 | The block is dedented prior to execution to enable execution of method | |
|
3376 | definitions. '>' and '+' characters at the beginning of a line are | |
|
3377 | ignored, to allow pasting directly from e-mails, diff files and | |
|
3378 | doctests (the '...' continuation prompt is also stripped). The | |
|
3379 | executed block is also assigned to variable named 'pasted_block' for | |
|
3380 | later editing with '%edit pasted_block'. | |
|
3381 | ||
|
3382 | You can also pass a variable name as an argument, e.g. '%paste foo'. | |
|
3383 | This assigns the pasted block to variable 'foo' as string, without | |
|
3384 | dedenting or executing it (preceding >>> and + is still stripped) | |
|
3385 | ||
|
3386 | '%paste -r' re-executes the block previously entered by cpaste. | |
|
3387 | ||
|
3388 | IPython statements (magics, shell escapes) are not supported (yet). | |
|
3389 | ||
|
3390 | See also | |
|
3391 | -------- | |
|
3392 | cpaste: manually paste code into terminal until you mark its end. | |
|
3393 | """ | |
|
3394 | opts,args = self.parse_options(parameter_s,'r:',mode='string') | |
|
3395 | par = args.strip() | |
|
3396 | if opts.has_key('r'): | |
|
3397 | self._rerun_pasted() | |
|
3398 | return | |
|
3399 | ||
|
3400 | text = self.shell.hooks.clipboard_get() | |
|
3401 | block = self._strip_pasted_lines_for_code(text.splitlines()) | |
|
3402 | self._execute_block(block, par) | |
|
3403 | ||
|
3334 | 3404 | def magic_quickref(self,arg): |
|
3335 | 3405 | """ Show a quick reference sheet """ |
|
3336 | 3406 | import IPython.core.usage |
@@ -2,8 +2,8 b'' | |||
|
2 | 2 | """Release data for the IPython project.""" |
|
3 | 3 | |
|
4 | 4 | #***************************************************************************** |
|
5 | # Copyright (C) 2001-2006 Fernando Perez <fperez@colorado.edu> | |
|
6 | # | |
|
5 | # Copyright (C) 2008-2009 The IPython Development Team | |
|
6 | # Copyright (C) 2001-2008 Fernando Perez <fperez@colorado.edu> | |
|
7 | 7 | # Copyright (c) 2001 Janko Hauser <jhauser@zscout.de> and Nathaniel Gray |
|
8 | 8 | # <n8gray@caltech.edu> |
|
9 | 9 | # |
@@ -20,10 +20,10 b" name = 'ipython'" | |||
|
20 | 20 | # because bdist_rpm does not accept dashes (an RPM) convention, and |
|
21 | 21 | # bdist_deb does not accept underscores (a Debian convention). |
|
22 | 22 | |
|
23 |
development = |
|
|
23 | development = False # change this to False to do a release | |
|
24 | 24 | version_base = '0.10' |
|
25 | 25 | branch = 'ipython' |
|
26 |
revision = '11 |
|
|
26 | revision = '1188' | |
|
27 | 27 | |
|
28 | 28 | if development: |
|
29 | 29 | if branch == 'ipython': |
@@ -100,7 +100,7 b' site <http://launchpad.net/ipython>`_.' | |||
|
100 | 100 | |
|
101 | 101 | license = 'BSD' |
|
102 | 102 | |
|
103 |
authors = {'Fernando' : ('Fernando Perez','fperez |
|
|
103 | authors = {'Fernando' : ('Fernando Perez','fperez.net@gmail.com'), | |
|
104 | 104 | 'Janko' : ('Janko Hauser','jhauser@zscout.de'), |
|
105 | 105 | 'Nathan' : ('Nathaniel Gray','n8gray@caltech.edu'), |
|
106 | 106 | 'Ville' : ('Ville Vainio','vivainio@gmail.com'), |
@@ -25,14 +25,14 b' def test_rehashx():' | |||
|
25 | 25 | _ip.magic('rehashx') |
|
26 | 26 | # Practically ALL ipython development systems will have more than 10 aliases |
|
27 | 27 | |
|
28 | assert len(_ip.IP.alias_table) > 10 | |
|
28 | yield (nt.assert_true, len(_ip.IP.alias_table) > 10) | |
|
29 | 29 | for key, val in _ip.IP.alias_table.items(): |
|
30 | 30 | # we must strip dots from alias names |
|
31 |
assert |
|
|
31 | nt.assert_true('.' not in key) | |
|
32 | 32 | |
|
33 | 33 | # rehashx must fill up syscmdlist |
|
34 | 34 | scoms = _ip.db['syscmdlist'] |
|
35 | assert len(scoms) > 10 | |
|
35 | yield (nt.assert_true, len(scoms) > 10) | |
|
36 | 36 | |
|
37 | 37 | |
|
38 | 38 | def doctest_hist_f(): |
@@ -42,7 +42,7 b' def doctest_hist_f():' | |||
|
42 | 42 | |
|
43 | 43 | In [10]: tfile = tempfile.mktemp('.py','tmp-ipython-') |
|
44 | 44 | |
|
45 |
In [11]: %hist |
|
|
45 | In [11]: %hist -n -f $tfile 3 | |
|
46 | 46 | """ |
|
47 | 47 | |
|
48 | 48 | |
@@ -51,9 +51,12 b' def doctest_hist_r():' | |||
|
51 | 51 | |
|
52 | 52 | XXX - This test is not recording the output correctly. Not sure why... |
|
53 | 53 | |
|
54 | In [20]: 'hist' in _ip.IP.lsmagic() | |
|
55 | Out[20]: True | |
|
56 | ||
|
54 | 57 | In [6]: x=1 |
|
55 | 58 | |
|
56 | In [7]: hist -n -r 2 | |
|
59 | In [7]: %hist -n -r 2 | |
|
57 | 60 | x=1 # random |
|
58 | 61 | hist -n -r 2 # random |
|
59 | 62 | """ |
@@ -94,12 +97,13 b' def test_shist():' | |||
|
94 | 97 | |
|
95 | 98 | @dec.skipif_not_numpy |
|
96 | 99 | def test_numpy_clear_array_undec(): |
|
100 | from IPython.extensions import clearcmd | |
|
101 | ||
|
97 | 102 | _ip.ex('import numpy as np') |
|
98 | 103 | _ip.ex('a = np.empty(2)') |
|
99 | ||
|
100 | yield nt.assert_true,'a' in _ip.user_ns | |
|
104 | yield (nt.assert_true, 'a' in _ip.user_ns) | |
|
101 | 105 | _ip.magic('clear array') |
|
102 | yield nt.assert_false,'a' in _ip.user_ns | |
|
106 | yield (nt.assert_false, 'a' in _ip.user_ns) | |
|
103 | 107 | |
|
104 | 108 | |
|
105 | 109 | @dec.skip() |
@@ -159,7 +163,6 b' def doctest_run_ns2():' | |||
|
159 | 163 | tclass.py: deleting object: C-first_pass |
|
160 | 164 | """ |
|
161 | 165 | |
|
162 | @dec.skip_win32 | |
|
163 | 166 | def doctest_run_builtins(): |
|
164 | 167 | """Check that %run doesn't damage __builtins__ via a doctest. |
|
165 | 168 | |
@@ -172,24 +175,34 b' def doctest_run_builtins():' | |||
|
172 | 175 | |
|
173 | 176 | In [2]: bid1 = id(__builtins__) |
|
174 | 177 | |
|
175 |
In [3]: f = tempfile. |
|
|
178 | In [3]: fname = tempfile.mkstemp()[1] | |
|
179 | ||
|
180 | In [3]: f = open(fname,'w') | |
|
176 | 181 | |
|
177 | 182 | In [4]: f.write('pass\\n') |
|
178 | 183 | |
|
179 | 184 | In [5]: f.flush() |
|
180 | 185 | |
|
181 |
In [6]: print |
|
|
182 |
|
|
|
186 | In [6]: print type(__builtins__) | |
|
187 | <type 'module'> | |
|
183 | 188 | |
|
184 |
In [7]: %run $f |
|
|
189 | In [7]: %run "$fname" | |
|
190 | ||
|
191 | In [7]: f.close() | |
|
185 | 192 | |
|
186 | 193 | In [8]: bid2 = id(__builtins__) |
|
187 | 194 | |
|
188 |
In [9]: print |
|
|
189 |
|
|
|
195 | In [9]: print type(__builtins__) | |
|
196 | <type 'module'> | |
|
190 | 197 | |
|
191 | 198 | In [10]: bid1 == bid2 |
|
192 | 199 | Out[10]: True |
|
200 | ||
|
201 | In [12]: try: | |
|
202 | ....: os.unlink(fname) | |
|
203 | ....: except: | |
|
204 | ....: pass | |
|
205 | ....: | |
|
193 | 206 | """ |
|
194 | 207 | |
|
195 | 208 | # For some tests, it will be handy to organize them in a class with a common |
@@ -199,23 +212,18 b' class TestMagicRun(object):' | |||
|
199 | 212 | |
|
200 | 213 | def setup(self): |
|
201 | 214 | """Make a valid python temp file.""" |
|
202 |
f = tempfile. |
|
|
215 | fname = tempfile.mkstemp()[1] | |
|
216 | f = open(fname,'w') | |
|
203 | 217 | f.write('pass\n') |
|
204 | 218 | f.flush() |
|
205 | 219 | self.tmpfile = f |
|
220 | self.fname = fname | |
|
206 | 221 | |
|
207 | 222 | def run_tmpfile(self): |
|
208 | 223 | # This fails on Windows if self.tmpfile.name has spaces or "~" in it. |
|
209 | 224 | # See below and ticket https://bugs.launchpad.net/bugs/366353 |
|
210 |
_ip.magic('run %s' % self. |
|
|
211 | ||
|
212 | # See https://bugs.launchpad.net/bugs/366353 | |
|
213 | @dec.skip_if_not_win32 | |
|
214 | def test_run_tempfile_path(self): | |
|
215 | tt.assert_equals(True,False,"%run doesn't work with tempfile paths on win32.") | |
|
225 | _ip.magic('run "%s"' % self.fname) | |
|
216 | 226 | |
|
217 | # See https://bugs.launchpad.net/bugs/366353 | |
|
218 | @dec.skip_win32 | |
|
219 | 227 | def test_builtins_id(self): |
|
220 | 228 | """Check that %run doesn't damage __builtins__ """ |
|
221 | 229 | |
@@ -225,8 +233,6 b' class TestMagicRun(object):' | |||
|
225 | 233 | bid2 = id(_ip.user_ns['__builtins__']) |
|
226 | 234 | tt.assert_equals(bid1, bid2) |
|
227 | 235 | |
|
228 | # See https://bugs.launchpad.net/bugs/366353 | |
|
229 | @dec.skip_win32 | |
|
230 | 236 | def test_builtins_type(self): |
|
231 | 237 | """Check that the type of __builtins__ doesn't change with %run. |
|
232 | 238 | |
@@ -237,8 +243,6 b' class TestMagicRun(object):' | |||
|
237 | 243 | self.run_tmpfile() |
|
238 | 244 | tt.assert_equals(type(_ip.user_ns['__builtins__']),type(sys)) |
|
239 | 245 | |
|
240 | # See https://bugs.launchpad.net/bugs/366353 | |
|
241 | @dec.skip_win32 | |
|
242 | 246 | def test_prompts(self): |
|
243 | 247 | """Test that prompts correctly generate after %run""" |
|
244 | 248 | self.run_tmpfile() |
@@ -247,3 +251,52 b' class TestMagicRun(object):' | |||
|
247 | 251 | |
|
248 | 252 | def teardown(self): |
|
249 | 253 | self.tmpfile.close() |
|
254 | try: | |
|
255 | os.unlink(self.fname) | |
|
256 | except: | |
|
257 | # On Windows, even though we close the file, we still can't delete | |
|
258 | # it. I have no clue why | |
|
259 | pass | |
|
260 | ||
|
261 | # Multiple tests for clipboard pasting | |
|
262 | def test_paste(): | |
|
263 | ||
|
264 | def paste(txt): | |
|
265 | hooks.clipboard_get = lambda : txt | |
|
266 | _ip.magic('paste') | |
|
267 | ||
|
268 | # Inject fake clipboard hook but save original so we can restore it later | |
|
269 | hooks = _ip.IP.hooks | |
|
270 | user_ns = _ip.user_ns | |
|
271 | original_clip = hooks.clipboard_get | |
|
272 | ||
|
273 | try: | |
|
274 | # This try/except with an emtpy except clause is here only because | |
|
275 | # try/yield/finally is invalid syntax in Python 2.4. This will be | |
|
276 | # removed when we drop 2.4-compatibility, and the emtpy except below | |
|
277 | # will be changed to a finally. | |
|
278 | ||
|
279 | # Run tests with fake clipboard function | |
|
280 | user_ns.pop('x', None) | |
|
281 | paste('x=1') | |
|
282 | yield (nt.assert_equal, user_ns['x'], 1) | |
|
283 | ||
|
284 | user_ns.pop('x', None) | |
|
285 | paste('>>> x=2') | |
|
286 | yield (nt.assert_equal, user_ns['x'], 2) | |
|
287 | ||
|
288 | paste(""" | |
|
289 | >>> x = [1,2,3] | |
|
290 | >>> y = [] | |
|
291 | >>> for i in x: | |
|
292 | ... y.append(i**2) | |
|
293 | ... | |
|
294 | """) | |
|
295 | yield (nt.assert_equal, user_ns['x'], [1,2,3]) | |
|
296 | yield (nt.assert_equal, user_ns['y'], [1,4,9]) | |
|
297 | except: | |
|
298 | pass | |
|
299 | ||
|
300 | # This should be in a finally clause, instead of the bare except above. | |
|
301 | # Restore original hook | |
|
302 | hooks.clipboard_get = original_clip |
@@ -91,7 +91,7 b' from inspect import getsourcefile, getfile, getmodule,\\' | |||
|
91 | 91 | # IPython's own modules |
|
92 | 92 | # Modified pdb which doesn't damage IPython's readline handling |
|
93 | 93 | from IPython.utils import PyColorize |
|
94 | from IPython.core import debugger | |
|
94 | from IPython.core import debugger, ipapi | |
|
95 | 95 | from IPython.utils.ipstruct import Struct |
|
96 | 96 | from IPython.core.excolors import exception_colors |
|
97 | 97 | from IPython.utils.genutils import Term,uniq_stable,error,info |
@@ -268,10 +268,12 b' def _formatTracebackLines(lnum, index, lines, Colors, lvals=None,scheme=None):' | |||
|
268 | 268 | |
|
269 | 269 | # This lets us get fully syntax-highlighted tracebacks. |
|
270 | 270 | if scheme is None: |
|
271 | try: | |
|
272 | scheme = __IPYTHON__.rc.colors | |
|
273 | except: | |
|
271 | ipinst = ipapi.get() | |
|
272 | if ipinst is not None: | |
|
273 | scheme = ipinst.IP.rc.colors | |
|
274 | else: | |
|
274 | 275 | scheme = DEFAULT_SCHEME |
|
276 | ||
|
275 | 277 | _line_format = _parser.format2 |
|
276 | 278 | |
|
277 | 279 | for line in lines: |
@@ -490,7 +492,9 b' class ListTB(TBTools):' | |||
|
490 | 492 | |
|
491 | 493 | # vds:>> |
|
492 | 494 | if have_filedata: |
|
493 | __IPYTHON__.hooks.synchronize_with_editor(filename, lineno, 0) | |
|
495 | ipinst = ipapi.get() | |
|
496 | if ipinst is not None: | |
|
497 | ipinst.IP.hooks.synchronize_with_editor(filename, lineno, 0) | |
|
494 | 498 | # vds:<< |
|
495 | 499 | |
|
496 | 500 | return list |
@@ -810,7 +814,9 b' class VerboseTB(TBTools):' | |||
|
810 | 814 | filepath, lnum = records[-1][1:3] |
|
811 | 815 | #print "file:", str(file), "linenb", str(lnum) # dbg |
|
812 | 816 | filepath = os.path.abspath(filepath) |
|
813 | __IPYTHON__.hooks.synchronize_with_editor(filepath, lnum, 0) | |
|
817 | ipinst = ipapi.get() | |
|
818 | if ipinst is not None: | |
|
819 | ipinst.IP.hooks.synchronize_with_editor(filepath, lnum, 0) | |
|
814 | 820 | # vds: << |
|
815 | 821 | |
|
816 | 822 | # return all our info assembled as a single string |
@@ -2,6 +2,9 b'' | |||
|
2 | 2 | |
|
3 | 3 | XXX - This module is missing proper docs. |
|
4 | 4 | """ |
|
5 | # Tell nose to skip this module | |
|
6 | __test__ = {} | |
|
7 | ||
|
5 | 8 | import sys |
|
6 | 9 | |
|
7 | 10 | from twisted.internet import reactor, threads |
@@ -1,7 +1,7 b'' | |||
|
1 | 1 | """ |
|
2 | 2 | IPython extension: autoreload modules before executing the next line |
|
3 | 3 | |
|
4 |
Try:: |
|
|
4 | Try:: | |
|
5 | 5 | |
|
6 | 6 | %autoreload? |
|
7 | 7 | |
@@ -32,7 +32,7 b' PY_COMPILED_EXT = _get_compiled_ext()' | |||
|
32 | 32 | class ModuleReloader(object): |
|
33 | 33 | failed = {} |
|
34 | 34 | """Modules that failed to reload: {module: mtime-on-failed-reload, ...}""" |
|
35 | ||
|
35 | ||
|
36 | 36 | modules = {} |
|
37 | 37 | """Modules specially marked as autoreloadable.""" |
|
38 | 38 | |
@@ -44,39 +44,39 b' class ModuleReloader(object):' | |||
|
44 | 44 | |
|
45 | 45 | old_objects = {} |
|
46 | 46 | """(module-name, name) -> weakref, for replacing old code objects""" |
|
47 | ||
|
47 | ||
|
48 | 48 | def check(self, check_all=False): |
|
49 | 49 | """Check whether some modules need to be reloaded.""" |
|
50 | ||
|
50 | ||
|
51 | 51 | if check_all or self.check_all: |
|
52 | 52 | modules = sys.modules.keys() |
|
53 | 53 | else: |
|
54 | 54 | modules = self.modules.keys() |
|
55 | ||
|
55 | ||
|
56 | 56 | for modname in modules: |
|
57 | 57 | m = sys.modules.get(modname, None) |
|
58 | 58 | |
|
59 | 59 | if modname in self.skip_modules: |
|
60 | 60 | continue |
|
61 | ||
|
61 | ||
|
62 | 62 | if not hasattr(m, '__file__'): |
|
63 | 63 | continue |
|
64 | ||
|
64 | ||
|
65 | 65 | if m.__name__ == '__main__': |
|
66 | 66 | # we cannot reload(__main__) |
|
67 | 67 | continue |
|
68 | ||
|
68 | ||
|
69 | 69 | filename = m.__file__ |
|
70 | 70 | dirname = os.path.dirname(filename) |
|
71 | 71 | path, ext = os.path.splitext(filename) |
|
72 | ||
|
72 | ||
|
73 | 73 | if ext.lower() == '.py': |
|
74 | 74 | ext = PY_COMPILED_EXT |
|
75 | 75 | filename = os.path.join(dirname, path + PY_COMPILED_EXT) |
|
76 | ||
|
76 | ||
|
77 | 77 | if ext != PY_COMPILED_EXT: |
|
78 | 78 | continue |
|
79 | ||
|
79 | ||
|
80 | 80 | try: |
|
81 | 81 | pymtime = os.stat(filename[:-1]).st_mtime |
|
82 | 82 | if pymtime <= os.stat(filename).st_mtime: |
@@ -85,7 +85,7 b' class ModuleReloader(object):' | |||
|
85 | 85 | continue |
|
86 | 86 | except OSError: |
|
87 | 87 | continue |
|
88 | ||
|
88 | ||
|
89 | 89 | try: |
|
90 | 90 | superreload(m, reload, self.old_objects) |
|
91 | 91 | if filename[:-1] in self.failed: |
@@ -118,12 +118,12 b' def update_class(old, new):' | |||
|
118 | 118 | new_obj = getattr(new, key) |
|
119 | 119 | except AttributeError: |
|
120 | 120 | # obsolete attribute: remove it |
|
121 |
try: |
|
|
121 | try: | |
|
122 | 122 | delattr(old, key) |
|
123 | 123 | except (AttributeError, TypeError): |
|
124 | 124 | pass |
|
125 | 125 | continue |
|
126 | ||
|
126 | ||
|
127 | 127 | if update_generic(old_obj, new_obj): continue |
|
128 | 128 | |
|
129 | 129 | try: |
@@ -146,9 +146,9 b' UPDATE_RULES = [' | |||
|
146 | 146 | (lambda a, b: isinstance2(a, b, types.TypeType), |
|
147 | 147 | update_class), |
|
148 | 148 | (lambda a, b: isinstance2(a, b, types.FunctionType), |
|
149 |
update_function), |
|
|
149 | update_function), | |
|
150 | 150 | (lambda a, b: isinstance2(a, b, property), |
|
151 |
update_property), |
|
|
151 | update_property), | |
|
152 | 152 | (lambda a, b: isinstance2(a, b, types.MethodType), |
|
153 | 153 | lambda a, b: update_function(a.im_func, b.im_func)), |
|
154 | 154 | ] |
@@ -168,15 +168,15 b' class StrongRef(object):' | |||
|
168 | 168 | |
|
169 | 169 | def superreload(module, reload=reload, old_objects={}): |
|
170 | 170 | """Enhanced version of the builtin reload function. |
|
171 | ||
|
171 | ||
|
172 | 172 | superreload remembers objects previously in the module, and |
|
173 | 173 | |
|
174 | 174 | - upgrades the class dictionary of every old class in the module |
|
175 | 175 | - upgrades the code object of every old function and method |
|
176 | 176 | - clears the module's namespace before reloading |
|
177 | ||
|
177 | ||
|
178 | 178 | """ |
|
179 | ||
|
179 | ||
|
180 | 180 | # collect old objects in the module |
|
181 | 181 | for name, obj in module.__dict__.items(): |
|
182 | 182 | if not hasattr(obj, '__module__') or obj.__module__ != module.__name__: |
@@ -199,7 +199,7 b' def superreload(module, reload=reload, old_objects={}):' | |||
|
199 | 199 | except (TypeError, AttributeError, KeyError): |
|
200 | 200 | pass |
|
201 | 201 | module = reload(module) |
|
202 | ||
|
202 | ||
|
203 | 203 | # iterate over all objects and update functions & classes |
|
204 | 204 | for name, new_obj in module.__dict__.items(): |
|
205 | 205 | key = (module.__name__, name) |
@@ -248,40 +248,46 b' def disable_autoreload():' | |||
|
248 | 248 | |
|
249 | 249 | def autoreload_f(self, parameter_s=''): |
|
250 | 250 | r""" %autoreload => Reload modules automatically |
|
251 | ||
|
251 | ||
|
252 | 252 | %autoreload |
|
253 | 253 | Reload all modules (except those excluded by %aimport) automatically now. |
|
254 | ||
|
254 | ||
|
255 | %autoreload 0 | |
|
256 | Disable automatic reloading. | |
|
257 | ||
|
255 | 258 | %autoreload 1 |
|
256 | 259 | Reload all modules imported with %aimport every time before executing |
|
257 | 260 | the Python code typed. |
|
258 | ||
|
261 | ||
|
259 | 262 | %autoreload 2 |
|
260 | 263 | Reload all modules (except those excluded by %aimport) every time |
|
261 | 264 | before executing the Python code typed. |
|
262 | ||
|
263 |
Reloading Python modules in a reliable way is in general |
|
|
264 |
and unexpected things may occur. %autoreload tries to |
|
|
265 |
around common pitfalls by replacing code objects |
|
|
266 |
previously in the module with new versions. This |
|
|
267 | things to work: | |
|
265 | ||
|
266 | Reloading Python modules in a reliable way is in general | |
|
267 | difficult, and unexpected things may occur. %autoreload tries to | |
|
268 | work around common pitfalls by replacing function code objects and | |
|
269 | parts of classes previously in the module with new versions. This | |
|
270 | makes the following things to work: | |
|
268 | 271 | |
|
269 | 272 | - Functions and classes imported via 'from xxx import foo' are upgraded |
|
270 | 273 | to new versions when 'xxx' is reloaded. |
|
274 | ||
|
271 | 275 | - Methods and properties of classes are upgraded on reload, so that |
|
272 | 276 | calling 'c.foo()' on an object 'c' created before the reload causes |
|
273 | 277 | the new code for 'foo' to be executed. |
|
274 | ||
|
278 | ||
|
275 | 279 | Some of the known remaining caveats are: |
|
276 | ||
|
280 | ||
|
277 | 281 | - Replacing code objects does not always succeed: changing a @property |
|
278 | 282 | in a class to an ordinary method or a method to a member variable |
|
279 | 283 | can cause problems (but in old objects only). |
|
284 | ||
|
280 | 285 | - Functions that are removed (eg. via monkey-patching) from a module |
|
281 | 286 | before it is reloaded are not upgraded. |
|
287 | ||
|
282 | 288 | - C extension modules cannot be reloaded, and so cannot be |
|
283 | 289 | autoreloaded. |
|
284 | ||
|
290 | ||
|
285 | 291 | """ |
|
286 | 292 | if parameter_s == '': |
|
287 | 293 | reloader.check(True) |
@@ -307,7 +313,7 b" def aimport_f(self, parameter_s=''):" | |||
|
307 | 313 | Mark module 'foo' to not be autoreloaded for %autoreload 1 |
|
308 | 314 | |
|
309 | 315 | """ |
|
310 | ||
|
316 | ||
|
311 | 317 | modname = parameter_s |
|
312 | 318 | if not modname: |
|
313 | 319 | to_reload = reloader.modules.keys() |
@@ -329,12 +335,15 b" def aimport_f(self, parameter_s=''):" | |||
|
329 | 335 | except KeyError: pass |
|
330 | 336 | reloader.modules[modname] = True |
|
331 | 337 | |
|
332 | mod = __import__(modname) | |
|
333 |
|
|
|
338 | # Inject module to user namespace; handle also submodules properly | |
|
339 | __import__(modname) | |
|
340 | basename = modname.split('.')[0] | |
|
341 | mod = sys.modules[basename] | |
|
342 | ip.to_user_ns({basename: mod}) | |
|
334 | 343 | |
|
335 | 344 | def init(): |
|
336 | 345 | ip.expose_magic('autoreload', autoreload_f) |
|
337 | 346 | ip.expose_magic('aimport', aimport_f) |
|
338 | 347 | ip.set_hook('pre_runcode_hook', runcode_hook) |
|
339 | ||
|
348 | ||
|
340 | 349 | init() |
@@ -3,6 +3,9 b' Base front end class for all async frontends.' | |||
|
3 | 3 | """ |
|
4 | 4 | __docformat__ = "restructuredtext en" |
|
5 | 5 | |
|
6 | # Tell nose to skip this module | |
|
7 | __test__ = {} | |
|
8 | ||
|
6 | 9 | #------------------------------------------------------------------------------- |
|
7 | 10 | # Copyright (C) 2008 The IPython Development Team |
|
8 | 11 | # |
@@ -10,20 +13,25 b' __docformat__ = "restructuredtext en"' | |||
|
10 | 13 | # the file COPYING, distributed as part of this software. |
|
11 | 14 | #------------------------------------------------------------------------------- |
|
12 | 15 | |
|
13 | ||
|
14 | 16 | #------------------------------------------------------------------------------- |
|
15 | 17 | # Imports |
|
16 | 18 | #------------------------------------------------------------------------------- |
|
17 | 19 | |
|
20 | # Third-party | |
|
21 | from twisted.python.failure import Failure | |
|
22 | from zope.interface import implements, classProvides | |
|
23 | ||
|
24 | # From IPython | |
|
18 | 25 | from IPython.external import guid |
|
19 | 26 | |
|
20 | from zope.interface import Interface, Attribute, implements, classProvides | |
|
21 | from twisted.python.failure import Failure | |
|
22 | from IPython.frontend.frontendbase import ( | |
|
23 | FrontEndBase, IFrontEnd, IFrontEndFactory) | |
|
27 | from IPython.frontend.frontendbase import (FrontEndBase, IFrontEnd, | |
|
28 | IFrontEndFactory) | |
|
24 | 29 | from IPython.kernel.core.history import FrontEndHistory |
|
25 | 30 | from IPython.kernel.engineservice import IEngineCore |
|
26 | 31 | |
|
32 | #----------------------------------------------------------------------------- | |
|
33 | # Classes and functions | |
|
34 | #----------------------------------------------------------------------------- | |
|
27 | 35 | |
|
28 | 36 | class AsyncFrontEndBase(FrontEndBase): |
|
29 | 37 | """ |
@@ -41,8 +49,7 b' class AsyncFrontEndBase(FrontEndBase):' | |||
|
41 | 49 | self.history = FrontEndHistory(input_cache=['']) |
|
42 | 50 | else: |
|
43 | 51 | self.history = history |
|
44 | ||
|
45 | ||
|
52 | ||
|
46 | 53 | def execute(self, block, blockID=None): |
|
47 | 54 | """Execute the block and return the deferred result. |
|
48 | 55 | |
@@ -73,5 +80,3 b' class AsyncFrontEndBase(FrontEndBase):' | |||
|
73 | 80 | errback=self.render_error) |
|
74 | 81 | |
|
75 | 82 | return d |
|
76 | ||
|
77 |
@@ -19,17 +19,17 b' __docformat__ = "restructuredtext en"' | |||
|
19 | 19 | from setuptools import setup |
|
20 | 20 | |
|
21 | 21 | infoPlist = dict( |
|
22 |
|
|
|
23 |
|
|
|
24 |
|
|
|
22 | CFBundleDevelopmentRegion='English', | |
|
23 | CFBundleIdentifier='org.scipy.ipython.cocoa_frontend', | |
|
24 | NSPrincipalClass='IPythonCocoaController', | |
|
25 | 25 | ) |
|
26 | 26 | |
|
27 | 27 | setup( |
|
28 |
|
|
|
28 | plugin=['IPythonCocoaFrontendLoader.py'], | |
|
29 | 29 | setup_requires=['py2app'], |
|
30 |
|
|
|
31 |
|
|
|
32 |
|
|
|
33 |
|
|
|
34 | )), | |
|
30 | options=dict(py2app=dict( | |
|
31 | plist=infoPlist, | |
|
32 | site_packages=True, | |
|
33 | excludes=['IPython','twisted','PyObjCTools'] | |
|
34 | )), | |
|
35 | 35 | ) No newline at end of file |
@@ -97,8 +97,8 b' class LineFrontEndBase(FrontEndBase):' | |||
|
97 | 97 | ---------- |
|
98 | 98 | line : string |
|
99 | 99 | |
|
100 |
Res |
|
|
101 | ------ | |
|
100 | Returns | |
|
101 | ------- | |
|
102 | 102 | The replacement for the line and the list of possible completions. |
|
103 | 103 | """ |
|
104 | 104 | completions = self.shell.complete(line) |
@@ -65,8 +65,8 b' class PrefilterFrontEnd(LineFrontEndBase):' | |||
|
65 | 65 | debug = False |
|
66 | 66 | |
|
67 | 67 | def __init__(self, ipython0=None, argv=None, *args, **kwargs): |
|
68 |
""" Parameters |
|
|
69 |
---------- |
|
|
68 | """ Parameters | |
|
69 | ---------- | |
|
70 | 70 | |
|
71 | 71 | ipython0: an optional ipython0 instance to use for command |
|
72 | 72 | prefiltering and completion. |
@@ -3,6 +3,9 b'' | |||
|
3 | 3 | """This file contains unittests for the asyncfrontendbase module.""" |
|
4 | 4 | |
|
5 | 5 | __docformat__ = "restructuredtext en" |
|
6 | ||
|
7 | # Tell nose to skip this module | |
|
8 | __test__ = {} | |
|
6 | 9 | |
|
7 | 10 | #--------------------------------------------------------------------------- |
|
8 | 11 | # Copyright (C) 2008 The IPython Development Team |
@@ -10,20 +13,21 b' __docformat__ = "restructuredtext en"' | |||
|
10 | 13 | # Distributed under the terms of the BSD License. The full license is in |
|
11 | 14 | # the file COPYING, distributed as part of this software. |
|
12 | 15 | #--------------------------------------------------------------------------- |
|
13 | ||
|
16 | ||
|
14 | 17 | #--------------------------------------------------------------------------- |
|
15 | 18 | # Imports |
|
16 | 19 | #--------------------------------------------------------------------------- |
|
17 | 20 | |
|
18 | # Tell nose to skip this module | |
|
19 | __test__ = {} | |
|
20 | ||
|
21 | 21 | from twisted.trial import unittest |
|
22 | ||
|
22 | 23 | from IPython.frontend.asyncfrontendbase import AsyncFrontEndBase |
|
23 | 24 | from IPython.frontend import frontendbase |
|
24 | 25 | from IPython.kernel.engineservice import EngineService |
|
25 | 26 | from IPython.testing.parametric import Parametric, parametric |
|
26 | 27 | |
|
28 | #----------------------------------------------------------------------------- | |
|
29 | # Classes and functions | |
|
30 | #----------------------------------------------------------------------------- | |
|
27 | 31 | |
|
28 | 32 | class FrontEndCallbackChecker(AsyncFrontEndBase): |
|
29 | 33 | """FrontEndBase subclass for checking callbacks""" |
@@ -106,4 +110,3 b' class TestAsyncFrontendBase(unittest.TestCase):' | |||
|
106 | 110 | def test_history_returns_none_at_startup(self): |
|
107 | 111 | self.assert_(self.fb.get_history_previous("")==None) |
|
108 | 112 | self.assert_(self.fb.get_history_next()==None) |
|
109 |
@@ -15,6 +15,7 b' __docformat__ = "restructuredtext en"' | |||
|
15 | 15 | from copy import copy, deepcopy |
|
16 | 16 | from cStringIO import StringIO |
|
17 | 17 | import string |
|
18 | import sys | |
|
18 | 19 | |
|
19 | 20 | from nose.tools import assert_equal |
|
20 | 21 | |
@@ -23,22 +24,6 b' from IPython.core.ipapi import get as get_ipython0' | |||
|
23 | 24 | from IPython.testing.plugin.ipdoctest import default_argv |
|
24 | 25 | |
|
25 | 26 | |
|
26 | def safe_deepcopy(d): | |
|
27 | """ Deep copy every key of the given dict, when possible. Elsewhere | |
|
28 | do a copy. | |
|
29 | """ | |
|
30 | copied_d = dict() | |
|
31 | for key, value in d.iteritems(): | |
|
32 | try: | |
|
33 | copied_d[key] = deepcopy(value) | |
|
34 | except: | |
|
35 | try: | |
|
36 | copied_d[key] = copy(value) | |
|
37 | except: | |
|
38 | copied_d[key] = value | |
|
39 | return copied_d | |
|
40 | ||
|
41 | ||
|
42 | 27 | class TestPrefilterFrontEnd(PrefilterFrontEnd): |
|
43 | 28 | |
|
44 | 29 | input_prompt_template = string.Template('') |
@@ -72,17 +57,34 b' def isolate_ipython0(func):' | |||
|
72 | 57 | with arguments. |
|
73 | 58 | """ |
|
74 | 59 | def my_func(): |
|
75 |
ip |
|
|
76 |
if ip |
|
|
60 | ip0 = get_ipython0() | |
|
61 | if ip0 is None: | |
|
77 | 62 | return func() |
|
78 | ipython0 = iplib.IP | |
|
79 | global_ns = safe_deepcopy(ipython0.user_global_ns) | |
|
80 |
user_ns = |
|
|
63 | # We have a real ipython running... | |
|
64 | user_ns = ip0.IP.user_ns | |
|
65 | user_global_ns = ip0.IP.user_global_ns | |
|
66 | ||
|
67 | # Previously the isolation was attempted with a deep copy of the user | |
|
68 | # dicts, but we found cases where this didn't work correctly. I'm not | |
|
69 | # quite sure why, but basically it did damage the user namespace, such | |
|
70 | # that later tests stopped working correctly. Instead we use a simpler | |
|
71 | # approach, just computing the list of added keys to the namespace and | |
|
72 | # eliminating those afterwards. Existing keys that may have been | |
|
73 | # modified remain modified. So far this has proven to be robust. | |
|
74 | ||
|
75 | # Compute set of old local/global keys | |
|
76 | old_locals = set(user_ns.keys()) | |
|
77 | old_globals = set(user_global_ns.keys()) | |
|
81 | 78 | try: |
|
82 | 79 | out = func() |
|
83 | 80 | finally: |
|
84 | ipython0.user_ns = user_ns | |
|
85 | ipython0.user_global_ns = global_ns | |
|
81 | # Find new keys, and if any, remove them | |
|
82 | new_locals = set(user_ns.keys()) - old_locals | |
|
83 | new_globals = set(user_global_ns.keys()) - old_globals | |
|
84 | for k in new_locals: | |
|
85 | del user_ns[k] | |
|
86 | for k in new_globals: | |
|
87 | del user_global_ns[k] | |
|
86 | 88 | # Undo the hack at creation of PrefilterFrontEnd |
|
87 | 89 | from IPython.core import iplib |
|
88 | 90 | iplib.InteractiveShell.isthreaded = False |
@@ -97,7 +99,7 b' def test_execution():' | |||
|
97 | 99 | """ Test execution of a command. |
|
98 | 100 | """ |
|
99 | 101 | f = TestPrefilterFrontEnd() |
|
100 |
f.input_buffer = 'print |
|
|
102 | f.input_buffer = 'print(1)' | |
|
101 | 103 | f._on_enter() |
|
102 | 104 | out_value = f.out.getvalue() |
|
103 | 105 | assert_equal(out_value, '1\n') |
@@ -228,7 +230,14 b' def test_completion_indexing():' | |||
|
228 | 230 | f._on_enter() |
|
229 | 231 | f.input_buffer = 'a[0].' |
|
230 | 232 | f.complete_current_input() |
|
231 | assert_equal(f.input_buffer, 'a[0].__') | |
|
233 | ||
|
234 | if sys.version_info[:2] >= (2,6): | |
|
235 | # In Python 2.6, ints picked up a few non __ methods, so now there are | |
|
236 | # no completions. | |
|
237 | assert_equal(f.input_buffer, 'a[0].') | |
|
238 | else: | |
|
239 | # Right answer for 2.4/2.5 | |
|
240 | assert_equal(f.input_buffer, 'a[0].__') | |
|
232 | 241 | |
|
233 | 242 | |
|
234 | 243 | @isolate_ipython0 |
@@ -238,8 +247,13 b' def test_completion_equal():' | |||
|
238 | 247 | f = TestPrefilterFrontEnd() |
|
239 | 248 | f.input_buffer = 'a=1.' |
|
240 | 249 | f.complete_current_input() |
|
241 | assert_equal(f.input_buffer, 'a=1.__') | |
|
242 | ||
|
250 | if sys.version_info[:2] >= (2,6): | |
|
251 | # In Python 2.6, ints picked up a few non __ methods, so now there are | |
|
252 | # no completions. | |
|
253 | assert_equal(f.input_buffer, 'a=1.') | |
|
254 | else: | |
|
255 | # Right answer for 2.4/2.5 | |
|
256 | assert_equal(f.input_buffer, 'a=1.__') | |
|
243 | 257 | |
|
244 | 258 | |
|
245 | 259 | if __name__ == '__main__': |
@@ -447,29 +447,30 b' class ConsoleWidget(editwindow.EditWindow):' | |||
|
447 | 447 | # different callbacks share local variables? |
|
448 | 448 | |
|
449 | 449 | # Intercept some specific keys. |
|
450 | if event.KeyCode == ord('L') and event.ControlDown() : | |
|
450 | key_code = event.GetKeyCode() | |
|
451 | if key_code == ord('L') and event.ControlDown() : | |
|
451 | 452 | self.scroll_to_bottom() |
|
452 |
elif |
|
|
453 | elif key_code == ord('K') and event.ControlDown() : | |
|
453 | 454 | self.input_buffer = '' |
|
454 |
elif |
|
|
455 | elif key_code == ord('A') and event.ControlDown() : | |
|
455 | 456 | self.GotoPos(self.GetLength()) |
|
456 | 457 | self.SetSelectionStart(self.current_prompt_pos) |
|
457 | 458 | self.SetSelectionEnd(self.GetCurrentPos()) |
|
458 | 459 | catched = True |
|
459 |
elif |
|
|
460 | elif key_code == ord('E') and event.ControlDown() : | |
|
460 | 461 | self.GotoPos(self.GetLength()) |
|
461 | 462 | catched = True |
|
462 |
elif |
|
|
463 | elif key_code == wx.WXK_PAGEUP: | |
|
463 | 464 | self.ScrollPages(-1) |
|
464 |
elif |
|
|
465 | elif key_code == wx.WXK_PAGEDOWN: | |
|
465 | 466 | self.ScrollPages(1) |
|
466 |
elif |
|
|
467 | elif key_code == wx.WXK_HOME: | |
|
467 | 468 | self.GotoPos(self.GetLength()) |
|
468 |
elif |
|
|
469 | elif key_code == wx.WXK_END: | |
|
469 | 470 | self.GotoPos(self.GetLength()) |
|
470 |
elif |
|
|
471 | elif key_code == wx.WXK_UP and event.ShiftDown(): | |
|
471 | 472 | self.ScrollLines(-1) |
|
472 |
elif |
|
|
473 | elif key_code == wx.WXK_DOWN and event.ShiftDown(): | |
|
473 | 474 | self.ScrollLines(1) |
|
474 | 475 | else: |
|
475 | 476 | catched = False |
@@ -477,13 +478,12 b' class ConsoleWidget(editwindow.EditWindow):' | |||
|
477 | 478 | if self.AutoCompActive(): |
|
478 | 479 | event.Skip() |
|
479 | 480 | else: |
|
480 |
if |
|
|
481 | event.Modifiers in (wx.MOD_NONE, wx.MOD_WIN, | |
|
482 | wx.MOD_SHIFT): | |
|
481 | if key_code in (13, wx.WXK_NUMPAD_ENTER): | |
|
482 | # XXX: not catching modifiers, to be wx2.6-compatible | |
|
483 | 483 | catched = True |
|
484 | 484 | if not self.enter_catched: |
|
485 | 485 | self.CallTipCancel() |
|
486 |
if event. |
|
|
486 | if event.ShiftDown(): | |
|
487 | 487 | # Try to force execution |
|
488 | 488 | self.GotoPos(self.GetLength()) |
|
489 | 489 | self.write('\n' + self.continuation_prompt(), |
@@ -493,19 +493,18 b' class ConsoleWidget(editwindow.EditWindow):' | |||
|
493 | 493 | self._on_enter() |
|
494 | 494 | self.enter_catched = True |
|
495 | 495 | |
|
496 |
elif |
|
|
497 | if event.Modifiers in (wx.MOD_NONE, wx.MOD_WIN): | |
|
496 | elif key_code == wx.WXK_HOME: | |
|
497 | if not event.ShiftDown(): | |
|
498 | 498 | self.GotoPos(self.current_prompt_pos) |
|
499 | 499 | catched = True |
|
500 | ||
|
501 | elif event.Modifiers == wx.MOD_SHIFT: | |
|
500 | else: | |
|
502 | 501 | # FIXME: This behavior is not ideal: if the selection |
|
503 | 502 | # is already started, it will jump. |
|
504 | 503 | self.SetSelectionStart(self.current_prompt_pos) |
|
505 | 504 | self.SetSelectionEnd(self.GetCurrentPos()) |
|
506 | 505 | catched = True |
|
507 | 506 | |
|
508 |
elif |
|
|
507 | elif key_code == wx.WXK_UP: | |
|
509 | 508 | if self.GetCurrentLine() > self.current_prompt_line: |
|
510 | 509 | if self.GetCurrentLine() == self.current_prompt_line + 1 \ |
|
511 | 510 | and self.GetColumn(self.GetCurrentPos()) < \ |
@@ -515,18 +514,18 b' class ConsoleWidget(editwindow.EditWindow):' | |||
|
515 | 514 | event.Skip() |
|
516 | 515 | catched = True |
|
517 | 516 | |
|
518 |
elif |
|
|
517 | elif key_code in (wx.WXK_LEFT, wx.WXK_BACK): | |
|
519 | 518 | if not self._keep_cursor_in_buffer(self.GetCurrentPos() - 1): |
|
520 | 519 | event.Skip() |
|
521 | 520 | catched = True |
|
522 | 521 | |
|
523 |
elif |
|
|
522 | elif key_code == wx.WXK_RIGHT: | |
|
524 | 523 | if not self._keep_cursor_in_buffer(self.GetCurrentPos() + 1): |
|
525 | 524 | event.Skip() |
|
526 | 525 | catched = True |
|
527 | 526 | |
|
528 | 527 | |
|
529 |
elif |
|
|
528 | elif key_code == wx.WXK_DELETE: | |
|
530 | 529 | if not self._keep_cursor_in_buffer(self.GetCurrentPos() - 1): |
|
531 | 530 | event.Skip() |
|
532 | 531 | catched = True |
@@ -535,7 +534,7 b' class ConsoleWidget(editwindow.EditWindow):' | |||
|
535 | 534 | # Put the cursor back in the edit region |
|
536 | 535 | if not self._keep_cursor_in_buffer(): |
|
537 | 536 | if not (self.GetCurrentPos() == self.GetLength() |
|
538 |
and |
|
|
537 | and key_code == wx.WXK_DELETE): | |
|
539 | 538 | event.Skip() |
|
540 | 539 | catched = True |
|
541 | 540 |
@@ -389,7 +389,8 b' class WxController(ConsoleWidget, PrefilterFrontEnd):' | |||
|
389 | 389 | """ |
|
390 | 390 | # FIXME: This method needs to be broken down in smaller ones. |
|
391 | 391 | current_line_num = self.GetCurrentLine() |
|
392 | if event.KeyCode in (ord('c'), ord('C')) and event.ControlDown(): | |
|
392 | key_code = event.GetKeyCode() | |
|
393 | if key_code in (ord('c'), ord('C')) and event.ControlDown(): | |
|
393 | 394 | # Capture Control-C |
|
394 | 395 | if self._input_state == 'subprocess': |
|
395 | 396 | if self.debug: |
@@ -403,40 +404,39 b' class WxController(ConsoleWidget, PrefilterFrontEnd):' | |||
|
403 | 404 | # XXX: We need to make really sure we |
|
404 | 405 | # get back to a prompt. |
|
405 | 406 | elif self._input_state == 'subprocess' and ( |
|
406 |
( |
|
|
407 | not event.ControlDown() ) | |
|
407 | ( key_code <256 and not event.ControlDown() ) | |
|
408 | 408 | or |
|
409 |
( |
|
|
409 | ( key_code in (ord('d'), ord('D')) and | |
|
410 | 410 | event.ControlDown())): |
|
411 | 411 | # We are running a process, we redirect keys. |
|
412 | 412 | ConsoleWidget._on_key_down(self, event, skip=skip) |
|
413 |
char = chr( |
|
|
413 | char = chr(key_code) | |
|
414 | 414 | # Deal with some inconsistency in wx keycodes: |
|
415 | 415 | if char == '\r': |
|
416 | 416 | char = '\n' |
|
417 | 417 | elif not event.ShiftDown(): |
|
418 | 418 | char = char.lower() |
|
419 |
if event.ControlDown() and |
|
|
419 | if event.ControlDown() and key_code in (ord('d'), ord('D')): | |
|
420 | 420 | char = '\04' |
|
421 | 421 | self._running_process.process.stdin.write(char) |
|
422 | 422 | self._running_process.process.stdin.flush() |
|
423 |
elif |
|
|
423 | elif key_code in (ord('('), 57, 53): | |
|
424 | 424 | # Calltips |
|
425 | 425 | event.Skip() |
|
426 | 426 | self.do_calltip() |
|
427 |
elif self.AutoCompActive() and not |
|
|
427 | elif self.AutoCompActive() and not key_code == ord('\t'): | |
|
428 | 428 | event.Skip() |
|
429 |
if |
|
|
429 | if key_code in (wx.WXK_BACK, wx.WXK_DELETE): | |
|
430 | 430 | wx.CallAfter(self._popup_completion, create=True) |
|
431 |
elif not |
|
|
431 | elif not key_code in (wx.WXK_UP, wx.WXK_DOWN, wx.WXK_LEFT, | |
|
432 | 432 | wx.WXK_RIGHT, wx.WXK_ESCAPE): |
|
433 | 433 | wx.CallAfter(self._popup_completion) |
|
434 | 434 | else: |
|
435 | 435 | # Up history |
|
436 |
if |
|
|
437 | ( current_line_num == self.current_prompt_line and | |
|
438 | event.Modifiers in (wx.MOD_NONE, wx.MOD_WIN) ) | |
|
439 |
|
|
|
436 | if key_code == wx.WXK_UP and ( | |
|
437 | event.ControlDown() or | |
|
438 | current_line_num == self.current_prompt_line | |
|
439 | ): | |
|
440 | 440 | new_buffer = self.get_history_previous( |
|
441 | 441 | self.input_buffer) |
|
442 | 442 | if new_buffer is not None: |
@@ -445,23 +445,24 b' class WxController(ConsoleWidget, PrefilterFrontEnd):' | |||
|
445 | 445 | # Go to first line, for seemless history up. |
|
446 | 446 | self.GotoPos(self.current_prompt_pos) |
|
447 | 447 | # Down history |
|
448 |
elif |
|
|
449 | ( current_line_num == self.LineCount -1 and | |
|
450 | event.Modifiers in (wx.MOD_NONE, wx.MOD_WIN) ) | |
|
451 |
|
|
|
448 | elif key_code == wx.WXK_DOWN and ( | |
|
449 | event.ControlDown() or | |
|
450 | current_line_num == self.LineCount -1 | |
|
451 | ): | |
|
452 | 452 | new_buffer = self.get_history_next() |
|
453 | 453 | if new_buffer is not None: |
|
454 | 454 | self.input_buffer = new_buffer |
|
455 | 455 | # Tab-completion |
|
456 |
elif |
|
|
456 | elif key_code == ord('\t'): | |
|
457 | 457 | current_line, current_line_num = self.CurLine |
|
458 |
if not re.match(r'^\s*$', |
|
|
458 | if not re.match(r'^%s\s*$' % self.continuation_prompt(), | |
|
459 | current_line): | |
|
459 | 460 | self.complete_current_input() |
|
460 | 461 | if self.AutoCompActive(): |
|
461 | 462 | wx.CallAfter(self._popup_completion, create=True) |
|
462 | 463 | else: |
|
463 | 464 | event.Skip() |
|
464 |
elif |
|
|
465 | elif key_code == wx.WXK_BACK: | |
|
465 | 466 | # If characters where erased, check if we have to |
|
466 | 467 | # remove a line. |
|
467 | 468 | # XXX: What about DEL? |
@@ -496,7 +497,7 b' class WxController(ConsoleWidget, PrefilterFrontEnd):' | |||
|
496 | 497 | def _on_key_up(self, event, skip=True): |
|
497 | 498 | """ Called when any key is released. |
|
498 | 499 | """ |
|
499 | if event.KeyCode in (59, ord('.')): | |
|
500 | if event.GetKeyCode() in (59, ord('.')): | |
|
500 | 501 | # Intercepting '.' |
|
501 | 502 | event.Skip() |
|
502 | 503 | wx.CallAfter(self._popup_completion, create=True) |
@@ -46,7 +46,7 b' class _Helper(object):' | |||
|
46 | 46 | |
|
47 | 47 | def __call__(self, *args, **kwds): |
|
48 | 48 | class DummyWriter(object): |
|
49 |
'''Dumy class to handle help output''' |
|
|
49 | '''Dumy class to handle help output''' | |
|
50 | 50 | def __init__(self, pager): |
|
51 | 51 | self._pager = pager |
|
52 | 52 |
@@ -76,12 +76,12 b' class WxNonBlockingIPShell(NonBlockingIPShell):' | |||
|
76 | 76 | """ A replacement from python's raw_input. |
|
77 | 77 | """ |
|
78 | 78 | self.answer = None |
|
79 |
if(self._threading == True): |
|
|
80 |
|
|
|
81 |
|
|
|
82 | time.sleep(.1) | |
|
79 | if(self._threading == True): | |
|
80 | wx.CallAfter(self._yesNoBox, prompt) | |
|
81 | while self.answer is None: | |
|
82 | time.sleep(.1) | |
|
83 | 83 | else: |
|
84 |
|
|
|
84 | self._yesNoBox(prompt) | |
|
85 | 85 | return self.answer |
|
86 | 86 | |
|
87 | 87 | def _yesNoBox(self, prompt): |
@@ -26,7 +26,7 b' import sys' | |||
|
26 | 26 | |
|
27 | 27 | from twisted.internet.error import ConnectionRefusedError |
|
28 | 28 | |
|
29 |
from IPython. |
|
|
29 | from IPython.core.ultratb import _fixed_getinnerframes, findsource | |
|
30 | 30 | from IPython.core import ipapi |
|
31 | 31 | |
|
32 | 32 | from IPython.kernel import error |
@@ -29,7 +29,7 b' import sys' | |||
|
29 | 29 | import traceback |
|
30 | 30 | |
|
31 | 31 | # Local imports. |
|
32 |
from IPython. |
|
|
32 | from IPython.core import ultratb | |
|
33 | 33 | from IPython.kernel.core.display_trap import DisplayTrap |
|
34 | 34 | from IPython.kernel.core.macro import Macro |
|
35 | 35 | from IPython.kernel.core.prompts import CachedOutput |
@@ -167,9 +167,9 b' class Interpreter(object):' | |||
|
167 | 167 | formatters=self.traceback_formatters) |
|
168 | 168 | |
|
169 | 169 | # This is used temporarily for reformating exceptions in certain |
|
170 |
# cases. It will go away once the ultra |
|
|
170 | # cases. It will go away once the ultratb stuff is ported | |
|
171 | 171 | # to ipython1 |
|
172 |
self.tbHandler = ultra |
|
|
172 | self.tbHandler = ultratb.FormattedTB(color_scheme='NoColor', | |
|
173 | 173 | mode='Context', |
|
174 | 174 | tb_offset=2) |
|
175 | 175 | |
@@ -729,8 +729,8 b' class Interpreter(object):' | |||
|
729 | 729 | def error(self, text): |
|
730 | 730 | """ Pass an error message back to the shell. |
|
731 | 731 | |
|
732 | Preconditions | |
|
733 |
----- |
|
|
732 | Notes | |
|
733 | ----- | |
|
734 | 734 | This should only be called when self.message is set. In other words, |
|
735 | 735 | when code is being executed. |
|
736 | 736 |
@@ -21,8 +21,8 b' __test__ = {}' | |||
|
21 | 21 | class NotificationCenter(object): |
|
22 | 22 | """Synchronous notification center |
|
23 | 23 | |
|
24 | Example | |
|
25 | ------- | |
|
24 | Examples | |
|
25 | -------- | |
|
26 | 26 | >>> import IPython.kernel.core.notification as notification |
|
27 | 27 | >>> def callback(theType, theSender, args={}): |
|
28 | 28 | ... print theType,theSender,args |
@@ -47,10 +47,10 b' class NotificationCenter(object):' | |||
|
47 | 47 | |
|
48 | 48 | def post_notification(self, theType, sender, **kwargs): |
|
49 | 49 | """Post notification (type,sender,**kwargs) to all registered |
|
50 |
observers. |
|
|
51 | ||
|
52 | Implementation | |
|
53 | -------------- | |
|
50 | observers. | |
|
51 | ||
|
52 | Implementation notes: | |
|
53 | ||
|
54 | 54 | * If no registered observers, performance is O(1). |
|
55 | 55 | * Notificaiton order is undefined. |
|
56 | 56 | * Notifications are posted synchronously. |
@@ -122,4 +122,4 b' class NotificationCenter(object):' | |||
|
122 | 122 | |
|
123 | 123 | |
|
124 | 124 | |
|
125 | sharedCenter = NotificationCenter() No newline at end of file | |
|
125 | sharedCenter = NotificationCenter() |
@@ -106,6 +106,9 b' def make_quoted_expr(s):' | |||
|
106 | 106 | def system_shell(cmd, verbose=False, debug=False, header=''): |
|
107 | 107 | """ Execute a command in the system shell; always return None. |
|
108 | 108 | |
|
109 | This returns None so it can be conveniently used in interactive loops | |
|
110 | without getting the return value (typically 0) printed many times. | |
|
111 | ||
|
109 | 112 | Parameters |
|
110 | 113 | ---------- |
|
111 | 114 | cmd : str |
@@ -117,11 +120,6 b" def system_shell(cmd, verbose=False, debug=False, header=''):" | |||
|
117 | 120 | header : str |
|
118 | 121 | Header to print to screen prior to the executed command. No extra |
|
119 | 122 | newlines are added. |
|
120 | ||
|
121 | Description | |
|
122 | ----------- | |
|
123 | This returns None so it can be conveniently used in interactive loops | |
|
124 | without getting the return value (typically 0) printed many times. | |
|
125 | 123 | """ |
|
126 | 124 | |
|
127 | 125 | if verbose or debug: |
@@ -23,6 +23,10 b' method that automatically added methods to engines.' | |||
|
23 | 23 | |
|
24 | 24 | __docformat__ = "restructuredtext en" |
|
25 | 25 | |
|
26 | # Tell nose to skip this module. I don't think we need this as nose | |
|
27 | # shouldn't ever be run on this! | |
|
28 | __test__ = {} | |
|
29 | ||
|
26 | 30 | #------------------------------------------------------------------------------- |
|
27 | 31 | # Copyright (C) 2008 The IPython Development Team |
|
28 | 32 | # |
@@ -34,12 +38,9 b' __docformat__ = "restructuredtext en"' | |||
|
34 | 38 | # Imports |
|
35 | 39 | #------------------------------------------------------------------------------- |
|
36 | 40 | |
|
37 | # Tell nose to skip the testing of this module | |
|
38 | __test__ = {} | |
|
39 | ||
|
40 | import os, sys, copy | |
|
41 | import copy | |
|
42 | import sys | |
|
41 | 43 | import cPickle as pickle |
|
42 | from new import instancemethod | |
|
43 | 44 | |
|
44 | 45 | from twisted.application import service |
|
45 | 46 | from twisted.internet import defer, reactor |
@@ -47,11 +48,7 b' from twisted.python import log, failure, components' | |||
|
47 | 48 | import zope.interface as zi |
|
48 | 49 | |
|
49 | 50 | from IPython.kernel.core.interpreter import Interpreter |
|
50 |
from IPython.kernel import newserialized, error |
|
|
51 | from IPython.kernel.util import printer | |
|
52 | from IPython.kernel.twistedutil import gatherBoth, DeferredList | |
|
53 | from IPython.kernel import codeutil | |
|
54 | ||
|
51 | from IPython.kernel import newserialized, error | |
|
55 | 52 | |
|
56 | 53 | #------------------------------------------------------------------------------- |
|
57 | 54 | # Interface specification for the Engine |
@@ -4,6 +4,9 b'' | |||
|
4 | 4 | |
|
5 | 5 | __docformat__ = "restructuredtext en" |
|
6 | 6 | |
|
7 | # Tell nose to skip this module | |
|
8 | __test__ = {} | |
|
9 | ||
|
7 | 10 | #------------------------------------------------------------------------------- |
|
8 | 11 | # Copyright (C) 2008 The IPython Development Team |
|
9 | 12 | # |
@@ -14,9 +17,9 b' __docformat__ = "restructuredtext en"' | |||
|
14 | 17 | #------------------------------------------------------------------------------- |
|
15 | 18 | # Imports |
|
16 | 19 | #------------------------------------------------------------------------------- |
|
20 | from twisted.python import failure | |
|
17 | 21 | |
|
18 | 22 | from IPython.kernel.core import error |
|
19 | from twisted.python import failure | |
|
20 | 23 | |
|
21 | 24 | #------------------------------------------------------------------------------- |
|
22 | 25 | # Error classes |
@@ -86,14 +86,13 b' class PendingResult(object):' | |||
|
86 | 86 | |
|
87 | 87 | A user should not create a `PendingResult` instance by hand. |
|
88 | 88 | |
|
89 | Methods | |
|
90 | ======= | |
|
89 | Methods: | |
|
91 | 90 | |
|
92 | 91 | * `get_result` |
|
93 | 92 | * `add_callback` |
|
94 | 93 | |
|
95 | Properties | |
|
96 | ========== | |
|
94 | Properties: | |
|
95 | ||
|
97 | 96 | * `r` |
|
98 | 97 | """ |
|
99 | 98 |
@@ -5,6 +5,9 b'' | |||
|
5 | 5 | |
|
6 | 6 | __docformat__ = "restructuredtext en" |
|
7 | 7 | |
|
8 | # Tell nose to skip this module | |
|
9 | __test__ = {} | |
|
10 | ||
|
8 | 11 | #------------------------------------------------------------------------------- |
|
9 | 12 | # Copyright (C) 2008 The IPython Development Team |
|
10 | 13 | # |
@@ -18,8 +21,8 b' __docformat__ = "restructuredtext en"' | |||
|
18 | 21 | |
|
19 | 22 | import cPickle as pickle |
|
20 | 23 | |
|
21 | from zope.interface import Interface, implements | |
|
22 | 24 | from twisted.python import components |
|
25 | from zope.interface import Interface, implements | |
|
23 | 26 | |
|
24 | 27 | try: |
|
25 | 28 | import numpy |
@@ -28,6 +31,10 b' except ImportError:' | |||
|
28 | 31 | |
|
29 | 32 | from IPython.kernel.error import SerializationError |
|
30 | 33 | |
|
34 | #----------------------------------------------------------------------------- | |
|
35 | # Classes and functions | |
|
36 | #----------------------------------------------------------------------------- | |
|
37 | ||
|
31 | 38 | class ISerialized(Interface): |
|
32 | 39 | |
|
33 | 40 | def getData(): |
|
1 | NO CONTENT: modified file chmod 100755 => 100644 |
@@ -414,7 +414,7 b' class ResultNS(object):' | |||
|
414 | 414 | This can be a bad idea, as it may corrupt standard behavior of the |
|
415 | 415 | ns object. |
|
416 | 416 | |
|
417 | Example | |
|
417 | Examples | |
|
418 | 418 | -------- |
|
419 | 419 | |
|
420 | 420 | >>> ns = ResultNS({'a':17,'foo':range(3)}) |
@@ -111,6 +111,13 b' has a few useful methods for navigation, like again(), edit(), jump(), seek()' | |||
|
111 | 111 | and back(). It can be reset for a new run via reset() or reloaded from disk |
|
112 | 112 | (in case you've edited the source) via reload(). See their docstrings below. |
|
113 | 113 | |
|
114 | Note: To make this simpler to explore, a file called "demo-exercizer.py" has | |
|
115 | been added to the "docs/examples/core" directory. Just cd to this directory in | |
|
116 | an IPython session, and type:: | |
|
117 | ||
|
118 | %run demo-exercizer.py | |
|
119 | ||
|
120 | and then follow the directions. | |
|
114 | 121 | |
|
115 | 122 | Example |
|
116 | 123 | ======= |
@@ -125,7 +132,7 b" print 'Hello, welcome to an interactive IPython demo.'" | |||
|
125 | 132 | # The mark below defines a block boundary, which is a point where IPython will |
|
126 | 133 | # stop execution and return to the interactive prompt. The dashes are actually |
|
127 | 134 | # optional and used only as a visual aid to clearly separate blocks while |
|
128 | editing the demo code. | |
|
135 | # editing the demo code. | |
|
129 | 136 | # <demo> stop |
|
130 | 137 | |
|
131 | 138 | x = 1 |
@@ -169,7 +176,7 b' import shlex' | |||
|
169 | 176 | import sys |
|
170 | 177 | |
|
171 | 178 | from IPython.utils.PyColorize import Parser |
|
172 | from IPython.utils.genutils import marquee, file_read, file_readlines | |
|
179 | from IPython.utils.genutils import marquee, file_read, file_readlines, Term | |
|
173 | 180 | |
|
174 | 181 | __all__ = ['Demo','IPythonDemo','LineDemo','IPythonLineDemo','DemoError'] |
|
175 | 182 | |
@@ -185,7 +192,7 b' class Demo(object):' | |||
|
185 | 192 | re_auto = re_mark('auto') |
|
186 | 193 | re_auto_all = re_mark('auto_all') |
|
187 | 194 | |
|
188 |
def __init__(self, |
|
|
195 | def __init__(self,src,title='',arg_str='',auto_all=None): | |
|
189 | 196 | """Make a new demo object. To run the demo, simply call the object. |
|
190 | 197 | |
|
191 | 198 | See the module docstring for full details and an example (you can use |
@@ -193,9 +200,14 b' class Demo(object):' | |||
|
193 | 200 | |
|
194 | 201 | Inputs: |
|
195 | 202 | |
|
196 | - fname = filename. | |
|
203 | - src is either a file, or file-like object, or a | |
|
204 | string that can be resolved to a filename. | |
|
197 | 205 | |
|
198 | 206 | Optional inputs: |
|
207 | ||
|
208 | - title: a string to use as the demo name. Of most use when the demo | |
|
209 | you are making comes from an object that has no filename, or if you | |
|
210 | want an alternate denotation distinct from the filename. | |
|
199 | 211 | |
|
200 | 212 | - arg_str(''): a string of arguments, internally converted to a list |
|
201 | 213 | just like sys.argv, so the demo script can see a similar |
@@ -207,9 +219,24 b' class Demo(object):' | |||
|
207 | 219 | can be changed at runtime simply by reassigning it to a boolean |
|
208 | 220 | value. |
|
209 | 221 | """ |
|
210 | ||
|
211 | self.fname = fname | |
|
212 | self.sys_argv = [fname] + shlex.split(arg_str) | |
|
222 | if hasattr(src, "read"): | |
|
223 | # It seems to be a file or a file-like object | |
|
224 | self.fobj = src | |
|
225 | self.fname = "from a file-like object" | |
|
226 | if title == '': | |
|
227 | self.title = "from a file-like object" | |
|
228 | else: | |
|
229 | self.title = title | |
|
230 | else: | |
|
231 | # Assume it's a string or something that can be converted to one | |
|
232 | self.fobj = open(src) | |
|
233 | self.fname = src | |
|
234 | if title == '': | |
|
235 | (filepath, filename) = os.path.split(src) | |
|
236 | self.title = filename | |
|
237 | else: | |
|
238 | self.title = title | |
|
239 | self.sys_argv = [src] + shlex.split(arg_str) | |
|
213 | 240 | self.auto_all = auto_all |
|
214 | 241 | |
|
215 | 242 | # get a few things from ipython. While it's a bit ugly design-wise, |
@@ -228,7 +255,7 b' class Demo(object):' | |||
|
228 | 255 | def reload(self): |
|
229 | 256 | """Reload source from disk and initialize state.""" |
|
230 | 257 | # read data and parse into blocks |
|
231 |
self.src = |
|
|
258 | self.src = self.fobj.read() | |
|
232 | 259 | src_b = [b.strip() for b in self.re_stop.split(self.src) if b] |
|
233 | 260 | self._silent = [bool(self.re_silent.findall(b)) for b in src_b] |
|
234 | 261 | self._auto = [bool(self.re_auto.findall(b)) for b in src_b] |
@@ -277,7 +304,7 b' class Demo(object):' | |||
|
277 | 304 | |
|
278 | 305 | if index is None: |
|
279 | 306 | if self.finished: |
|
280 | print 'Demo finished. Use reset() if you want to rerun it.' | |
|
307 | print >>Term.cout, 'Demo finished. Use <demo_name>.reset() if you want to rerun it.' | |
|
281 | 308 | return None |
|
282 | 309 | index = self.block_index |
|
283 | 310 | else: |
@@ -346,26 +373,27 b' class Demo(object):' | |||
|
346 | 373 | if index is None: |
|
347 | 374 | return |
|
348 | 375 | |
|
349 | print self.marquee('<%s> block # %s (%s remaining)' % | |
|
350 |
(self. |
|
|
351 |
|
|
|
376 | print >>Term.cout, self.marquee('<%s> block # %s (%s remaining)' % | |
|
377 | (self.title,index,self.nblocks-index-1)) | |
|
378 | print >>Term.cout,(self.src_blocks_colored[index]) | |
|
352 | 379 | sys.stdout.flush() |
|
353 | 380 | |
|
354 | 381 | def show_all(self): |
|
355 | 382 | """Show entire demo on screen, block by block""" |
|
356 | 383 | |
|
357 |
fname = self. |
|
|
384 | fname = self.title | |
|
385 | title = self.title | |
|
358 | 386 | nblocks = self.nblocks |
|
359 | 387 | silent = self._silent |
|
360 | 388 | marquee = self.marquee |
|
361 | 389 | for index,block in enumerate(self.src_blocks_colored): |
|
362 | 390 | if silent[index]: |
|
363 | print marquee('<%s> SILENT block # %s (%s remaining)' % | |
|
364 |
( |
|
|
391 | print >>Term.cout, marquee('<%s> SILENT block # %s (%s remaining)' % | |
|
392 | (title,index,nblocks-index-1)) | |
|
365 | 393 | else: |
|
366 | print marquee('<%s> block # %s (%s remaining)' % | |
|
367 |
( |
|
|
368 | print block, | |
|
394 | print >>Term.cout, marquee('<%s> block # %s (%s remaining)' % | |
|
395 | (title,index,nblocks-index-1)) | |
|
396 | print >>Term.cout, block, | |
|
369 | 397 | sys.stdout.flush() |
|
370 | 398 | |
|
371 | 399 | def runlines(self,source): |
@@ -390,18 +418,18 b' class Demo(object):' | |||
|
390 | 418 | next_block = self.src_blocks[index] |
|
391 | 419 | self.block_index += 1 |
|
392 | 420 | if self._silent[index]: |
|
393 | print marquee('Executing silent block # %s (%s remaining)' % | |
|
421 | print >>Term.cout, marquee('Executing silent block # %s (%s remaining)' % | |
|
394 | 422 | (index,self.nblocks-index-1)) |
|
395 | 423 | else: |
|
396 | 424 | self.pre_cmd() |
|
397 | 425 | self.show(index) |
|
398 | 426 | if self.auto_all or self._auto[index]: |
|
399 | print marquee('output:') | |
|
427 | print >>Term.cout, marquee('output:') | |
|
400 | 428 | else: |
|
401 | print marquee('Press <q> to quit, <Enter> to execute...'), | |
|
429 | print >>Term.cout, marquee('Press <q> to quit, <Enter> to execute...'), | |
|
402 | 430 | ans = raw_input().strip() |
|
403 | 431 | if ans: |
|
404 | print marquee('Block NOT executed') | |
|
432 | print >>Term.cout, marquee('Block NOT executed') | |
|
405 | 433 | return |
|
406 | 434 | try: |
|
407 | 435 | save_argv = sys.argv |
@@ -419,10 +447,10 b' class Demo(object):' | |||
|
419 | 447 | if self.block_index == self.nblocks: |
|
420 | 448 | mq1 = self.marquee('END OF DEMO') |
|
421 | 449 | if mq1: |
|
422 | # avoid spurious prints if empty marquees are used | |
|
423 | ||
|
424 | print mq1 | |
|
425 | print self.marquee('Use reset() if you want to rerun it.') | |
|
450 | # avoid spurious print >>Term.cout,s if empty marquees are used | |
|
451 | print >>Term.cout | |
|
452 | print >>Term.cout, mq1 | |
|
453 | print >>Term.cout, self.marquee('Use <demo_name>.reset() if you want to rerun it.') | |
|
426 | 454 | self.finished = True |
|
427 | 455 | |
|
428 | 456 | # These methods are meant to be overridden by subclasses who may wish to |
@@ -471,9 +499,9 b' class LineDemo(Demo):' | |||
|
471 | 499 | def reload(self): |
|
472 | 500 | """Reload source from disk and initialize state.""" |
|
473 | 501 | # read data and parse into blocks |
|
474 |
src_b = [l for l in |
|
|
502 | src_b = [l for l in self.fobj.readline() if l.strip()] | |
|
475 | 503 | nblocks = len(src_b) |
|
476 |
self.src = os.linesep.join( |
|
|
504 | self.src = os.linesep.join(self.fobj.readlines()) | |
|
477 | 505 | self._silent = [False]*nblocks |
|
478 | 506 | self._auto = [True]*nblocks |
|
479 | 507 | self.auto_all = True |
@@ -494,29 +522,29 b' class IPythonLineDemo(IPythonDemo,LineDemo):' | |||
|
494 | 522 | |
|
495 | 523 | class ClearMixin(object): |
|
496 | 524 | """Use this mixin to make Demo classes with less visual clutter. |
|
497 | ||
|
525 | ||
|
498 | 526 | Demos using this mixin will clear the screen before every block and use |
|
499 | 527 | blank marquees. |
|
500 | ||
|
528 | ||
|
501 | 529 | Note that in order for the methods defined here to actually override those |
|
502 | 530 | of the classes it's mixed with, it must go /first/ in the inheritance |
|
503 | 531 | tree. For example: |
|
504 | ||
|
532 | ||
|
505 | 533 | class ClearIPDemo(ClearMixin,IPythonDemo): pass |
|
506 | ||
|
534 | ||
|
507 | 535 | will provide an IPythonDemo class with the mixin's features. |
|
508 | 536 | """ |
|
509 | 537 | |
|
510 | 538 | def marquee(self,txt='',width=78,mark='*'): |
|
511 | 539 | """Blank marquee that returns '' no matter what the input.""" |
|
512 | 540 | return '' |
|
513 | ||
|
541 | ||
|
514 | 542 | def pre_cmd(self): |
|
515 | 543 | """Method called before executing each block. |
|
516 | ||
|
544 | ||
|
517 | 545 | This one simply clears the screen.""" |
|
518 | os.system('clear') | |
|
519 | ||
|
546 | from IPython.utils.platutils import term_clear | |
|
547 | term_clear() | |
|
520 | 548 | |
|
521 | 549 | class ClearDemo(ClearMixin,Demo): |
|
522 | 550 | pass |
@@ -45,10 +45,10 b' def skipif(skip_condition=True, msg=None):' | |||
|
45 | 45 | Parameters |
|
46 | 46 | ---------- |
|
47 | 47 | skip_condition : bool or callable. |
|
48 |
|
|
|
49 |
|
|
|
50 |
|
|
|
51 |
|
|
|
48 | Flag to determine whether to skip test. If the condition is a | |
|
49 | callable, it is used at runtime to dynamically make the decision. This | |
|
50 | is useful for tests that may require costly imports, to delay the cost | |
|
51 | until the test suite is actually executed. | |
|
52 | 52 | msg : string |
|
53 | 53 | Message to give on raising a SkipTest exception |
|
54 | 54 |
@@ -24,6 +24,7 b' import os' | |||
|
24 | 24 | import os.path as path |
|
25 | 25 | import sys |
|
26 | 26 | import subprocess |
|
27 | import tempfile | |
|
27 | 28 | import time |
|
28 | 29 | import warnings |
|
29 | 30 | |
@@ -50,6 +51,7 b' def test_for(mod):' | |||
|
50 | 51 | |
|
51 | 52 | have_curses = test_for('_curses') |
|
52 | 53 | have_wx = test_for('wx') |
|
54 | have_wx_aui = test_for('wx.aui') | |
|
53 | 55 | have_zi = test_for('zope.interface') |
|
54 | 56 | have_twisted = test_for('twisted') |
|
55 | 57 | have_foolscap = test_for('foolscap') |
@@ -69,8 +71,9 b' def make_exclude():' | |||
|
69 | 71 | pjoin('IPython', 'frontend', 'process', 'winprocess.py'), |
|
70 | 72 | pjoin('IPython_doctest_plugin'), |
|
71 | 73 | pjoin('IPython', 'extensions', 'ipy_'), |
|
72 |
pjoin('IPython', 'extensions', ' |
|
|
74 | pjoin('IPython', 'extensions', 'PhysicalQInput'), | |
|
73 | 75 | pjoin('IPython', 'extensions', 'PhysicalQInteractive'), |
|
76 | pjoin('IPython', 'extensions', 'InterpreterPasteInput'), | |
|
74 | 77 | pjoin('IPython', 'extensions', 'scitedirector'), |
|
75 | 78 | pjoin('IPython', 'extensions', 'numeric_formats'), |
|
76 | 79 | pjoin('IPython', 'testing', 'attic'), |
@@ -88,6 +91,9 b' def make_exclude():' | |||
|
88 | 91 | if not have_gtk or not have_gobject: |
|
89 | 92 | EXCLUDE.append(pjoin('IPython', 'lib', 'inputhookgtk')) |
|
90 | 93 | |
|
94 | if not have_wx_aui: | |
|
95 | EXCLUDE.append(pjoin('IPython', 'gui', 'wx', 'wxIPython')) | |
|
96 | ||
|
91 | 97 | if not have_objc: |
|
92 | 98 | EXCLUDE.append(pjoin('IPython', 'frontend', 'cocoa')) |
|
93 | 99 | |
@@ -109,6 +115,27 b' def make_exclude():' | |||
|
109 | 115 | if not have_pexpect: |
|
110 | 116 | EXCLUDE.append(pjoin('IPython', 'scripts', 'irunner')) |
|
111 | 117 | |
|
118 | # This is scary. We still have things in frontend and testing that | |
|
119 | # are being tested by nose that use twisted. We need to rethink | |
|
120 | # how we are isolating dependencies in testing. | |
|
121 | if not (have_twisted and have_zi and have_foolscap): | |
|
122 | EXCLUDE.append(pjoin('IPython', 'frontend', 'asyncfrontendbase')) | |
|
123 | EXCLUDE.append(pjoin('IPython', 'frontend', 'prefilterfrontend')) | |
|
124 | EXCLUDE.append(pjoin('IPython', 'frontend', 'frontendbase')) | |
|
125 | EXCLUDE.append(pjoin('IPython', 'frontend', 'linefrontendbase')) | |
|
126 | EXCLUDE.append(pjoin('IPython', 'frontend', 'tests', | |
|
127 | 'test_linefrontend')) | |
|
128 | EXCLUDE.append(pjoin('IPython', 'frontend', 'tests', | |
|
129 | 'test_frontendbase')) | |
|
130 | EXCLUDE.append(pjoin('IPython', 'frontend', 'tests', | |
|
131 | 'test_prefilterfrontend')) | |
|
132 | EXCLUDE.append(pjoin('IPython', 'frontend', 'tests', | |
|
133 | 'test_asyncfrontendbase')), | |
|
134 | EXCLUDE.append(pjoin('IPython', 'testing', 'parametric')) | |
|
135 | EXCLUDE.append(pjoin('IPython', 'testing', 'util')) | |
|
136 | EXCLUDE.append(pjoin('IPython', 'testing', 'tests', | |
|
137 | 'test_decorators_trial')) | |
|
138 | ||
|
112 | 139 | # Skip shell always because of a bug in FakeModule. |
|
113 | 140 | EXCLUDE.append(pjoin('IPython', 'core', 'shell')) |
|
114 | 141 | |
@@ -118,6 +145,7 b' def make_exclude():' | |||
|
118 | 145 | |
|
119 | 146 | return EXCLUDE |
|
120 | 147 | |
|
148 | ||
|
121 | 149 | #----------------------------------------------------------------------------- |
|
122 | 150 | # Functions and classes |
|
123 | 151 | #----------------------------------------------------------------------------- |
@@ -196,9 +224,29 b' class IPTester(object):' | |||
|
196 | 224 | # Assemble call |
|
197 | 225 | self.call_args = self.runner+self.params |
|
198 | 226 | |
|
199 | def run(self): | |
|
200 | """Run the stored commands""" | |
|
201 | return subprocess.call(self.call_args) | |
|
227 | if sys.platform == 'win32': | |
|
228 | def run(self): | |
|
229 | """Run the stored commands""" | |
|
230 | # On Windows, cd to temporary directory to run tests. Otherwise, | |
|
231 | # Twisted's trial may not be able to execute 'trial IPython', since | |
|
232 | # it will confuse the IPython module name with the ipython | |
|
233 | # execution scripts, because the windows file system isn't case | |
|
234 | # sensitive. | |
|
235 | # We also use os.system instead of subprocess.call, because I was | |
|
236 | # having problems with subprocess and I just don't know enough | |
|
237 | # about win32 to debug this reliably. Os.system may be the 'old | |
|
238 | # fashioned' way to do it, but it works just fine. If someone | |
|
239 | # later can clean this up that's fine, as long as the tests run | |
|
240 | # reliably in win32. | |
|
241 | curdir = os.getcwd() | |
|
242 | os.chdir(tempfile.gettempdir()) | |
|
243 | stat = os.system(' '.join(self.call_args)) | |
|
244 | os.chdir(curdir) | |
|
245 | return stat | |
|
246 | else: | |
|
247 | def run(self): | |
|
248 | """Run the stored commands""" | |
|
249 | return subprocess.call(self.call_args) | |
|
202 | 250 | |
|
203 | 251 | |
|
204 | 252 | def make_runners(): |
@@ -244,7 +292,7 b' def run_iptestall():' | |||
|
244 | 292 | t_start = time.time() |
|
245 | 293 | for name,runner in runners.iteritems(): |
|
246 | 294 | print '*'*77 |
|
247 |
print 'IPython test |
|
|
295 | print 'IPython test group:',name | |
|
248 | 296 | res = runner.run() |
|
249 | 297 | if res: |
|
250 | 298 | failed[name] = res |
@@ -255,14 +303,14 b' def run_iptestall():' | |||
|
255 | 303 | # summarize results |
|
256 | 304 | |
|
257 | 305 | print '*'*77 |
|
258 |
print 'Ran %s test |
|
|
306 | print 'Ran %s test groups in %.3fs' % (nrunners, t_tests) | |
|
259 | 307 | |
|
260 | 308 | if not failed: |
|
261 | 309 | print 'OK' |
|
262 | 310 | else: |
|
263 | 311 | # If anything went wrong, point out what command to rerun manually to |
|
264 | 312 | # see the actual errors and individual summary |
|
265 |
print 'ERROR - %s out of %s test |
|
|
313 | print 'ERROR - %s out of %s test groups failed.' % (nfail, nrunners) | |
|
266 | 314 | for name in failed: |
|
267 | 315 | failed_runner = runners[name] |
|
268 | 316 | print '-'*40 |
@@ -283,4 +331,4 b' def main():' | |||
|
283 | 331 | |
|
284 | 332 | |
|
285 | 333 | if __name__ == '__main__': |
|
286 | main() No newline at end of file | |
|
334 | main() |
@@ -208,6 +208,15 b' def start_ipython():' | |||
|
208 | 208 | _ip.IP.magic_run_ori = _ip.IP.magic_run |
|
209 | 209 | _ip.IP.magic_run = im |
|
210 | 210 | |
|
211 | # XXX - For some very bizarre reason, the loading of %history by default is | |
|
212 | # failing. This needs to be fixed later, but for now at least this ensures | |
|
213 | # that tests that use %hist run to completion. | |
|
214 | from IPython.core import history | |
|
215 | history.init_ipython(_ip) | |
|
216 | if not hasattr(_ip.IP,'magic_history'): | |
|
217 | raise RuntimeError("Can't load magics, aborting") | |
|
218 | ||
|
219 | ||
|
211 | 220 | # The start call MUST be made here. I'm not sure yet why it doesn't work if |
|
212 | 221 | # it is made later, at plugin initialization time, but in all my tests, that's |
|
213 | 222 | # the case. |
@@ -431,7 +440,29 b' class DocTestCase(doctests.DocTestCase):' | |||
|
431 | 440 | _ip.IP.user_ns.update(self._dt_test.globs) |
|
432 | 441 | self._dt_test.globs = _ip.IP.user_ns |
|
433 | 442 | |
|
434 |
|
|
|
443 | super(DocTestCase, self).setUp() | |
|
444 | ||
|
445 | def tearDown(self): | |
|
446 | # XXX - fperez: I am not sure if this is truly a bug in nose 0.11, but | |
|
447 | # it does look like one to me: its tearDown method tries to run | |
|
448 | # | |
|
449 | # delattr(__builtin__, self._result_var) | |
|
450 | # | |
|
451 | # without checking that the attribute really is there; it implicitly | |
|
452 | # assumes it should have been set via displayhook. But if the | |
|
453 | # displayhook was never called, this doesn't necessarily happen. I | |
|
454 | # haven't been able to find a little self-contained example outside of | |
|
455 | # ipython that would show the problem so I can report it to the nose | |
|
456 | # team, but it does happen a lot in our code. | |
|
457 | # | |
|
458 | # So here, we just protect as narrowly as possible by trapping an | |
|
459 | # attribute error whose message would be the name of self._result_var, | |
|
460 | # and letting any other error propagate. | |
|
461 | try: | |
|
462 | super(DocTestCase, self).tearDown() | |
|
463 | except AttributeError, exc: | |
|
464 | if exc.args[0] != self._result_var: | |
|
465 | raise | |
|
435 | 466 | |
|
436 | 467 | |
|
437 | 468 | # A simple subclassing of the original with a different class name, so we can |
@@ -10,9 +10,10 b' class C(object):' | |||
|
10 | 10 | pass |
|
11 | 11 | #print 'deleting object...' # dbg |
|
12 | 12 | |
|
13 | c = C() | |
|
13 | if __name__ == '__main__': | |
|
14 | c = C() | |
|
14 | 15 | |
|
15 | c_refs = gc.get_referrers(c) | |
|
16 | ref_ids = map(id,c_refs) | |
|
16 | c_refs = gc.get_referrers(c) | |
|
17 | ref_ids = map(id,c_refs) | |
|
17 | 18 | |
|
18 | print 'c referrers:',map(type,c_refs) | |
|
19 | print 'c referrers:',map(type,c_refs) |
@@ -21,7 +21,7 b' from twisted.internet import defer' | |||
|
21 | 21 | class DeferredTestCase(unittest.TestCase): |
|
22 | 22 | |
|
23 | 23 | def assertDeferredEquals(self, deferred, expectedResult, |
|
24 |
|
|
|
24 | chainDeferred=None): | |
|
25 | 25 | """Calls assertEquals on the result of the deferred and expectedResult. |
|
26 | 26 | |
|
27 | 27 | chainDeferred can be used to pass in previous Deferred objects that |
@@ -32,7 +32,7 b' class DeferredTestCase(unittest.TestCase):' | |||
|
32 | 32 | |
|
33 | 33 | if chainDeferred is None: |
|
34 | 34 | chainDeferred = defer.succeed(None) |
|
35 |
|
|
|
35 | ||
|
36 | 36 | def gotResult(actualResult): |
|
37 | 37 | self.assertEquals(actualResult, expectedResult) |
|
38 | 38 | |
@@ -41,7 +41,7 b' class DeferredTestCase(unittest.TestCase):' | |||
|
41 | 41 | return chainDeferred.addCallback(lambda _: deferred) |
|
42 | 42 | |
|
43 | 43 | def assertDeferredRaises(self, deferred, expectedException, |
|
44 |
|
|
|
44 | chainDeferred=None): | |
|
45 | 45 | """Calls assertRaises on the Failure of the deferred and expectedException. |
|
46 | 46 | |
|
47 | 47 | chainDeferred can be used to pass in previous Deferred objects that |
@@ -881,7 +881,7 b' def doctest_reload():' | |||
|
881 | 881 | |
|
882 | 882 | This routine: |
|
883 | 883 | |
|
884 | - reloads doctest | |
|
884 | - imports doctest but does NOT reload it (see below). | |
|
885 | 885 | |
|
886 | 886 | - resets its global 'master' attribute to None, so that multiple uses of |
|
887 | 887 | the module interactively don't produce cumulative reports. |
@@ -890,20 +890,20 b' def doctest_reload():' | |||
|
890 | 890 | modified displayhook. Doctest expects the default displayhook behavior |
|
891 | 891 | deep down, so our modification breaks it completely. For this reason, a |
|
892 | 892 | hard monkeypatch seems like a reasonable solution rather than asking |
|
893 |
users to manually use a different doctest runner when under IPython. |
|
|
893 | users to manually use a different doctest runner when under IPython. | |
|
894 | 894 |
|
|
895 | import doctest | |
|
896 | reload(doctest) | |
|
897 | doctest.master=None | |
|
895 | Notes | |
|
896 | ----- | |
|
898 | 897 |
|
|
899 | try: | |
|
900 | doctest.DocTestRunner | |
|
901 | except AttributeError: | |
|
902 | # This is only for python 2.3 compatibility, remove once we move to | |
|
903 | # 2.4 only. | |
|
904 | pass | |
|
905 | else: | |
|
906 | doctest.DocTestRunner.run = dhook_wrap(doctest.DocTestRunner.run) | |
|
898 | This function *used to* reload doctest, but this has been disabled because | |
|
899 | reloading doctest unconditionally can cause massive breakage of other | |
|
900 | doctest-dependent modules already in memory, such as those for IPython's | |
|
901 | own testing system. The name wasn't changed to avoid breaking people's | |
|
902 | code, but the reload call isn't actually made anymore.""" | |
|
903 | ||
|
904 | import doctest | |
|
905 | doctest.master = None | |
|
906 | doctest.DocTestRunner.run = dhook_wrap(doctest.DocTestRunner.run) | |
|
907 | 907 | |
|
908 | 908 | #---------------------------------------------------------------------------- |
|
909 | 909 | class HomeDirError(Error): |
@@ -23,11 +23,6 b" elif sys.platform == 'win32':" | |||
|
23 | 23 | import platutils_win32 as _platutils |
|
24 | 24 | else: |
|
25 | 25 | import platutils_dummy as _platutils |
|
26 | import warnings | |
|
27 | warnings.warn("Platutils not available for platform '%s', some features may be missing" % | |
|
28 | os.name) | |
|
29 | del warnings | |
|
30 | ||
|
31 | 26 | |
|
32 | 27 | # Functionality that's logically common to all platforms goes here, each |
|
33 | 28 | # platform-specific module only provides the bits that are OS-dependent. |
@@ -36,6 +31,9 b' else:' | |||
|
36 | 31 | # there is a public, cross-platform way of toggling the term title control on |
|
37 | 32 | # and off. We should make this a stateful object later on so that each user |
|
38 | 33 | # can have its own instance if needed. |
|
34 | def term_clear(): | |
|
35 | _platutils.term_clear() | |
|
36 | ||
|
39 | 37 | def toggle_set_term_title(val): |
|
40 | 38 | """Control whether set_term_title is active or not. |
|
41 | 39 | |
@@ -103,4 +101,3 b' def get_long_path_name(path):' | |||
|
103 | 101 | def freeze_term_title(): |
|
104 | 102 | warnings.warn("This function is deprecated, use toggle_set_term_title()") |
|
105 | 103 | _platutils.ignore_termtitle = True |
|
106 |
@@ -20,6 +20,7 b' ignore_termtitle = True' | |||
|
20 | 20 | def _dummy_op(*a, **b): |
|
21 | 21 | """ A no-op function """ |
|
22 | 22 | |
|
23 | ||
|
23 | 24 | def _set_term_title_xterm(title): |
|
24 | 25 | """ Change virtual terminal title in xterm-workalikes """ |
|
25 | 26 | |
@@ -31,10 +32,16 b" if os.environ.get('TERM','') == 'xterm':" | |||
|
31 | 32 | else: |
|
32 | 33 | set_term_title = _dummy_op |
|
33 | 34 | |
|
35 | ||
|
34 | 36 | def find_cmd(cmd): |
|
35 | 37 | """Find the full path to a command using which.""" |
|
36 | 38 | return os.popen('which %s' % cmd).read().strip() |
|
37 | 39 | |
|
40 | ||
|
38 | 41 | def get_long_path_name(path): |
|
39 | 42 | """Dummy no-op.""" |
|
40 | 43 | return path |
|
44 | ||
|
45 | ||
|
46 | def term_clear(): | |
|
47 | os.system('clear') |
@@ -42,18 +42,26 b' except ImportError:' | |||
|
42 | 42 | # non-zero return code signals error, don't try again |
|
43 | 43 | ignore_termtitle = True |
|
44 | 44 | |
|
45 | ||
|
45 | 46 | def find_cmd(cmd): |
|
46 | 47 | """Find the full path to a .bat or .exe using the win32api module.""" |
|
47 | 48 | try: |
|
48 | import win32api | |
|
49 | from win32api import SearchPath | |
|
49 | 50 | except ImportError: |
|
50 | 51 | raise ImportError('you need to have pywin32 installed for this to work') |
|
51 | 52 | else: |
|
52 | try: | |
|
53 | (path, offest) = win32api.SearchPath(os.environ['PATH'],cmd + '.exe') | |
|
54 | except: | |
|
55 | (path, offset) = win32api.SearchPath(os.environ['PATH'],cmd + '.bat') | |
|
56 | return path | |
|
53 | PATH = os.environ['PATH'] | |
|
54 | extensions = ['.exe', '.com', '.bat', '.py'] | |
|
55 | path = None | |
|
56 | for ext in extensions: | |
|
57 | try: | |
|
58 | path = SearchPath(PATH,cmd + ext)[0] | |
|
59 | except: | |
|
60 | pass | |
|
61 | if path is None: | |
|
62 | raise OSError("command %r not found" % cmd) | |
|
63 | else: | |
|
64 | return path | |
|
57 | 65 | |
|
58 | 66 | |
|
59 | 67 | def get_long_path_name(path): |
@@ -80,3 +88,7 b' def get_long_path_name(path):' | |||
|
80 | 88 | return path |
|
81 | 89 | else: |
|
82 | 90 | return buf.value |
|
91 | ||
|
92 | ||
|
93 | def term_clear(): | |
|
94 | os.system('cls') |
@@ -3,6 +3,8 b'' | |||
|
3 | 3 | |
|
4 | 4 | from IPython.kernel import client |
|
5 | 5 | import time |
|
6 | import sys | |
|
7 | flush = sys.stdout.flush | |
|
6 | 8 | |
|
7 | 9 | tc = client.TaskClient() |
|
8 | 10 | mec = client.MultiEngineClient() |
@@ -16,6 +18,7 b' for i in range(6):' | |||
|
16 | 18 | time.sleep(1.0) |
|
17 | 19 | print "Queue status (vebose=False)" |
|
18 | 20 | print tc.queue_status() |
|
21 | flush() | |
|
19 | 22 | |
|
20 | 23 | for i in range(24): |
|
21 | 24 | tc.run(client.StringTask('time.sleep(1)')) |
@@ -24,12 +27,14 b' for i in range(6):' | |||
|
24 | 27 | time.sleep(1.0) |
|
25 | 28 | print "Queue status (vebose=True)" |
|
26 | 29 | print tc.queue_status(True) |
|
30 | flush() | |
|
27 | 31 | |
|
28 | 32 | for i in range(12): |
|
29 | 33 | tc.run(client.StringTask('time.sleep(2)')) |
|
30 | 34 | |
|
31 | 35 | print "Queue status (vebose=True)" |
|
32 | 36 | print tc.queue_status(True) |
|
37 | flush() | |
|
33 | 38 | |
|
34 | 39 | qs = tc.queue_status(True) |
|
35 | 40 | sched = qs['scheduled'] |
@@ -41,4 +46,5 b' for i in range(6):' | |||
|
41 | 46 | time.sleep(1.0) |
|
42 | 47 | print "Queue status (vebose=True)" |
|
43 | 48 | print tc.queue_status(True) |
|
49 | flush() | |
|
44 | 50 |
@@ -1,3 +1,11 b'' | |||
|
1 | .. Developers should add in this file, during each release cycle, information | |
|
2 | .. about important changes they've made, in a summary format that's meant for | |
|
3 | .. end users. For each release we normally have three sections: features, bug | |
|
4 | .. fixes and api breakage. | |
|
5 | .. Please remember to credit the authors of the contributions by name, | |
|
6 | .. especially when they are new users or developers who do not regularly | |
|
7 | .. participate in IPython's development. | |
|
8 | ||
|
1 | 9 | .. _changes: |
|
2 | 10 | |
|
3 | 11 | ========== |
@@ -6,19 +14,27 b" What's new" | |||
|
6 | 14 | |
|
7 | 15 | .. contents:: |
|
8 | 16 | .. |
|
9 |
1 Release |
|
|
10 | 2 Release 0.9 | |
|
17 | 1 Release dev | |
|
18 | 1.1 New features | |
|
19 | 1.2 Bug fixes | |
|
20 | 1.3 Backwards incompatible changes | |
|
21 | 2 Release 0.10 | |
|
11 | 22 | 2.1 New features |
|
12 | 23 | 2.2 Bug fixes |
|
13 | 24 | 2.3 Backwards incompatible changes |
|
14 | 2.4 Changes merged in from IPython1 | |
|
15 | 2.4.1 New features | |
|
16 | 2.4.2 Bug fixes | |
|
17 | 2.4.3 Backwards incompatible changes | |
|
18 | 3 Release 0.8.4 | |
|
19 | 4 Release 0.8.3 | |
|
20 | 5 Release 0.8.2 | |
|
21 | 6 Older releases | |
|
25 | 3 Release 0.9.1 | |
|
26 | 4 Release 0.9 | |
|
27 | 4.1 New features | |
|
28 | 4.2 Bug fixes | |
|
29 | 4.3 Backwards incompatible changes | |
|
30 | 4.4 Changes merged in from IPython1 | |
|
31 | 4.4.1 New features | |
|
32 | 4.4.2 Bug fixes | |
|
33 | 4.4.3 Backwards incompatible changes | |
|
34 | 5 Release 0.8.4 | |
|
35 | 6 Release 0.8.3 | |
|
36 | 7 Release 0.8.2 | |
|
37 | 8 Older releases | |
|
22 | 38 | .. |
|
23 | 39 | |
|
24 | 40 | Release dev |
@@ -27,25 +43,139 b' Release dev' | |||
|
27 | 43 | New features |
|
28 | 44 | ------------ |
|
29 | 45 | |
|
46 | Bug fixes | |
|
47 | --------- | |
|
48 | ||
|
49 | Backwards incompatible changes | |
|
50 | ------------------------------ | |
|
51 | ||
|
52 | ||
|
53 | Release 0.10 | |
|
54 | ============ | |
|
55 | ||
|
56 | This release brings months of slow but steady development, and will be the last | |
|
57 | before a major restructuring and cleanup of IPython's internals that is already | |
|
58 | under way. For this reason, we hope that 0.10 will be a stable and robust | |
|
59 | release so that while users adapt to some of the API changes that will come | |
|
60 | with the refactoring that will become IPython 0.11, they can safely use 0.10 in | |
|
61 | all existing projects with minimal changes (if any). | |
|
62 | ||
|
63 | IPython 0.10 is now a medium-sized project, with roughly (as reported by David | |
|
64 | Wheeler's :command:`sloccount` utility) 40750 lines of Python code, and a diff | |
|
65 | between 0.9.1 and this release that contains almost 28000 lines of code and | |
|
66 | documentation. Our documentation, in PDF format, is a 495-page long PDF | |
|
67 | document (also available in HTML format, both generated from the same sources). | |
|
68 | ||
|
69 | Many users and developers contributed code, features, bug reports and ideas to | |
|
70 | this release. Please do not hesitate in contacting us if we've failed to | |
|
71 | acknowledge your contribution here. In particular, for this release we have | |
|
72 | contribution from the following people, a mix of new and regular names (in | |
|
73 | alphabetical order by first name): | |
|
74 | ||
|
75 | * Alexander Clausen: fix #341726. | |
|
76 | * Brian Granger: lots of work everywhere (features, bug fixes, etc). | |
|
77 | * Daniel Ashbrook: bug report on MemoryError during compilation, now fixed. | |
|
78 | * Darren Dale: improvements to documentation build system, feedback, design | |
|
79 | ideas. | |
|
80 | * Fernando Perez: various places. | |
|
81 | * Gaël Varoquaux: core code, ipythonx GUI, design discussions, etc. Lots... | |
|
82 | * John Hunter: suggestions, bug fixes, feedback. | |
|
83 | * Jorgen Stenarson: work on many fronts, tests, fixes, win32 support, etc. | |
|
84 | * Laurent Dufréchou: many improvements to ipython-wx standalone app. | |
|
85 | * Lukasz Pankowski: prefilter, `%edit`, demo improvements. | |
|
86 | * Matt Foster: TextMate support in `%edit`. | |
|
87 | * Nathaniel Smith: fix #237073. | |
|
88 | * Pauli Virtanen: fixes and improvements to extensions, documentation. | |
|
89 | * Prabhu Ramachandran: improvements to `%timeit`. | |
|
90 | * Robert Kern: several extensions. | |
|
91 | * Sameer D'Costa: help on critical bug #269966. | |
|
92 | * Stephan Peijnik: feedback on Debian compliance and many man pages. | |
|
93 | * Tom Fetherston: many improvements to :mod:`IPython.demo` module. | |
|
94 | * Ville Vainio: lots of work everywhere (features, bug fixes, etc). | |
|
95 | * Vishal Vasta: ssh support in ipcluster. | |
|
96 | * Walter Doerwald: work on the :mod:`IPython.ipipe` system. | |
|
97 | ||
|
98 | Below we give an overview of new features, bug fixes and backwards-incompatible | |
|
99 | changes. For a detailed account of every change made, feel free to view the | |
|
100 | project log with :command:`bzr log`. | |
|
101 | ||
|
102 | New features | |
|
103 | ------------ | |
|
104 | ||
|
105 | * New `%paste` magic automatically extracts current contents of clipboard and | |
|
106 | pastes it directly, while correctly handling code that is indented or | |
|
107 | prepended with `>>>` or `...` python prompt markers. A very useful new | |
|
108 | feature contributed by Robert Kern. | |
|
109 | ||
|
110 | * IPython 'demos', created with the :mod:`IPython.demo` module, can now be | |
|
111 | created from files on disk or strings in memory. Other fixes and | |
|
112 | improvements to the demo system, by Tom Fetherston. | |
|
113 | ||
|
114 | * Added :func:`find_cmd` function to :mod:`IPython.platutils` module, to find | |
|
115 | commands in a cross-platform manner. | |
|
116 | ||
|
117 | * Many improvements and fixes to Gaël Varoquaux's :command:`ipythonx`, a | |
|
118 | WX-based lightweight IPython instance that can be easily embedded in other WX | |
|
119 | applications. These improvements have made it possible to now have an | |
|
120 | embedded IPython in Mayavi and other tools. | |
|
121 | ||
|
122 | * :class:`MultiengineClient` objects now have a :meth:`benchmark` method. | |
|
123 | ||
|
124 | * The manual now includes a full set of auto-generated API documents from the | |
|
125 | code sources, using Sphinx and some of our own support code. We are now | |
|
126 | using the `Numpy Documentation Standard`_ for all docstrings, and we have | |
|
127 | tried to update as many existing ones as possible to this format. | |
|
128 | ||
|
129 | .. _Numpy Documentation Standard: http://projects.scipy.org/numpy/wiki/CodingStyleGuidelines#docstring-standard | |
|
130 | ||
|
131 | * The new :mod:`IPython.Extensions.ipy_pretty` extension by Robert Kern | |
|
132 | provides configurable pretty-printing. | |
|
133 | ||
|
134 | * Many improvements to the :command:`ipython-wx` standalone WX-based IPython | |
|
135 | application by Laurent Dufréchou. It can optionally run in a thread, and | |
|
136 | this can be toggled at runtime (allowing the loading of Matplotlib in a | |
|
137 | running session without ill effects). | |
|
138 | ||
|
139 | * IPython includes a copy of Steven Bethard's argparse_ in the | |
|
140 | :mod:`IPython.external` package, so we can use it internally and it is also | |
|
141 | available to any IPython user. By installing it in this manner, we ensure | |
|
142 | zero conflicts with any system-wide installation you may already have while | |
|
143 | minimizing external dependencies for new users. | |
|
144 | ||
|
145 | * An improved and much more robust test suite, that runs groups of tests in | |
|
146 | separate subprocesses using either Nose or Twisted's :command:`trial` runner | |
|
147 | to ensure proper management of Twisted-using code. The test suite degrades | |
|
148 | gracefully if optional dependencies are not available, so that the | |
|
149 | :command:`iptest` command can be run with only Nose installed and nothing | |
|
150 | else. We also have more and cleaner test decorators to better select tests | |
|
151 | depending on runtime conditions, do setup/teardown, etc. | |
|
152 | ||
|
30 | 153 | * The new ipcluster now has a fully working ssh mode that should work on |
|
31 | 154 | Linux, Unix and OS X. Thanks to Vishal Vatsa for implementing this! |
|
32 | 155 | |
|
33 | 156 | * The wonderful TextMate editor can now be used with %edit on OS X. Thanks |
|
34 | 157 | to Matt Foster for this patch. |
|
35 | 158 | |
|
159 | * The documentation regarding parallel uses of IPython, including MPI and PBS, | |
|
160 | has been significantly updated and improved. | |
|
161 | ||
|
162 | * The developer guidelines in the documentation have been updated to explain | |
|
163 | our workflow using :command:`bzr` and Launchpad. | |
|
164 | ||
|
36 | 165 | * Fully refactored :command:`ipcluster` command line program for starting |
|
37 | 166 | IPython clusters. This new version is a complete rewrite and 1) is fully |
|
38 | 167 | cross platform (we now use Twisted's process management), 2) has much |
|
39 | improved performance, 3) uses subcommands for different types of clusters, | |
|
40 |
|
|
|
41 |
|
|
|
42 | for starting engines using PBS. However, this new version of ipcluster | |
|
43 | should be considered a technology preview. We plan on changing the API | |
|
44 | in significant ways before it is final. | |
|
168 | improved performance, 3) uses subcommands for different types of clusters, 4) | |
|
169 | uses argparse for parsing command line options, 5) has better support for | |
|
170 | starting clusters using :command:`mpirun`, 6) has experimental support for | |
|
171 | starting engines using PBS. It can also reuse FURL files, by appropriately | |
|
172 | passing options to its subcommands. However, this new version of ipcluster | |
|
173 | should be considered a technology preview. We plan on changing the API in | |
|
174 | significant ways before it is final. | |
|
45 | 175 | |
|
46 | 176 | * The :mod:`argparse` module has been added to :mod:`IPython.external`. |
|
47 | 177 | |
|
48 |
* Full |
|
|
178 | * Full description of the security model added to the docs. | |
|
49 | 179 | |
|
50 | 180 | * cd completer: show bookmarks if no other completions are available. |
|
51 | 181 | |
@@ -55,13 +185,45 b' New features' | |||
|
55 | 185 | [~]|1> _prompt_title = 'sudo!' |
|
56 | 186 | sudo![~]|2> |
|
57 | 187 | |
|
58 | * %edit: If you do '%edit pasted_block', pasted_block | |
|
59 | variable gets updated with new data (so repeated | |
|
60 | editing makes sense) | |
|
188 | * %edit: If you do '%edit pasted_block', pasted_block variable gets updated | |
|
189 | with new data (so repeated editing makes sense) | |
|
61 | 190 | |
|
62 | 191 | Bug fixes |
|
63 | 192 | --------- |
|
64 | 193 | |
|
194 | * Fix #368719, removed top-level debian/ directory to make the job of Debian | |
|
195 | packagers easier. | |
|
196 | ||
|
197 | * Fix #291143 by including man pages contributed by Stephan Peijnik from the | |
|
198 | Debian project. | |
|
199 | ||
|
200 | * Fix #358202, effectively a race condition, by properly synchronizing file | |
|
201 | creation at cluster startup time. | |
|
202 | ||
|
203 | * `%timeit` now handles correctly functions that take a long time to execute | |
|
204 | even the first time, by not repeating them. | |
|
205 | ||
|
206 | * Fix #239054, releasing of references after exiting. | |
|
207 | ||
|
208 | * Fix #341726, thanks to Alexander Clausen. | |
|
209 | ||
|
210 | * Fix #269966. This long-standing and very difficult bug (which is actually a | |
|
211 | problem in Python itself) meant long-running sessions would inevitably grow | |
|
212 | in memory size, often with catastrophic consequences if users had large | |
|
213 | objects in their scripts. Now, using `%run` repeatedly should not cause any | |
|
214 | memory leaks. Special thanks to John Hunter and Sameer D'Costa for their | |
|
215 | help with this bug. | |
|
216 | ||
|
217 | * Fix #295371, bug in `%history`. | |
|
218 | ||
|
219 | * Improved support for py2exe. | |
|
220 | ||
|
221 | * Fix #270856: IPython hangs with PyGTK | |
|
222 | ||
|
223 | * Fix #270998: A magic with no docstring breaks the '%magic magic' | |
|
224 | ||
|
225 | * fix #271684: -c startup commands screw up raw vs. native history | |
|
226 | ||
|
65 | 227 | * Numerous bugs on Windows with the new ipcluster have been fixed. |
|
66 | 228 | |
|
67 | 229 | * The ipengine and ipcontroller scripts now handle missing furl files |
@@ -81,12 +243,26 b' Bug fixes' | |||
|
81 | 243 | Backwards incompatible changes |
|
82 | 244 | ------------------------------ |
|
83 | 245 | |
|
246 | * `ipykit` and related files were unmaintained and have been removed. | |
|
247 | ||
|
248 | * The :func:`IPython.genutils.doctest_reload` does not actually call | |
|
249 | `reload(doctest)` anymore, as this was causing many problems with the test | |
|
250 | suite. It still resets `doctest.master` to None. | |
|
251 | ||
|
252 | * While we have not deliberately broken Python 2.4 compatibility, only minor | |
|
253 | testing was done with Python 2.4, while 2.5 and 2.6 were fully tested. But | |
|
254 | if you encounter problems with 2.4, please do report them as bugs. | |
|
255 | ||
|
256 | * The :command:`ipcluster` now requires a mode argument; for example to start a | |
|
257 | cluster on the local machine with 4 engines, you must now type:: | |
|
258 | ||
|
259 | $ ipcluster local -n 4 | |
|
260 | ||
|
84 | 261 | * The controller now has a ``-r`` flag that needs to be used if you want to |
|
85 | 262 | reuse existing furl files. Otherwise they are deleted (the default). |
|
86 | 263 | |
|
87 |
* Remove ipy_leo.py. |
|
|
88 | (done to decouple it from ipython release cycle) | |
|
89 | ||
|
264 | * Remove ipy_leo.py. You can use :command:`easy_install ipython-extension` to | |
|
265 | get it. (done to decouple it from ipython release cycle) | |
|
90 | 266 | |
|
91 | 267 | |
|
92 | 268 | Release 0.9.1 |
@@ -175,11 +175,16 b' In order to configure less as your default pager, do the following:' | |||
|
175 | 175 | properly interpret control sequences, which is how color |
|
176 | 176 | information is given to your terminal. |
|
177 | 177 | |
|
178 | For the bash shell, add to your ~/.bashrc file the lines:: | |
|
179 | ||
|
180 | export PAGER=less | |
|
181 | export LESS=-r | |
|
182 | ||
|
178 | 183 | For the csh or tcsh shells, add to your ~/.cshrc file the lines:: |
|
179 | 184 | |
|
180 | 185 | setenv PAGER less |
|
181 | 186 | setenv LESS -r |
|
182 | ||
|
187 | ||
|
183 | 188 | There is similar syntax for other Unix shells, look at your system |
|
184 | 189 | documentation for details. |
|
185 | 190 |
@@ -476,8 +476,17 b' if we want to have a codebase that works directly on both 2.x and 3.x.' | |||
|
476 | 476 | |
|
477 | 477 | 1. The syntax for exceptions changed (PEP 3110). The old |
|
478 | 478 | `except exc, var` changed to `except exc as var`. At last |
|
479 | count there was 78 occurences of this usage in the codebase | |
|
480 | ||
|
479 | count there was 78 occurences of this usage in the codebase. This | |
|
480 | is a particularly problematic issue, because it's not easy to | |
|
481 | implement it in a 2.5-compatible way. | |
|
482 | ||
|
483 | Because it is quite difficult to support simultaneously Python 2.5 and 3.x, we | |
|
484 | will likely at some point put out a release that requires strictly 2.6 and | |
|
485 | abandons 2.5 compatibility. This will then allow us to port the code to using | |
|
486 | :func:`print` as a function, `except exc as var` syntax, etc. But as of | |
|
487 | version 0.11 at least, we will retain Python 2.5 compatibility. | |
|
488 | ||
|
489 | ||
|
481 | 490 | .. [Bazaar] Bazaar. http://bazaar-vcs.org/ |
|
482 | 491 | .. [Launchpad] Launchpad. http://www.launchpad.net/ipython |
|
483 | 492 | .. [reStructuredText] reStructuredText. http://docutils.sourceforge.net/rst.html |
@@ -9,14 +9,16 b' install all of its dependencies.' | |||
|
9 | 9 | |
|
10 | 10 | |
|
11 | 11 | Please let us know if you have problems installing IPython or any of its |
|
12 |
dependencies. IPython requires Python version 2. |
|
|
13 | has been done on version 2.6, and so far everything looks fine. We have *not* | |
|
14 | yet started to port IPython to Python 3.0, where the language changes are much | |
|
15 | more significant. | |
|
12 | dependencies. Officially, IPython requires Python version 2.5 or 2.6. We | |
|
13 | have *not* yet started to port IPython to Python 3.0. | |
|
16 | 14 | |
|
17 | 15 | .. warning:: |
|
18 | 16 | |
|
19 | IPython will not work with Python 2.4 or below. | |
|
17 | Officially, IPython supports Python versions 2.5 and 2.6. | |
|
18 | ||
|
19 | IPython 0.10 has only been well tested with Python 2.5 and 2.6. Parts of | |
|
20 | it may work with Python 2.4, but we do not officially support Python 2.4 | |
|
21 | anymore. If you need to use 2.4, you can still run IPython 0.9. | |
|
20 | 22 | |
|
21 | 23 | Some of the installation approaches use the :mod:`setuptools` package and its |
|
22 | 24 | :command:`easy_install` command line program. In many scenarios, this provides |
@@ -85,8 +87,8 b' Windows' | |||
|
85 | 87 | |
|
86 | 88 | There are a few caveats for Windows users. The main issue is that a basic |
|
87 | 89 | ``python setup.py install`` approach won't create ``.bat`` file or Start Menu |
|
88 |
shortcuts, which most users want. To get an installation with these, |
|
|
89 | two choices: | |
|
90 | shortcuts, which most users want. To get an installation with these, you can | |
|
91 | use any of the following alternatives: | |
|
90 | 92 | |
|
91 | 93 | 1. Install using :command:`easy_install`. |
|
92 | 94 | |
@@ -96,6 +98,16 b' two choices:' | |||
|
96 | 98 | 3. Install from source, but using :mod:`setuptools` (``python setupegg.py |
|
97 | 99 | install``). |
|
98 | 100 | |
|
101 | IPython by default runs in a termninal window, but the normal terminal | |
|
102 | application supplied by Microsoft Windows is very primitive. You may want to | |
|
103 | download the excellent and free Console_ application instead, which is a far | |
|
104 | superior tool. You can even configure Console to give you by default an | |
|
105 | IPython tab, which is very convenient to create new IPython sessions directly | |
|
106 | from the working terminal. | |
|
107 | ||
|
108 | .. _Console: http://sourceforge.net/projects/console | |
|
109 | ||
|
110 | ||
|
99 | 111 | Installing the development version |
|
100 | 112 | ---------------------------------- |
|
101 | 113 |
@@ -1329,8 +1329,9 b' For stand-alone use of the feature in your programs which do not use' | |||
|
1329 | 1329 | IPython at all, put the following lines toward the top of your 'main' |
|
1330 | 1330 | routine:: |
|
1331 | 1331 | |
|
1332 |
import sys |
|
|
1333 | sys.excepthook = IPython.ultraTB.FormattedTB(mode='Verbose', | |
|
1332 | import sys | |
|
1333 | from IPython.core import ultratb | |
|
1334 | sys.excepthook = ultratb.FormattedTB(mode='Verbose', | |
|
1334 | 1335 | color_scheme='Linux', call_pdb=1) |
|
1335 | 1336 | |
|
1336 | 1337 | The mode keyword can be either 'Verbose' or 'Plain', giving either very |
@@ -38,7 +38,7 b' To use code that calls MPI, there are typically two things that MPI requires.' | |||
|
38 | 38 | There are a couple of ways that you can start the IPython engines and get these things to happen. |
|
39 | 39 | |
|
40 | 40 | Automatic starting using :command:`mpiexec` and :command:`ipcluster` |
|
41 | ------------------------------------------------------------------- | |
|
41 | -------------------------------------------------------------------- | |
|
42 | 42 | |
|
43 | 43 | The easiest approach is to use the `mpiexec` mode of :command:`ipcluster`, which will first start a controller and then a set of engines using :command:`mpiexec`:: |
|
44 | 44 | |
@@ -48,7 +48,7 b' This approach is best as interrupting :command:`ipcluster` will automatically' | |||
|
48 | 48 | stop and clean up the controller and engines. |
|
49 | 49 | |
|
50 | 50 | Manual starting using :command:`mpiexec` |
|
51 | --------------------------------------- | |
|
51 | ---------------------------------------- | |
|
52 | 52 | |
|
53 | 53 | If you want to start the IPython engines using the :command:`mpiexec`, just do:: |
|
54 | 54 | |
@@ -154,4 +154,4 b' compiled C, C++ and Fortran libraries that have been exposed to Python.' | |||
|
154 | 154 | .. [MPI] Message Passing Interface. http://www-unix.mcs.anl.gov/mpi/ |
|
155 | 155 | .. [mpi4py] MPI for Python. mpi4py: http://mpi4py.scipy.org/ |
|
156 | 156 | .. [OpenMPI] Open MPI. http://www.open-mpi.org/ |
|
157 | .. [PyTrilinos] PyTrilinos. http://trilinos.sandia.gov/packages/pytrilinos/ No newline at end of file | |
|
157 | .. [PyTrilinos] PyTrilinos. http://trilinos.sandia.gov/packages/pytrilinos/ |
@@ -65,11 +65,7 b' def install():' | |||
|
65 | 65 | link = pjoin(ip_start_menu, 'scipy.lnk') |
|
66 | 66 | cmd = '"%s" -p scipy' % ipybase |
|
67 | 67 | mkshortcut(python,'IPython (scipy profile)',link,cmd) |
|
68 | ||
|
69 | link = pjoin(ip_start_menu, 'IPython test suite.lnk') | |
|
70 | cmd = '"%s" -vv' % pjoin(scripts, 'iptest') | |
|
71 | mkshortcut(python,'Run the IPython test suite',link,cmd) | |
|
72 | ||
|
68 | ||
|
73 | 69 | link = pjoin(ip_start_menu, 'ipcontroller.lnk') |
|
74 | 70 | cmd = '"%s" -xy' % pjoin(scripts, 'ipcontroller') |
|
75 | 71 | mkshortcut(python,'IPython controller',link,cmd) |
@@ -78,14 +78,38 b" if len(sys.argv) >= 2 and sys.argv[1] in ('sdist','bdist_rpm'):" | |||
|
78 | 78 | #('docs/magic.tex', |
|
79 | 79 | #['IPython/Magic.py'], |
|
80 | 80 | #"cd doc && ./update_magic.sh" ), |
|
81 | ||
|
81 | ||
|
82 | ('docs/man/ipcluster.1.gz', | |
|
83 | ['docs/man/ipcluster.1'], | |
|
84 | 'cd docs/man && gzip -9c ipcluster.1 > ipcluster.1.gz'), | |
|
85 | ||
|
86 | ('docs/man/ipcontroller.1.gz', | |
|
87 | ['docs/man/ipcontroller.1'], | |
|
88 | 'cd docs/man && gzip -9c ipcontroller.1 > ipcontroller.1.gz'), | |
|
89 | ||
|
90 | ('docs/man/ipengine.1.gz', | |
|
91 | ['docs/man/ipengine.1'], | |
|
92 | 'cd docs/man && gzip -9c ipengine.1 > ipengine.1.gz'), | |
|
93 | ||
|
82 | 94 | ('docs/man/ipython.1.gz', |
|
83 | 95 | ['docs/man/ipython.1'], |
|
84 |
|
|
|
96 | 'cd docs/man && gzip -9c ipython.1 > ipython.1.gz'), | |
|
97 | ||
|
98 | ('docs/man/ipython-wx.1.gz', | |
|
99 | ['docs/man/ipython-wx.1'], | |
|
100 | 'cd docs/man && gzip -9c ipython-wx.1 > ipython-wx.1.gz'), | |
|
101 | ||
|
102 | ('docs/man/ipythonx.1.gz', | |
|
103 | ['docs/man/ipythonx.1'], | |
|
104 | 'cd docs/man && gzip -9c ipythonx.1 > ipythonx.1.gz'), | |
|
105 | ||
|
106 | ('docs/man/irunner.1.gz', | |
|
107 | ['docs/man/irunner.1'], | |
|
108 | 'cd docs/man && gzip -9c irunner.1 > irunner.1.gz'), | |
|
85 | 109 | |
|
86 | 110 | ('docs/man/pycolor.1.gz', |
|
87 | 111 | ['docs/man/pycolor.1'], |
|
88 |
|
|
|
112 | 'cd docs/man && gzip -9c pycolor.1 > pycolor.1.gz'), | |
|
89 | 113 | ] |
|
90 | 114 | |
|
91 | 115 | # Only build the docs if sphinx is present |
@@ -57,7 +57,7 b' def file_doesnt_endwith(test,endings):' | |||
|
57 | 57 | # Basic project information |
|
58 | 58 | #--------------------------------------------------------------------------- |
|
59 | 59 | |
|
60 |
# |
|
|
60 | # release.py contains version, authors, license, url, keywords, etc. | |
|
61 | 61 | execfile(pjoin('IPython','core','release.py')) |
|
62 | 62 | |
|
63 | 63 | # Create a dict with the basic information |
@@ -227,6 +227,31 b' def find_data_files():' | |||
|
227 | 227 | |
|
228 | 228 | return data_files |
|
229 | 229 | |
|
230 | ||
|
231 | def make_man_update_target(manpage): | |
|
232 | """Return a target_update-compliant tuple for the given manpage. | |
|
233 | ||
|
234 | Parameters | |
|
235 | ---------- | |
|
236 | manpage : string | |
|
237 | Name of the manpage, must include the section number (trailing number). | |
|
238 | ||
|
239 | Example | |
|
240 | ------- | |
|
241 | ||
|
242 | >>> make_man_update_target('ipython.1') #doctest: +NORMALIZE_WHITESPACE | |
|
243 | ('docs/man/ipython.1.gz', | |
|
244 | ['docs/man/ipython.1'], | |
|
245 | 'cd docs/man && gzip -9c ipython.1 > ipython.1.gz') | |
|
246 | """ | |
|
247 | man_dir = pjoin('docs', 'man') | |
|
248 | manpage_gz = manpage + '.gz' | |
|
249 | manpath = pjoin(man_dir, manpage) | |
|
250 | manpath_gz = pjoin(man_dir, manpage_gz) | |
|
251 | gz_cmd = ( "cd %(man_dir)s && gzip -9c %(manpage)s > %(manpage_gz)s" % | |
|
252 | locals() ) | |
|
253 | return (manpath_gz, [manpath], gz_cmd) | |
|
254 | ||
|
230 | 255 | #--------------------------------------------------------------------------- |
|
231 | 256 | # Find scripts |
|
232 | 257 | #--------------------------------------------------------------------------- |
@@ -5,8 +5,6 b' import sys' | |||
|
5 | 5 | |
|
6 | 6 | # now, import setuptools and call the actual setup |
|
7 | 7 | import setuptools |
|
8 | # print sys.argv | |
|
9 | #sys.argv=['','bdist_egg'] | |
|
10 | 8 | execfile('setup.py') |
|
11 | 9 | |
|
12 | 10 | # clean up the junk left around by setuptools |
@@ -1,15 +1,54 b'' | |||
|
1 | #!/usr/bin/env python | |
|
2 | """Utility to look for hard tabs and \r characters in all sources. | |
|
3 | ||
|
4 | Usage: | |
|
5 | ||
|
6 | ./check_sources.py | |
|
7 | ||
|
8 | It prints summaries and if chosen, line-by-line info of where \\t or \\r | |
|
9 | characters can be found in our source tree. | |
|
10 | """ | |
|
11 | ||
|
12 | # Config | |
|
13 | # If true, all lines that have tabs are printed, with line number | |
|
14 | full_report_tabs = True | |
|
15 | # If true, all lines that have tabs are printed, with line number | |
|
16 | full_report_rets = False | |
|
17 | ||
|
18 | # Code begins | |
|
1 | 19 | from IPython.external.path import path |
|
2 | fs = path('..').walkfiles('*.py') | |
|
3 | 20 | |
|
4 | for f in fs: | |
|
21 | rets = [] | |
|
22 | tabs = [] | |
|
23 | ||
|
24 | for f in path('..').walkfiles('*.py'): | |
|
5 | 25 | errs = '' |
|
6 | 26 | cont = f.bytes() |
|
7 | 27 | if '\t' in cont: |
|
8 | 28 | errs+='t' |
|
29 | tabs.append(f) | |
|
9 | 30 | |
|
10 | 31 | if '\r' in cont: |
|
11 | 32 | errs+='r' |
|
33 | rets.append(f) | |
|
12 | 34 | |
|
13 | 35 | if errs: |
|
14 | 36 | print "%3s" % errs, f |
|
15 | ||
|
37 | ||
|
38 | if 't' in errs and full_report_tabs: | |
|
39 | for ln,line in enumerate(f.lines()): | |
|
40 | if '\t' in line: | |
|
41 | print 'TAB:',ln,':',line, | |
|
42 | ||
|
43 | if 'r' in errs and full_report_rets: | |
|
44 | for ln,line in enumerate(open(f.abspath(),'rb')): | |
|
45 | if '\r' in line: | |
|
46 | print 'RET:',ln,':',line, | |
|
47 | ||
|
48 | # Summary at the end, to call cleanup tools if necessary | |
|
49 | if tabs: | |
|
50 | print 'Hard tabs found. These can be cleaned with untabify:' | |
|
51 | for f in tabs: print f, | |
|
52 | if rets: | |
|
53 | print 'Carriage returns (\\r) found in:' | |
|
54 | for f in rets: print f, |
@@ -1,20 +1,19 b'' | |||
|
1 | 1 | #!/usr/bin/env python |
|
2 |
""" |
|
|
3 | """ | |
|
2 | """Script to check that all code in a directory compiles correctly. | |
|
4 | 3 |
|
|
5 | import os | |
|
6 | import sys | |
|
4 | Usage: | |
|
7 | 5 |
|
|
6 | compile.py | |
|
8 | 7 |
|
|
9 | vstr = '.'.join(map(str,sys.version_info[:2])) | |
|
8 | This script verifies that all Python files in the directory where run, and all | |
|
9 | of its subdirectories, compile correctly. | |
|
10 | 10 |
|
|
11 | stat = os.system('python %s/lib/python%s/compileall.py .' % (sys.prefix,vstr)) | |
|
11 | Before a release, call this script from the top-level directory. | |
|
12 | """ | |
|
13 | ||
|
14 | import sys | |
|
12 | 15 | |
|
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' | |
|
16 | from toollib import compile_tree | |
|
19 | 17 | |
|
20 | sys.exit(stat) | |
|
18 | if __name__ == '__main__': | |
|
19 | compile_tree() |
@@ -2,35 +2,22 b'' | |||
|
2 | 2 | """Simple script to create a tarball with proper bzr version info. |
|
3 | 3 | """ |
|
4 | 4 | |
|
5 |
import os |
|
|
5 | import os | |
|
6 | import sys | |
|
7 | import shutil | |
|
6 | 8 | |
|
7 | basever = '0.9.0' | |
|
9 | from toollib import * | |
|
8 | 10 | |
|
9 | def oscmd(c): | |
|
10 | print ">",c | |
|
11 | s = os.system(c) | |
|
12 | if s: | |
|
13 | print "Error",s | |
|
14 | sys.exit(s) | |
|
11 | c('python update_revnum.py') | |
|
15 | 12 | |
|
16 | def verinfo(): | |
|
17 | ||
|
18 | out = os.popen('bzr version-info') | |
|
19 | pairs = (l.split(':',1) for l in out) | |
|
20 | d = dict(((k,v.strip()) for (k,v) in pairs)) | |
|
21 | return d | |
|
22 | ||
|
23 | basename = 'ipython' | |
|
24 | ||
|
25 | #tarname = '%s.r%s.tgz' % (basename, ver) | |
|
26 | oscmd('python update_revnum.py') | |
|
13 | execfile('../IPython/core/release.py') # defines version_base | |
|
27 | 14 | |
|
28 | ver = verinfo() | |
|
15 | ver = version_info() | |
|
29 | 16 | |
|
30 | 17 | if ver['branch-nick'] == 'ipython': |
|
31 |
tarname = 'ipython-%s.bzr.r%s.tgz' % (base |
|
|
18 | tarname = 'ipython-%s.bzr.r%s.tgz' % (version_base, ver['revno']) | |
|
32 | 19 | else: |
|
33 |
tarname = 'ipython-%s.bzr.r%s.%s.tgz' % (base |
|
|
20 | tarname = 'ipython-%s.bzr.r%s.%s.tgz' % (version_base, ver['revno'], | |
|
34 | 21 | ver['branch-nick']) |
|
35 | 22 | |
|
36 |
|
|
|
23 | c('bzr export ' + tarname) |
@@ -1,58 +1,43 b'' | |||
|
1 | #!/bin/sh | |
|
2 |
|
|
|
1 | #!/usr/bin/env python | |
|
2 | """IPython release script. | |
|
3 | 3 | |
|
4 | PYVER=`python -V 2>&1 | awk '{print $2}' | awk -F '.' '{print $1$2}' ` | |
|
5 | version=`ipython -Version` | |
|
6 | ipdir=~/ipython/ipython | |
|
7 | ipbackupdir=~/ipython/backup | |
|
4 | This should only be run at real release time. | |
|
5 | """ | |
|
8 | 6 | |
|
9 | echo | |
|
10 | echo "Releasing IPython version $version" | |
|
11 | echo "==================================" | |
|
7 | from toollib import * | |
|
12 | 8 | |
|
13 | # Perform local backup | |
|
14 | cd $ipdir/tools | |
|
15 | ./make_tarball.py | |
|
16 | mv ipython-*.tgz $ipbackupdir | |
|
17 | ||
|
18 | # Clean up build/dist directories | |
|
19 | rm -rf $ipdir/build/* | |
|
20 | rm -rf $ipdir/dist/* | |
|
9 | # Get main ipython dir, this will raise if it doesn't pass some checks | |
|
10 | ipdir = get_ipdir() | |
|
11 | cd(ipdir) | |
|
21 | 12 | |
|
22 | # Build source and binary distros | |
|
23 | cd $ipdir | |
|
24 | ./setup.py sdist --formats=gztar | |
|
13 | # Load release info | |
|
14 | execfile(pjoin('IPython','core','release.py')) | |
|
25 | 15 | |
|
26 | # Build version-specific RPMs, where we must use the --python option to ensure | |
|
27 | # that the resulting RPM is really built with the requested python version (so | |
|
28 | # things go to lib/python2.X/...) | |
|
29 | #python2.4 ./setup.py bdist_rpm --binary-only --release=py24 --python=/usr/bin/python2.4 | |
|
30 | #python2.5 ./setup.py bdist_rpm --binary-only --release=py25 --python=/usr/bin/python2.5 | |
|
16 | # Where I keep static backups of each release | |
|
17 | ipbackupdir = os.path.expanduser('~/ipython/backup') | |
|
31 | 18 | |
|
32 | # Build eggs | |
|
33 | python2.4 ./setup_bdist_egg.py | |
|
34 | python2.5 ./setup_bdist_egg.py | |
|
19 | ||
|
20 | print "Releasing IPython version $version" | |
|
21 | print "==================================" | |
|
35 | 22 | |
|
36 | # Call the windows build separately, so that the extra Windows scripts don't | |
|
37 | # get pulled into Unix builds (setup.py has code which checks for | |
|
38 | # bdist_wininst) | |
|
39 | ./setup.py bdist_wininst --install-script=ipython_win_post_install.py | |
|
23 | # Perform local backup | |
|
24 | c('./make_tarball.py') | |
|
25 | c('mv ipython-*.tgz %s' % ipbackupdir) | |
|
40 | 26 | |
|
41 | # Change name so retarded Vista runs the installer correctly | |
|
42 | rename 's/win32/win32-setup/' $ipdir/dist/*.exe | |
|
27 | # Build release files | |
|
28 | c('./mkrel.py %s' % ipdir) | |
|
43 | 29 | |
|
44 | 30 | # Register with the Python Package Index (PyPI) |
|
45 |
|
|
|
46 | cd $ipdir | |
|
47 | ./setup.py register | |
|
31 | print "Registering with PyPI..." | |
|
32 | c('./setup.py register') | |
|
48 | 33 | |
|
49 | 34 | # Upload all files |
|
50 | cd $ipdir/dist | |
|
51 |
|
|
|
52 | scp * ipython@ipython.scipy.org:www/dist/ | |
|
35 | cd('dist') | |
|
36 | print "Uploading distribution files..." | |
|
37 | c('scp * ipython@ipython.scipy.org:www/dist/') | |
|
53 | 38 | |
|
54 |
|
|
|
55 |
cd |
|
|
56 | scp `ls -1tr *tgz | tail -1` ipython@ipython.scipy.org:www/backup/ | |
|
39 | print "Uploading backup files..." | |
|
40 | cd(ipbackupdir) | |
|
41 | c('scp `ls -1tr *tgz | tail -1` ipython@ipython.scipy.org:www/backup/') | |
|
57 | 42 | |
|
58 |
|
|
|
43 | print "Done!" |
@@ -1,3 +1,9 b'' | |||
|
1 | """XXX - What exactly is the use of this script? | |
|
2 | ||
|
3 | I (fperez) tried it quickly and it doesn't work in its current form. Either it | |
|
4 | needs to be fixed and documented or removed. | |
|
5 | """ | |
|
6 | ||
|
1 | 7 | import cProfile as profile |
|
2 | 8 | import sys |
|
3 | 9 | #import profile |
@@ -1,5 +1,5 b'' | |||
|
1 | 1 | #!/bin/sh |
|
2 | ||
|
2 | # Simple upload script to push up into the testing directory a local build | |
|
3 | 3 | ipdir=$PWD/.. |
|
4 | 4 | |
|
5 | 5 | cd $ipdir/dist |
@@ -1,23 +1,32 b'' | |||
|
1 | 1 | #!/usr/bin/env python |
|
2 |
""" |
|
|
2 | """Change the revision number in release.py | |
|
3 | ||
|
4 | This edits in-place release.py to update the revision number from bzr info. | |
|
5 | ||
|
6 | Usage: | |
|
7 | ||
|
8 | ./update_revnum.py""" | |
|
3 | 9 | |
|
4 | 10 | import os |
|
5 |
import |
|
|
11 | import pprint | |
|
12 | import re | |
|
6 | 13 | |
|
7 | def verinfo(): | |
|
8 | ||
|
9 | out = os.popen('bzr version-info') | |
|
10 | pairs = (l.split(':',1) for l in out) | |
|
11 | d = dict(((k,v.strip()) for (k,v) in pairs)) | |
|
12 | return d | |
|
14 | from toollib import * | |
|
13 | 15 | |
|
14 | ver = verinfo() | |
|
16 | if __name__ == '__main__': | |
|
17 | ver = version_info() | |
|
15 | 18 | |
|
16 | pprint.pprint(ver) | |
|
19 | pprint.pprint(ver) | |
|
17 | 20 | |
|
18 | rfile = open('../IPython/core/release.py','rb').read() | |
|
19 |
newcont = re.sub(r'revision\s*=.*', |
|
|
21 | rfile = open('../IPython/core/release.py','rb').read() | |
|
22 | newcont = re.sub(r'revision\s*=.*', | |
|
23 | "revision = '%s'" % ver['revno'], | |
|
24 | rfile) | |
|
20 | 25 | |
|
21 | newcont = re.sub(r'^branch\s*=[^=].*', "branch = '%s'" % ver['branch-nick'], newcont ) | |
|
26 | newcont = re.sub(r'^branch\s*=[^=].*', | |
|
27 | "branch = '%s'" % ver['branch-nick'], | |
|
28 | newcont) | |
|
22 | 29 | |
|
23 |
open('../IPython/core/release.py','wb') |
|
|
30 | f = open('../IPython/core/release.py','wb') | |
|
31 | f.write(newcont) | |
|
32 | f.close() |
|
1 | NO CONTENT: file was removed | |
This diff has been collapsed as it changes many lines, (1067 lines changed) Show them Hide them |
|
1 | NO CONTENT: file was removed | |
This diff has been collapsed as it changes many lines, (800 lines changed) Show them Hide them |
|
1 | NO CONTENT: file was removed |
|
1 | NO CONTENT: file was removed |
|
1 | NO CONTENT: file was removed |
|
1 | NO CONTENT: file was removed |
|
1 | NO CONTENT: file was removed |
|
1 | NO CONTENT: file was removed |
|
1 | NO CONTENT: file was removed |
|
1 | NO CONTENT: file was removed |
|
1 | NO CONTENT: file was removed |
General Comments 0
You need to be logged in to leave comments.
Login now