##// END OF EJS Templates
Merging with upstream trunk
Fernando Perez -
r2354:d30c181f merge
parent child Browse files
Show More

The requested changes are too big and content was truncated. Show full diff

@@ -0,0 +1,184 b''
1 import os
2
3 c = get_config()
4
5 #-----------------------------------------------------------------------------
6 # Select which launchers to use
7 #-----------------------------------------------------------------------------
8
9 # This allows you to control what method is used to start the controller
10 # and engines. The following methods are currently supported:
11 # - Start as a regular process on localhost.
12 # - Start using mpiexec.
13 # - Start using the Windows HPC Server 2008 scheduler
14 # - Start using PBS
15 # - Start using SSH (currently broken)
16
17
18 # The selected launchers can be configured below.
19
20 # Options are:
21 # - LocalControllerLauncher
22 # - MPIExecControllerLauncher
23 # - PBSControllerLauncher
24 # - WindowsHPCControllerLauncher
25 # c.Global.controller_launcher = 'IPython.kernel.launcher.LocalControllerLauncher'
26
27 # Options are:
28 # - LocalEngineSetLauncher
29 # - MPIExecEngineSetLauncher
30 # - PBSEngineSetLauncher
31 # - WindowsHPCEngineSetLauncher
32 # c.Global.engine_launcher = 'IPython.kernel.launcher.LocalEngineSetLauncher'
33
34 #-----------------------------------------------------------------------------
35 # Global configuration
36 #-----------------------------------------------------------------------------
37
38 # The default number of engines that will be started. This is overridden by
39 # the -n command line option: "ipcluster start -n 4"
40 # c.Global.n = 2
41
42 # Log to a file in cluster_dir/log, otherwise just log to sys.stdout.
43 # c.Global.log_to_file = False
44
45 # Remove old logs from cluster_dir/log before starting.
46 # c.Global.clean_logs = True
47
48 # The working directory for the process. The application will use os.chdir
49 # to change to this directory before starting.
50 # c.Global.work_dir = os.getcwd()
51
52
53 #-----------------------------------------------------------------------------
54 # Local process launchers
55 #-----------------------------------------------------------------------------
56
57 # The command line arguments to call the controller with.
58 # c.LocalControllerLauncher.controller_args = \
59 # ['--log-to-file','--log-level', '40']
60
61 # The working directory for the controller
62 # c.LocalEngineSetLauncher.work_dir = u''
63
64 # Command line argument passed to the engines.
65 # c.LocalEngineSetLauncher.engine_args = ['--log-to-file','--log-level', '40']
66
67 #-----------------------------------------------------------------------------
68 # MPIExec launchers
69 #-----------------------------------------------------------------------------
70
71 # The mpiexec/mpirun command to use in started the controller.
72 # c.MPIExecControllerLauncher.mpi_cmd = ['mpiexec']
73
74 # Additional arguments to pass to the actual mpiexec command.
75 # c.MPIExecControllerLauncher.mpi_args = []
76
77 # The command line argument to call the controller with.
78 # c.MPIExecControllerLauncher.controller_args = \
79 # ['--log-to-file','--log-level', '40']
80
81
82 # The mpiexec/mpirun command to use in started the controller.
83 # c.MPIExecEngineSetLauncher.mpi_cmd = ['mpiexec']
84
85 # Additional arguments to pass to the actual mpiexec command.
86 # c.MPIExecEngineSetLauncher.mpi_args = []
87
88 # Command line argument passed to the engines.
89 # c.MPIExecEngineSetLauncher.engine_args = ['--log-to-file','--log-level', '40']
90
91 # The default number of engines to start if not given elsewhere.
92 # c.MPIExecEngineSetLauncher.n = 1
93
94 #-----------------------------------------------------------------------------
95 # SSH launchers
96 #-----------------------------------------------------------------------------
97
98 # Todo
99
100
101 #-----------------------------------------------------------------------------
102 # Unix batch (PBS) schedulers launchers
103 #-----------------------------------------------------------------------------
104
105 # The command line program to use to submit a PBS job.
106 # c.PBSControllerLauncher.submit_command = 'qsub'
107
108 # The command line program to use to delete a PBS job.
109 # c.PBSControllerLauncher.delete_command = 'qdel'
110
111 # A regular expression that takes the output of qsub and find the job id.
112 # c.PBSControllerLauncher.job_id_regexp = r'\d+'
113
114 # The batch submission script used to start the controller. This is where
115 # environment variables would be setup, etc. This string is interpolated using
116 # the Itpl module in IPython.external. Basically, you can use ${n} for the
117 # number of engine and ${cluster_dir} for the cluster_dir.
118 # c.PBSControllerLauncher.batch_template = """"""
119
120 # The name of the instantiated batch script that will actually be used to
121 # submit the job. This will be written to the cluster directory.
122 # c.PBSControllerLauncher.batch_file_name = u'pbs_batch_script_controller'
123
124
125 # The command line program to use to submit a PBS job.
126 # c.PBSEngineSetLauncher.submit_command = 'qsub'
127
128 # The command line program to use to delete a PBS job.
129 # c.PBSEngineSetLauncher.delete_command = 'qdel'
130
131 # A regular expression that takes the output of qsub and find the job id.
132 # c.PBSEngineSetLauncher.job_id_regexp = r'\d+'
133
134 # The batch submission script used to start the engines. This is where
135 # environment variables would be setup, etc. This string is interpolated using
136 # the Itpl module in IPython.external. Basically, you can use ${n} for the
137 # number of engine and ${cluster_dir} for the cluster_dir.
138 # c.PBSEngineSetLauncher.batch_template = """"""
139
140 # The name of the instantiated batch script that will actually be used to
141 # submit the job. This will be written to the cluster directory.
142 # c.PBSEngineSetLauncher.batch_file_name = u'pbs_batch_script_engines'
143
144 #-----------------------------------------------------------------------------
145 # Windows HPC Server 2008 launcher configuration
146 #-----------------------------------------------------------------------------
147
148 # c.IPControllerJob.job_name = 'IPController'
149 # c.IPControllerJob.is_exclusive = False
150 # c.IPControllerJob.username = r'USERDOMAIN\USERNAME'
151 # c.IPControllerJob.priority = 'Highest'
152 # c.IPControllerJob.requested_nodes = ''
153 # c.IPControllerJob.project = 'MyProject'
154
155 # c.IPControllerTask.task_name = 'IPController'
156 # c.IPControllerTask.controller_cmd = [u'ipcontroller.exe']
157 # c.IPControllerTask.controller_args = ['--log-to-file', '--log-level', '40']
158 # c.IPControllerTask.environment_variables = {}
159
160 # c.WindowsHPCControllerLauncher.scheduler = 'HEADNODE'
161 # c.WindowsHPCControllerLauncher.job_file_name = u'ipcontroller_job.xml'
162
163
164 # c.IPEngineSetJob.job_name = 'IPEngineSet'
165 # c.IPEngineSetJob.is_exclusive = False
166 # c.IPEngineSetJob.username = r'USERDOMAIN\USERNAME'
167 # c.IPEngineSetJob.priority = 'Highest'
168 # c.IPEngineSetJob.requested_nodes = ''
169 # c.IPEngineSetJob.project = 'MyProject'
170
171 # c.IPEngineTask.task_name = 'IPEngine'
172 # c.IPEngineTask.engine_cmd = [u'ipengine.exe']
173 # c.IPEngineTask.engine_args = ['--log-to-file', '--log-level', '40']
174 # c.IPEngineTask.environment_variables = {}
175
176 # c.WindowsHPCEngineSetLauncher.scheduler = 'HEADNODE'
177 # c.WindowsHPCEngineSetLauncher.job_file_name = u'ipengineset_job.xml'
178
179
180
181
182
183
184
@@ -0,0 +1,136 b''
1 from IPython.config.loader import Config
2
3 c = get_config()
4
5 #-----------------------------------------------------------------------------
6 # Global configuration
7 #-----------------------------------------------------------------------------
8
9 # Basic Global config attributes
10
11 # Start up messages are logged to stdout using the logging module.
12 # These all happen before the twisted reactor is started and are
13 # useful for debugging purposes. Can be (10=DEBUG,20=INFO,30=WARN,40=CRITICAL)
14 # and smaller is more verbose.
15 # c.Global.log_level = 20
16
17 # Log to a file in cluster_dir/log, otherwise just log to sys.stdout.
18 # c.Global.log_to_file = False
19
20 # Remove old logs from cluster_dir/log before starting.
21 # c.Global.clean_logs = True
22
23 # A list of Python statements that will be run before starting the
24 # controller. This is provided because occasionally certain things need to
25 # be imported in the controller for pickling to work.
26 # c.Global.import_statements = ['import math']
27
28 # Reuse the controller's FURL files. If False, FURL files are regenerated
29 # each time the controller is run. If True, they will be reused, *but*, you
30 # also must set the network ports by hand. If set, this will override the
31 # values set for the client and engine connections below.
32 # c.Global.reuse_furls = True
33
34 # Enable SSL encryption on all connections to the controller. If set, this
35 # will override the values set for the client and engine connections below.
36 # c.Global.secure = True
37
38 # The working directory for the process. The application will use os.chdir
39 # to change to this directory before starting.
40 # c.Global.work_dir = os.getcwd()
41
42 #-----------------------------------------------------------------------------
43 # Configure the client services
44 #-----------------------------------------------------------------------------
45
46 # Basic client service config attributes
47
48 # The network interface the controller will listen on for client connections.
49 # This should be an IP address or hostname of the controller's host. The empty
50 # string means listen on all interfaces.
51 # c.FCClientServiceFactory.ip = ''
52
53 # The TCP/IP port the controller will listen on for client connections. If 0
54 # a random port will be used. If the controller's host has a firewall running
55 # it must allow incoming traffic on this port.
56 # c.FCClientServiceFactory.port = 0
57
58 # The client learns how to connect to the controller by looking at the
59 # location field embedded in the FURL. If this field is empty, all network
60 # interfaces that the controller is listening on will be listed. To have the
61 # client connect on a particular interface, list it here.
62 # c.FCClientServiceFactory.location = ''
63
64 # Use SSL encryption for the client connection.
65 # c.FCClientServiceFactory.secure = True
66
67 # Reuse the client FURL each time the controller is started. If set, you must
68 # also pick a specific network port above (FCClientServiceFactory.port).
69 # c.FCClientServiceFactory.reuse_furls = False
70
71 #-----------------------------------------------------------------------------
72 # Configure the engine services
73 #-----------------------------------------------------------------------------
74
75 # Basic config attributes for the engine services.
76
77 # The network interface the controller will listen on for engine connections.
78 # This should be an IP address or hostname of the controller's host. The empty
79 # string means listen on all interfaces.
80 # c.FCEngineServiceFactory.ip = ''
81
82 # The TCP/IP port the controller will listen on for engine connections. If 0
83 # a random port will be used. If the controller's host has a firewall running
84 # it must allow incoming traffic on this port.
85 # c.FCEngineServiceFactory.port = 0
86
87 # The engine learns how to connect to the controller by looking at the
88 # location field embedded in the FURL. If this field is empty, all network
89 # interfaces that the controller is listening on will be listed. To have the
90 # client connect on a particular interface, list it here.
91 # c.FCEngineServiceFactory.location = ''
92
93 # Use SSL encryption for the engine connection.
94 # c.FCEngineServiceFactory.secure = True
95
96 # Reuse the client FURL each time the controller is started. If set, you must
97 # also pick a specific network port above (FCClientServiceFactory.port).
98 # c.FCEngineServiceFactory.reuse_furls = False
99
100 #-----------------------------------------------------------------------------
101 # Developer level configuration attributes
102 #-----------------------------------------------------------------------------
103
104 # You shouldn't have to modify anything in this section. These attributes
105 # are more for developers who want to change the behavior of the controller
106 # at a fundamental level.
107
108 # c.FCClientServiceFactory.cert_file = u'ipcontroller-client.pem'
109
110 # default_client_interfaces = Config()
111 # default_client_interfaces.Task.interface_chain = [
112 # 'IPython.kernel.task.ITaskController',
113 # 'IPython.kernel.taskfc.IFCTaskController'
114 # ]
115 #
116 # default_client_interfaces.Task.furl_file = u'ipcontroller-tc.furl'
117 #
118 # default_client_interfaces.MultiEngine.interface_chain = [
119 # 'IPython.kernel.multiengine.IMultiEngine',
120 # 'IPython.kernel.multienginefc.IFCSynchronousMultiEngine'
121 # ]
122 #
123 # default_client_interfaces.MultiEngine.furl_file = u'ipcontroller-mec.furl'
124 #
125 # c.FCEngineServiceFactory.interfaces = default_client_interfaces
126
127 # c.FCEngineServiceFactory.cert_file = u'ipcontroller-engine.pem'
128
129 # default_engine_interfaces = Config()
130 # default_engine_interfaces.Default.interface_chain = [
131 # 'IPython.kernel.enginefc.IFCControllerBase'
132 # ]
133 #
134 # default_engine_interfaces.Default.furl_file = u'ipcontroller-engine.furl'
135 #
136 # c.FCEngineServiceFactory.interfaces = default_engine_interfaces
@@ -0,0 +1,90 b''
1 c = get_config()
2
3 #-----------------------------------------------------------------------------
4 # Global configuration
5 #-----------------------------------------------------------------------------
6
7 # Start up messages are logged to stdout using the logging module.
8 # These all happen before the twisted reactor is started and are
9 # useful for debugging purposes. Can be (10=DEBUG,20=INFO,30=WARN,40=CRITICAL)
10 # and smaller is more verbose.
11 # c.Global.log_level = 20
12
13 # Log to a file in cluster_dir/log, otherwise just log to sys.stdout.
14 # c.Global.log_to_file = False
15
16 # Remove old logs from cluster_dir/log before starting.
17 # c.Global.clean_logs = True
18
19 # A list of strings that will be executed in the users namespace on the engine
20 # before it connects to the controller.
21 # c.Global.exec_lines = ['import numpy']
22
23 # The engine will try to connect to the controller multiple times, to allow
24 # the controller time to startup and write its FURL file. These parameters
25 # control the number of retries (connect_max_tries) and the initial delay
26 # (connect_delay) between attemps. The actual delay between attempts gets
27 # longer each time by a factor of 1.5 (delay[i] = 1.5*delay[i-1])
28 # those attemps.
29 # c.Global.connect_delay = 0.1
30 # c.Global.connect_max_tries = 15
31
32 # By default, the engine will look for the controller's FURL file in its own
33 # cluster directory. Sometimes, the FURL file will be elsewhere and this
34 # attribute can be set to the full path of the FURL file.
35 # c.Global.furl_file = u''
36
37 # The working directory for the process. The application will use os.chdir
38 # to change to this directory before starting.
39 # c.Global.work_dir = os.getcwd()
40
41 #-----------------------------------------------------------------------------
42 # MPI configuration
43 #-----------------------------------------------------------------------------
44
45 # Upon starting the engine can be configured to call MPI_Init. This section
46 # configures that.
47
48 # Select which MPI section to execute to setup MPI. The value of this
49 # attribute must match the name of another attribute in the MPI config
50 # section (mpi4py, pytrilinos, etc.). This can also be set by the --mpi
51 # command line option.
52 # c.MPI.use = ''
53
54 # Initialize MPI using mpi4py. To use this, set c.MPI.use = 'mpi4py' to use
55 # --mpi=mpi4py at the command line.
56 # c.MPI.mpi4py = """from mpi4py import MPI as mpi
57 # mpi.size = mpi.COMM_WORLD.Get_size()
58 # mpi.rank = mpi.COMM_WORLD.Get_rank()
59 # """
60
61 # Initialize MPI using pytrilinos. To use this, set c.MPI.use = 'pytrilinos'
62 # to use --mpi=pytrilinos at the command line.
63 # c.MPI.pytrilinos = """from PyTrilinos import Epetra
64 # class SimpleStruct:
65 # pass
66 # mpi = SimpleStruct()
67 # mpi.rank = 0
68 # mpi.size = 0
69 # """
70
71 #-----------------------------------------------------------------------------
72 # Developer level configuration attributes
73 #-----------------------------------------------------------------------------
74
75 # You shouldn't have to modify anything in this section. These attributes
76 # are more for developers who want to change the behavior of the controller
77 # at a fundamental level.
78
79 # You should not have to change these attributes.
80
81 # c.Global.shell_class = 'IPython.kernel.core.interpreter.Interpreter'
82
83 # c.Global.furl_file_name = u'ipcontroller-engine.furl'
84
85
86
87
88
89
90
@@ -0,0 +1,148 b''
1 # Get the config being loaded so we can set attributes on it
2 c = get_config()
3
4 #-----------------------------------------------------------------------------
5 # Global options
6 #-----------------------------------------------------------------------------
7
8 # c.Global.display_banner = True
9
10 # c.Global.classic = False
11
12 # c.Global.nosep = True
13
14 # Set this to determine the detail of what is logged at startup.
15 # The default is 30 and possible values are 0,10,20,30,40,50.
16 # c.Global.log_level = 20
17
18 # This should be a list of importable Python modules that have an
19 # load_in_ipython(ip) method. This method gets called when the extension
20 # is loaded. You can put your extensions anywhere they can be imported
21 # but we add the extensions subdir of the ipython directory to sys.path
22 # during extension loading, so you can put them there as well.
23 # c.Global.extensions = [
24 # 'myextension'
25 # ]
26
27 # These lines are run in IPython in the user's namespace after extensions
28 # are loaded. They can contain full IPython syntax with magics etc.
29 # c.Global.exec_lines = [
30 # 'import numpy',
31 # 'a = 10; b = 20',
32 # '1/0'
33 # ]
34
35 # These files are run in IPython in the user's namespace. Files with a .py
36 # extension need to be pure Python. Files with a .ipy extension can have
37 # custom IPython syntax (like magics, etc.).
38 # These files need to be in the cwd, the ipython_dir or be absolute paths.
39 # c.Global.exec_files = [
40 # 'mycode.py',
41 # 'fancy.ipy'
42 # ]
43
44 #-----------------------------------------------------------------------------
45 # InteractiveShell options
46 #-----------------------------------------------------------------------------
47
48 # c.InteractiveShell.autocall = 1
49
50 # c.InteractiveShell.autoedit_syntax = False
51
52 # c.InteractiveShell.autoindent = True
53
54 # c.InteractiveShell.automagic = False
55
56 # c.InteractiveShell.banner1 = 'This if for overriding the default IPython banner'
57
58 # c.InteractiveShell.banner2 = "This is for extra banner text"
59
60 # c.InteractiveShell.cache_size = 1000
61
62 # c.InteractiveShell.colors = 'LightBG'
63
64 # c.InteractiveShell.color_info = True
65
66 # c.InteractiveShell.confirm_exit = True
67
68 # c.InteractiveShell.deep_reload = False
69
70 # c.InteractiveShell.editor = 'nano'
71
72 # c.InteractiveShell.logstart = True
73
74 # c.InteractiveShell.logfile = u'ipython_log.py'
75
76 # c.InteractiveShell.logappend = u'mylog.py'
77
78 # c.InteractiveShell.object_info_string_level = 0
79
80 # c.InteractiveShell.pager = 'less'
81
82 # c.InteractiveShell.pdb = False
83
84 # c.InteractiveShell.pprint = True
85
86 # c.InteractiveShell.prompt_in1 = 'In [\#]: '
87 # c.InteractiveShell.prompt_in2 = ' .\D.: '
88 # c.InteractiveShell.prompt_out = 'Out[\#]: '
89 # c.InteractiveShell.prompts_pad_left = True
90
91 # c.InteractiveShell.quiet = False
92
93 # Readline
94 # c.InteractiveShell.readline_use = True
95
96 # c.InteractiveShell.readline_parse_and_bind = [
97 # 'tab: complete',
98 # '"\C-l": possible-completions',
99 # 'set show-all-if-ambiguous on',
100 # '"\C-o": tab-insert',
101 # '"\M-i": " "',
102 # '"\M-o": "\d\d\d\d"',
103 # '"\M-I": "\d\d\d\d"',
104 # '"\C-r": reverse-search-history',
105 # '"\C-s": forward-search-history',
106 # '"\C-p": history-search-backward',
107 # '"\C-n": history-search-forward',
108 # '"\e[A": history-search-backward',
109 # '"\e[B": history-search-forward',
110 # '"\C-k": kill-line',
111 # '"\C-u": unix-line-discard',
112 # ]
113 # c.InteractiveShell.readline_remove_delims = '-/~'
114 # c.InteractiveShell.readline_merge_completions = True
115 # c.InteractiveShell.readline_omit_names = 0
116
117 # c.InteractiveShell.screen_length = 0
118
119 # c.InteractiveShell.separate_in = '\n'
120 # c.InteractiveShell.separate_out = ''
121 # c.InteractiveShell.separate_out2 = ''
122
123 # c.InteractiveShell.system_header = "IPython system call: "
124
125 # c.InteractiveShell.system_verbose = True
126
127 # c.InteractiveShell.term_title = False
128
129 # c.InteractiveShell.wildcards_case_sensitive = True
130
131 # c.InteractiveShell.xmode = 'Context'
132
133 #-----------------------------------------------------------------------------
134 # PrefilterManager options
135 #-----------------------------------------------------------------------------
136
137 # c.PrefilterManager.multi_line_specials = True
138
139 #-----------------------------------------------------------------------------
140 # AliasManager options
141 #-----------------------------------------------------------------------------
142
143 # Do this to disable all defaults
144 # c.AliasManager.default_aliases = []
145
146 # c.AliasManager.user_aliases = [
147 # ('foo', 'echo Hi')
148 # ] No newline at end of file
@@ -0,0 +1,62 b''
1 from os.path import join
2 pjoin = join
3
4 from IPython.utils.genutils import get_ipython_dir, get_security_dir
5 security_dir = get_security_dir()
6
7
8 ENGINE_LOGFILE = ''
9
10 ENGINE_FURL_FILE = 'ipcontroller-engine.furl'
11
12 MPI_CONFIG_MPI4PY = """from mpi4py import MPI as mpi
13 mpi.size = mpi.COMM_WORLD.Get_size()
14 mpi.rank = mpi.COMM_WORLD.Get_rank()
15 """
16
17 MPI_CONFIG_PYTRILINOS = """from PyTrilinos import Epetra
18 class SimpleStruct:
19 pass
20 mpi = SimpleStruct()
21 mpi.rank = 0
22 mpi.size = 0
23 """
24
25 MPI_DEFAULT = ''
26
27 CONTROLLER_LOGFILE = ''
28 CONTROLLER_IMPORT_STATEMENT = ''
29 CONTROLLER_REUSE_FURLS = False
30
31 ENGINE_TUB_IP = ''
32 ENGINE_TUB_PORT = 0
33 ENGINE_TUB_LOCATION = ''
34 ENGINE_TUB_SECURE = True
35 ENGINE_TUB_CERT_FILE = 'ipcontroller-engine.pem'
36 ENGINE_FC_INTERFACE = 'IPython.kernel.enginefc.IFCControllerBase'
37 ENGINE_FURL_FILE = 'ipcontroller-engine.furl'
38
39 CONTROLLER_INTERFACES = dict(
40 TASK = dict(
41 CONTROLLER_INTERFACE = 'IPython.kernel.task.ITaskController',
42 FC_INTERFACE = 'IPython.kernel.taskfc.IFCTaskController',
43 FURL_FILE = pjoin(security_dir, 'ipcontroller-tc.furl')
44 ),
45 MULTIENGINE = dict(
46 CONTROLLER_INTERFACE = 'IPython.kernel.multiengine.IMultiEngine',
47 FC_INTERFACE = 'IPython.kernel.multienginefc.IFCSynchronousMultiEngine',
48 FURL_FILE = pjoin(security_dir, 'ipcontroller-mec.furl')
49 )
50 )
51
52 CLIENT_TUB_IP = ''
53 CLIENT_TUB_PORT = 0
54 CLIENT_TUB_LOCATION = ''
55 CLIENT_TUB_SECURE = True
56 CLIENT_TUB_CERT_FILE = 'ipcontroller-client.pem'
57
58 CLIENT_INTERFACES = dict(
59 TASK = dict(FURL_FILE = 'ipcontroller-tc.furl'),
60 MULTIENGINE = dict(FURLFILE='ipcontroller-mec.furl')
61 )
62
@@ -0,0 +1,336 b''
1 #!/usr/bin/env python
2 # encoding: utf-8
3 """A simple configuration system.
4
5 Authors:
6
7 * Brian Granger
8 """
9
10 #-----------------------------------------------------------------------------
11 # Copyright (C) 2008-2009 The IPython Development Team
12 #
13 # Distributed under the terms of the BSD License. The full license is in
14 # the file COPYING, distributed as part of this software.
15 #-----------------------------------------------------------------------------
16
17 #-----------------------------------------------------------------------------
18 # Imports
19 #-----------------------------------------------------------------------------
20
21 import __builtin__
22 import os
23 import sys
24
25 from IPython.external import argparse
26 from IPython.utils.genutils import filefind
27
28 #-----------------------------------------------------------------------------
29 # Exceptions
30 #-----------------------------------------------------------------------------
31
32
33 class ConfigError(Exception):
34 pass
35
36
37 class ConfigLoaderError(ConfigError):
38 pass
39
40
41 #-----------------------------------------------------------------------------
42 # Config class for holding config information
43 #-----------------------------------------------------------------------------
44
45
46 class Config(dict):
47 """An attribute based dict that can do smart merges."""
48
49 def __init__(self, *args, **kwds):
50 dict.__init__(self, *args, **kwds)
51 # This sets self.__dict__ = self, but it has to be done this way
52 # because we are also overriding __setattr__.
53 dict.__setattr__(self, '__dict__', self)
54
55 def _merge(self, other):
56 to_update = {}
57 for k, v in other.items():
58 if not self.has_key(k):
59 to_update[k] = v
60 else: # I have this key
61 if isinstance(v, Config):
62 # Recursively merge common sub Configs
63 self[k]._merge(v)
64 else:
65 # Plain updates for non-Configs
66 to_update[k] = v
67
68 self.update(to_update)
69
70 def _is_section_key(self, key):
71 if key[0].upper()==key[0] and not key.startswith('_'):
72 return True
73 else:
74 return False
75
76 def has_key(self, key):
77 if self._is_section_key(key):
78 return True
79 else:
80 return dict.has_key(self, key)
81
82 def _has_section(self, key):
83 if self._is_section_key(key):
84 if dict.has_key(self, key):
85 return True
86 return False
87
88 def copy(self):
89 return type(self)(dict.copy(self))
90
91 def __copy__(self):
92 return self.copy()
93
94 def __deepcopy__(self, memo):
95 import copy
96 return type(self)(copy.deepcopy(self.items()))
97
98 def __getitem__(self, key):
99 # Because we use this for an exec namespace, we need to delegate
100 # the lookup of names in __builtin__ to itself. This means
101 # that you can't have section or attribute names that are
102 # builtins.
103 try:
104 return getattr(__builtin__, key)
105 except AttributeError:
106 pass
107 if self._is_section_key(key):
108 try:
109 return dict.__getitem__(self, key)
110 except KeyError:
111 c = Config()
112 dict.__setitem__(self, key, c)
113 return c
114 else:
115 return dict.__getitem__(self, key)
116
117 def __setitem__(self, key, value):
118 # Don't allow names in __builtin__ to be modified.
119 if hasattr(__builtin__, key):
120 raise ConfigError('Config variable names cannot have the same name '
121 'as a Python builtin: %s' % key)
122 if self._is_section_key(key):
123 if not isinstance(value, Config):
124 raise ValueError('values whose keys begin with an uppercase '
125 'char must be Config instances: %r, %r' % (key, value))
126 else:
127 dict.__setitem__(self, key, value)
128
129 def __getattr__(self, key):
130 try:
131 return self.__getitem__(key)
132 except KeyError, e:
133 raise AttributeError(e)
134
135 def __setattr__(self, key, value):
136 try:
137 self.__setitem__(key, value)
138 except KeyError, e:
139 raise AttributeError(e)
140
141 def __delattr__(self, key):
142 try:
143 dict.__delitem__(self, key)
144 except KeyError, e:
145 raise AttributeError(e)
146
147
148 #-----------------------------------------------------------------------------
149 # Config loading classes
150 #-----------------------------------------------------------------------------
151
152
153 class ConfigLoader(object):
154 """A object for loading configurations from just about anywhere.
155
156 The resulting configuration is packaged as a :class:`Struct`.
157
158 Notes
159 -----
160 A :class:`ConfigLoader` does one thing: load a config from a source
161 (file, command line arguments) and returns the data as a :class:`Struct`.
162 There are lots of things that :class:`ConfigLoader` does not do. It does
163 not implement complex logic for finding config files. It does not handle
164 default values or merge multiple configs. These things need to be
165 handled elsewhere.
166 """
167
168 def __init__(self):
169 """A base class for config loaders.
170
171 Examples
172 --------
173
174 >>> cl = ConfigLoader()
175 >>> config = cl.load_config()
176 >>> config
177 {}
178 """
179 self.clear()
180
181 def clear(self):
182 self.config = Config()
183
184 def load_config(self):
185 """Load a config from somewhere, return a Struct.
186
187 Usually, this will cause self.config to be set and then returned.
188 """
189 return self.config
190
191
192 class FileConfigLoader(ConfigLoader):
193 """A base class for file based configurations.
194
195 As we add more file based config loaders, the common logic should go
196 here.
197 """
198 pass
199
200
201 class PyFileConfigLoader(FileConfigLoader):
202 """A config loader for pure python files.
203
204 This calls execfile on a plain python file and looks for attributes
205 that are all caps. These attribute are added to the config Struct.
206 """
207
208 def __init__(self, filename, path=None):
209 """Build a config loader for a filename and path.
210
211 Parameters
212 ----------
213 filename : str
214 The file name of the config file.
215 path : str, list, tuple
216 The path to search for the config file on, or a sequence of
217 paths to try in order.
218 """
219 super(PyFileConfigLoader, self).__init__()
220 self.filename = filename
221 self.path = path
222 self.full_filename = ''
223 self.data = None
224
225 def load_config(self):
226 """Load the config from a file and return it as a Struct."""
227 self._find_file()
228 self._read_file_as_dict()
229 self._convert_to_config()
230 return self.config
231
232 def _find_file(self):
233 """Try to find the file by searching the paths."""
234 self.full_filename = filefind(self.filename, self.path)
235
236 def _read_file_as_dict(self):
237 """Load the config file into self.config, with recursive loading."""
238 # This closure is made available in the namespace that is used
239 # to exec the config file. This allows users to call
240 # load_subconfig('myconfig.py') to load config files recursively.
241 # It needs to be a closure because it has references to self.path
242 # and self.config. The sub-config is loaded with the same path
243 # as the parent, but it uses an empty config which is then merged
244 # with the parents.
245 def load_subconfig(fname):
246 loader = PyFileConfigLoader(fname, self.path)
247 try:
248 sub_config = loader.load_config()
249 except IOError:
250 # Pass silently if the sub config is not there. This happens
251 # when a user us using a profile, but not the default config.
252 pass
253 else:
254 self.config._merge(sub_config)
255
256 # Again, this needs to be a closure and should be used in config
257 # files to get the config being loaded.
258 def get_config():
259 return self.config
260
261 namespace = dict(load_subconfig=load_subconfig, get_config=get_config)
262 execfile(self.full_filename, namespace)
263
264 def _convert_to_config(self):
265 if self.data is None:
266 ConfigLoaderError('self.data does not exist')
267
268
269 class CommandLineConfigLoader(ConfigLoader):
270 """A config loader for command line arguments.
271
272 As we add more command line based loaders, the common logic should go
273 here.
274 """
275
276
277 class NoConfigDefault(object): pass
278 NoConfigDefault = NoConfigDefault()
279
280
281 class ArgParseConfigLoader(CommandLineConfigLoader):
282
283 # arguments = [(('-f','--file'),dict(type=str,dest='file'))]
284 arguments = ()
285
286 def __init__(self, *args, **kw):
287 """Create a config loader for use with argparse.
288
289 The args and kwargs arguments here are passed onto the constructor
290 of :class:`argparse.ArgumentParser`.
291 """
292 super(CommandLineConfigLoader, self).__init__()
293 self.args = args
294 self.kw = kw
295
296 def load_config(self, args=None):
297 """Parse command line arguments and return as a Struct."""
298 self._create_parser()
299 self._parse_args(args)
300 self._convert_to_config()
301 return self.config
302
303 def get_extra_args(self):
304 if hasattr(self, 'extra_args'):
305 return self.extra_args
306 else:
307 return []
308
309 def _create_parser(self):
310 self.parser = argparse.ArgumentParser(*self.args, **self.kw)
311 self._add_arguments()
312 self._add_other_arguments()
313
314 def _add_other_arguments(self):
315 pass
316
317 def _add_arguments(self):
318 for argument in self.arguments:
319 if not argument[1].has_key('default'):
320 argument[1]['default'] = NoConfigDefault
321 self.parser.add_argument(*argument[0],**argument[1])
322
323 def _parse_args(self, args=None):
324 """self.parser->self.parsed_data"""
325 if args is None:
326 self.parsed_data, self.extra_args = self.parser.parse_known_args()
327 else:
328 self.parsed_data, self.extra_args = self.parser.parse_known_args(args)
329
330 def _convert_to_config(self):
331 """self.parsed_data->self.config"""
332 for k, v in vars(self.parsed_data).items():
333 if v is not NoConfigDefault:
334 exec_str = 'self.config.' + k + '= v'
335 exec exec_str in locals(), globals()
336
@@ -0,0 +1,24 b''
1 c = get_config()
2
3 # This can be used at any point in a config file to load a sub config
4 # and merge it into the current one.
5 load_subconfig('ipython_config.py')
6
7 lines = """
8 from IPython.kernel.client import *
9 """
10
11 # You have to make sure that attributes that are containers already
12 # exist before using them. Simple assigning a new list will override
13 # all previous values.
14 if hasattr(c.Global, 'exec_lines'):
15 c.Global.exec_lines.append(lines)
16 else:
17 c.Global.exec_lines = [lines]
18
19 # Load the parallelmagic extension to enable %result, %px, %autopx magics.
20 if hasattr(c.Global, 'extensions'):
21 c.Global.extensions.append('parallelmagic')
22 else:
23 c.Global.extensions = ['parallelmagic']
24
@@ -0,0 +1,19 b''
1 c = get_config()
2
3 # This can be used at any point in a config file to load a sub config
4 # and merge it into the current one.
5 load_subconfig('ipython_config.py')
6
7 lines = """
8 import cmath
9 from math import *
10 """
11
12 # You have to make sure that attributes that are containers already
13 # exist before using them. Simple assigning a new list will override
14 # all previous values.
15 if hasattr(c.Global, 'exec_lines'):
16 c.Global.exec_lines.append(lines)
17 else:
18 c.Global.exec_lines = [lines]
19
@@ -0,0 +1,20 b''
1 c = get_config()
2
3 # This can be used at any point in a config file to load a sub config
4 # and merge it into the current one.
5 load_subconfig('ipython_config.py')
6
7 lines = """
8 import numpy
9 import scipy
10 import numpy as np
11 import scipy as sp
12 """
13
14 # You have to make sure that attributes that are containers already
15 # exist before using them. Simple assigning a new list will override
16 # all previous values.
17 if hasattr(c.Global, 'exec_lines'):
18 c.Global.exec_lines.append(lines)
19 else:
20 c.Global.exec_lines = [lines] No newline at end of file
@@ -0,0 +1,22 b''
1 c = get_config()
2
3 # This can be used at any point in a config file to load a sub config
4 # and merge it into the current one.
5 load_subconfig('ipython_config.py')
6
7 lines = """
8 import matplotlib
9 %gui -a wx
10 matplotlib.use('wxagg')
11 matplotlib.interactive(True)
12 from matplotlib import pyplot as plt
13 from matplotlib.pyplot import *
14 """
15
16 # You have to make sure that attributes that are containers already
17 # exist before using them. Simple assigning a new list will override
18 # all previous values.
19 if hasattr(c.Global, 'exec_lines'):
20 c.Global.exec_lines.append(lines)
21 else:
22 c.Global.exec_lines = [lines] No newline at end of file
@@ -0,0 +1,29 b''
1 c = get_config()
2
3 # This can be used at any point in a config file to load a sub config
4 # and merge it into the current one.
5 load_subconfig('ipython_config.py')
6
7 c.InteractiveShell.prompt_in1 = '\C_LightGreen\u@\h\C_LightBlue[\C_LightCyan\Y1\C_LightBlue]\C_Green|\#> '
8 c.InteractiveShell.prompt_in2 = '\C_Green|\C_LightGreen\D\C_Green> '
9 c.InteractiveShell.prompt_out = '<\#> '
10
11 c.InteractiveShell.prompts_pad_left = True
12
13 c.InteractiveShell.separate_in = ''
14 c.InteractiveShell.separate_out = ''
15 c.InteractiveShell.separate_out2 = ''
16
17 c.PrefilterManager.multi_line_specials = True
18
19 lines = """
20 %rehashx
21 """
22
23 # You have to make sure that attributes that are containers already
24 # exist before using them. Simple assigning a new list will override
25 # all previous values.
26 if hasattr(c.Global, 'exec_lines'):
27 c.Global.exec_lines.append(lines)
28 else:
29 c.Global.exec_lines = [lines] No newline at end of file
@@ -0,0 +1,21 b''
1 c = get_config()
2
3 # This can be used at any point in a config file to load a sub config
4 # and merge it into the current one.
5 load_subconfig('ipython_config.py')
6
7 lines = """
8 from __future__ import division
9 from sympy import *
10 x, y, z = symbols('xyz')
11 k, m, n = symbols('kmn', integer=True)
12 f, g, h = map(Function, 'fgh')
13 """
14
15 # You have to make sure that attributes that are containers already
16 # exist before using them. Simple assigning a new list will override
17 # all previous values.
18 if hasattr(c.Global, 'exec_lines'):
19 c.Global.exec_lines.append(lines)
20 else:
21 c.Global.exec_lines = [lines]
@@ -0,0 +1,5 b''
1 #!/usr/bin/env python
2 # encoding: utf-8
3
4
5
@@ -0,0 +1,163 b''
1 #!/usr/bin/env python
2 # encoding: utf-8
3 """
4 Tests for IPython.config.loader
5
6 Authors:
7
8 * Brian Granger
9 * Fernando Perez (design help)
10 """
11
12 #-----------------------------------------------------------------------------
13 # Copyright (C) 2008-2009 The IPython Development Team
14 #
15 # Distributed under the terms of the BSD License. The full license is in
16 # the file COPYING, distributed as part of this software.
17 #-----------------------------------------------------------------------------
18
19 #-----------------------------------------------------------------------------
20 # Imports
21 #-----------------------------------------------------------------------------
22
23 import os
24 from tempfile import mkstemp
25 from unittest import TestCase
26
27 from IPython.config.loader import (
28 Config,
29 PyFileConfigLoader,
30 ArgParseConfigLoader,
31 ConfigError
32 )
33
34 #-----------------------------------------------------------------------------
35 # Actual tests
36 #-----------------------------------------------------------------------------
37
38
39 pyfile = """
40 a = 10
41 b = 20
42 Foo.Bar.value = 10
43 Foo.Bam.value = range(10)
44 D.C.value = 'hi there'
45 """
46
47 class TestPyFileCL(TestCase):
48
49 def test_basic(self):
50 fd, fname = mkstemp()
51 f = os.fdopen(fd, 'w')
52 f.write(pyfile)
53 f.close()
54 # Unlink the file
55 cl = PyFileConfigLoader(fname)
56 config = cl.load_config()
57 self.assertEquals(config.a, 10)
58 self.assertEquals(config.b, 20)
59 self.assertEquals(config.Foo.Bar.value, 10)
60 self.assertEquals(config.Foo.Bam.value, range(10))
61 self.assertEquals(config.D.C.value, 'hi there')
62
63
64 class TestArgParseCL(TestCase):
65
66 def test_basic(self):
67
68 class MyLoader(ArgParseConfigLoader):
69 arguments = (
70 (('-f','--foo'), dict(dest='Global.foo', type=str)),
71 (('-b',), dict(dest='MyClass.bar', type=int)),
72 (('-n',), dict(dest='n', action='store_true')),
73 (('Global.bam',), dict(type=str))
74 )
75
76 cl = MyLoader()
77 config = cl.load_config('-f hi -b 10 -n wow'.split())
78 self.assertEquals(config.Global.foo, 'hi')
79 self.assertEquals(config.MyClass.bar, 10)
80 self.assertEquals(config.n, True)
81 self.assertEquals(config.Global.bam, 'wow')
82
83 def test_add_arguments(self):
84
85 class MyLoader(ArgParseConfigLoader):
86 def _add_arguments(self):
87 subparsers = self.parser.add_subparsers(dest='subparser_name')
88 subparser1 = subparsers.add_parser('1')
89 subparser1.add_argument('-x',dest='Global.x')
90 subparser2 = subparsers.add_parser('2')
91 subparser2.add_argument('y')
92
93 cl = MyLoader()
94 config = cl.load_config('2 frobble'.split())
95 self.assertEquals(config.subparser_name, '2')
96 self.assertEquals(config.y, 'frobble')
97 config = cl.load_config('1 -x frobble'.split())
98 self.assertEquals(config.subparser_name, '1')
99 self.assertEquals(config.Global.x, 'frobble')
100
101 class TestConfig(TestCase):
102
103 def test_setget(self):
104 c = Config()
105 c.a = 10
106 self.assertEquals(c.a, 10)
107 self.assertEquals(c.has_key('b'), False)
108
109 def test_auto_section(self):
110 c = Config()
111 self.assertEquals(c.has_key('A'), True)
112 self.assertEquals(c._has_section('A'), False)
113 A = c.A
114 A.foo = 'hi there'
115 self.assertEquals(c._has_section('A'), True)
116 self.assertEquals(c.A.foo, 'hi there')
117 del c.A
118 self.assertEquals(len(c.A.keys()),0)
119
120 def test_merge_doesnt_exist(self):
121 c1 = Config()
122 c2 = Config()
123 c2.bar = 10
124 c2.Foo.bar = 10
125 c1._merge(c2)
126 self.assertEquals(c1.Foo.bar, 10)
127 self.assertEquals(c1.bar, 10)
128 c2.Bar.bar = 10
129 c1._merge(c2)
130 self.assertEquals(c1.Bar.bar, 10)
131
132 def test_merge_exists(self):
133 c1 = Config()
134 c2 = Config()
135 c1.Foo.bar = 10
136 c1.Foo.bam = 30
137 c2.Foo.bar = 20
138 c2.Foo.wow = 40
139 c1._merge(c2)
140 self.assertEquals(c1.Foo.bam, 30)
141 self.assertEquals(c1.Foo.bar, 20)
142 self.assertEquals(c1.Foo.wow, 40)
143 c2.Foo.Bam.bam = 10
144 c1._merge(c2)
145 self.assertEquals(c1.Foo.Bam.bam, 10)
146
147 def test_deepcopy(self):
148 c1 = Config()
149 c1.Foo.bar = 10
150 c1.Foo.bam = 30
151 c1.a = 'asdf'
152 c1.b = range(10)
153 import copy
154 c2 = copy.deepcopy(c1)
155 self.assertEquals(c1, c2)
156 self.assert_(c1 is not c2)
157 self.assert_(c1.Foo is not c2.Foo)
158
159 def test_builtin(self):
160 c1 = Config()
161 exec 'foo = True' in c1
162 self.assertEquals(c1.foo, True)
163 self.assertRaises(ConfigError, setattr, c1, 'ValueError', 10)
@@ -0,0 +1,262 b''
1 #!/usr/bin/env python
2 # encoding: utf-8
3 """
4 IPython's alias component
5
6 Authors:
7
8 * Brian Granger
9 """
10
11 #-----------------------------------------------------------------------------
12 # Copyright (C) 2008-2009 The IPython Development Team
13 #
14 # Distributed under the terms of the BSD License. The full license is in
15 # the file COPYING, distributed as part of this software.
16 #-----------------------------------------------------------------------------
17
18 #-----------------------------------------------------------------------------
19 # Imports
20 #-----------------------------------------------------------------------------
21
22 import __builtin__
23 import keyword
24 import os
25 import re
26 import sys
27
28 from IPython.core.component import Component
29 from IPython.core.splitinput import split_user_input
30
31 from IPython.utils.traitlets import CBool, List, Instance
32 from IPython.utils.genutils import error
33 from IPython.utils.autoattr import auto_attr
34
35 #-----------------------------------------------------------------------------
36 # Utilities
37 #-----------------------------------------------------------------------------
38
39 # This is used as the pattern for calls to split_user_input.
40 shell_line_split = re.compile(r'^(\s*)(\S*\s*)(.*$)')
41
42 def default_aliases():
43 # Make some aliases automatically
44 # Prepare list of shell aliases to auto-define
45 if os.name == 'posix':
46 default_aliases = ('mkdir mkdir', 'rmdir rmdir',
47 'mv mv -i','rm rm -i','cp cp -i',
48 'cat cat','less less','clear clear',
49 # a better ls
50 'ls ls -F',
51 # long ls
52 'll ls -lF')
53 # Extra ls aliases with color, which need special treatment on BSD
54 # variants
55 ls_extra = ( # color ls
56 'lc ls -F -o --color',
57 # ls normal files only
58 'lf ls -F -o --color %l | grep ^-',
59 # ls symbolic links
60 'lk ls -F -o --color %l | grep ^l',
61 # directories or links to directories,
62 'ldir ls -F -o --color %l | grep /$',
63 # things which are executable
64 'lx ls -F -o --color %l | grep ^-..x',
65 )
66 # The BSDs don't ship GNU ls, so they don't understand the
67 # --color switch out of the box
68 if 'bsd' in sys.platform:
69 ls_extra = ( # ls normal files only
70 'lf ls -lF | grep ^-',
71 # ls symbolic links
72 'lk ls -lF | grep ^l',
73 # directories or links to directories,
74 'ldir ls -lF | grep /$',
75 # things which are executable
76 'lx ls -lF | grep ^-..x',
77 )
78 default_aliases = default_aliases + ls_extra
79 elif os.name in ['nt','dos']:
80 default_aliases = ('ls dir /on',
81 'ddir dir /ad /on', 'ldir dir /ad /on',
82 'mkdir mkdir','rmdir rmdir','echo echo',
83 'ren ren','cls cls','copy copy')
84 else:
85 default_aliases = ()
86 return [s.split(None,1) for s in default_aliases]
87
88
89 class AliasError(Exception):
90 pass
91
92
93 class InvalidAliasError(AliasError):
94 pass
95
96
97 #-----------------------------------------------------------------------------
98 # Main AliasManager class
99 #-----------------------------------------------------------------------------
100
101
102 class AliasManager(Component):
103
104 default_aliases = List(default_aliases(), config=True)
105 user_aliases = List(default_value=[], config=True)
106
107 def __init__(self, parent, config=None):
108 super(AliasManager, self).__init__(parent, config=config)
109 self.alias_table = {}
110 self.exclude_aliases()
111 self.init_aliases()
112
113 @auto_attr
114 def shell(self):
115 return Component.get_instances(
116 root=self.root,
117 klass='IPython.core.iplib.InteractiveShell')[0]
118
119 def __contains__(self, name):
120 if name in self.alias_table:
121 return True
122 else:
123 return False
124
125 @property
126 def aliases(self):
127 return [(item[0], item[1][1]) for item in self.alias_table.iteritems()]
128
129 def exclude_aliases(self):
130 # set of things NOT to alias (keywords, builtins and some magics)
131 no_alias = set(['cd','popd','pushd','dhist','alias','unalias'])
132 no_alias.update(set(keyword.kwlist))
133 no_alias.update(set(__builtin__.__dict__.keys()))
134 self.no_alias = no_alias
135
136 def init_aliases(self):
137 # Load default aliases
138 for name, cmd in self.default_aliases:
139 self.soft_define_alias(name, cmd)
140
141 # Load user aliases
142 for name, cmd in self.user_aliases:
143 self.soft_define_alias(name, cmd)
144
145 def clear_aliases(self):
146 self.alias_table.clear()
147
148 def soft_define_alias(self, name, cmd):
149 """Define an alias, but don't raise on an AliasError."""
150 try:
151 self.define_alias(name, cmd)
152 except AliasError, e:
153 error("Invalid alias: %s" % e)
154
155 def define_alias(self, name, cmd):
156 """Define a new alias after validating it.
157
158 This will raise an :exc:`AliasError` if there are validation
159 problems.
160 """
161 nargs = self.validate_alias(name, cmd)
162 self.alias_table[name] = (nargs, cmd)
163
164 def undefine_alias(self, name):
165 if self.alias_table.has_key(name):
166 del self.alias_table[name]
167
168 def validate_alias(self, name, cmd):
169 """Validate an alias and return the its number of arguments."""
170 if name in self.no_alias:
171 raise InvalidAliasError("The name %s can't be aliased "
172 "because it is a keyword or builtin." % name)
173 if not (isinstance(cmd, basestring)):
174 raise InvalidAliasError("An alias command must be a string, "
175 "got: %r" % name)
176 nargs = cmd.count('%s')
177 if nargs>0 and cmd.find('%l')>=0:
178 raise InvalidAliasError('The %s and %l specifiers are mutually '
179 'exclusive in alias definitions.')
180 return nargs
181
182 def call_alias(self, alias, rest=''):
183 """Call an alias given its name and the rest of the line."""
184 cmd = self.transform_alias(alias, rest)
185 try:
186 self.shell.system(cmd)
187 except:
188 self.shell.showtraceback()
189
190 def transform_alias(self, alias,rest=''):
191 """Transform alias to system command string."""
192 nargs, cmd = self.alias_table[alias]
193
194 if ' ' in cmd and os.path.isfile(cmd):
195 cmd = '"%s"' % cmd
196
197 # Expand the %l special to be the user's input line
198 if cmd.find('%l') >= 0:
199 cmd = cmd.replace('%l', rest)
200 rest = ''
201 if nargs==0:
202 # Simple, argument-less aliases
203 cmd = '%s %s' % (cmd, rest)
204 else:
205 # Handle aliases with positional arguments
206 args = rest.split(None, nargs)
207 if len(args) < nargs:
208 raise AliasError('Alias <%s> requires %s arguments, %s given.' %
209 (alias, nargs, len(args)))
210 cmd = '%s %s' % (cmd % tuple(args[:nargs]),' '.join(args[nargs:]))
211 return cmd
212
213 def expand_alias(self, line):
214 """ Expand an alias in the command line
215
216 Returns the provided command line, possibly with the first word
217 (command) translated according to alias expansion rules.
218
219 [ipython]|16> _ip.expand_aliases("np myfile.txt")
220 <16> 'q:/opt/np/notepad++.exe myfile.txt'
221 """
222
223 pre,fn,rest = split_user_input(line)
224 res = pre + self.expand_aliases(fn, rest)
225 return res
226
227 def expand_aliases(self, fn, rest):
228 """Expand multiple levels of aliases:
229
230 if:
231
232 alias foo bar /tmp
233 alias baz foo
234
235 then:
236
237 baz huhhahhei -> bar /tmp huhhahhei
238
239 """
240 line = fn + " " + rest
241
242 done = set()
243 while 1:
244 pre,fn,rest = split_user_input(line, shell_line_split)
245 if fn in self.alias_table:
246 if fn in done:
247 warn("Cyclic alias definition, repeated '%s'" % fn)
248 return ""
249 done.add(fn)
250
251 l2 = self.transform_alias(fn, rest)
252 if l2 == line:
253 break
254 # ls -> ls -F should not recurse forever
255 if l2.split(None,1)[0] == line.split(None,1)[0]:
256 line = l2
257 break
258 line=l2
259 else:
260 break
261
262 return line
@@ -0,0 +1,364 b''
1 #!/usr/bin/env python
2 # encoding: utf-8
3 """
4 An application for IPython.
5
6 All top-level applications should use the classes in this module for
7 handling configuration and creating componenets.
8
9 The job of an :class:`Application` is to create the master configuration
10 object and then create the components, passing the config to them.
11
12 Authors:
13
14 * Brian Granger
15 * Fernando Perez
16
17 Notes
18 -----
19 """
20
21 #-----------------------------------------------------------------------------
22 # Copyright (C) 2008-2009 The IPython Development Team
23 #
24 # Distributed under the terms of the BSD License. The full license is in
25 # the file COPYING, distributed as part of this software.
26 #-----------------------------------------------------------------------------
27
28 #-----------------------------------------------------------------------------
29 # Imports
30 #-----------------------------------------------------------------------------
31
32 import logging
33 import os
34 import sys
35
36 from IPython.core import release
37 from IPython.utils.genutils import get_ipython_dir
38 from IPython.config.loader import (
39 PyFileConfigLoader,
40 ArgParseConfigLoader,
41 Config,
42 NoConfigDefault
43 )
44
45 #-----------------------------------------------------------------------------
46 # Classes and functions
47 #-----------------------------------------------------------------------------
48
49
50 class BaseAppArgParseConfigLoader(ArgParseConfigLoader):
51 """Default command line options for IPython based applications."""
52
53 def _add_other_arguments(self):
54 self.parser.add_argument('--ipython-dir',
55 dest='Global.ipython_dir',type=unicode,
56 help='Set to override default location of Global.ipython_dir.',
57 default=NoConfigDefault,
58 metavar='Global.ipython_dir')
59 self.parser.add_argument('-p', '--profile',
60 dest='Global.profile',type=unicode,
61 help='The string name of the ipython profile to be used.',
62 default=NoConfigDefault,
63 metavar='Global.profile')
64 self.parser.add_argument('--log-level',
65 dest="Global.log_level",type=int,
66 help='Set the log level (0,10,20,30,40,50). Default is 30.',
67 default=NoConfigDefault,
68 metavar='Global.log_level')
69 self.parser.add_argument('--config-file',
70 dest='Global.config_file',type=unicode,
71 help='Set the config file name to override default.',
72 default=NoConfigDefault,
73 metavar='Global.config_file')
74
75
76 class ApplicationError(Exception):
77 pass
78
79
80 class Application(object):
81 """Load a config, construct components and set them running."""
82
83 name = u'ipython'
84 description = 'IPython: an enhanced interactive Python shell.'
85 config_file_name = u'ipython_config.py'
86 default_log_level = logging.WARN
87
88 def __init__(self):
89 self._exiting = False
90 self.init_logger()
91 # Track the default and actual separately because some messages are
92 # only printed if we aren't using the default.
93 self.default_config_file_name = self.config_file_name
94
95 def init_logger(self):
96 self.log = logging.getLogger(self.__class__.__name__)
97 # This is used as the default until the command line arguments are read.
98 self.log.setLevel(self.default_log_level)
99 self._log_handler = logging.StreamHandler()
100 self._log_formatter = logging.Formatter("[%(name)s] %(message)s")
101 self._log_handler.setFormatter(self._log_formatter)
102 self.log.addHandler(self._log_handler)
103
104 def _set_log_level(self, level):
105 self.log.setLevel(level)
106
107 def _get_log_level(self):
108 return self.log.level
109
110 log_level = property(_get_log_level, _set_log_level)
111
112 def start(self):
113 """Start the application."""
114 self.attempt(self.create_default_config)
115 self.log_default_config()
116 self.set_default_config_log_level()
117 self.attempt(self.pre_load_command_line_config)
118 self.attempt(self.load_command_line_config, action='abort')
119 self.set_command_line_config_log_level()
120 self.attempt(self.post_load_command_line_config)
121 self.log_command_line_config()
122 self.attempt(self.find_ipython_dir)
123 self.attempt(self.find_resources)
124 self.attempt(self.find_config_file_name)
125 self.attempt(self.find_config_file_paths)
126 self.attempt(self.pre_load_file_config)
127 self.attempt(self.load_file_config)
128 self.set_file_config_log_level()
129 self.attempt(self.post_load_file_config)
130 self.log_file_config()
131 self.attempt(self.merge_configs)
132 self.log_master_config()
133 self.attempt(self.pre_construct)
134 self.attempt(self.construct)
135 self.attempt(self.post_construct)
136 self.attempt(self.start_app)
137
138 #-------------------------------------------------------------------------
139 # Various stages of Application creation
140 #-------------------------------------------------------------------------
141
142 def create_default_config(self):
143 """Create defaults that can't be set elsewhere.
144
145 For the most part, we try to set default in the class attributes
146 of Components. But, defaults the top-level Application (which is
147 not a HasTraitlets or Component) are not set in this way. Instead
148 we set them here. The Global section is for variables like this that
149 don't belong to a particular component.
150 """
151 self.default_config = Config()
152 self.default_config.Global.ipython_dir = get_ipython_dir()
153 self.default_config.Global.log_level = self.log_level
154
155 def log_default_config(self):
156 self.log.debug('Default config loaded:')
157 self.log.debug(repr(self.default_config))
158
159 def set_default_config_log_level(self):
160 try:
161 self.log_level = self.default_config.Global.log_level
162 except AttributeError:
163 # Fallback to the default_log_level class attribute
164 pass
165
166 def create_command_line_config(self):
167 """Create and return a command line config loader."""
168 return BaseAppArgParseConfigLoader(
169 description=self.description,
170 version=release.version
171 )
172
173 def pre_load_command_line_config(self):
174 """Do actions just before loading the command line config."""
175 pass
176
177 def load_command_line_config(self):
178 """Load the command line config."""
179 loader = self.create_command_line_config()
180 self.command_line_config = loader.load_config()
181 self.extra_args = loader.get_extra_args()
182
183 def set_command_line_config_log_level(self):
184 try:
185 self.log_level = self.command_line_config.Global.log_level
186 except AttributeError:
187 pass
188
189 def post_load_command_line_config(self):
190 """Do actions just after loading the command line config."""
191 pass
192
193 def log_command_line_config(self):
194 self.log.debug("Command line config loaded:")
195 self.log.debug(repr(self.command_line_config))
196
197 def find_ipython_dir(self):
198 """Set the IPython directory.
199
200 This sets ``self.ipython_dir``, but the actual value that is passed
201 to the application is kept in either ``self.default_config`` or
202 ``self.command_line_config``. This also adds ``self.ipython_dir`` to
203 ``sys.path`` so config files there can be references by other config
204 files.
205 """
206
207 try:
208 self.ipython_dir = self.command_line_config.Global.ipython_dir
209 except AttributeError:
210 self.ipython_dir = self.default_config.Global.ipython_dir
211 sys.path.append(os.path.abspath(self.ipython_dir))
212 if not os.path.isdir(self.ipython_dir):
213 os.makedirs(self.ipython_dir, mode=0777)
214 self.log.debug("IPYTHON_DIR set to: %s" % self.ipython_dir)
215
216 def find_resources(self):
217 """Find other resources that need to be in place.
218
219 Things like cluster directories need to be in place to find the
220 config file. These happen right after the IPython directory has
221 been set.
222 """
223 pass
224
225 def find_config_file_name(self):
226 """Find the config file name for this application.
227
228 This must set ``self.config_file_name`` to the filename of the
229 config file to use (just the filename). The search paths for the
230 config file are set in :meth:`find_config_file_paths` and then passed
231 to the config file loader where they are resolved to an absolute path.
232
233 If a profile has been set at the command line, this will resolve
234 it.
235 """
236
237 try:
238 self.config_file_name = self.command_line_config.Global.config_file
239 except AttributeError:
240 pass
241
242 try:
243 self.profile_name = self.command_line_config.Global.profile
244 name_parts = self.config_file_name.split('.')
245 name_parts.insert(1, u'_' + self.profile_name + u'.')
246 self.config_file_name = ''.join(name_parts)
247 except AttributeError:
248 pass
249
250 def find_config_file_paths(self):
251 """Set the search paths for resolving the config file.
252
253 This must set ``self.config_file_paths`` to a sequence of search
254 paths to pass to the config file loader.
255 """
256 self.config_file_paths = (os.getcwd(), self.ipython_dir)
257
258 def pre_load_file_config(self):
259 """Do actions before the config file is loaded."""
260 pass
261
262 def load_file_config(self):
263 """Load the config file.
264
265 This tries to load the config file from disk. If successful, the
266 ``CONFIG_FILE`` config variable is set to the resolved config file
267 location. If not successful, an empty config is used.
268 """
269 self.log.debug("Attempting to load config file: %s" % self.config_file_name)
270 loader = PyFileConfigLoader(self.config_file_name,
271 path=self.config_file_paths)
272 try:
273 self.file_config = loader.load_config()
274 self.file_config.Global.config_file = loader.full_filename
275 except IOError:
276 # Only warn if the default config file was NOT being used.
277 if not self.config_file_name==self.default_config_file_name:
278 self.log.warn("Config file not found, skipping: %s" % \
279 self.config_file_name, exc_info=True)
280 self.file_config = Config()
281 except:
282 self.log.warn("Error loading config file: %s" % \
283 self.config_file_name, exc_info=True)
284 self.file_config = Config()
285
286 def set_file_config_log_level(self):
287 # We need to keeep self.log_level updated. But we only use the value
288 # of the file_config if a value was not specified at the command
289 # line, because the command line overrides everything.
290 if not hasattr(self.command_line_config.Global, 'log_level'):
291 try:
292 self.log_level = self.file_config.Global.log_level
293 except AttributeError:
294 pass # Use existing value
295
296 def post_load_file_config(self):
297 """Do actions after the config file is loaded."""
298 pass
299
300 def log_file_config(self):
301 if hasattr(self.file_config.Global, 'config_file'):
302 self.log.debug("Config file loaded: %s" % self.file_config.Global.config_file)
303 self.log.debug(repr(self.file_config))
304
305 def merge_configs(self):
306 """Merge the default, command line and file config objects."""
307 config = Config()
308 config._merge(self.default_config)
309 config._merge(self.file_config)
310 config._merge(self.command_line_config)
311 self.master_config = config
312
313 def log_master_config(self):
314 self.log.debug("Master config created:")
315 self.log.debug(repr(self.master_config))
316
317 def pre_construct(self):
318 """Do actions after the config has been built, but before construct."""
319 pass
320
321 def construct(self):
322 """Construct the main components that make up this app."""
323 self.log.debug("Constructing components for application")
324
325 def post_construct(self):
326 """Do actions after construct, but before starting the app."""
327 pass
328
329 def start_app(self):
330 """Actually start the app."""
331 self.log.debug("Starting application")
332
333 #-------------------------------------------------------------------------
334 # Utility methods
335 #-------------------------------------------------------------------------
336
337 def abort(self):
338 """Abort the starting of the application."""
339 if self._exiting:
340 pass
341 else:
342 self.log.critical("Aborting application: %s" % self.name, exc_info=True)
343 self._exiting = True
344 sys.exit(1)
345
346 def exit(self, exit_status=0):
347 if self._exiting:
348 pass
349 else:
350 self.log.debug("Exiting application: %s" % self.name)
351 self._exiting = True
352 sys.exit(exit_status)
353
354 def attempt(self, func, action='abort'):
355 try:
356 func()
357 except SystemExit:
358 raise
359 except:
360 if action == 'abort':
361 self.abort()
362 elif action == 'exit':
363 self.exit(0)
364
@@ -0,0 +1,45 b''
1 #!/usr/bin/env python
2 # encoding: utf-8
3 """
4 Autocall capabilities for IPython.core.
5
6 Authors:
7
8 * Brian Granger
9 * Fernando Perez
10
11 Notes
12 -----
13 """
14
15 #-----------------------------------------------------------------------------
16 # Copyright (C) 2008-2009 The IPython Development Team
17 #
18 # Distributed under the terms of the BSD License. The full license is in
19 # the file COPYING, distributed as part of this software.
20 #-----------------------------------------------------------------------------
21
22 #-----------------------------------------------------------------------------
23 # Imports
24 #-----------------------------------------------------------------------------
25
26
27 #-----------------------------------------------------------------------------
28 # Code
29 #-----------------------------------------------------------------------------
30
31 class IPyAutocall(object):
32 """ Instances of this class are always autocalled
33
34 This happens regardless of 'autocall' variable state. Use this to
35 develop macro-like mechanisms.
36 """
37
38 def set_ip(self,ip):
39 """ Will be used to set _ip point to current ipython instance b/f call
40
41 Override this method if you don't want this to happen.
42
43 """
44 self._ip = ip
45
@@ -0,0 +1,118 b''
1 #!/usr/bin/env python
2 # encoding: utf-8
3 """
4 A context manager for managing things injected into :mod:`__builtin__`.
5
6 Authors:
7
8 * Brian Granger
9 """
10
11 #-----------------------------------------------------------------------------
12 # Copyright (C) 2008-2009 The IPython Development Team
13 #
14 # Distributed under the terms of the BSD License. The full license is in
15 # the file COPYING, distributed as part of this software.
16 #-----------------------------------------------------------------------------
17
18 #-----------------------------------------------------------------------------
19 # Imports
20 #-----------------------------------------------------------------------------
21
22 import __builtin__
23
24 from IPython.core.component import Component
25 from IPython.core.quitter import Quitter
26
27 from IPython.utils.autoattr import auto_attr
28
29 #-----------------------------------------------------------------------------
30 # Classes and functions
31 #-----------------------------------------------------------------------------
32
33
34 class BuiltinUndefined(object): pass
35 BuiltinUndefined = BuiltinUndefined()
36
37
38 class BuiltinTrap(Component):
39
40 def __init__(self, parent):
41 super(BuiltinTrap, self).__init__(parent, None, None)
42 self._orig_builtins = {}
43 # We define this to track if a single BuiltinTrap is nested.
44 # Only turn off the trap when the outermost call to __exit__ is made.
45 self._nested_level = 0
46
47 @auto_attr
48 def shell(self):
49 return Component.get_instances(
50 root=self.root,
51 klass='IPython.core.iplib.InteractiveShell')[0]
52
53 def __enter__(self):
54 if self._nested_level == 0:
55 self.set()
56 self._nested_level += 1
57 # I return self, so callers can use add_builtin in a with clause.
58 return self
59
60 def __exit__(self, type, value, traceback):
61 if self._nested_level == 1:
62 self.unset()
63 self._nested_level -= 1
64 # Returning False will cause exceptions to propagate
65 return False
66
67 def add_builtin(self, key, value):
68 """Add a builtin and save the original."""
69 orig = __builtin__.__dict__.get(key, BuiltinUndefined)
70 self._orig_builtins[key] = orig
71 __builtin__.__dict__[key] = value
72
73 def remove_builtin(self, key):
74 """Remove an added builtin and re-set the original."""
75 try:
76 orig = self._orig_builtins.pop(key)
77 except KeyError:
78 pass
79 else:
80 if orig is BuiltinUndefined:
81 del __builtin__.__dict__[key]
82 else:
83 __builtin__.__dict__[key] = orig
84
85 def set(self):
86 """Store ipython references in the __builtin__ namespace."""
87 self.add_builtin('exit', Quitter(self.shell, 'exit'))
88 self.add_builtin('quit', Quitter(self.shell, 'quit'))
89 self.add_builtin('get_ipython', self.shell.get_ipython)
90
91 # Recursive reload function
92 try:
93 from IPython.lib import deepreload
94 if self.shell.deep_reload:
95 self.add_builtin('reload', deepreload.reload)
96 else:
97 self.add_builtin('dreload', deepreload.reload)
98 del deepreload
99 except ImportError:
100 pass
101
102 # Keep in the builtins a flag for when IPython is active. We set it
103 # with setdefault so that multiple nested IPythons don't clobber one
104 # another. Each will increase its value by one upon being activated,
105 # which also gives us a way to determine the nesting level.
106 __builtin__.__dict__.setdefault('__IPYTHON__active',0)
107
108 def unset(self):
109 """Remove any builtins which might have been added by add_builtins, or
110 restore overwritten ones to their previous values."""
111 for key in self._orig_builtins.keys():
112 self.remove_builtin(key)
113 self._orig_builtins.clear()
114 self._builtins_added = False
115 try:
116 del __builtin__.__dict__['__IPYTHON__active']
117 except KeyError:
118 pass
@@ -0,0 +1,346 b''
1 #!/usr/bin/env python
2 # encoding: utf-8
3 """
4 A lightweight component system for IPython.
5
6 Authors:
7
8 * Brian Granger
9 * Fernando Perez
10 """
11
12 #-----------------------------------------------------------------------------
13 # Copyright (C) 2008-2009 The IPython Development Team
14 #
15 # Distributed under the terms of the BSD License. The full license is in
16 # the file COPYING, distributed as part of this software.
17 #-----------------------------------------------------------------------------
18
19 #-----------------------------------------------------------------------------
20 # Imports
21 #-----------------------------------------------------------------------------
22
23 from copy import deepcopy
24 import datetime
25 from weakref import WeakValueDictionary
26
27 from IPython.utils.importstring import import_item
28 from IPython.config.loader import Config
29 from IPython.utils.traitlets import (
30 HasTraitlets, TraitletError, MetaHasTraitlets, Instance, This
31 )
32
33
34 #-----------------------------------------------------------------------------
35 # Helper classes for Components
36 #-----------------------------------------------------------------------------
37
38
39 class ComponentError(Exception):
40 pass
41
42 class MetaComponentTracker(type):
43 """A metaclass that tracks instances of Components and its subclasses."""
44
45 def __init__(cls, name, bases, d):
46 super(MetaComponentTracker, cls).__init__(name, bases, d)
47 cls.__instance_refs = WeakValueDictionary()
48 cls.__numcreated = 0
49
50 def __call__(cls, *args, **kw):
51 """Called when a class is called (instantiated)!!!
52
53 When a Component or subclass is instantiated, this is called and
54 the instance is saved in a WeakValueDictionary for tracking.
55 """
56 instance = cls.__new__(cls, *args, **kw)
57
58 # Register the instance before __init__ is called so get_instances
59 # works inside __init__ methods!
60 indices = cls.register_instance(instance)
61
62 # This is in a try/except because of the __init__ method fails, the
63 # instance is discarded and shouldn't be tracked.
64 try:
65 if isinstance(instance, cls):
66 cls.__init__(instance, *args, **kw)
67 except:
68 # Unregister the instance because __init__ failed!
69 cls.unregister_instances(indices)
70 raise
71 else:
72 return instance
73
74 def register_instance(cls, instance):
75 """Register instance with cls and its subclasses."""
76 # indices is a list of the keys used to register the instance
77 # with. This list is needed if the instance needs to be unregistered.
78 indices = []
79 for c in cls.__mro__:
80 if issubclass(cls, c) and issubclass(c, Component):
81 c.__numcreated += 1
82 indices.append(c.__numcreated)
83 c.__instance_refs[c.__numcreated] = instance
84 else:
85 break
86 return indices
87
88 def unregister_instances(cls, indices):
89 """Unregister instance with cls and its subclasses."""
90 for c, index in zip(cls.__mro__, indices):
91 try:
92 del c.__instance_refs[index]
93 except KeyError:
94 pass
95
96 def clear_instances(cls):
97 """Clear all instances tracked by cls."""
98 cls.__instance_refs.clear()
99 cls.__numcreated = 0
100
101 def get_instances(cls, name=None, root=None, klass=None):
102 """Get all instances of cls and its subclasses.
103
104 Parameters
105 ----------
106 name : str
107 Limit to components with this name.
108 root : Component or subclass
109 Limit to components having this root.
110 klass : class or str
111 Limits to instances of the class or its subclasses. If a str
112 is given ut must be in the form 'foo.bar.MyClass'. The str
113 form of this argument is useful for forward declarations.
114 """
115 if klass is not None:
116 if isinstance(klass, basestring):
117 klass = import_item(klass)
118 # Limit search to instances of klass for performance
119 if issubclass(klass, Component):
120 return klass.get_instances(name=name, root=root)
121 instances = cls.__instance_refs.values()
122 if name is not None:
123 instances = [i for i in instances if i.name == name]
124 if klass is not None:
125 instances = [i for i in instances if isinstance(i, klass)]
126 if root is not None:
127 instances = [i for i in instances if i.root == root]
128 return instances
129
130 def get_instances_by_condition(cls, call, name=None, root=None,
131 klass=None):
132 """Get all instances of cls, i such that call(i)==True.
133
134 This also takes the ``name`` and ``root`` and ``classname``
135 arguments of :meth:`get_instance`
136 """
137 return [i for i in cls.get_instances(name, root, klass) if call(i)]
138
139
140 def masquerade_as(instance, cls):
141 """Let instance masquerade as an instance of cls.
142
143 Sometimes, such as in testing code, it is useful to let a class
144 masquerade as another. Python, being duck typed, allows this by
145 default. But, instances of components are tracked by their class type.
146
147 After calling this, ``cls.get_instances()`` will return ``instance``. This
148 does not, however, cause ``isinstance(instance, cls)`` to return ``True``.
149
150 Parameters
151 ----------
152 instance : an instance of a Component or Component subclass
153 The instance that will pretend to be a cls.
154 cls : subclass of Component
155 The Component subclass that instance will pretend to be.
156 """
157 cls.register_instance(instance)
158
159
160 class ComponentNameGenerator(object):
161 """A Singleton to generate unique component names."""
162
163 def __init__(self, prefix):
164 self.prefix = prefix
165 self.i = 0
166
167 def __call__(self):
168 count = self.i
169 self.i += 1
170 return "%s%s" % (self.prefix, count)
171
172
173 ComponentNameGenerator = ComponentNameGenerator('ipython.component')
174
175
176 class MetaComponent(MetaHasTraitlets, MetaComponentTracker):
177 pass
178
179
180 #-----------------------------------------------------------------------------
181 # Component implementation
182 #-----------------------------------------------------------------------------
183
184
185 class Component(HasTraitlets):
186
187 __metaclass__ = MetaComponent
188
189 # Traitlets are fun!
190 config = Instance(Config,(),{})
191 parent = This()
192 root = This()
193 created = None
194
195 def __init__(self, parent, name=None, config=None):
196 """Create a component given a parent and possibly and name and config.
197
198 Parameters
199 ----------
200 parent : Component subclass
201 The parent in the component graph. The parent is used
202 to get the root of the component graph.
203 name : str
204 The unique name of the component. If empty, then a unique
205 one will be autogenerated.
206 config : Config
207 If this is empty, self.config = parent.config, otherwise
208 self.config = config and root.config is ignored. This argument
209 should only be used to *override* the automatic inheritance of
210 parent.config. If a caller wants to modify parent.config
211 (not override), the caller should make a copy and change
212 attributes and then pass the copy to this argument.
213
214 Notes
215 -----
216 Subclasses of Component must call the :meth:`__init__` method of
217 :class:`Component` *before* doing anything else and using
218 :func:`super`::
219
220 class MyComponent(Component):
221 def __init__(self, parent, name=None, config=None):
222 super(MyComponent, self).__init__(parent, name, config)
223 # Then any other code you need to finish initialization.
224
225 This ensures that the :attr:`parent`, :attr:`name` and :attr:`config`
226 attributes are handled properly.
227 """
228 super(Component, self).__init__()
229 self._children = []
230 if name is None:
231 self.name = ComponentNameGenerator()
232 else:
233 self.name = name
234 self.root = self # This is the default, it is set when parent is set
235 self.parent = parent
236 if config is not None:
237 self.config = config
238 # We used to deepcopy, but for now we are trying to just save
239 # by reference. This *could* have side effects as all components
240 # will share config. In fact, I did find such a side effect in
241 # _config_changed below. If a config attribute value was a mutable type
242 # all instances of a component were getting the same copy, effectively
243 # making that a class attribute.
244 # self.config = deepcopy(config)
245 else:
246 if self.parent is not None:
247 self.config = self.parent.config
248 # We used to deepcopy, but for now we are trying to just save
249 # by reference. This *could* have side effects as all components
250 # will share config. In fact, I did find such a side effect in
251 # _config_changed below. If a config attribute value was a mutable type
252 # all instances of a component were getting the same copy, effectively
253 # making that a class attribute.
254 # self.config = deepcopy(self.parent.config)
255
256 self.created = datetime.datetime.now()
257
258 #-------------------------------------------------------------------------
259 # Static traitlet notifiations
260 #-------------------------------------------------------------------------
261
262 def _parent_changed(self, name, old, new):
263 if old is not None:
264 old._remove_child(self)
265 if new is not None:
266 new._add_child(self)
267
268 if new is None:
269 self.root = self
270 else:
271 self.root = new.root
272
273 def _root_changed(self, name, old, new):
274 if self.parent is None:
275 if not (new is self):
276 raise ComponentError("Root not self, but parent is None.")
277 else:
278 if not self.parent.root is new:
279 raise ComponentError("Error in setting the root attribute: "
280 "root != parent.root")
281
282 def _config_changed(self, name, old, new):
283 """Update all the class traits having ``config=True`` as metadata.
284
285 For any class traitlet with a ``config`` metadata attribute that is
286 ``True``, we update the traitlet with the value of the corresponding
287 config entry.
288 """
289 # Get all traitlets with a config metadata entry that is True
290 traitlets = self.traitlets(config=True)
291
292 # We auto-load config section for this class as well as any parent
293 # classes that are Component subclasses. This starts with Component
294 # and works down the mro loading the config for each section.
295 section_names = [cls.__name__ for cls in \
296 reversed(self.__class__.__mro__) if
297 issubclass(cls, Component) and issubclass(self.__class__, cls)]
298
299 for sname in section_names:
300 # Don't do a blind getattr as that would cause the config to
301 # dynamically create the section with name self.__class__.__name__.
302 if new._has_section(sname):
303 my_config = new[sname]
304 for k, v in traitlets.items():
305 # Don't allow traitlets with config=True to start with
306 # uppercase. Otherwise, they are confused with Config
307 # subsections. But, developers shouldn't have uppercase
308 # attributes anyways! (PEP 6)
309 if k[0].upper()==k[0] and not k.startswith('_'):
310 raise ComponentError('Component traitlets with '
311 'config=True must start with a lowercase so they are '
312 'not confused with Config subsections: %s.%s' % \
313 (self.__class__.__name__, k))
314 try:
315 # Here we grab the value from the config
316 # If k has the naming convention of a config
317 # section, it will be auto created.
318 config_value = my_config[k]
319 except KeyError:
320 pass
321 else:
322 # print "Setting %s.%s from %s.%s=%r" % \
323 # (self.__class__.__name__,k,sname,k,config_value)
324 # We have to do a deepcopy here if we don't deepcopy the entire
325 # config object. If we don't, a mutable config_value will be
326 # shared by all instances, effectively making it a class attribute.
327 setattr(self, k, deepcopy(config_value))
328
329 @property
330 def children(self):
331 """A list of all my child components."""
332 return self._children
333
334 def _remove_child(self, child):
335 """A private method for removing children components."""
336 if child in self._children:
337 index = self._children.index(child)
338 del self._children[index]
339
340 def _add_child(self, child):
341 """A private method for adding children components."""
342 if child not in self._children:
343 self._children.append(child)
344
345 def __repr__(self):
346 return "<%s('%s')>" % (self.__class__.__name__, self.name)
@@ -0,0 +1,77 b''
1 #!/usr/bin/env python
2 # encoding: utf-8
3 """
4 A context manager for handling sys.displayhook.
5
6 Authors:
7
8 * Robert Kern
9 * Brian Granger
10 """
11
12 #-----------------------------------------------------------------------------
13 # Copyright (C) 2008-2009 The IPython Development Team
14 #
15 # Distributed under the terms of the BSD License. The full license is in
16 # the file COPYING, distributed as part of this software.
17 #-----------------------------------------------------------------------------
18
19 #-----------------------------------------------------------------------------
20 # Imports
21 #-----------------------------------------------------------------------------
22
23 import sys
24
25 from IPython.core.component import Component
26
27 from IPython.utils.autoattr import auto_attr
28
29 #-----------------------------------------------------------------------------
30 # Classes and functions
31 #-----------------------------------------------------------------------------
32
33
34 class DisplayTrap(Component):
35 """Object to manage sys.displayhook.
36
37 This came from IPython.core.kernel.display_hook, but is simplified
38 (no callbacks or formatters) until more of the core is refactored.
39 """
40
41 def __init__(self, parent, hook):
42 super(DisplayTrap, self).__init__(parent, None, None)
43 self.hook = hook
44 self.old_hook = None
45 # We define this to track if a single BuiltinTrap is nested.
46 # Only turn off the trap when the outermost call to __exit__ is made.
47 self._nested_level = 0
48
49 # @auto_attr
50 # def shell(self):
51 # return Component.get_instances(
52 # root=self.root,
53 # klass='IPython.core.iplib.InteractiveShell')[0]
54
55 def __enter__(self):
56 if self._nested_level == 0:
57 self.set()
58 self._nested_level += 1
59 return self
60
61 def __exit__(self, type, value, traceback):
62 if self._nested_level == 1:
63 self.unset()
64 self._nested_level -= 1
65 # Returning False will cause exceptions to propagate
66 return False
67
68 def set(self):
69 """Set the hook."""
70 if sys.displayhook is not self.hook:
71 self.old_hook = sys.displayhook
72 sys.displayhook = self.hook
73
74 def unset(self):
75 """Unset the hook."""
76 sys.displayhook = self.old_hook
77
@@ -0,0 +1,272 b''
1 #!/usr/bin/env python
2 # encoding: utf-8
3 """
4 An embedded IPython shell.
5
6 Authors:
7
8 * Brian Granger
9 * Fernando Perez
10
11 Notes
12 -----
13 """
14
15 #-----------------------------------------------------------------------------
16 # Copyright (C) 2008-2009 The IPython Development Team
17 #
18 # Distributed under the terms of the BSD License. The full license is in
19 # the file COPYING, distributed as part of this software.
20 #-----------------------------------------------------------------------------
21
22 #-----------------------------------------------------------------------------
23 # Imports
24 #-----------------------------------------------------------------------------
25
26 from __future__ import with_statement
27
28 import sys
29 from contextlib import nested
30
31 from IPython.core import ultratb
32 from IPython.core.iplib import InteractiveShell
33 from IPython.core.ipapp import load_default_config
34
35 from IPython.utils.traitlets import Bool, Str, CBool
36 from IPython.utils.genutils import ask_yes_no
37
38
39 #-----------------------------------------------------------------------------
40 # Classes and functions
41 #-----------------------------------------------------------------------------
42
43 # This is an additional magic that is exposed in embedded shells.
44 def kill_embedded(self,parameter_s=''):
45 """%kill_embedded : deactivate for good the current embedded IPython.
46
47 This function (after asking for confirmation) sets an internal flag so that
48 an embedded IPython will never activate again. This is useful to
49 permanently disable a shell that is being called inside a loop: once you've
50 figured out what you needed from it, you may then kill it and the program
51 will then continue to run without the interactive shell interfering again.
52 """
53
54 kill = ask_yes_no("Are you sure you want to kill this embedded instance "
55 "(y/n)? [y/N] ",'n')
56 if kill:
57 self.embedded_active = False
58 print "This embedded IPython will not reactivate anymore once you exit."
59
60
61 class InteractiveShellEmbed(InteractiveShell):
62
63 dummy_mode = Bool(False)
64 exit_msg = Str('')
65 embedded = CBool(True)
66 embedded_active = CBool(True)
67 # Like the base class display_banner is not configurable, but here it
68 # is True by default.
69 display_banner = CBool(True)
70
71 def __init__(self, parent=None, config=None, ipython_dir=None, usage=None,
72 user_ns=None, user_global_ns=None,
73 banner1=None, banner2=None, display_banner=None,
74 custom_exceptions=((),None), exit_msg=''):
75
76 self.save_sys_ipcompleter()
77
78 super(InteractiveShellEmbed,self).__init__(
79 parent=parent, config=config, ipython_dir=ipython_dir, usage=usage,
80 user_ns=user_ns, user_global_ns=user_global_ns,
81 banner1=banner1, banner2=banner2, display_banner=display_banner,
82 custom_exceptions=custom_exceptions)
83
84 self.exit_msg = exit_msg
85 self.define_magic("kill_embedded", kill_embedded)
86
87 # don't use the ipython crash handler so that user exceptions aren't
88 # trapped
89 sys.excepthook = ultratb.FormattedTB(color_scheme=self.colors,
90 mode=self.xmode,
91 call_pdb=self.pdb)
92
93 self.restore_sys_ipcompleter()
94
95 def init_sys_modules(self):
96 pass
97
98 def save_sys_ipcompleter(self):
99 """Save readline completer status."""
100 try:
101 #print 'Save completer',sys.ipcompleter # dbg
102 self.sys_ipcompleter_orig = sys.ipcompleter
103 except:
104 pass # not nested with IPython
105
106 def restore_sys_ipcompleter(self):
107 """Restores the readline completer which was in place.
108
109 This allows embedded IPython within IPython not to disrupt the
110 parent's completion.
111 """
112 try:
113 self.readline.set_completer(self.sys_ipcompleter_orig)
114 sys.ipcompleter = self.sys_ipcompleter_orig
115 except:
116 pass
117
118 def __call__(self, header='', local_ns=None, global_ns=None, dummy=None,
119 stack_depth=1):
120 """Activate the interactive interpreter.
121
122 __call__(self,header='',local_ns=None,global_ns,dummy=None) -> Start
123 the interpreter shell with the given local and global namespaces, and
124 optionally print a header string at startup.
125
126 The shell can be globally activated/deactivated using the
127 set/get_dummy_mode methods. This allows you to turn off a shell used
128 for debugging globally.
129
130 However, *each* time you call the shell you can override the current
131 state of dummy_mode with the optional keyword parameter 'dummy'. For
132 example, if you set dummy mode on with IPShell.set_dummy_mode(1), you
133 can still have a specific call work by making it as IPShell(dummy=0).
134
135 The optional keyword parameter dummy controls whether the call
136 actually does anything.
137 """
138
139 # If the user has turned it off, go away
140 if not self.embedded_active:
141 return
142
143 # Normal exits from interactive mode set this flag, so the shell can't
144 # re-enter (it checks this variable at the start of interactive mode).
145 self.exit_now = False
146
147 # Allow the dummy parameter to override the global __dummy_mode
148 if dummy or (dummy != 0 and self.dummy_mode):
149 return
150
151 if self.has_readline:
152 self.set_completer()
153
154 # self.banner is auto computed
155 if header:
156 self.old_banner2 = self.banner2
157 self.banner2 = self.banner2 + '\n' + header + '\n'
158
159 # Call the embedding code with a stack depth of 1 so it can skip over
160 # our call and get the original caller's namespaces.
161 self.mainloop(local_ns, global_ns, stack_depth=stack_depth)
162
163 self.banner2 = self.old_banner2
164
165 if self.exit_msg is not None:
166 print self.exit_msg
167
168 self.restore_sys_ipcompleter()
169
170 def mainloop(self, local_ns=None, global_ns=None, stack_depth=0,
171 display_banner=None):
172 """Embeds IPython into a running python program.
173
174 Input:
175
176 - header: An optional header message can be specified.
177
178 - local_ns, global_ns: working namespaces. If given as None, the
179 IPython-initialized one is updated with __main__.__dict__, so that
180 program variables become visible but user-specific configuration
181 remains possible.
182
183 - stack_depth: specifies how many levels in the stack to go to
184 looking for namespaces (when local_ns and global_ns are None). This
185 allows an intermediate caller to make sure that this function gets
186 the namespace from the intended level in the stack. By default (0)
187 it will get its locals and globals from the immediate caller.
188
189 Warning: it's possible to use this in a program which is being run by
190 IPython itself (via %run), but some funny things will happen (a few
191 globals get overwritten). In the future this will be cleaned up, as
192 there is no fundamental reason why it can't work perfectly."""
193
194 # Get locals and globals from caller
195 if local_ns is None or global_ns is None:
196 call_frame = sys._getframe(stack_depth).f_back
197
198 if local_ns is None:
199 local_ns = call_frame.f_locals
200 if global_ns is None:
201 global_ns = call_frame.f_globals
202
203 # Update namespaces and fire up interpreter
204
205 # The global one is easy, we can just throw it in
206 self.user_global_ns = global_ns
207
208 # but the user/local one is tricky: ipython needs it to store internal
209 # data, but we also need the locals. We'll copy locals in the user
210 # one, but will track what got copied so we can delete them at exit.
211 # This is so that a later embedded call doesn't see locals from a
212 # previous call (which most likely existed in a separate scope).
213 local_varnames = local_ns.keys()
214 self.user_ns.update(local_ns)
215 #self.user_ns['local_ns'] = local_ns # dbg
216
217 # Patch for global embedding to make sure that things don't overwrite
218 # user globals accidentally. Thanks to Richard <rxe@renre-europe.com>
219 # FIXME. Test this a bit more carefully (the if.. is new)
220 if local_ns is None and global_ns is None:
221 self.user_global_ns.update(__main__.__dict__)
222
223 # make sure the tab-completer has the correct frame information, so it
224 # actually completes using the frame's locals/globals
225 self.set_completer_frame()
226
227 with nested(self.builtin_trap, self.display_trap):
228 self.interact(display_banner=display_banner)
229
230 # now, purge out the user namespace from anything we might have added
231 # from the caller's local namespace
232 delvar = self.user_ns.pop
233 for var in local_varnames:
234 delvar(var,None)
235
236
237 _embedded_shell = None
238
239
240 def embed(header='', config=None, usage=None, banner1=None, banner2=None,
241 display_banner=True, exit_msg=''):
242 """Call this to embed IPython at the current point in your program.
243
244 The first invocation of this will create an :class:`InteractiveShellEmbed`
245 instance and then call it. Consecutive calls just call the already
246 created instance.
247
248 Here is a simple example::
249
250 from IPython import embed
251 a = 10
252 b = 20
253 embed('First time')
254 c = 30
255 d = 40
256 embed
257
258 Full customization can be done by passing a :class:`Struct` in as the
259 config argument.
260 """
261 if config is None:
262 config = load_default_config()
263 config.InteractiveShellEmbed = config.InteractiveShell
264 global _embedded_shell
265 if _embedded_shell is None:
266 _embedded_shell = InteractiveShellEmbed(
267 config=config, usage=usage,
268 banner1=banner1, banner2=banner2,
269 display_banner=display_banner, exit_msg=exit_msg
270 )
271 _embedded_shell(header=header, stack_depth=2)
272
@@ -0,0 +1,52 b''
1 #!/usr/bin/env python
2 # encoding: utf-8
3 """
4 Global exception classes for IPython.core.
5
6 Authors:
7
8 * Brian Granger
9 * Fernando Perez
10
11 Notes
12 -----
13 """
14
15 #-----------------------------------------------------------------------------
16 # Copyright (C) 2008-2009 The IPython Development Team
17 #
18 # Distributed under the terms of the BSD License. The full license is in
19 # the file COPYING, distributed as part of this software.
20 #-----------------------------------------------------------------------------
21
22 #-----------------------------------------------------------------------------
23 # Imports
24 #-----------------------------------------------------------------------------
25
26 #-----------------------------------------------------------------------------
27 # Exception classes
28 #-----------------------------------------------------------------------------
29
30 class IPythonCoreError(Exception):
31 pass
32
33
34 class TryNext(IPythonCoreError):
35 """Try next hook exception.
36
37 Raise this in your hook function to indicate that the next hook handler
38 should be used to handle the operation. If you pass arguments to the
39 constructor those arguments will be used by the next hook instead of the
40 original ones.
41 """
42
43 def __init__(self, *args, **kwargs):
44 self.args = args
45 self.kwargs = kwargs
46
47 class UsageError(IPythonCoreError):
48 """Error in magic function arguments, etc.
49
50 Something that probably won't warrant a full traceback, but should
51 nevertheless interrupt a macro / batch file.
52 """ No newline at end of file
@@ -0,0 +1,38 b''
1 #!/usr/bin/env python
2 # encoding: utf-8
3 """
4 This module is *completely* deprecated and should no longer be used for
5 any purpose. Currently, we have a few parts of the core that have
6 not been componentized and thus, still rely on this module. When everything
7 has been made into a component, this module will be sent to deathrow.
8 """
9
10 #-----------------------------------------------------------------------------
11 # Copyright (C) 2008-2009 The IPython Development Team
12 #
13 # Distributed under the terms of the BSD License. The full license is in
14 # the file COPYING, distributed as part of this software.
15 #-----------------------------------------------------------------------------
16
17 #-----------------------------------------------------------------------------
18 # Imports
19 #-----------------------------------------------------------------------------
20
21 from IPython.core.error import TryNext, UsageError, IPythonCoreError
22
23 #-----------------------------------------------------------------------------
24 # Classes and functions
25 #-----------------------------------------------------------------------------
26
27
28 def get():
29 """Get the most recently created InteractiveShell instance."""
30 from IPython.core.iplib import InteractiveShell
31 insts = InteractiveShell.get_instances()
32 if len(insts)==0:
33 return None
34 most_recent = insts[0]
35 for inst in insts[1:]:
36 if inst.created > most_recent.created:
37 most_recent = inst
38 return most_recent
This diff has been collapsed as it changes many lines, (544 lines changed) Show them Hide them
@@ -0,0 +1,544 b''
1 #!/usr/bin/env python
2 # encoding: utf-8
3 """
4 The :class:`~IPython.core.application.Application` object for the command
5 line :command:`ipython` program.
6
7 Authors:
8
9 * Brian Granger
10 * Fernando Perez
11
12 Notes
13 -----
14 """
15
16 #-----------------------------------------------------------------------------
17 # Copyright (C) 2008-2009 The IPython Development Team
18 #
19 # Distributed under the terms of the BSD License. The full license is in
20 # the file COPYING, distributed as part of this software.
21 #-----------------------------------------------------------------------------
22
23 #-----------------------------------------------------------------------------
24 # Imports
25 #-----------------------------------------------------------------------------
26
27 import logging
28 import os
29 import sys
30 import warnings
31
32 from IPython.core.application import Application, BaseAppArgParseConfigLoader
33 from IPython.core import release
34 from IPython.core.iplib import InteractiveShell
35 from IPython.config.loader import (
36 NoConfigDefault,
37 Config,
38 PyFileConfigLoader
39 )
40
41 from IPython.lib import inputhook
42
43 from IPython.utils.genutils import filefind, get_ipython_dir
44
45 #-----------------------------------------------------------------------------
46 # Utilities and helpers
47 #-----------------------------------------------------------------------------
48
49
50 ipython_desc = """
51 A Python shell with automatic history (input and output), dynamic object
52 introspection, easier configuration, command completion, access to the system
53 shell and more.
54 """
55
56 def pylab_warning():
57 msg = """
58
59 IPython's -pylab mode has been disabled until matplotlib supports this version
60 of IPython. This version of IPython has greatly improved GUI integration that
61 matplotlib will soon be able to take advantage of. This will eventually
62 result in greater stability and a richer API for matplotlib under IPython.
63 However during this transition, you will either need to use an older version
64 of IPython, or do the following to use matplotlib interactively::
65
66 import matplotlib
67 matplotlib.interactive(True)
68 matplotlib.use('wxagg') # adjust for your backend
69 %gui -a wx # adjust for your GUI
70 from matplotlib import pyplot as plt
71
72 See the %gui magic for information on the new interface.
73 """
74 warnings.warn(msg, category=DeprecationWarning, stacklevel=1)
75
76
77 #-----------------------------------------------------------------------------
78 # Main classes and functions
79 #-----------------------------------------------------------------------------
80
81 cl_args = (
82 (('--autocall',), dict(
83 type=int, dest='InteractiveShell.autocall', default=NoConfigDefault,
84 help='Set the autocall value (0,1,2).',
85 metavar='InteractiveShell.autocall')
86 ),
87 (('--autoindent',), dict(
88 action='store_true', dest='InteractiveShell.autoindent', default=NoConfigDefault,
89 help='Turn on autoindenting.')
90 ),
91 (('--no-autoindent',), dict(
92 action='store_false', dest='InteractiveShell.autoindent', default=NoConfigDefault,
93 help='Turn off autoindenting.')
94 ),
95 (('--automagic',), dict(
96 action='store_true', dest='InteractiveShell.automagic', default=NoConfigDefault,
97 help='Turn on the auto calling of magic commands.')
98 ),
99 (('--no-automagic',), dict(
100 action='store_false', dest='InteractiveShell.automagic', default=NoConfigDefault,
101 help='Turn off the auto calling of magic commands.')
102 ),
103 (('--autoedit-syntax',), dict(
104 action='store_true', dest='InteractiveShell.autoedit_syntax', default=NoConfigDefault,
105 help='Turn on auto editing of files with syntax errors.')
106 ),
107 (('--no-autoedit-syntax',), dict(
108 action='store_false', dest='InteractiveShell.autoedit_syntax', default=NoConfigDefault,
109 help='Turn off auto editing of files with syntax errors.')
110 ),
111 (('--banner',), dict(
112 action='store_true', dest='Global.display_banner', default=NoConfigDefault,
113 help='Display a banner upon starting IPython.')
114 ),
115 (('--no-banner',), dict(
116 action='store_false', dest='Global.display_banner', default=NoConfigDefault,
117 help="Don't display a banner upon starting IPython.")
118 ),
119 (('--cache-size',), dict(
120 type=int, dest='InteractiveShell.cache_size', default=NoConfigDefault,
121 help="Set the size of the output cache.",
122 metavar='InteractiveShell.cache_size')
123 ),
124 (('--classic',), dict(
125 action='store_true', dest='Global.classic', default=NoConfigDefault,
126 help="Gives IPython a similar feel to the classic Python prompt.")
127 ),
128 (('--colors',), dict(
129 type=str, dest='InteractiveShell.colors', default=NoConfigDefault,
130 help="Set the color scheme (NoColor, Linux, and LightBG).",
131 metavar='InteractiveShell.colors')
132 ),
133 (('--color-info',), dict(
134 action='store_true', dest='InteractiveShell.color_info', default=NoConfigDefault,
135 help="Enable using colors for info related things.")
136 ),
137 (('--no-color-info',), dict(
138 action='store_false', dest='InteractiveShell.color_info', default=NoConfigDefault,
139 help="Disable using colors for info related things.")
140 ),
141 (('--confirm-exit',), dict(
142 action='store_true', dest='InteractiveShell.confirm_exit', default=NoConfigDefault,
143 help="Prompt the user when existing.")
144 ),
145 (('--no-confirm-exit',), dict(
146 action='store_false', dest='InteractiveShell.confirm_exit', default=NoConfigDefault,
147 help="Don't prompt the user when existing.")
148 ),
149 (('--deep-reload',), dict(
150 action='store_true', dest='InteractiveShell.deep_reload', default=NoConfigDefault,
151 help="Enable deep (recursive) reloading by default.")
152 ),
153 (('--no-deep-reload',), dict(
154 action='store_false', dest='InteractiveShell.deep_reload', default=NoConfigDefault,
155 help="Disable deep (recursive) reloading by default.")
156 ),
157 (('--editor',), dict(
158 type=str, dest='InteractiveShell.editor', default=NoConfigDefault,
159 help="Set the editor used by IPython (default to $EDITOR/vi/notepad).",
160 metavar='InteractiveShell.editor')
161 ),
162 (('--log','-l'), dict(
163 action='store_true', dest='InteractiveShell.logstart', default=NoConfigDefault,
164 help="Start logging to the default file (./ipython_log.py).")
165 ),
166 (('--logfile','-lf'), dict(
167 type=unicode, dest='InteractiveShell.logfile', default=NoConfigDefault,
168 help="Start logging to logfile.",
169 metavar='InteractiveShell.logfile')
170 ),
171 (('--log-append','-la'), dict(
172 type=unicode, dest='InteractiveShell.logappend', default=NoConfigDefault,
173 help="Start logging to the give file in append mode.",
174 metavar='InteractiveShell.logfile')
175 ),
176 (('--pdb',), dict(
177 action='store_true', dest='InteractiveShell.pdb', default=NoConfigDefault,
178 help="Enable auto calling the pdb debugger after every exception.")
179 ),
180 (('--no-pdb',), dict(
181 action='store_false', dest='InteractiveShell.pdb', default=NoConfigDefault,
182 help="Disable auto calling the pdb debugger after every exception.")
183 ),
184 (('--pprint',), dict(
185 action='store_true', dest='InteractiveShell.pprint', default=NoConfigDefault,
186 help="Enable auto pretty printing of results.")
187 ),
188 (('--no-pprint',), dict(
189 action='store_false', dest='InteractiveShell.pprint', default=NoConfigDefault,
190 help="Disable auto auto pretty printing of results.")
191 ),
192 (('--prompt-in1','-pi1'), dict(
193 type=str, dest='InteractiveShell.prompt_in1', default=NoConfigDefault,
194 help="Set the main input prompt ('In [\#]: ')",
195 metavar='InteractiveShell.prompt_in1')
196 ),
197 (('--prompt-in2','-pi2'), dict(
198 type=str, dest='InteractiveShell.prompt_in2', default=NoConfigDefault,
199 help="Set the secondary input prompt (' .\D.: ')",
200 metavar='InteractiveShell.prompt_in2')
201 ),
202 (('--prompt-out','-po'), dict(
203 type=str, dest='InteractiveShell.prompt_out', default=NoConfigDefault,
204 help="Set the output prompt ('Out[\#]:')",
205 metavar='InteractiveShell.prompt_out')
206 ),
207 (('--quick',), dict(
208 action='store_true', dest='Global.quick', default=NoConfigDefault,
209 help="Enable quick startup with no config files.")
210 ),
211 (('--readline',), dict(
212 action='store_true', dest='InteractiveShell.readline_use', default=NoConfigDefault,
213 help="Enable readline for command line usage.")
214 ),
215 (('--no-readline',), dict(
216 action='store_false', dest='InteractiveShell.readline_use', default=NoConfigDefault,
217 help="Disable readline for command line usage.")
218 ),
219 (('--screen-length','-sl'), dict(
220 type=int, dest='InteractiveShell.screen_length', default=NoConfigDefault,
221 help='Number of lines on screen, used to control printing of long strings.',
222 metavar='InteractiveShell.screen_length')
223 ),
224 (('--separate-in','-si'), dict(
225 type=str, dest='InteractiveShell.separate_in', default=NoConfigDefault,
226 help="Separator before input prompts. Default '\n'.",
227 metavar='InteractiveShell.separate_in')
228 ),
229 (('--separate-out','-so'), dict(
230 type=str, dest='InteractiveShell.separate_out', default=NoConfigDefault,
231 help="Separator before output prompts. Default 0 (nothing).",
232 metavar='InteractiveShell.separate_out')
233 ),
234 (('--separate-out2','-so2'), dict(
235 type=str, dest='InteractiveShell.separate_out2', default=NoConfigDefault,
236 help="Separator after output prompts. Default 0 (nonight).",
237 metavar='InteractiveShell.separate_out2')
238 ),
239 (('-no-sep',), dict(
240 action='store_true', dest='Global.nosep', default=NoConfigDefault,
241 help="Eliminate all spacing between prompts.")
242 ),
243 (('--term-title',), dict(
244 action='store_true', dest='InteractiveShell.term_title', default=NoConfigDefault,
245 help="Enable auto setting the terminal title.")
246 ),
247 (('--no-term-title',), dict(
248 action='store_false', dest='InteractiveShell.term_title', default=NoConfigDefault,
249 help="Disable auto setting the terminal title.")
250 ),
251 (('--xmode',), dict(
252 type=str, dest='InteractiveShell.xmode', default=NoConfigDefault,
253 help="Exception mode ('Plain','Context','Verbose')",
254 metavar='InteractiveShell.xmode')
255 ),
256 (('--ext',), dict(
257 type=str, dest='Global.extra_extension', default=NoConfigDefault,
258 help="The dotted module name of an IPython extension to load.",
259 metavar='Global.extra_extension')
260 ),
261 (('-c',), dict(
262 type=str, dest='Global.code_to_run', default=NoConfigDefault,
263 help="Execute the given command string.",
264 metavar='Global.code_to_run')
265 ),
266 (('-i',), dict(
267 action='store_true', dest='Global.force_interact', default=NoConfigDefault,
268 help="If running code from the command line, become interactive afterwards.")
269 ),
270 (('--wthread',), dict(
271 action='store_true', dest='Global.wthread', default=NoConfigDefault,
272 help="Enable wxPython event loop integration.")
273 ),
274 (('--q4thread','--qthread'), dict(
275 action='store_true', dest='Global.q4thread', default=NoConfigDefault,
276 help="Enable Qt4 event loop integration. Qt3 is no longer supported.")
277 ),
278 (('--gthread',), dict(
279 action='store_true', dest='Global.gthread', default=NoConfigDefault,
280 help="Enable GTK event loop integration.")
281 ),
282 # # These are only here to get the proper deprecation warnings
283 (('--pylab',), dict(
284 action='store_true', dest='Global.pylab', default=NoConfigDefault,
285 help="Disabled. Pylab has been disabled until matplotlib "
286 "supports this version of IPython.")
287 )
288 )
289
290
291 class IPythonAppCLConfigLoader(BaseAppArgParseConfigLoader):
292
293 arguments = cl_args
294
295
296 default_config_file_name = u'ipython_config.py'
297
298
299 class IPythonApp(Application):
300 name = u'ipython'
301 description = 'IPython: an enhanced interactive Python shell.'
302 config_file_name = default_config_file_name
303
304 def create_default_config(self):
305 super(IPythonApp, self).create_default_config()
306 self.default_config.Global.display_banner = True
307
308 # If the -c flag is given or a file is given to run at the cmd line
309 # like "ipython foo.py", normally we exit without starting the main
310 # loop. The force_interact config variable allows a user to override
311 # this and interact. It is also set by the -i cmd line flag, just
312 # like Python.
313 self.default_config.Global.force_interact = False
314
315 # By default always interact by starting the IPython mainloop.
316 self.default_config.Global.interact = True
317
318 # No GUI integration by default
319 self.default_config.Global.wthread = False
320 self.default_config.Global.q4thread = False
321 self.default_config.Global.gthread = False
322
323 def create_command_line_config(self):
324 """Create and return a command line config loader."""
325 return IPythonAppCLConfigLoader(
326 description=self.description,
327 version=release.version
328 )
329
330 def post_load_command_line_config(self):
331 """Do actions after loading cl config."""
332 clc = self.command_line_config
333
334 # Display the deprecation warnings about threaded shells
335 if hasattr(clc.Global, 'pylab'):
336 pylab_warning()
337 del clc.Global['pylab']
338
339 def load_file_config(self):
340 if hasattr(self.command_line_config.Global, 'quick'):
341 if self.command_line_config.Global.quick:
342 self.file_config = Config()
343 return
344 super(IPythonApp, self).load_file_config()
345
346 def post_load_file_config(self):
347 if hasattr(self.command_line_config.Global, 'extra_extension'):
348 if not hasattr(self.file_config.Global, 'extensions'):
349 self.file_config.Global.extensions = []
350 self.file_config.Global.extensions.append(
351 self.command_line_config.Global.extra_extension)
352 del self.command_line_config.Global.extra_extension
353
354 def pre_construct(self):
355 config = self.master_config
356
357 if hasattr(config.Global, 'classic'):
358 if config.Global.classic:
359 config.InteractiveShell.cache_size = 0
360 config.InteractiveShell.pprint = 0
361 config.InteractiveShell.prompt_in1 = '>>> '
362 config.InteractiveShell.prompt_in2 = '... '
363 config.InteractiveShell.prompt_out = ''
364 config.InteractiveShell.separate_in = \
365 config.InteractiveShell.separate_out = \
366 config.InteractiveShell.separate_out2 = ''
367 config.InteractiveShell.colors = 'NoColor'
368 config.InteractiveShell.xmode = 'Plain'
369
370 if hasattr(config.Global, 'nosep'):
371 if config.Global.nosep:
372 config.InteractiveShell.separate_in = \
373 config.InteractiveShell.separate_out = \
374 config.InteractiveShell.separate_out2 = ''
375
376 # if there is code of files to run from the cmd line, don't interact
377 # unless the -i flag (Global.force_interact) is true.
378 code_to_run = config.Global.get('code_to_run','')
379 file_to_run = False
380 if len(self.extra_args)>=1:
381 if self.extra_args[0]:
382 file_to_run = True
383 if file_to_run or code_to_run:
384 if not config.Global.force_interact:
385 config.Global.interact = False
386
387 def construct(self):
388 # I am a little hesitant to put these into InteractiveShell itself.
389 # But that might be the place for them
390 sys.path.insert(0, '')
391
392 # Create an InteractiveShell instance
393 self.shell = InteractiveShell(
394 parent=None,
395 config=self.master_config
396 )
397
398 def post_construct(self):
399 """Do actions after construct, but before starting the app."""
400 config = self.master_config
401
402 # shell.display_banner should always be False for the terminal
403 # based app, because we call shell.show_banner() by hand below
404 # so the banner shows *before* all extension loading stuff.
405 self.shell.display_banner = False
406
407 if config.Global.display_banner and \
408 config.Global.interact:
409 self.shell.show_banner()
410
411 # Make sure there is a space below the banner.
412 if self.log_level <= logging.INFO: print
413
414 # Now a variety of things that happen after the banner is printed.
415 self._enable_gui()
416 self._load_extensions()
417 self._run_exec_lines()
418 self._run_exec_files()
419 self._run_cmd_line_code()
420
421 def _enable_gui(self):
422 """Enable GUI event loop integration."""
423 config = self.master_config
424 try:
425 # Enable GUI integration
426 if config.Global.wthread:
427 self.log.info("Enabling wx GUI event loop integration")
428 inputhook.enable_wx(app=True)
429 elif config.Global.q4thread:
430 self.log.info("Enabling Qt4 GUI event loop integration")
431 inputhook.enable_qt4(app=True)
432 elif config.Global.gthread:
433 self.log.info("Enabling GTK GUI event loop integration")
434 inputhook.enable_gtk(app=True)
435 except:
436 self.log.warn("Error in enabling GUI event loop integration:")
437 self.shell.showtraceback()
438
439 def _load_extensions(self):
440 """Load all IPython extensions in Global.extensions.
441
442 This uses the :meth:`InteractiveShell.load_extensions` to load all
443 the extensions listed in ``self.master_config.Global.extensions``.
444 """
445 try:
446 if hasattr(self.master_config.Global, 'extensions'):
447 self.log.debug("Loading IPython extensions...")
448 extensions = self.master_config.Global.extensions
449 for ext in extensions:
450 try:
451 self.log.info("Loading IPython extension: %s" % ext)
452 self.shell.load_extension(ext)
453 except:
454 self.log.warn("Error in loading extension: %s" % ext)
455 self.shell.showtraceback()
456 except:
457 self.log.warn("Unknown error in loading extensions:")
458 self.shell.showtraceback()
459
460 def _run_exec_lines(self):
461 """Run lines of code in Global.exec_lines in the user's namespace."""
462 try:
463 if hasattr(self.master_config.Global, 'exec_lines'):
464 self.log.debug("Running code from Global.exec_lines...")
465 exec_lines = self.master_config.Global.exec_lines
466 for line in exec_lines:
467 try:
468 self.log.info("Running code in user namespace: %s" % line)
469 self.shell.runlines(line)
470 except:
471 self.log.warn("Error in executing line in user namespace: %s" % line)
472 self.shell.showtraceback()
473 except:
474 self.log.warn("Unknown error in handling Global.exec_lines:")
475 self.shell.showtraceback()
476
477 def _exec_file(self, fname):
478 full_filename = filefind(fname, [u'.', self.ipython_dir])
479 if os.path.isfile(full_filename):
480 if full_filename.endswith(u'.py'):
481 self.log.info("Running file in user namespace: %s" % full_filename)
482 self.shell.safe_execfile(full_filename, self.shell.user_ns)
483 elif full_filename.endswith('.ipy'):
484 self.log.info("Running file in user namespace: %s" % full_filename)
485 self.shell.safe_execfile_ipy(full_filename)
486 else:
487 self.log.warn("File does not have a .py or .ipy extension: <%s>" % full_filename)
488
489 def _run_exec_files(self):
490 try:
491 if hasattr(self.master_config.Global, 'exec_files'):
492 self.log.debug("Running files in Global.exec_files...")
493 exec_files = self.master_config.Global.exec_files
494 for fname in exec_files:
495 self._exec_file(fname)
496 except:
497 self.log.warn("Unknown error in handling Global.exec_files:")
498 self.shell.showtraceback()
499
500 def _run_cmd_line_code(self):
501 if hasattr(self.master_config.Global, 'code_to_run'):
502 line = self.master_config.Global.code_to_run
503 try:
504 self.log.info("Running code given at command line (-c): %s" % line)
505 self.shell.runlines(line)
506 except:
507 self.log.warn("Error in executing line in user namespace: %s" % line)
508 self.shell.showtraceback()
509 return
510 # Like Python itself, ignore the second if the first of these is present
511 try:
512 fname = self.extra_args[0]
513 except:
514 pass
515 else:
516 try:
517 self._exec_file(fname)
518 except:
519 self.log.warn("Error in executing file in user namespace: %s" % fname)
520 self.shell.showtraceback()
521
522 def start_app(self):
523 if self.master_config.Global.interact:
524 self.log.debug("Starting IPython's mainloop...")
525 self.shell.mainloop()
526
527
528 def load_default_config(ipython_dir=None):
529 """Load the default config file from the default ipython_dir.
530
531 This is useful for embedded shells.
532 """
533 if ipython_dir is None:
534 ipython_dir = get_ipython_dir()
535 cl = PyFileConfigLoader(default_config_file_name, ipython_dir)
536 config = cl.load_config()
537 return config
538
539
540 def launch_new_instance():
541 """Create and run a full blown IPython instance"""
542 app = IPythonApp()
543 app.start()
544
This diff has been collapsed as it changes many lines, (2488 lines changed) Show them Hide them
@@ -0,0 +1,2488 b''
1 # -*- coding: utf-8 -*-
2 """
3 Main IPython Component
4 """
5
6 #-----------------------------------------------------------------------------
7 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de>
8 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
9 # Copyright (C) 2008-2009 The IPython Development Team
10 #
11 # Distributed under the terms of the BSD License. The full license is in
12 # the file COPYING, distributed as part of this software.
13 #-----------------------------------------------------------------------------
14
15 #-----------------------------------------------------------------------------
16 # Imports
17 #-----------------------------------------------------------------------------
18
19 from __future__ import with_statement
20
21 import __builtin__
22 import StringIO
23 import bdb
24 import codeop
25 import exceptions
26 import new
27 import os
28 import re
29 import string
30 import sys
31 import tempfile
32 from contextlib import nested
33
34 from IPython.core import ultratb
35 from IPython.core import debugger, oinspect
36 from IPython.core import shadowns
37 from IPython.core import history as ipcorehist
38 from IPython.core import prefilter
39 from IPython.core.alias import AliasManager
40 from IPython.core.builtin_trap import BuiltinTrap
41 from IPython.core.display_trap import DisplayTrap
42 from IPython.core.fakemodule import FakeModule, init_fakemod_dict
43 from IPython.core.logger import Logger
44 from IPython.core.magic import Magic
45 from IPython.core.prompts import CachedOutput
46 from IPython.core.prefilter import PrefilterManager
47 from IPython.core.component import Component
48 from IPython.core.usage import interactive_usage, default_banner
49 from IPython.core.error import TryNext, UsageError
50
51 from IPython.utils import pickleshare
52 from IPython.external.Itpl import ItplNS
53 from IPython.lib.backgroundjobs import BackgroundJobManager
54 from IPython.utils.ipstruct import Struct
55 from IPython.utils import PyColorize
56 from IPython.utils.genutils import *
57 from IPython.utils.genutils import get_ipython_dir
58 from IPython.utils.platutils import toggle_set_term_title, set_term_title
59 from IPython.utils.strdispatch import StrDispatch
60 from IPython.utils.syspathcontext import prepended_to_syspath
61
62 # from IPython.utils import growl
63 # growl.start("IPython")
64
65 from IPython.utils.traitlets import (
66 Int, Str, CBool, CaselessStrEnum, Enum, List, Unicode
67 )
68
69 #-----------------------------------------------------------------------------
70 # Globals
71 #-----------------------------------------------------------------------------
72
73
74 # store the builtin raw_input globally, and use this always, in case user code
75 # overwrites it (like wx.py.PyShell does)
76 raw_input_original = raw_input
77
78 # compiled regexps for autoindent management
79 dedent_re = re.compile(r'^\s+raise|^\s+return|^\s+pass')
80
81
82 #-----------------------------------------------------------------------------
83 # Utilities
84 #-----------------------------------------------------------------------------
85
86
87 ini_spaces_re = re.compile(r'^(\s+)')
88
89
90 def num_ini_spaces(strng):
91 """Return the number of initial spaces in a string"""
92
93 ini_spaces = ini_spaces_re.match(strng)
94 if ini_spaces:
95 return ini_spaces.end()
96 else:
97 return 0
98
99
100 def softspace(file, newvalue):
101 """Copied from code.py, to remove the dependency"""
102
103 oldvalue = 0
104 try:
105 oldvalue = file.softspace
106 except AttributeError:
107 pass
108 try:
109 file.softspace = newvalue
110 except (AttributeError, TypeError):
111 # "attribute-less object" or "read-only attributes"
112 pass
113 return oldvalue
114
115
116 class SpaceInInput(exceptions.Exception): pass
117
118 class Bunch: pass
119
120 class InputList(list):
121 """Class to store user input.
122
123 It's basically a list, but slices return a string instead of a list, thus
124 allowing things like (assuming 'In' is an instance):
125
126 exec In[4:7]
127
128 or
129
130 exec In[5:9] + In[14] + In[21:25]"""
131
132 def __getslice__(self,i,j):
133 return ''.join(list.__getslice__(self,i,j))
134
135
136 class SyntaxTB(ultratb.ListTB):
137 """Extension which holds some state: the last exception value"""
138
139 def __init__(self,color_scheme = 'NoColor'):
140 ultratb.ListTB.__init__(self,color_scheme)
141 self.last_syntax_error = None
142
143 def __call__(self, etype, value, elist):
144 self.last_syntax_error = value
145 ultratb.ListTB.__call__(self,etype,value,elist)
146
147 def clear_err_state(self):
148 """Return the current error state and clear it"""
149 e = self.last_syntax_error
150 self.last_syntax_error = None
151 return e
152
153
154 def get_default_editor():
155 try:
156 ed = os.environ['EDITOR']
157 except KeyError:
158 if os.name == 'posix':
159 ed = 'vi' # the only one guaranteed to be there!
160 else:
161 ed = 'notepad' # same in Windows!
162 return ed
163
164
165 def get_default_colors():
166 if sys.platform=='darwin':
167 return "LightBG"
168 elif os.name=='nt':
169 return 'Linux'
170 else:
171 return 'Linux'
172
173
174 class SeparateStr(Str):
175 """A Str subclass to validate separate_in, separate_out, etc.
176
177 This is a Str based traitlet that converts '0'->'' and '\\n'->'\n'.
178 """
179
180 def validate(self, obj, value):
181 if value == '0': value = ''
182 value = value.replace('\\n','\n')
183 return super(SeparateStr, self).validate(obj, value)
184
185
186 #-----------------------------------------------------------------------------
187 # Main IPython class
188 #-----------------------------------------------------------------------------
189
190
191 class InteractiveShell(Component, Magic):
192 """An enhanced, interactive shell for Python."""
193
194 autocall = Enum((0,1,2), default_value=1, config=True)
195 autoedit_syntax = CBool(False, config=True)
196 autoindent = CBool(True, config=True)
197 automagic = CBool(True, config=True)
198 banner = Str('')
199 banner1 = Str(default_banner, config=True)
200 banner2 = Str('', config=True)
201 cache_size = Int(1000, config=True)
202 color_info = CBool(True, config=True)
203 colors = CaselessStrEnum(('NoColor','LightBG','Linux'),
204 default_value=get_default_colors(), config=True)
205 confirm_exit = CBool(True, config=True)
206 debug = CBool(False, config=True)
207 deep_reload = CBool(False, config=True)
208 # This display_banner only controls whether or not self.show_banner()
209 # is called when mainloop/interact are called. The default is False
210 # because for the terminal based application, the banner behavior
211 # is controlled by Global.display_banner, which IPythonApp looks at
212 # to determine if *it* should call show_banner() by hand or not.
213 display_banner = CBool(False) # This isn't configurable!
214 embedded = CBool(False)
215 embedded_active = CBool(False)
216 editor = Str(get_default_editor(), config=True)
217 filename = Str("<ipython console>")
218 ipython_dir= Unicode('', config=True) # Set to get_ipython_dir() in __init__
219 logstart = CBool(False, config=True)
220 logfile = Str('', config=True)
221 logappend = Str('', config=True)
222 object_info_string_level = Enum((0,1,2), default_value=0,
223 config=True)
224 pager = Str('less', config=True)
225 pdb = CBool(False, config=True)
226 pprint = CBool(True, config=True)
227 profile = Str('', config=True)
228 prompt_in1 = Str('In [\\#]: ', config=True)
229 prompt_in2 = Str(' .\\D.: ', config=True)
230 prompt_out = Str('Out[\\#]: ', config=True)
231 prompts_pad_left = CBool(True, config=True)
232 quiet = CBool(False, config=True)
233
234 readline_use = CBool(True, config=True)
235 readline_merge_completions = CBool(True, config=True)
236 readline_omit__names = Enum((0,1,2), default_value=0, config=True)
237 readline_remove_delims = Str('-/~', config=True)
238 readline_parse_and_bind = List([
239 'tab: complete',
240 '"\C-l": possible-completions',
241 'set show-all-if-ambiguous on',
242 '"\C-o": tab-insert',
243 '"\M-i": " "',
244 '"\M-o": "\d\d\d\d"',
245 '"\M-I": "\d\d\d\d"',
246 '"\C-r": reverse-search-history',
247 '"\C-s": forward-search-history',
248 '"\C-p": history-search-backward',
249 '"\C-n": history-search-forward',
250 '"\e[A": history-search-backward',
251 '"\e[B": history-search-forward',
252 '"\C-k": kill-line',
253 '"\C-u": unix-line-discard',
254 ], allow_none=False, config=True)
255
256 screen_length = Int(0, config=True)
257
258 # Use custom TraitletTypes that convert '0'->'' and '\\n'->'\n'
259 separate_in = SeparateStr('\n', config=True)
260 separate_out = SeparateStr('', config=True)
261 separate_out2 = SeparateStr('', config=True)
262
263 system_header = Str('IPython system call: ', config=True)
264 system_verbose = CBool(False, config=True)
265 term_title = CBool(False, config=True)
266 wildcards_case_sensitive = CBool(True, config=True)
267 xmode = CaselessStrEnum(('Context','Plain', 'Verbose'),
268 default_value='Context', config=True)
269
270 autoexec = List(allow_none=False)
271
272 # class attribute to indicate whether the class supports threads or not.
273 # Subclasses with thread support should override this as needed.
274 isthreaded = False
275
276 def __init__(self, parent=None, config=None, ipython_dir=None, usage=None,
277 user_ns=None, user_global_ns=None,
278 banner1=None, banner2=None, display_banner=None,
279 custom_exceptions=((),None)):
280
281 # This is where traitlets with a config_key argument are updated
282 # from the values on config.
283 super(InteractiveShell, self).__init__(parent, config=config)
284
285 # These are relatively independent and stateless
286 self.init_ipython_dir(ipython_dir)
287 self.init_instance_attrs()
288 self.init_term_title()
289 self.init_usage(usage)
290 self.init_banner(banner1, banner2, display_banner)
291
292 # Create namespaces (user_ns, user_global_ns, etc.)
293 self.init_create_namespaces(user_ns, user_global_ns)
294 # This has to be done after init_create_namespaces because it uses
295 # something in self.user_ns, but before init_sys_modules, which
296 # is the first thing to modify sys.
297 self.save_sys_module_state()
298 self.init_sys_modules()
299
300 self.init_history()
301 self.init_encoding()
302 self.init_prefilter()
303
304 Magic.__init__(self, self)
305
306 self.init_syntax_highlighting()
307 self.init_hooks()
308 self.init_pushd_popd_magic()
309 self.init_traceback_handlers(custom_exceptions)
310 self.init_user_ns()
311 self.init_logger()
312 self.init_alias()
313 self.init_builtins()
314
315 # pre_config_initialization
316 self.init_shadow_hist()
317
318 # The next section should contain averything that was in ipmaker.
319 self.init_logstart()
320
321 # The following was in post_config_initialization
322 self.init_inspector()
323 self.init_readline()
324 self.init_prompts()
325 self.init_displayhook()
326 self.init_reload_doctest()
327 self.init_magics()
328 self.init_pdb()
329 self.hooks.late_startup_hook()
330
331 def get_ipython(self):
332 return self
333
334 #-------------------------------------------------------------------------
335 # Traitlet changed handlers
336 #-------------------------------------------------------------------------
337
338 def _banner1_changed(self):
339 self.compute_banner()
340
341 def _banner2_changed(self):
342 self.compute_banner()
343
344 def _ipython_dir_changed(self, name, new):
345 if not os.path.isdir(new):
346 os.makedirs(new, mode = 0777)
347 if not os.path.isdir(self.ipython_extension_dir):
348 os.makedirs(self.ipython_extension_dir, mode = 0777)
349
350 @property
351 def ipython_extension_dir(self):
352 return os.path.join(self.ipython_dir, 'extensions')
353
354 @property
355 def usable_screen_length(self):
356 if self.screen_length == 0:
357 return 0
358 else:
359 num_lines_bot = self.separate_in.count('\n')+1
360 return self.screen_length - num_lines_bot
361
362 def _term_title_changed(self, name, new_value):
363 self.init_term_title()
364
365 def set_autoindent(self,value=None):
366 """Set the autoindent flag, checking for readline support.
367
368 If called with no arguments, it acts as a toggle."""
369
370 if not self.has_readline:
371 if os.name == 'posix':
372 warn("The auto-indent feature requires the readline library")
373 self.autoindent = 0
374 return
375 if value is None:
376 self.autoindent = not self.autoindent
377 else:
378 self.autoindent = value
379
380 #-------------------------------------------------------------------------
381 # init_* methods called by __init__
382 #-------------------------------------------------------------------------
383
384 def init_ipython_dir(self, ipython_dir):
385 if ipython_dir is not None:
386 self.ipython_dir = ipython_dir
387 self.config.Global.ipython_dir = self.ipython_dir
388 return
389
390 if hasattr(self.config.Global, 'ipython_dir'):
391 self.ipython_dir = self.config.Global.ipython_dir
392 else:
393 self.ipython_dir = get_ipython_dir()
394
395 # All children can just read this
396 self.config.Global.ipython_dir = self.ipython_dir
397
398 def init_instance_attrs(self):
399 self.jobs = BackgroundJobManager()
400 self.more = False
401
402 # command compiler
403 self.compile = codeop.CommandCompiler()
404
405 # User input buffer
406 self.buffer = []
407
408 # Make an empty namespace, which extension writers can rely on both
409 # existing and NEVER being used by ipython itself. This gives them a
410 # convenient location for storing additional information and state
411 # their extensions may require, without fear of collisions with other
412 # ipython names that may develop later.
413 self.meta = Struct()
414
415 # Object variable to store code object waiting execution. This is
416 # used mainly by the multithreaded shells, but it can come in handy in
417 # other situations. No need to use a Queue here, since it's a single
418 # item which gets cleared once run.
419 self.code_to_run = None
420
421 # Flag to mark unconditional exit
422 self.exit_now = False
423
424 # Temporary files used for various purposes. Deleted at exit.
425 self.tempfiles = []
426
427 # Keep track of readline usage (later set by init_readline)
428 self.has_readline = False
429
430 # keep track of where we started running (mainly for crash post-mortem)
431 # This is not being used anywhere currently.
432 self.starting_dir = os.getcwd()
433
434 # Indentation management
435 self.indent_current_nsp = 0
436
437 def init_term_title(self):
438 # Enable or disable the terminal title.
439 if self.term_title:
440 toggle_set_term_title(True)
441 set_term_title('IPython: ' + abbrev_cwd())
442 else:
443 toggle_set_term_title(False)
444
445 def init_usage(self, usage=None):
446 if usage is None:
447 self.usage = interactive_usage
448 else:
449 self.usage = usage
450
451 def init_encoding(self):
452 # Get system encoding at startup time. Certain terminals (like Emacs
453 # under Win32 have it set to None, and we need to have a known valid
454 # encoding to use in the raw_input() method
455 try:
456 self.stdin_encoding = sys.stdin.encoding or 'ascii'
457 except AttributeError:
458 self.stdin_encoding = 'ascii'
459
460 def init_syntax_highlighting(self):
461 # Python source parser/formatter for syntax highlighting
462 pyformat = PyColorize.Parser().format
463 self.pycolorize = lambda src: pyformat(src,'str',self.colors)
464
465 def init_pushd_popd_magic(self):
466 # for pushd/popd management
467 try:
468 self.home_dir = get_home_dir()
469 except HomeDirError, msg:
470 fatal(msg)
471
472 self.dir_stack = []
473
474 def init_logger(self):
475 self.logger = Logger(self, logfname='ipython_log.py', logmode='rotate')
476 # local shortcut, this is used a LOT
477 self.log = self.logger.log
478
479 def init_logstart(self):
480 if self.logappend:
481 self.magic_logstart(self.logappend + ' append')
482 elif self.logfile:
483 self.magic_logstart(self.logfile)
484 elif self.logstart:
485 self.magic_logstart()
486
487 def init_builtins(self):
488 self.builtin_trap = BuiltinTrap(self)
489
490 def init_inspector(self):
491 # Object inspector
492 self.inspector = oinspect.Inspector(oinspect.InspectColors,
493 PyColorize.ANSICodeColors,
494 'NoColor',
495 self.object_info_string_level)
496
497 def init_prompts(self):
498 # Initialize cache, set in/out prompts and printing system
499 self.outputcache = CachedOutput(self,
500 self.cache_size,
501 self.pprint,
502 input_sep = self.separate_in,
503 output_sep = self.separate_out,
504 output_sep2 = self.separate_out2,
505 ps1 = self.prompt_in1,
506 ps2 = self.prompt_in2,
507 ps_out = self.prompt_out,
508 pad_left = self.prompts_pad_left)
509
510 # user may have over-ridden the default print hook:
511 try:
512 self.outputcache.__class__.display = self.hooks.display
513 except AttributeError:
514 pass
515
516 def init_displayhook(self):
517 self.display_trap = DisplayTrap(self, self.outputcache)
518
519 def init_reload_doctest(self):
520 # Do a proper resetting of doctest, including the necessary displayhook
521 # monkeypatching
522 try:
523 doctest_reload()
524 except ImportError:
525 warn("doctest module does not exist.")
526
527 #-------------------------------------------------------------------------
528 # Things related to the banner
529 #-------------------------------------------------------------------------
530
531 def init_banner(self, banner1, banner2, display_banner):
532 if banner1 is not None:
533 self.banner1 = banner1
534 if banner2 is not None:
535 self.banner2 = banner2
536 if display_banner is not None:
537 self.display_banner = display_banner
538 self.compute_banner()
539
540 def show_banner(self, banner=None):
541 if banner is None:
542 banner = self.banner
543 self.write(banner)
544
545 def compute_banner(self):
546 self.banner = self.banner1 + '\n'
547 if self.profile:
548 self.banner += '\nIPython profile: %s\n' % self.profile
549 if self.banner2:
550 self.banner += '\n' + self.banner2 + '\n'
551
552 #-------------------------------------------------------------------------
553 # Things related to injections into the sys module
554 #-------------------------------------------------------------------------
555
556 def save_sys_module_state(self):
557 """Save the state of hooks in the sys module.
558
559 This has to be called after self.user_ns is created.
560 """
561 self._orig_sys_module_state = {}
562 self._orig_sys_module_state['stdin'] = sys.stdin
563 self._orig_sys_module_state['stdout'] = sys.stdout
564 self._orig_sys_module_state['stderr'] = sys.stderr
565 self._orig_sys_module_state['excepthook'] = sys.excepthook
566 try:
567 self._orig_sys_modules_main_name = self.user_ns['__name__']
568 except KeyError:
569 pass
570
571 def restore_sys_module_state(self):
572 """Restore the state of the sys module."""
573 try:
574 for k, v in self._orig_sys_module_state.items():
575 setattr(sys, k, v)
576 except AttributeError:
577 pass
578 try:
579 delattr(sys, 'ipcompleter')
580 except AttributeError:
581 pass
582 # Reset what what done in self.init_sys_modules
583 try:
584 sys.modules[self.user_ns['__name__']] = self._orig_sys_modules_main_name
585 except (AttributeError, KeyError):
586 pass
587
588 #-------------------------------------------------------------------------
589 # Things related to hooks
590 #-------------------------------------------------------------------------
591
592 def init_hooks(self):
593 # hooks holds pointers used for user-side customizations
594 self.hooks = Struct()
595
596 self.strdispatchers = {}
597
598 # Set all default hooks, defined in the IPython.hooks module.
599 import IPython.core.hooks
600 hooks = IPython.core.hooks
601 for hook_name in hooks.__all__:
602 # default hooks have priority 100, i.e. low; user hooks should have
603 # 0-100 priority
604 self.set_hook(hook_name,getattr(hooks,hook_name), 100)
605
606 def set_hook(self,name,hook, priority = 50, str_key = None, re_key = None):
607 """set_hook(name,hook) -> sets an internal IPython hook.
608
609 IPython exposes some of its internal API as user-modifiable hooks. By
610 adding your function to one of these hooks, you can modify IPython's
611 behavior to call at runtime your own routines."""
612
613 # At some point in the future, this should validate the hook before it
614 # accepts it. Probably at least check that the hook takes the number
615 # of args it's supposed to.
616
617 f = new.instancemethod(hook,self,self.__class__)
618
619 # check if the hook is for strdispatcher first
620 if str_key is not None:
621 sdp = self.strdispatchers.get(name, StrDispatch())
622 sdp.add_s(str_key, f, priority )
623 self.strdispatchers[name] = sdp
624 return
625 if re_key is not None:
626 sdp = self.strdispatchers.get(name, StrDispatch())
627 sdp.add_re(re.compile(re_key), f, priority )
628 self.strdispatchers[name] = sdp
629 return
630
631 dp = getattr(self.hooks, name, None)
632 if name not in IPython.core.hooks.__all__:
633 print "Warning! Hook '%s' is not one of %s" % (name, IPython.core.hooks.__all__ )
634 if not dp:
635 dp = IPython.core.hooks.CommandChainDispatcher()
636
637 try:
638 dp.add(f,priority)
639 except AttributeError:
640 # it was not commandchain, plain old func - replace
641 dp = f
642
643 setattr(self.hooks,name, dp)
644
645 #-------------------------------------------------------------------------
646 # Things related to the "main" module
647 #-------------------------------------------------------------------------
648
649 def new_main_mod(self,ns=None):
650 """Return a new 'main' module object for user code execution.
651 """
652 main_mod = self._user_main_module
653 init_fakemod_dict(main_mod,ns)
654 return main_mod
655
656 def cache_main_mod(self,ns,fname):
657 """Cache a main module's namespace.
658
659 When scripts are executed via %run, we must keep a reference to the
660 namespace of their __main__ module (a FakeModule instance) around so
661 that Python doesn't clear it, rendering objects defined therein
662 useless.
663
664 This method keeps said reference in a private dict, keyed by the
665 absolute path of the module object (which corresponds to the script
666 path). This way, for multiple executions of the same script we only
667 keep one copy of the namespace (the last one), thus preventing memory
668 leaks from old references while allowing the objects from the last
669 execution to be accessible.
670
671 Note: we can not allow the actual FakeModule instances to be deleted,
672 because of how Python tears down modules (it hard-sets all their
673 references to None without regard for reference counts). This method
674 must therefore make a *copy* of the given namespace, to allow the
675 original module's __dict__ to be cleared and reused.
676
677
678 Parameters
679 ----------
680 ns : a namespace (a dict, typically)
681
682 fname : str
683 Filename associated with the namespace.
684
685 Examples
686 --------
687
688 In [10]: import IPython
689
690 In [11]: _ip.cache_main_mod(IPython.__dict__,IPython.__file__)
691
692 In [12]: IPython.__file__ in _ip._main_ns_cache
693 Out[12]: True
694 """
695 self._main_ns_cache[os.path.abspath(fname)] = ns.copy()
696
697 def clear_main_mod_cache(self):
698 """Clear the cache of main modules.
699
700 Mainly for use by utilities like %reset.
701
702 Examples
703 --------
704
705 In [15]: import IPython
706
707 In [16]: _ip.cache_main_mod(IPython.__dict__,IPython.__file__)
708
709 In [17]: len(_ip._main_ns_cache) > 0
710 Out[17]: True
711
712 In [18]: _ip.clear_main_mod_cache()
713
714 In [19]: len(_ip._main_ns_cache) == 0
715 Out[19]: True
716 """
717 self._main_ns_cache.clear()
718
719 #-------------------------------------------------------------------------
720 # Things related to debugging
721 #-------------------------------------------------------------------------
722
723 def init_pdb(self):
724 # Set calling of pdb on exceptions
725 # self.call_pdb is a property
726 self.call_pdb = self.pdb
727
728 def _get_call_pdb(self):
729 return self._call_pdb
730
731 def _set_call_pdb(self,val):
732
733 if val not in (0,1,False,True):
734 raise ValueError,'new call_pdb value must be boolean'
735
736 # store value in instance
737 self._call_pdb = val
738
739 # notify the actual exception handlers
740 self.InteractiveTB.call_pdb = val
741 if self.isthreaded:
742 try:
743 self.sys_excepthook.call_pdb = val
744 except:
745 warn('Failed to activate pdb for threaded exception handler')
746
747 call_pdb = property(_get_call_pdb,_set_call_pdb,None,
748 'Control auto-activation of pdb at exceptions')
749
750 def debugger(self,force=False):
751 """Call the pydb/pdb debugger.
752
753 Keywords:
754
755 - force(False): by default, this routine checks the instance call_pdb
756 flag and does not actually invoke the debugger if the flag is false.
757 The 'force' option forces the debugger to activate even if the flag
758 is false.
759 """
760
761 if not (force or self.call_pdb):
762 return
763
764 if not hasattr(sys,'last_traceback'):
765 error('No traceback has been produced, nothing to debug.')
766 return
767
768 # use pydb if available
769 if debugger.has_pydb:
770 from pydb import pm
771 else:
772 # fallback to our internal debugger
773 pm = lambda : self.InteractiveTB.debugger(force=True)
774 self.history_saving_wrapper(pm)()
775
776 #-------------------------------------------------------------------------
777 # Things related to IPython's various namespaces
778 #-------------------------------------------------------------------------
779
780 def init_create_namespaces(self, user_ns=None, user_global_ns=None):
781 # Create the namespace where the user will operate. user_ns is
782 # normally the only one used, and it is passed to the exec calls as
783 # the locals argument. But we do carry a user_global_ns namespace
784 # given as the exec 'globals' argument, This is useful in embedding
785 # situations where the ipython shell opens in a context where the
786 # distinction between locals and globals is meaningful. For
787 # non-embedded contexts, it is just the same object as the user_ns dict.
788
789 # FIXME. For some strange reason, __builtins__ is showing up at user
790 # level as a dict instead of a module. This is a manual fix, but I
791 # should really track down where the problem is coming from. Alex
792 # Schmolck reported this problem first.
793
794 # A useful post by Alex Martelli on this topic:
795 # Re: inconsistent value from __builtins__
796 # Von: Alex Martelli <aleaxit@yahoo.com>
797 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
798 # Gruppen: comp.lang.python
799
800 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
801 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
802 # > <type 'dict'>
803 # > >>> print type(__builtins__)
804 # > <type 'module'>
805 # > Is this difference in return value intentional?
806
807 # Well, it's documented that '__builtins__' can be either a dictionary
808 # or a module, and it's been that way for a long time. Whether it's
809 # intentional (or sensible), I don't know. In any case, the idea is
810 # that if you need to access the built-in namespace directly, you
811 # should start with "import __builtin__" (note, no 's') which will
812 # definitely give you a module. Yeah, it's somewhat confusing:-(.
813
814 # These routines return properly built dicts as needed by the rest of
815 # the code, and can also be used by extension writers to generate
816 # properly initialized namespaces.
817 user_ns, user_global_ns = self.make_user_namespaces(user_ns,
818 user_global_ns)
819
820 # Assign namespaces
821 # This is the namespace where all normal user variables live
822 self.user_ns = user_ns
823 self.user_global_ns = user_global_ns
824
825 # An auxiliary namespace that checks what parts of the user_ns were
826 # loaded at startup, so we can list later only variables defined in
827 # actual interactive use. Since it is always a subset of user_ns, it
828 # doesn't need to be seaparately tracked in the ns_table
829 self.user_config_ns = {}
830
831 # A namespace to keep track of internal data structures to prevent
832 # them from cluttering user-visible stuff. Will be updated later
833 self.internal_ns = {}
834
835 # Now that FakeModule produces a real module, we've run into a nasty
836 # problem: after script execution (via %run), the module where the user
837 # code ran is deleted. Now that this object is a true module (needed
838 # so docetst and other tools work correctly), the Python module
839 # teardown mechanism runs over it, and sets to None every variable
840 # present in that module. Top-level references to objects from the
841 # script survive, because the user_ns is updated with them. However,
842 # calling functions defined in the script that use other things from
843 # the script will fail, because the function's closure had references
844 # to the original objects, which are now all None. So we must protect
845 # these modules from deletion by keeping a cache.
846 #
847 # To avoid keeping stale modules around (we only need the one from the
848 # last run), we use a dict keyed with the full path to the script, so
849 # only the last version of the module is held in the cache. Note,
850 # however, that we must cache the module *namespace contents* (their
851 # __dict__). Because if we try to cache the actual modules, old ones
852 # (uncached) could be destroyed while still holding references (such as
853 # those held by GUI objects that tend to be long-lived)>
854 #
855 # The %reset command will flush this cache. See the cache_main_mod()
856 # and clear_main_mod_cache() methods for details on use.
857
858 # This is the cache used for 'main' namespaces
859 self._main_ns_cache = {}
860 # And this is the single instance of FakeModule whose __dict__ we keep
861 # copying and clearing for reuse on each %run
862 self._user_main_module = FakeModule()
863
864 # A table holding all the namespaces IPython deals with, so that
865 # introspection facilities can search easily.
866 self.ns_table = {'user':user_ns,
867 'user_global':user_global_ns,
868 'internal':self.internal_ns,
869 'builtin':__builtin__.__dict__
870 }
871
872 # Similarly, track all namespaces where references can be held and that
873 # we can safely clear (so it can NOT include builtin). This one can be
874 # a simple list.
875 self.ns_refs_table = [ user_ns, user_global_ns, self.user_config_ns,
876 self.internal_ns, self._main_ns_cache ]
877
878 def init_sys_modules(self):
879 # We need to insert into sys.modules something that looks like a
880 # module but which accesses the IPython namespace, for shelve and
881 # pickle to work interactively. Normally they rely on getting
882 # everything out of __main__, but for embedding purposes each IPython
883 # instance has its own private namespace, so we can't go shoving
884 # everything into __main__.
885
886 # note, however, that we should only do this for non-embedded
887 # ipythons, which really mimic the __main__.__dict__ with their own
888 # namespace. Embedded instances, on the other hand, should not do
889 # this because they need to manage the user local/global namespaces
890 # only, but they live within a 'normal' __main__ (meaning, they
891 # shouldn't overtake the execution environment of the script they're
892 # embedded in).
893
894 # This is overridden in the InteractiveShellEmbed subclass to a no-op.
895
896 try:
897 main_name = self.user_ns['__name__']
898 except KeyError:
899 raise KeyError('user_ns dictionary MUST have a "__name__" key')
900 else:
901 sys.modules[main_name] = FakeModule(self.user_ns)
902
903 def make_user_namespaces(self, user_ns=None, user_global_ns=None):
904 """Return a valid local and global user interactive namespaces.
905
906 This builds a dict with the minimal information needed to operate as a
907 valid IPython user namespace, which you can pass to the various
908 embedding classes in ipython. The default implementation returns the
909 same dict for both the locals and the globals to allow functions to
910 refer to variables in the namespace. Customized implementations can
911 return different dicts. The locals dictionary can actually be anything
912 following the basic mapping protocol of a dict, but the globals dict
913 must be a true dict, not even a subclass. It is recommended that any
914 custom object for the locals namespace synchronize with the globals
915 dict somehow.
916
917 Raises TypeError if the provided globals namespace is not a true dict.
918
919 :Parameters:
920 user_ns : dict-like, optional
921 The current user namespace. The items in this namespace should
922 be included in the output. If None, an appropriate blank
923 namespace should be created.
924 user_global_ns : dict, optional
925 The current user global namespace. The items in this namespace
926 should be included in the output. If None, an appropriate
927 blank namespace should be created.
928
929 :Returns:
930 A tuple pair of dictionary-like object to be used as the local namespace
931 of the interpreter and a dict to be used as the global namespace.
932 """
933
934 if user_ns is None:
935 # Set __name__ to __main__ to better match the behavior of the
936 # normal interpreter.
937 user_ns = {'__name__' :'__main__',
938 '__builtins__' : __builtin__,
939 }
940 else:
941 user_ns.setdefault('__name__','__main__')
942 user_ns.setdefault('__builtins__',__builtin__)
943
944 if user_global_ns is None:
945 user_global_ns = user_ns
946 if type(user_global_ns) is not dict:
947 raise TypeError("user_global_ns must be a true dict; got %r"
948 % type(user_global_ns))
949
950 return user_ns, user_global_ns
951
952 def init_user_ns(self):
953 """Initialize all user-visible namespaces to their minimum defaults.
954
955 Certain history lists are also initialized here, as they effectively
956 act as user namespaces.
957
958 Notes
959 -----
960 All data structures here are only filled in, they are NOT reset by this
961 method. If they were not empty before, data will simply be added to
962 therm.
963 """
964 # Store myself as the public api!!!
965 self.user_ns['get_ipython'] = self.get_ipython
966
967 # make global variables for user access to the histories
968 self.user_ns['_ih'] = self.input_hist
969 self.user_ns['_oh'] = self.output_hist
970 self.user_ns['_dh'] = self.dir_hist
971
972 # user aliases to input and output histories
973 self.user_ns['In'] = self.input_hist
974 self.user_ns['Out'] = self.output_hist
975
976 self.user_ns['_sh'] = shadowns
977
978 # Put 'help' in the user namespace
979 try:
980 from site import _Helper
981 self.user_ns['help'] = _Helper()
982 except ImportError:
983 warn('help() not available - check site.py')
984
985 def reset(self):
986 """Clear all internal namespaces.
987
988 Note that this is much more aggressive than %reset, since it clears
989 fully all namespaces, as well as all input/output lists.
990 """
991 for ns in self.ns_refs_table:
992 ns.clear()
993
994 self.alias_manager.clear_aliases()
995
996 # Clear input and output histories
997 self.input_hist[:] = []
998 self.input_hist_raw[:] = []
999 self.output_hist.clear()
1000
1001 # Restore the user namespaces to minimal usability
1002 self.init_user_ns()
1003
1004 # Restore the default and user aliases
1005 self.alias_manager.init_aliases()
1006
1007 def push(self, variables, interactive=True):
1008 """Inject a group of variables into the IPython user namespace.
1009
1010 Parameters
1011 ----------
1012 variables : dict, str or list/tuple of str
1013 The variables to inject into the user's namespace. If a dict,
1014 a simple update is done. If a str, the string is assumed to
1015 have variable names separated by spaces. A list/tuple of str
1016 can also be used to give the variable names. If just the variable
1017 names are give (list/tuple/str) then the variable values looked
1018 up in the callers frame.
1019 interactive : bool
1020 If True (default), the variables will be listed with the ``who``
1021 magic.
1022 """
1023 vdict = None
1024
1025 # We need a dict of name/value pairs to do namespace updates.
1026 if isinstance(variables, dict):
1027 vdict = variables
1028 elif isinstance(variables, (basestring, list, tuple)):
1029 if isinstance(variables, basestring):
1030 vlist = variables.split()
1031 else:
1032 vlist = variables
1033 vdict = {}
1034 cf = sys._getframe(1)
1035 for name in vlist:
1036 try:
1037 vdict[name] = eval(name, cf.f_globals, cf.f_locals)
1038 except:
1039 print ('Could not get variable %s from %s' %
1040 (name,cf.f_code.co_name))
1041 else:
1042 raise ValueError('variables must be a dict/str/list/tuple')
1043
1044 # Propagate variables to user namespace
1045 self.user_ns.update(vdict)
1046
1047 # And configure interactive visibility
1048 config_ns = self.user_config_ns
1049 if interactive:
1050 for name, val in vdict.iteritems():
1051 config_ns.pop(name, None)
1052 else:
1053 for name,val in vdict.iteritems():
1054 config_ns[name] = val
1055
1056 #-------------------------------------------------------------------------
1057 # Things related to history management
1058 #-------------------------------------------------------------------------
1059
1060 def init_history(self):
1061 # List of input with multi-line handling.
1062 self.input_hist = InputList()
1063 # This one will hold the 'raw' input history, without any
1064 # pre-processing. This will allow users to retrieve the input just as
1065 # it was exactly typed in by the user, with %hist -r.
1066 self.input_hist_raw = InputList()
1067
1068 # list of visited directories
1069 try:
1070 self.dir_hist = [os.getcwd()]
1071 except OSError:
1072 self.dir_hist = []
1073
1074 # dict of output history
1075 self.output_hist = {}
1076
1077 # Now the history file
1078 if self.profile:
1079 histfname = 'history-%s' % self.profile
1080 else:
1081 histfname = 'history'
1082 self.histfile = os.path.join(self.ipython_dir, histfname)
1083
1084 # Fill the history zero entry, user counter starts at 1
1085 self.input_hist.append('\n')
1086 self.input_hist_raw.append('\n')
1087
1088 def init_shadow_hist(self):
1089 try:
1090 self.db = pickleshare.PickleShareDB(self.ipython_dir + "/db")
1091 except exceptions.UnicodeDecodeError:
1092 print "Your ipython_dir can't be decoded to unicode!"
1093 print "Please set HOME environment variable to something that"
1094 print r"only has ASCII characters, e.g. c:\home"
1095 print "Now it is", self.ipython_dir
1096 sys.exit()
1097 self.shadowhist = ipcorehist.ShadowHist(self.db)
1098
1099 def savehist(self):
1100 """Save input history to a file (via readline library)."""
1101
1102 if not self.has_readline:
1103 return
1104
1105 try:
1106 self.readline.write_history_file(self.histfile)
1107 except:
1108 print 'Unable to save IPython command history to file: ' + \
1109 `self.histfile`
1110
1111 def reloadhist(self):
1112 """Reload the input history from disk file."""
1113
1114 if self.has_readline:
1115 try:
1116 self.readline.clear_history()
1117 self.readline.read_history_file(self.shell.histfile)
1118 except AttributeError:
1119 pass
1120
1121 def history_saving_wrapper(self, func):
1122 """ Wrap func for readline history saving
1123
1124 Convert func into callable that saves & restores
1125 history around the call """
1126
1127 if not self.has_readline:
1128 return func
1129
1130 def wrapper():
1131 self.savehist()
1132 try:
1133 func()
1134 finally:
1135 readline.read_history_file(self.histfile)
1136 return wrapper
1137
1138 #-------------------------------------------------------------------------
1139 # Things related to exception handling and tracebacks (not debugging)
1140 #-------------------------------------------------------------------------
1141
1142 def init_traceback_handlers(self, custom_exceptions):
1143 # Syntax error handler.
1144 self.SyntaxTB = SyntaxTB(color_scheme='NoColor')
1145
1146 # The interactive one is initialized with an offset, meaning we always
1147 # want to remove the topmost item in the traceback, which is our own
1148 # internal code. Valid modes: ['Plain','Context','Verbose']
1149 self.InteractiveTB = ultratb.AutoFormattedTB(mode = 'Plain',
1150 color_scheme='NoColor',
1151 tb_offset = 1)
1152
1153 # IPython itself shouldn't crash. This will produce a detailed
1154 # post-mortem if it does. But we only install the crash handler for
1155 # non-threaded shells, the threaded ones use a normal verbose reporter
1156 # and lose the crash handler. This is because exceptions in the main
1157 # thread (such as in GUI code) propagate directly to sys.excepthook,
1158 # and there's no point in printing crash dumps for every user exception.
1159 if self.isthreaded:
1160 ipCrashHandler = ultratb.FormattedTB()
1161 else:
1162 from IPython.core import crashhandler
1163 ipCrashHandler = crashhandler.IPythonCrashHandler(self)
1164 self.set_crash_handler(ipCrashHandler)
1165
1166 # and add any custom exception handlers the user may have specified
1167 self.set_custom_exc(*custom_exceptions)
1168
1169 def set_crash_handler(self, crashHandler):
1170 """Set the IPython crash handler.
1171
1172 This must be a callable with a signature suitable for use as
1173 sys.excepthook."""
1174
1175 # Install the given crash handler as the Python exception hook
1176 sys.excepthook = crashHandler
1177
1178 # The instance will store a pointer to this, so that runtime code
1179 # (such as magics) can access it. This is because during the
1180 # read-eval loop, it gets temporarily overwritten (to deal with GUI
1181 # frameworks).
1182 self.sys_excepthook = sys.excepthook
1183
1184 def set_custom_exc(self,exc_tuple,handler):
1185 """set_custom_exc(exc_tuple,handler)
1186
1187 Set a custom exception handler, which will be called if any of the
1188 exceptions in exc_tuple occur in the mainloop (specifically, in the
1189 runcode() method.
1190
1191 Inputs:
1192
1193 - exc_tuple: a *tuple* of valid exceptions to call the defined
1194 handler for. It is very important that you use a tuple, and NOT A
1195 LIST here, because of the way Python's except statement works. If
1196 you only want to trap a single exception, use a singleton tuple:
1197
1198 exc_tuple == (MyCustomException,)
1199
1200 - handler: this must be defined as a function with the following
1201 basic interface: def my_handler(self,etype,value,tb).
1202
1203 This will be made into an instance method (via new.instancemethod)
1204 of IPython itself, and it will be called if any of the exceptions
1205 listed in the exc_tuple are caught. If the handler is None, an
1206 internal basic one is used, which just prints basic info.
1207
1208 WARNING: by putting in your own exception handler into IPython's main
1209 execution loop, you run a very good chance of nasty crashes. This
1210 facility should only be used if you really know what you are doing."""
1211
1212 assert type(exc_tuple)==type(()) , \
1213 "The custom exceptions must be given AS A TUPLE."
1214
1215 def dummy_handler(self,etype,value,tb):
1216 print '*** Simple custom exception handler ***'
1217 print 'Exception type :',etype
1218 print 'Exception value:',value
1219 print 'Traceback :',tb
1220 print 'Source code :','\n'.join(self.buffer)
1221
1222 if handler is None: handler = dummy_handler
1223
1224 self.CustomTB = new.instancemethod(handler,self,self.__class__)
1225 self.custom_exceptions = exc_tuple
1226
1227 def excepthook(self, etype, value, tb):
1228 """One more defense for GUI apps that call sys.excepthook.
1229
1230 GUI frameworks like wxPython trap exceptions and call
1231 sys.excepthook themselves. I guess this is a feature that
1232 enables them to keep running after exceptions that would
1233 otherwise kill their mainloop. This is a bother for IPython
1234 which excepts to catch all of the program exceptions with a try:
1235 except: statement.
1236
1237 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
1238 any app directly invokes sys.excepthook, it will look to the user like
1239 IPython crashed. In order to work around this, we can disable the
1240 CrashHandler and replace it with this excepthook instead, which prints a
1241 regular traceback using our InteractiveTB. In this fashion, apps which
1242 call sys.excepthook will generate a regular-looking exception from
1243 IPython, and the CrashHandler will only be triggered by real IPython
1244 crashes.
1245
1246 This hook should be used sparingly, only in places which are not likely
1247 to be true IPython errors.
1248 """
1249 self.showtraceback((etype,value,tb),tb_offset=0)
1250
1251 def showtraceback(self,exc_tuple = None,filename=None,tb_offset=None):
1252 """Display the exception that just occurred.
1253
1254 If nothing is known about the exception, this is the method which
1255 should be used throughout the code for presenting user tracebacks,
1256 rather than directly invoking the InteractiveTB object.
1257
1258 A specific showsyntaxerror() also exists, but this method can take
1259 care of calling it if needed, so unless you are explicitly catching a
1260 SyntaxError exception, don't try to analyze the stack manually and
1261 simply call this method."""
1262
1263
1264 # Though this won't be called by syntax errors in the input line,
1265 # there may be SyntaxError cases whith imported code.
1266
1267 try:
1268 if exc_tuple is None:
1269 etype, value, tb = sys.exc_info()
1270 else:
1271 etype, value, tb = exc_tuple
1272
1273 if etype is SyntaxError:
1274 self.showsyntaxerror(filename)
1275 elif etype is UsageError:
1276 print "UsageError:", value
1277 else:
1278 # WARNING: these variables are somewhat deprecated and not
1279 # necessarily safe to use in a threaded environment, but tools
1280 # like pdb depend on their existence, so let's set them. If we
1281 # find problems in the field, we'll need to revisit their use.
1282 sys.last_type = etype
1283 sys.last_value = value
1284 sys.last_traceback = tb
1285
1286 if etype in self.custom_exceptions:
1287 self.CustomTB(etype,value,tb)
1288 else:
1289 self.InteractiveTB(etype,value,tb,tb_offset=tb_offset)
1290 if self.InteractiveTB.call_pdb and self.has_readline:
1291 # pdb mucks up readline, fix it back
1292 self.set_completer()
1293 except KeyboardInterrupt:
1294 self.write("\nKeyboardInterrupt\n")
1295
1296 def showsyntaxerror(self, filename=None):
1297 """Display the syntax error that just occurred.
1298
1299 This doesn't display a stack trace because there isn't one.
1300
1301 If a filename is given, it is stuffed in the exception instead
1302 of what was there before (because Python's parser always uses
1303 "<string>" when reading from a string).
1304 """
1305 etype, value, last_traceback = sys.exc_info()
1306
1307 # See note about these variables in showtraceback() below
1308 sys.last_type = etype
1309 sys.last_value = value
1310 sys.last_traceback = last_traceback
1311
1312 if filename and etype is SyntaxError:
1313 # Work hard to stuff the correct filename in the exception
1314 try:
1315 msg, (dummy_filename, lineno, offset, line) = value
1316 except:
1317 # Not the format we expect; leave it alone
1318 pass
1319 else:
1320 # Stuff in the right filename
1321 try:
1322 # Assume SyntaxError is a class exception
1323 value = SyntaxError(msg, (filename, lineno, offset, line))
1324 except:
1325 # If that failed, assume SyntaxError is a string
1326 value = msg, (filename, lineno, offset, line)
1327 self.SyntaxTB(etype,value,[])
1328
1329 def edit_syntax_error(self):
1330 """The bottom half of the syntax error handler called in the main loop.
1331
1332 Loop until syntax error is fixed or user cancels.
1333 """
1334
1335 while self.SyntaxTB.last_syntax_error:
1336 # copy and clear last_syntax_error
1337 err = self.SyntaxTB.clear_err_state()
1338 if not self._should_recompile(err):
1339 return
1340 try:
1341 # may set last_syntax_error again if a SyntaxError is raised
1342 self.safe_execfile(err.filename,self.user_ns)
1343 except:
1344 self.showtraceback()
1345 else:
1346 try:
1347 f = file(err.filename)
1348 try:
1349 # This should be inside a display_trap block and I
1350 # think it is.
1351 sys.displayhook(f.read())
1352 finally:
1353 f.close()
1354 except:
1355 self.showtraceback()
1356
1357 def _should_recompile(self,e):
1358 """Utility routine for edit_syntax_error"""
1359
1360 if e.filename in ('<ipython console>','<input>','<string>',
1361 '<console>','<BackgroundJob compilation>',
1362 None):
1363
1364 return False
1365 try:
1366 if (self.autoedit_syntax and
1367 not self.ask_yes_no('Return to editor to correct syntax error? '
1368 '[Y/n] ','y')):
1369 return False
1370 except EOFError:
1371 return False
1372
1373 def int0(x):
1374 try:
1375 return int(x)
1376 except TypeError:
1377 return 0
1378 # always pass integer line and offset values to editor hook
1379 try:
1380 self.hooks.fix_error_editor(e.filename,
1381 int0(e.lineno),int0(e.offset),e.msg)
1382 except TryNext:
1383 warn('Could not open editor')
1384 return False
1385 return True
1386
1387 #-------------------------------------------------------------------------
1388 # Things related to tab completion
1389 #-------------------------------------------------------------------------
1390
1391 def complete(self, text):
1392 """Return a sorted list of all possible completions on text.
1393
1394 Inputs:
1395
1396 - text: a string of text to be completed on.
1397
1398 This is a wrapper around the completion mechanism, similar to what
1399 readline does at the command line when the TAB key is hit. By
1400 exposing it as a method, it can be used by other non-readline
1401 environments (such as GUIs) for text completion.
1402
1403 Simple usage example:
1404
1405 In [7]: x = 'hello'
1406
1407 In [8]: x
1408 Out[8]: 'hello'
1409
1410 In [9]: print x
1411 hello
1412
1413 In [10]: _ip.complete('x.l')
1414 Out[10]: ['x.ljust', 'x.lower', 'x.lstrip']
1415 """
1416
1417 # Inject names into __builtin__ so we can complete on the added names.
1418 with self.builtin_trap:
1419 complete = self.Completer.complete
1420 state = 0
1421 # use a dict so we get unique keys, since ipyhton's multiple
1422 # completers can return duplicates. When we make 2.4 a requirement,
1423 # start using sets instead, which are faster.
1424 comps = {}
1425 while True:
1426 newcomp = complete(text,state,line_buffer=text)
1427 if newcomp is None:
1428 break
1429 comps[newcomp] = 1
1430 state += 1
1431 outcomps = comps.keys()
1432 outcomps.sort()
1433 #print "T:",text,"OC:",outcomps # dbg
1434 #print "vars:",self.user_ns.keys()
1435 return outcomps
1436
1437 def set_custom_completer(self,completer,pos=0):
1438 """Adds a new custom completer function.
1439
1440 The position argument (defaults to 0) is the index in the completers
1441 list where you want the completer to be inserted."""
1442
1443 newcomp = new.instancemethod(completer,self.Completer,
1444 self.Completer.__class__)
1445 self.Completer.matchers.insert(pos,newcomp)
1446
1447 def set_completer(self):
1448 """Reset readline's completer to be our own."""
1449 self.readline.set_completer(self.Completer.complete)
1450
1451 def set_completer_frame(self, frame=None):
1452 """Set the frame of the completer."""
1453 if frame:
1454 self.Completer.namespace = frame.f_locals
1455 self.Completer.global_namespace = frame.f_globals
1456 else:
1457 self.Completer.namespace = self.user_ns
1458 self.Completer.global_namespace = self.user_global_ns
1459
1460 #-------------------------------------------------------------------------
1461 # Things related to readline
1462 #-------------------------------------------------------------------------
1463
1464 def init_readline(self):
1465 """Command history completion/saving/reloading."""
1466
1467 self.rl_next_input = None
1468 self.rl_do_indent = False
1469
1470 if not self.readline_use:
1471 return
1472
1473 import IPython.utils.rlineimpl as readline
1474
1475 if not readline.have_readline:
1476 self.has_readline = 0
1477 self.readline = None
1478 # no point in bugging windows users with this every time:
1479 warn('Readline services not available on this platform.')
1480 else:
1481 sys.modules['readline'] = readline
1482 import atexit
1483 from IPython.core.completer import IPCompleter
1484 self.Completer = IPCompleter(self,
1485 self.user_ns,
1486 self.user_global_ns,
1487 self.readline_omit__names,
1488 self.alias_manager.alias_table)
1489 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
1490 self.strdispatchers['complete_command'] = sdisp
1491 self.Completer.custom_completers = sdisp
1492 # Platform-specific configuration
1493 if os.name == 'nt':
1494 self.readline_startup_hook = readline.set_pre_input_hook
1495 else:
1496 self.readline_startup_hook = readline.set_startup_hook
1497
1498 # Load user's initrc file (readline config)
1499 # Or if libedit is used, load editrc.
1500 inputrc_name = os.environ.get('INPUTRC')
1501 if inputrc_name is None:
1502 home_dir = get_home_dir()
1503 if home_dir is not None:
1504 inputrc_name = '.inputrc'
1505 if readline.uses_libedit:
1506 inputrc_name = '.editrc'
1507 inputrc_name = os.path.join(home_dir, inputrc_name)
1508 if os.path.isfile(inputrc_name):
1509 try:
1510 readline.read_init_file(inputrc_name)
1511 except:
1512 warn('Problems reading readline initialization file <%s>'
1513 % inputrc_name)
1514
1515 self.has_readline = 1
1516 self.readline = readline
1517 # save this in sys so embedded copies can restore it properly
1518 sys.ipcompleter = self.Completer.complete
1519 self.set_completer()
1520
1521 # Configure readline according to user's prefs
1522 # This is only done if GNU readline is being used. If libedit
1523 # is being used (as on Leopard) the readline config is
1524 # not run as the syntax for libedit is different.
1525 if not readline.uses_libedit:
1526 for rlcommand in self.readline_parse_and_bind:
1527 #print "loading rl:",rlcommand # dbg
1528 readline.parse_and_bind(rlcommand)
1529
1530 # Remove some chars from the delimiters list. If we encounter
1531 # unicode chars, discard them.
1532 delims = readline.get_completer_delims().encode("ascii", "ignore")
1533 delims = delims.translate(string._idmap,
1534 self.readline_remove_delims)
1535 readline.set_completer_delims(delims)
1536 # otherwise we end up with a monster history after a while:
1537 readline.set_history_length(1000)
1538 try:
1539 #print '*** Reading readline history' # dbg
1540 readline.read_history_file(self.histfile)
1541 except IOError:
1542 pass # It doesn't exist yet.
1543
1544 atexit.register(self.atexit_operations)
1545 del atexit
1546
1547 # Configure auto-indent for all platforms
1548 self.set_autoindent(self.autoindent)
1549
1550 def set_next_input(self, s):
1551 """ Sets the 'default' input string for the next command line.
1552
1553 Requires readline.
1554
1555 Example:
1556
1557 [D:\ipython]|1> _ip.set_next_input("Hello Word")
1558 [D:\ipython]|2> Hello Word_ # cursor is here
1559 """
1560
1561 self.rl_next_input = s
1562
1563 def pre_readline(self):
1564 """readline hook to be used at the start of each line.
1565
1566 Currently it handles auto-indent only."""
1567
1568 #debugx('self.indent_current_nsp','pre_readline:')
1569
1570 if self.rl_do_indent:
1571 self.readline.insert_text(self._indent_current_str())
1572 if self.rl_next_input is not None:
1573 self.readline.insert_text(self.rl_next_input)
1574 self.rl_next_input = None
1575
1576 def _indent_current_str(self):
1577 """return the current level of indentation as a string"""
1578 return self.indent_current_nsp * ' '
1579
1580 #-------------------------------------------------------------------------
1581 # Things related to magics
1582 #-------------------------------------------------------------------------
1583
1584 def init_magics(self):
1585 # Set user colors (don't do it in the constructor above so that it
1586 # doesn't crash if colors option is invalid)
1587 self.magic_colors(self.colors)
1588
1589 def magic(self,arg_s):
1590 """Call a magic function by name.
1591
1592 Input: a string containing the name of the magic function to call and any
1593 additional arguments to be passed to the magic.
1594
1595 magic('name -opt foo bar') is equivalent to typing at the ipython
1596 prompt:
1597
1598 In[1]: %name -opt foo bar
1599
1600 To call a magic without arguments, simply use magic('name').
1601
1602 This provides a proper Python function to call IPython's magics in any
1603 valid Python code you can type at the interpreter, including loops and
1604 compound statements.
1605 """
1606
1607 args = arg_s.split(' ',1)
1608 magic_name = args[0]
1609 magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
1610
1611 try:
1612 magic_args = args[1]
1613 except IndexError:
1614 magic_args = ''
1615 fn = getattr(self,'magic_'+magic_name,None)
1616 if fn is None:
1617 error("Magic function `%s` not found." % magic_name)
1618 else:
1619 magic_args = self.var_expand(magic_args,1)
1620 with nested(self.builtin_trap,):
1621 result = fn(magic_args)
1622 return result
1623
1624 def define_magic(self, magicname, func):
1625 """Expose own function as magic function for ipython
1626
1627 def foo_impl(self,parameter_s=''):
1628 'My very own magic!. (Use docstrings, IPython reads them).'
1629 print 'Magic function. Passed parameter is between < >:'
1630 print '<%s>' % parameter_s
1631 print 'The self object is:',self
1632
1633 self.define_magic('foo',foo_impl)
1634 """
1635
1636 import new
1637 im = new.instancemethod(func,self, self.__class__)
1638 old = getattr(self, "magic_" + magicname, None)
1639 setattr(self, "magic_" + magicname, im)
1640 return old
1641
1642 #-------------------------------------------------------------------------
1643 # Things related to macros
1644 #-------------------------------------------------------------------------
1645
1646 def define_macro(self, name, themacro):
1647 """Define a new macro
1648
1649 Parameters
1650 ----------
1651 name : str
1652 The name of the macro.
1653 themacro : str or Macro
1654 The action to do upon invoking the macro. If a string, a new
1655 Macro object is created by passing the string to it.
1656 """
1657
1658 from IPython.core import macro
1659
1660 if isinstance(themacro, basestring):
1661 themacro = macro.Macro(themacro)
1662 if not isinstance(themacro, macro.Macro):
1663 raise ValueError('A macro must be a string or a Macro instance.')
1664 self.user_ns[name] = themacro
1665
1666 #-------------------------------------------------------------------------
1667 # Things related to the running of system commands
1668 #-------------------------------------------------------------------------
1669
1670 def system(self, cmd):
1671 """Make a system call, using IPython."""
1672 return self.hooks.shell_hook(self.var_expand(cmd, depth=2))
1673
1674 #-------------------------------------------------------------------------
1675 # Things related to aliases
1676 #-------------------------------------------------------------------------
1677
1678 def init_alias(self):
1679 self.alias_manager = AliasManager(self, config=self.config)
1680 self.ns_table['alias'] = self.alias_manager.alias_table,
1681
1682 #-------------------------------------------------------------------------
1683 # Things related to the running of code
1684 #-------------------------------------------------------------------------
1685
1686 def ex(self, cmd):
1687 """Execute a normal python statement in user namespace."""
1688 with nested(self.builtin_trap,):
1689 exec cmd in self.user_global_ns, self.user_ns
1690
1691 def ev(self, expr):
1692 """Evaluate python expression expr in user namespace.
1693
1694 Returns the result of evaluation
1695 """
1696 with nested(self.builtin_trap,):
1697 return eval(expr, self.user_global_ns, self.user_ns)
1698
1699 def mainloop(self, display_banner=None):
1700 """Start the mainloop.
1701
1702 If an optional banner argument is given, it will override the
1703 internally created default banner.
1704 """
1705
1706 with nested(self.builtin_trap, self.display_trap):
1707
1708 # if you run stuff with -c <cmd>, raw hist is not updated
1709 # ensure that it's in sync
1710 if len(self.input_hist) != len (self.input_hist_raw):
1711 self.input_hist_raw = InputList(self.input_hist)
1712
1713 while 1:
1714 try:
1715 self.interact(display_banner=display_banner)
1716 #self.interact_with_readline()
1717 # XXX for testing of a readline-decoupled repl loop, call
1718 # interact_with_readline above
1719 break
1720 except KeyboardInterrupt:
1721 # this should not be necessary, but KeyboardInterrupt
1722 # handling seems rather unpredictable...
1723 self.write("\nKeyboardInterrupt in interact()\n")
1724
1725 def interact_prompt(self):
1726 """ Print the prompt (in read-eval-print loop)
1727
1728 Provided for those who want to implement their own read-eval-print loop (e.g. GUIs), not
1729 used in standard IPython flow.
1730 """
1731 if self.more:
1732 try:
1733 prompt = self.hooks.generate_prompt(True)
1734 except:
1735 self.showtraceback()
1736 if self.autoindent:
1737 self.rl_do_indent = True
1738
1739 else:
1740 try:
1741 prompt = self.hooks.generate_prompt(False)
1742 except:
1743 self.showtraceback()
1744 self.write(prompt)
1745
1746 def interact_handle_input(self,line):
1747 """ Handle the input line (in read-eval-print loop)
1748
1749 Provided for those who want to implement their own read-eval-print loop (e.g. GUIs), not
1750 used in standard IPython flow.
1751 """
1752 if line.lstrip() == line:
1753 self.shadowhist.add(line.strip())
1754 lineout = self.prefilter_manager.prefilter_lines(line,self.more)
1755
1756 if line.strip():
1757 if self.more:
1758 self.input_hist_raw[-1] += '%s\n' % line
1759 else:
1760 self.input_hist_raw.append('%s\n' % line)
1761
1762
1763 self.more = self.push_line(lineout)
1764 if (self.SyntaxTB.last_syntax_error and
1765 self.autoedit_syntax):
1766 self.edit_syntax_error()
1767
1768 def interact_with_readline(self):
1769 """ Demo of using interact_handle_input, interact_prompt
1770
1771 This is the main read-eval-print loop. If you need to implement your own (e.g. for GUI),
1772 it should work like this.
1773 """
1774 self.readline_startup_hook(self.pre_readline)
1775 while not self.exit_now:
1776 self.interact_prompt()
1777 if self.more:
1778 self.rl_do_indent = True
1779 else:
1780 self.rl_do_indent = False
1781 line = raw_input_original().decode(self.stdin_encoding)
1782 self.interact_handle_input(line)
1783
1784 def interact(self, display_banner=None):
1785 """Closely emulate the interactive Python console."""
1786
1787 # batch run -> do not interact
1788 if self.exit_now:
1789 return
1790
1791 if display_banner is None:
1792 display_banner = self.display_banner
1793 if display_banner:
1794 self.show_banner()
1795
1796 more = 0
1797
1798 # Mark activity in the builtins
1799 __builtin__.__dict__['__IPYTHON__active'] += 1
1800
1801 if self.has_readline:
1802 self.readline_startup_hook(self.pre_readline)
1803 # exit_now is set by a call to %Exit or %Quit, through the
1804 # ask_exit callback.
1805
1806 while not self.exit_now:
1807 self.hooks.pre_prompt_hook()
1808 if more:
1809 try:
1810 prompt = self.hooks.generate_prompt(True)
1811 except:
1812 self.showtraceback()
1813 if self.autoindent:
1814 self.rl_do_indent = True
1815
1816 else:
1817 try:
1818 prompt = self.hooks.generate_prompt(False)
1819 except:
1820 self.showtraceback()
1821 try:
1822 line = self.raw_input(prompt, more)
1823 if self.exit_now:
1824 # quick exit on sys.std[in|out] close
1825 break
1826 if self.autoindent:
1827 self.rl_do_indent = False
1828
1829 except KeyboardInterrupt:
1830 #double-guard against keyboardinterrupts during kbdint handling
1831 try:
1832 self.write('\nKeyboardInterrupt\n')
1833 self.resetbuffer()
1834 # keep cache in sync with the prompt counter:
1835 self.outputcache.prompt_count -= 1
1836
1837 if self.autoindent:
1838 self.indent_current_nsp = 0
1839 more = 0
1840 except KeyboardInterrupt:
1841 pass
1842 except EOFError:
1843 if self.autoindent:
1844 self.rl_do_indent = False
1845 self.readline_startup_hook(None)
1846 self.write('\n')
1847 self.exit()
1848 except bdb.BdbQuit:
1849 warn('The Python debugger has exited with a BdbQuit exception.\n'
1850 'Because of how pdb handles the stack, it is impossible\n'
1851 'for IPython to properly format this particular exception.\n'
1852 'IPython will resume normal operation.')
1853 except:
1854 # exceptions here are VERY RARE, but they can be triggered
1855 # asynchronously by signal handlers, for example.
1856 self.showtraceback()
1857 else:
1858 more = self.push_line(line)
1859 if (self.SyntaxTB.last_syntax_error and
1860 self.autoedit_syntax):
1861 self.edit_syntax_error()
1862
1863 # We are off again...
1864 __builtin__.__dict__['__IPYTHON__active'] -= 1
1865
1866 def safe_execfile(self, fname, *where, **kw):
1867 """A safe version of the builtin execfile().
1868
1869 This version will never throw an exception, but instead print
1870 helpful error messages to the screen. This only works on pure
1871 Python files with the .py extension.
1872
1873 Parameters
1874 ----------
1875 fname : string
1876 The name of the file to be executed.
1877 where : tuple
1878 One or two namespaces, passed to execfile() as (globals,locals).
1879 If only one is given, it is passed as both.
1880 exit_ignore : bool (False)
1881 If True, then don't print errors for non-zero exit statuses.
1882 """
1883 kw.setdefault('exit_ignore', False)
1884
1885 fname = os.path.abspath(os.path.expanduser(fname))
1886
1887 # Make sure we have a .py file
1888 if not fname.endswith('.py'):
1889 warn('File must end with .py to be run using execfile: <%s>' % fname)
1890
1891 # Make sure we can open the file
1892 try:
1893 with open(fname) as thefile:
1894 pass
1895 except:
1896 warn('Could not open file <%s> for safe execution.' % fname)
1897 return
1898
1899 # Find things also in current directory. This is needed to mimic the
1900 # behavior of running a script from the system command line, where
1901 # Python inserts the script's directory into sys.path
1902 dname = os.path.dirname(fname)
1903
1904 with prepended_to_syspath(dname):
1905 try:
1906 if sys.platform == 'win32' and sys.version_info < (2,5,1):
1907 # Work around a bug in Python for Windows. The bug was
1908 # fixed in in Python 2.5 r54159 and 54158, but that's still
1909 # SVN Python as of March/07. For details, see:
1910 # http://projects.scipy.org/ipython/ipython/ticket/123
1911 try:
1912 globs,locs = where[0:2]
1913 except:
1914 try:
1915 globs = locs = where[0]
1916 except:
1917 globs = locs = globals()
1918 exec file(fname) in globs,locs
1919 else:
1920 execfile(fname,*where)
1921 except SyntaxError:
1922 self.showsyntaxerror()
1923 warn('Failure executing file: <%s>' % fname)
1924 except SystemExit, status:
1925 # Code that correctly sets the exit status flag to success (0)
1926 # shouldn't be bothered with a traceback. Note that a plain
1927 # sys.exit() does NOT set the message to 0 (it's empty) so that
1928 # will still get a traceback. Note that the structure of the
1929 # SystemExit exception changed between Python 2.4 and 2.5, so
1930 # the checks must be done in a version-dependent way.
1931 show = False
1932 if status.args[0]==0 and not kw['exit_ignore']:
1933 show = True
1934 if show:
1935 self.showtraceback()
1936 warn('Failure executing file: <%s>' % fname)
1937 except:
1938 self.showtraceback()
1939 warn('Failure executing file: <%s>' % fname)
1940
1941 def safe_execfile_ipy(self, fname):
1942 """Like safe_execfile, but for .ipy files with IPython syntax.
1943
1944 Parameters
1945 ----------
1946 fname : str
1947 The name of the file to execute. The filename must have a
1948 .ipy extension.
1949 """
1950 fname = os.path.abspath(os.path.expanduser(fname))
1951
1952 # Make sure we have a .py file
1953 if not fname.endswith('.ipy'):
1954 warn('File must end with .py to be run using execfile: <%s>' % fname)
1955
1956 # Make sure we can open the file
1957 try:
1958 with open(fname) as thefile:
1959 pass
1960 except:
1961 warn('Could not open file <%s> for safe execution.' % fname)
1962 return
1963
1964 # Find things also in current directory. This is needed to mimic the
1965 # behavior of running a script from the system command line, where
1966 # Python inserts the script's directory into sys.path
1967 dname = os.path.dirname(fname)
1968
1969 with prepended_to_syspath(dname):
1970 try:
1971 with open(fname) as thefile:
1972 script = thefile.read()
1973 # self.runlines currently captures all exceptions
1974 # raise in user code. It would be nice if there were
1975 # versions of runlines, execfile that did raise, so
1976 # we could catch the errors.
1977 self.runlines(script, clean=True)
1978 except:
1979 self.showtraceback()
1980 warn('Unknown failure executing file: <%s>' % fname)
1981
1982 def _is_secondary_block_start(self, s):
1983 if not s.endswith(':'):
1984 return False
1985 if (s.startswith('elif') or
1986 s.startswith('else') or
1987 s.startswith('except') or
1988 s.startswith('finally')):
1989 return True
1990
1991 def cleanup_ipy_script(self, script):
1992 """Make a script safe for self.runlines()
1993
1994 Currently, IPython is lines based, with blocks being detected by
1995 empty lines. This is a problem for block based scripts that may
1996 not have empty lines after blocks. This script adds those empty
1997 lines to make scripts safe for running in the current line based
1998 IPython.
1999 """
2000 res = []
2001 lines = script.splitlines()
2002 level = 0
2003
2004 for l in lines:
2005 lstripped = l.lstrip()
2006 stripped = l.strip()
2007 if not stripped:
2008 continue
2009 newlevel = len(l) - len(lstripped)
2010 if level > 0 and newlevel == 0 and \
2011 not self._is_secondary_block_start(stripped):
2012 # add empty line
2013 res.append('')
2014 res.append(l)
2015 level = newlevel
2016
2017 return '\n'.join(res) + '\n'
2018
2019 def runlines(self, lines, clean=False):
2020 """Run a string of one or more lines of source.
2021
2022 This method is capable of running a string containing multiple source
2023 lines, as if they had been entered at the IPython prompt. Since it
2024 exposes IPython's processing machinery, the given strings can contain
2025 magic calls (%magic), special shell access (!cmd), etc.
2026 """
2027
2028 if isinstance(lines, (list, tuple)):
2029 lines = '\n'.join(lines)
2030
2031 if clean:
2032 lines = self.cleanup_ipy_script(lines)
2033
2034 # We must start with a clean buffer, in case this is run from an
2035 # interactive IPython session (via a magic, for example).
2036 self.resetbuffer()
2037 lines = lines.splitlines()
2038 more = 0
2039
2040 with nested(self.builtin_trap, self.display_trap):
2041 for line in lines:
2042 # skip blank lines so we don't mess up the prompt counter, but do
2043 # NOT skip even a blank line if we are in a code block (more is
2044 # true)
2045
2046 if line or more:
2047 # push to raw history, so hist line numbers stay in sync
2048 self.input_hist_raw.append("# " + line + "\n")
2049 prefiltered = self.prefilter_manager.prefilter_lines(line,more)
2050 more = self.push_line(prefiltered)
2051 # IPython's runsource returns None if there was an error
2052 # compiling the code. This allows us to stop processing right
2053 # away, so the user gets the error message at the right place.
2054 if more is None:
2055 break
2056 else:
2057 self.input_hist_raw.append("\n")
2058 # final newline in case the input didn't have it, so that the code
2059 # actually does get executed
2060 if more:
2061 self.push_line('\n')
2062
2063 def runsource(self, source, filename='<input>', symbol='single'):
2064 """Compile and run some source in the interpreter.
2065
2066 Arguments are as for compile_command().
2067
2068 One several things can happen:
2069
2070 1) The input is incorrect; compile_command() raised an
2071 exception (SyntaxError or OverflowError). A syntax traceback
2072 will be printed by calling the showsyntaxerror() method.
2073
2074 2) The input is incomplete, and more input is required;
2075 compile_command() returned None. Nothing happens.
2076
2077 3) The input is complete; compile_command() returned a code
2078 object. The code is executed by calling self.runcode() (which
2079 also handles run-time exceptions, except for SystemExit).
2080
2081 The return value is:
2082
2083 - True in case 2
2084
2085 - False in the other cases, unless an exception is raised, where
2086 None is returned instead. This can be used by external callers to
2087 know whether to continue feeding input or not.
2088
2089 The return value can be used to decide whether to use sys.ps1 or
2090 sys.ps2 to prompt the next line."""
2091
2092 # if the source code has leading blanks, add 'if 1:\n' to it
2093 # this allows execution of indented pasted code. It is tempting
2094 # to add '\n' at the end of source to run commands like ' a=1'
2095 # directly, but this fails for more complicated scenarios
2096 source=source.encode(self.stdin_encoding)
2097 if source[:1] in [' ', '\t']:
2098 source = 'if 1:\n%s' % source
2099
2100 try:
2101 code = self.compile(source,filename,symbol)
2102 except (OverflowError, SyntaxError, ValueError, TypeError, MemoryError):
2103 # Case 1
2104 self.showsyntaxerror(filename)
2105 return None
2106
2107 if code is None:
2108 # Case 2
2109 return True
2110
2111 # Case 3
2112 # We store the code object so that threaded shells and
2113 # custom exception handlers can access all this info if needed.
2114 # The source corresponding to this can be obtained from the
2115 # buffer attribute as '\n'.join(self.buffer).
2116 self.code_to_run = code
2117 # now actually execute the code object
2118 if self.runcode(code) == 0:
2119 return False
2120 else:
2121 return None
2122
2123 def runcode(self,code_obj):
2124 """Execute a code object.
2125
2126 When an exception occurs, self.showtraceback() is called to display a
2127 traceback.
2128
2129 Return value: a flag indicating whether the code to be run completed
2130 successfully:
2131
2132 - 0: successful execution.
2133 - 1: an error occurred.
2134 """
2135
2136 # Set our own excepthook in case the user code tries to call it
2137 # directly, so that the IPython crash handler doesn't get triggered
2138 old_excepthook,sys.excepthook = sys.excepthook, self.excepthook
2139
2140 # we save the original sys.excepthook in the instance, in case config
2141 # code (such as magics) needs access to it.
2142 self.sys_excepthook = old_excepthook
2143 outflag = 1 # happens in more places, so it's easier as default
2144 try:
2145 try:
2146 self.hooks.pre_runcode_hook()
2147 exec code_obj in self.user_global_ns, self.user_ns
2148 finally:
2149 # Reset our crash handler in place
2150 sys.excepthook = old_excepthook
2151 except SystemExit:
2152 self.resetbuffer()
2153 self.showtraceback()
2154 warn("Type %exit or %quit to exit IPython "
2155 "(%Exit or %Quit do so unconditionally).",level=1)
2156 except self.custom_exceptions:
2157 etype,value,tb = sys.exc_info()
2158 self.CustomTB(etype,value,tb)
2159 except:
2160 self.showtraceback()
2161 else:
2162 outflag = 0
2163 if softspace(sys.stdout, 0):
2164 print
2165 # Flush out code object which has been run (and source)
2166 self.code_to_run = None
2167 return outflag
2168
2169 def push_line(self, line):
2170 """Push a line to the interpreter.
2171
2172 The line should not have a trailing newline; it may have
2173 internal newlines. The line is appended to a buffer and the
2174 interpreter's runsource() method is called with the
2175 concatenated contents of the buffer as source. If this
2176 indicates that the command was executed or invalid, the buffer
2177 is reset; otherwise, the command is incomplete, and the buffer
2178 is left as it was after the line was appended. The return
2179 value is 1 if more input is required, 0 if the line was dealt
2180 with in some way (this is the same as runsource()).
2181 """
2182
2183 # autoindent management should be done here, and not in the
2184 # interactive loop, since that one is only seen by keyboard input. We
2185 # need this done correctly even for code run via runlines (which uses
2186 # push).
2187
2188 #print 'push line: <%s>' % line # dbg
2189 for subline in line.splitlines():
2190 self._autoindent_update(subline)
2191 self.buffer.append(line)
2192 more = self.runsource('\n'.join(self.buffer), self.filename)
2193 if not more:
2194 self.resetbuffer()
2195 return more
2196
2197 def _autoindent_update(self,line):
2198 """Keep track of the indent level."""
2199
2200 #debugx('line')
2201 #debugx('self.indent_current_nsp')
2202 if self.autoindent:
2203 if line:
2204 inisp = num_ini_spaces(line)
2205 if inisp < self.indent_current_nsp:
2206 self.indent_current_nsp = inisp
2207
2208 if line[-1] == ':':
2209 self.indent_current_nsp += 4
2210 elif dedent_re.match(line):
2211 self.indent_current_nsp -= 4
2212 else:
2213 self.indent_current_nsp = 0
2214
2215 def resetbuffer(self):
2216 """Reset the input buffer."""
2217 self.buffer[:] = []
2218
2219 def raw_input(self,prompt='',continue_prompt=False):
2220 """Write a prompt and read a line.
2221
2222 The returned line does not include the trailing newline.
2223 When the user enters the EOF key sequence, EOFError is raised.
2224
2225 Optional inputs:
2226
2227 - prompt(''): a string to be printed to prompt the user.
2228
2229 - continue_prompt(False): whether this line is the first one or a
2230 continuation in a sequence of inputs.
2231 """
2232 # growl.notify("raw_input: ", "prompt = %r\ncontinue_prompt = %s" % (prompt, continue_prompt))
2233
2234 # Code run by the user may have modified the readline completer state.
2235 # We must ensure that our completer is back in place.
2236
2237 if self.has_readline:
2238 self.set_completer()
2239
2240 try:
2241 line = raw_input_original(prompt).decode(self.stdin_encoding)
2242 except ValueError:
2243 warn("\n********\nYou or a %run:ed script called sys.stdin.close()"
2244 " or sys.stdout.close()!\nExiting IPython!")
2245 self.ask_exit()
2246 return ""
2247
2248 # Try to be reasonably smart about not re-indenting pasted input more
2249 # than necessary. We do this by trimming out the auto-indent initial
2250 # spaces, if the user's actual input started itself with whitespace.
2251 #debugx('self.buffer[-1]')
2252
2253 if self.autoindent:
2254 if num_ini_spaces(line) > self.indent_current_nsp:
2255 line = line[self.indent_current_nsp:]
2256 self.indent_current_nsp = 0
2257
2258 # store the unfiltered input before the user has any chance to modify
2259 # it.
2260 if line.strip():
2261 if continue_prompt:
2262 self.input_hist_raw[-1] += '%s\n' % line
2263 if self.has_readline and self.readline_use:
2264 try:
2265 histlen = self.readline.get_current_history_length()
2266 if histlen > 1:
2267 newhist = self.input_hist_raw[-1].rstrip()
2268 self.readline.remove_history_item(histlen-1)
2269 self.readline.replace_history_item(histlen-2,
2270 newhist.encode(self.stdin_encoding))
2271 except AttributeError:
2272 pass # re{move,place}_history_item are new in 2.4.
2273 else:
2274 self.input_hist_raw.append('%s\n' % line)
2275 # only entries starting at first column go to shadow history
2276 if line.lstrip() == line:
2277 self.shadowhist.add(line.strip())
2278 elif not continue_prompt:
2279 self.input_hist_raw.append('\n')
2280 try:
2281 lineout = self.prefilter_manager.prefilter_lines(line,continue_prompt)
2282 except:
2283 # blanket except, in case a user-defined prefilter crashes, so it
2284 # can't take all of ipython with it.
2285 self.showtraceback()
2286 return ''
2287 else:
2288 return lineout
2289
2290 #-------------------------------------------------------------------------
2291 # Working with components
2292 #-------------------------------------------------------------------------
2293
2294 def get_component(self, name=None, klass=None):
2295 """Fetch a component by name and klass in my tree."""
2296 c = Component.get_instances(root=self, name=name, klass=klass)
2297 if len(c) == 0:
2298 return None
2299 if len(c) == 1:
2300 return c[0]
2301 else:
2302 return c
2303
2304 #-------------------------------------------------------------------------
2305 # IPython extensions
2306 #-------------------------------------------------------------------------
2307
2308 def load_extension(self, module_str):
2309 """Load an IPython extension by its module name.
2310
2311 An IPython extension is an importable Python module that has
2312 a function with the signature::
2313
2314 def load_ipython_extension(ipython):
2315 # Do things with ipython
2316
2317 This function is called after your extension is imported and the
2318 currently active :class:`InteractiveShell` instance is passed as
2319 the only argument. You can do anything you want with IPython at
2320 that point, including defining new magic and aliases, adding new
2321 components, etc.
2322
2323 The :func:`load_ipython_extension` will be called again is you
2324 load or reload the extension again. It is up to the extension
2325 author to add code to manage that.
2326
2327 You can put your extension modules anywhere you want, as long as
2328 they can be imported by Python's standard import mechanism. However,
2329 to make it easy to write extensions, you can also put your extensions
2330 in ``os.path.join(self.ipython_dir, 'extensions')``. This directory
2331 is added to ``sys.path`` automatically.
2332 """
2333 from IPython.utils.syspathcontext import prepended_to_syspath
2334
2335 if module_str not in sys.modules:
2336 with prepended_to_syspath(self.ipython_extension_dir):
2337 __import__(module_str)
2338 mod = sys.modules[module_str]
2339 self._call_load_ipython_extension(mod)
2340
2341 def unload_extension(self, module_str):
2342 """Unload an IPython extension by its module name.
2343
2344 This function looks up the extension's name in ``sys.modules`` and
2345 simply calls ``mod.unload_ipython_extension(self)``.
2346 """
2347 if module_str in sys.modules:
2348 mod = sys.modules[module_str]
2349 self._call_unload_ipython_extension(mod)
2350
2351 def reload_extension(self, module_str):
2352 """Reload an IPython extension by calling reload.
2353
2354 If the module has not been loaded before,
2355 :meth:`InteractiveShell.load_extension` is called. Otherwise
2356 :func:`reload` is called and then the :func:`load_ipython_extension`
2357 function of the module, if it exists is called.
2358 """
2359 from IPython.utils.syspathcontext import prepended_to_syspath
2360
2361 with prepended_to_syspath(self.ipython_extension_dir):
2362 if module_str in sys.modules:
2363 mod = sys.modules[module_str]
2364 reload(mod)
2365 self._call_load_ipython_extension(mod)
2366 else:
2367 self.load_extension(module_str)
2368
2369 def _call_load_ipython_extension(self, mod):
2370 if hasattr(mod, 'load_ipython_extension'):
2371 mod.load_ipython_extension(self)
2372
2373 def _call_unload_ipython_extension(self, mod):
2374 if hasattr(mod, 'unload_ipython_extension'):
2375 mod.unload_ipython_extension(self)
2376
2377 #-------------------------------------------------------------------------
2378 # Things related to the prefilter
2379 #-------------------------------------------------------------------------
2380
2381 def init_prefilter(self):
2382 self.prefilter_manager = PrefilterManager(self, config=self.config)
2383
2384 #-------------------------------------------------------------------------
2385 # Utilities
2386 #-------------------------------------------------------------------------
2387
2388 def getoutput(self, cmd):
2389 return getoutput(self.var_expand(cmd,depth=2),
2390 header=self.system_header,
2391 verbose=self.system_verbose)
2392
2393 def getoutputerror(self, cmd):
2394 return getoutputerror(self.var_expand(cmd,depth=2),
2395 header=self.system_header,
2396 verbose=self.system_verbose)
2397
2398 def var_expand(self,cmd,depth=0):
2399 """Expand python variables in a string.
2400
2401 The depth argument indicates how many frames above the caller should
2402 be walked to look for the local namespace where to expand variables.
2403
2404 The global namespace for expansion is always the user's interactive
2405 namespace.
2406 """
2407
2408 return str(ItplNS(cmd,
2409 self.user_ns, # globals
2410 # Skip our own frame in searching for locals:
2411 sys._getframe(depth+1).f_locals # locals
2412 ))
2413
2414 def mktempfile(self,data=None):
2415 """Make a new tempfile and return its filename.
2416
2417 This makes a call to tempfile.mktemp, but it registers the created
2418 filename internally so ipython cleans it up at exit time.
2419
2420 Optional inputs:
2421
2422 - data(None): if data is given, it gets written out to the temp file
2423 immediately, and the file is closed again."""
2424
2425 filename = tempfile.mktemp('.py','ipython_edit_')
2426 self.tempfiles.append(filename)
2427
2428 if data:
2429 tmp_file = open(filename,'w')
2430 tmp_file.write(data)
2431 tmp_file.close()
2432 return filename
2433
2434 def write(self,data):
2435 """Write a string to the default output"""
2436 Term.cout.write(data)
2437
2438 def write_err(self,data):
2439 """Write a string to the default error output"""
2440 Term.cerr.write(data)
2441
2442 def ask_yes_no(self,prompt,default=True):
2443 if self.quiet:
2444 return True
2445 return ask_yes_no(prompt,default)
2446
2447 #-------------------------------------------------------------------------
2448 # Things related to IPython exiting
2449 #-------------------------------------------------------------------------
2450
2451 def ask_exit(self):
2452 """ Call for exiting. Can be overiden and used as a callback. """
2453 self.exit_now = True
2454
2455 def exit(self):
2456 """Handle interactive exit.
2457
2458 This method calls the ask_exit callback."""
2459 if self.confirm_exit:
2460 if self.ask_yes_no('Do you really want to exit ([y]/n)?','y'):
2461 self.ask_exit()
2462 else:
2463 self.ask_exit()
2464
2465 def atexit_operations(self):
2466 """This will be executed at the time of exit.
2467
2468 Saving of persistent data should be performed here.
2469 """
2470 self.savehist()
2471
2472 # Cleanup all tempfiles left around
2473 for tfile in self.tempfiles:
2474 try:
2475 os.unlink(tfile)
2476 except OSError:
2477 pass
2478
2479 # Clear all user namespaces to release all references cleanly.
2480 self.reset()
2481
2482 # Run user hooks
2483 self.hooks.shutdown_hook()
2484
2485 def cleanup(self):
2486 self.restore_sys_module_state()
2487
2488
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100755
NO CONTENT: new file 100755
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100755
NO CONTENT: new file 100755
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100755
NO CONTENT: new file 100755
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100755
NO CONTENT: new file 100755
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100755
NO CONTENT: new file 100755
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100755
NO CONTENT: new file 100755
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
This diff has been collapsed as it changes many lines, (1254 lines changed) Show them Hide them
@@ -1,1246 +1,42 b''
1 # -*- coding: utf-8 -*-
1 #!/usr/bin/env python
2 """IPython Shell classes.
2 # encoding: utf-8
3 """
4 A backwards compatibility layer for IPython.Shell.
3
5
4 All the matplotlib support code was co-developed with John Hunter,
6 Previously, IPython had an IPython.Shell module. IPython.Shell has been moved
5 matplotlib's author.
7 to IPython.core.shell and is being refactored. This new module is provided
8 for backwards compatability. We strongly encourage everyone to start using
9 the new code in IPython.core.shell.
6 """
10 """
7
11
8 #*****************************************************************************
12 #-----------------------------------------------------------------------------
9 # Copyright (C) 2001-2006 Fernando Perez <fperez@colorado.edu>
13 # Copyright (C) 2008-2009 The IPython Development Team
10 #
14 #
11 # Distributed under the terms of the BSD License. The full license is in
15 # Distributed under the terms of the BSD License. The full license is in
12 # the file COPYING, distributed as part of this software.
16 # the file COPYING, distributed as part of this software.
13 #*****************************************************************************
14
15 # Code begins
16 # Stdlib imports
17 import __builtin__
18 import __main__
19 import Queue
20 import inspect
21 import os
22 import sys
23 import thread
24 import threading
25 import time
26
27 from signal import signal, SIGINT
28
29 try:
30 import ctypes
31 HAS_CTYPES = True
32 except ImportError:
33 HAS_CTYPES = False
34
35 # IPython imports
36 import IPython
37 from IPython import ultraTB, ipapi
38 from IPython.Magic import Magic
39 from IPython.genutils import Term,warn,error,flag_calls, ask_yes_no
40 from IPython.iplib import InteractiveShell
41 from IPython.ipmaker import make_IPython
42 from IPython.ipstruct import Struct
43 from IPython.testing import decorators as testdec
44
45 # Globals
46 # global flag to pass around information about Ctrl-C without exceptions
47 KBINT = False
48
49 # global flag to turn on/off Tk support.
50 USE_TK = False
51
52 # ID for the main thread, used for cross-thread exceptions
53 MAIN_THREAD_ID = thread.get_ident()
54
55 # Tag when runcode() is active, for exception handling
56 CODE_RUN = None
57
58 # Default timeout for waiting for multithreaded shells (in seconds)
59 GUI_TIMEOUT = 10
60
61 #-----------------------------------------------------------------------------
62 # This class is trivial now, but I want to have it in to publish a clean
63 # interface. Later when the internals are reorganized, code that uses this
64 # shouldn't have to change.
65
66 class IPShell:
67 """Create an IPython instance."""
68
69 def __init__(self,argv=None,user_ns=None,user_global_ns=None,
70 debug=1,shell_class=InteractiveShell):
71 self.IP = make_IPython(argv,user_ns=user_ns,
72 user_global_ns=user_global_ns,
73 debug=debug,shell_class=shell_class)
74
75 def mainloop(self,sys_exit=0,banner=None):
76 self.IP.mainloop(banner)
77 if sys_exit:
78 sys.exit()
79
80 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
81 def kill_embedded(self,parameter_s=''):
82 """%kill_embedded : deactivate for good the current embedded IPython.
83
84 This function (after asking for confirmation) sets an internal flag so that
85 an embedded IPython will never activate again. This is useful to
86 permanently disable a shell that is being called inside a loop: once you've
87 figured out what you needed from it, you may then kill it and the program
88 will then continue to run without the interactive shell interfering again.
89 """
90
91 kill = ask_yes_no("Are you sure you want to kill this embedded instance "
92 "(y/n)? [y/N] ",'n')
93 if kill:
94 self.shell.embedded_active = False
95 print "This embedded IPython will not reactivate anymore once you exit."
96
97 class IPShellEmbed:
98 """Allow embedding an IPython shell into a running program.
99
100 Instances of this class are callable, with the __call__ method being an
101 alias to the embed() method of an InteractiveShell instance.
102
103 Usage (see also the example-embed.py file for a running example):
104
105 ipshell = IPShellEmbed([argv,banner,exit_msg,rc_override])
106
107 - argv: list containing valid command-line options for IPython, as they
108 would appear in sys.argv[1:].
109
110 For example, the following command-line options:
111
112 $ ipython -prompt_in1 'Input <\\#>' -colors LightBG
113
114 would be passed in the argv list as:
115
116 ['-prompt_in1','Input <\\#>','-colors','LightBG']
117
118 - banner: string which gets printed every time the interpreter starts.
119
120 - exit_msg: string which gets printed every time the interpreter exits.
121
122 - rc_override: a dict or Struct of configuration options such as those
123 used by IPython. These options are read from your ~/.ipython/ipythonrc
124 file when the Shell object is created. Passing an explicit rc_override
125 dict with any options you want allows you to override those values at
126 creation time without having to modify the file. This way you can create
127 embeddable instances configured in any way you want without editing any
128 global files (thus keeping your interactive IPython configuration
129 unchanged).
130
131 Then the ipshell instance can be called anywhere inside your code:
132
133 ipshell(header='') -> Opens up an IPython shell.
134
135 - header: string printed by the IPython shell upon startup. This can let
136 you know where in your code you are when dropping into the shell. Note
137 that 'banner' gets prepended to all calls, so header is used for
138 location-specific information.
139
140 For more details, see the __call__ method below.
141
142 When the IPython shell is exited with Ctrl-D, normal program execution
143 resumes.
144
145 This functionality was inspired by a posting on comp.lang.python by cmkl
146 <cmkleffner@gmx.de> on Dec. 06/01 concerning similar uses of pyrepl, and
147 by the IDL stop/continue commands."""
148
149 def __init__(self,argv=None,banner='',exit_msg=None,rc_override=None,
150 user_ns=None):
151 """Note that argv here is a string, NOT a list."""
152 self.set_banner(banner)
153 self.set_exit_msg(exit_msg)
154 self.set_dummy_mode(0)
155
156 # sys.displayhook is a global, we need to save the user's original
157 # Don't rely on __displayhook__, as the user may have changed that.
158 self.sys_displayhook_ori = sys.displayhook
159
160 # save readline completer status
161 try:
162 #print 'Save completer',sys.ipcompleter # dbg
163 self.sys_ipcompleter_ori = sys.ipcompleter
164 except:
165 pass # not nested with IPython
166
167 self.IP = make_IPython(argv,rc_override=rc_override,
168 embedded=True,
169 user_ns=user_ns)
170
171 ip = ipapi.IPApi(self.IP)
172 ip.expose_magic("kill_embedded",kill_embedded)
173
174 # copy our own displayhook also
175 self.sys_displayhook_embed = sys.displayhook
176 # and leave the system's display hook clean
177 sys.displayhook = self.sys_displayhook_ori
178 # don't use the ipython crash handler so that user exceptions aren't
179 # trapped
180 sys.excepthook = ultraTB.FormattedTB(color_scheme = self.IP.rc.colors,
181 mode = self.IP.rc.xmode,
182 call_pdb = self.IP.rc.pdb)
183 self.restore_system_completer()
184
185 def restore_system_completer(self):
186 """Restores the readline completer which was in place.
187
188 This allows embedded IPython within IPython not to disrupt the
189 parent's completion.
190 """
191
192 try:
193 self.IP.readline.set_completer(self.sys_ipcompleter_ori)
194 sys.ipcompleter = self.sys_ipcompleter_ori
195 except:
196 pass
197
198 def __call__(self,header='',local_ns=None,global_ns=None,dummy=None):
199 """Activate the interactive interpreter.
200
201 __call__(self,header='',local_ns=None,global_ns,dummy=None) -> Start
202 the interpreter shell with the given local and global namespaces, and
203 optionally print a header string at startup.
204
205 The shell can be globally activated/deactivated using the
206 set/get_dummy_mode methods. This allows you to turn off a shell used
207 for debugging globally.
208
209 However, *each* time you call the shell you can override the current
210 state of dummy_mode with the optional keyword parameter 'dummy'. For
211 example, if you set dummy mode on with IPShell.set_dummy_mode(1), you
212 can still have a specific call work by making it as IPShell(dummy=0).
213
214 The optional keyword parameter dummy controls whether the call
215 actually does anything. """
216
217 # If the user has turned it off, go away
218 if not self.IP.embedded_active:
219 return
220
221 # Normal exits from interactive mode set this flag, so the shell can't
222 # re-enter (it checks this variable at the start of interactive mode).
223 self.IP.exit_now = False
224
225 # Allow the dummy parameter to override the global __dummy_mode
226 if dummy or (dummy != 0 and self.__dummy_mode):
227 return
228
229 # Set global subsystems (display,completions) to our values
230 sys.displayhook = self.sys_displayhook_embed
231 if self.IP.has_readline:
232 self.IP.set_completer()
233
234 if self.banner and header:
235 format = '%s\n%s\n'
236 else:
237 format = '%s%s\n'
238 banner = format % (self.banner,header)
239
240 # Call the embedding code with a stack depth of 1 so it can skip over
241 # our call and get the original caller's namespaces.
242 self.IP.embed_mainloop(banner,local_ns,global_ns,stack_depth=1)
243
244 if self.exit_msg:
245 print self.exit_msg
246
247 # Restore global systems (display, completion)
248 sys.displayhook = self.sys_displayhook_ori
249 self.restore_system_completer()
250
251 def set_dummy_mode(self,dummy):
252 """Sets the embeddable shell's dummy mode parameter.
253
254 set_dummy_mode(dummy): dummy = 0 or 1.
255
256 This parameter is persistent and makes calls to the embeddable shell
257 silently return without performing any action. This allows you to
258 globally activate or deactivate a shell you're using with a single call.
259
260 If you need to manually"""
261
18
262 if dummy not in [0,1,False,True]:
19 from warnings import warn
263 raise ValueError,'dummy parameter must be boolean'
264 self.__dummy_mode = dummy
265
20
266 def get_dummy_mode(self):
21 msg = """
267 """Return the current value of the dummy mode parameter.
22 This module (IPython.Shell) is deprecated. The classes that were in this
268 """
23 module have been replaced by:
269 return self.__dummy_mode
270
271 def set_banner(self,banner):
272 """Sets the global banner.
273
24
274 This banner gets prepended to every header printed when the shell
25 IPShell->IPython.core.iplib.InteractiveShell
275 instance is called."""
26 IPShellEmbed->IPython.core.embed.InteractiveShellEmbed
276
27
277 self.banner = banner
28 Please migrate your code to use these classes instead.
278
279 def set_exit_msg(self,exit_msg):
280 """Sets the global exit_msg.
281
282 This exit message gets printed upon exiting every time the embedded
283 shell is called. It is None by default. """
284
285 self.exit_msg = exit_msg
286
287 #-----------------------------------------------------------------------------
288 if HAS_CTYPES:
289 # Add async exception support. Trick taken from:
290 # http://sebulba.wikispaces.com/recipe+thread2
291 def _async_raise(tid, exctype):
292 """raises the exception, performs cleanup if needed"""
293 if not inspect.isclass(exctype):
294 raise TypeError("Only types can be raised (not instances)")
295 # Explicit cast to c_long is necessary for 64-bit support:
296 # See https://bugs.launchpad.net/ipython/+bug/237073
297 res = ctypes.pythonapi.PyThreadState_SetAsyncExc(ctypes.c_long(tid),
298 ctypes.py_object(exctype))
299 if res == 0:
300 raise ValueError("invalid thread id")
301 elif res != 1:
302 # If it returns a number greater than one, you're in trouble,
303 # and you should call it again with exc=NULL to revert the effect
304 ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, 0)
305 raise SystemError("PyThreadState_SetAsyncExc failed")
306
307 def sigint_handler(signum,stack_frame):
308 """Sigint handler for threaded apps.
309
310 This is a horrible hack to pass information about SIGINT _without_
311 using exceptions, since I haven't been able to properly manage
312 cross-thread exceptions in GTK/WX. In fact, I don't think it can be
313 done (or at least that's my understanding from a c.l.py thread where
314 this was discussed)."""
315
316 global KBINT
317
318 if CODE_RUN:
319 _async_raise(MAIN_THREAD_ID,KeyboardInterrupt)
320 else:
321 KBINT = True
322 print '\nKeyboardInterrupt - Press <Enter> to continue.',
323 Term.cout.flush()
324
325 else:
326 def sigint_handler(signum,stack_frame):
327 """Sigint handler for threaded apps.
328
329 This is a horrible hack to pass information about SIGINT _without_
330 using exceptions, since I haven't been able to properly manage
331 cross-thread exceptions in GTK/WX. In fact, I don't think it can be
332 done (or at least that's my understanding from a c.l.py thread where
333 this was discussed)."""
334
335 global KBINT
336
337 print '\nKeyboardInterrupt - Press <Enter> to continue.',
338 Term.cout.flush()
339 # Set global flag so that runsource can know that Ctrl-C was hit
340 KBINT = True
341
342
343 class MTInteractiveShell(InteractiveShell):
344 """Simple multi-threaded shell."""
345
346 # Threading strategy taken from:
347 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/65109, by Brian
348 # McErlean and John Finlay. Modified with corrections by Antoon Pardon,
349 # from the pygtk mailing list, to avoid lockups with system calls.
350
351 # class attribute to indicate whether the class supports threads or not.
352 # Subclasses with thread support should override this as needed.
353 isthreaded = True
354
355 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
356 user_ns=None,user_global_ns=None,banner2='',
357 gui_timeout=GUI_TIMEOUT,**kw):
358 """Similar to the normal InteractiveShell, but with threading control"""
359
360 InteractiveShell.__init__(self,name,usage,rc,user_ns,
361 user_global_ns,banner2)
362
363 # Timeout we wait for GUI thread
364 self.gui_timeout = gui_timeout
365
366 # A queue to hold the code to be executed.
367 self.code_queue = Queue.Queue()
368
369 # Stuff to do at closing time
370 self._kill = None
371 on_kill = kw.get('on_kill', [])
372 # Check that all things to kill are callable:
373 for t in on_kill:
374 if not callable(t):
375 raise TypeError,'on_kill must be a list of callables'
376 self.on_kill = on_kill
377 # thread identity of the "worker thread" (that may execute code directly)
378 self.worker_ident = None
379
380 def runsource(self, source, filename="<input>", symbol="single"):
381 """Compile and run some source in the interpreter.
382
383 Modified version of code.py's runsource(), to handle threading issues.
384 See the original for full docstring details."""
385
386 global KBINT
387
388 # If Ctrl-C was typed, we reset the flag and return right away
389 if KBINT:
390 KBINT = False
391 return False
392
393 if self._kill:
394 # can't queue new code if we are being killed
395 return True
396
397 try:
398 code = self.compile(source, filename, symbol)
399 except (OverflowError, SyntaxError, ValueError):
400 # Case 1
401 self.showsyntaxerror(filename)
402 return False
403
404 if code is None:
405 # Case 2
406 return True
407
408 # shortcut - if we are in worker thread, or the worker thread is not
409 # running, execute directly (to allow recursion and prevent deadlock if
410 # code is run early in IPython construction)
411
412 if (self.worker_ident is None
413 or self.worker_ident == thread.get_ident() ):
414 InteractiveShell.runcode(self,code)
415 return False
416
417 # Case 3
418 # Store code in queue, so the execution thread can handle it.
419
420 completed_ev, received_ev = threading.Event(), threading.Event()
421
422 self.code_queue.put((code,completed_ev, received_ev))
423 # first make sure the message was received, with timeout
424 received_ev.wait(self.gui_timeout)
425 if not received_ev.isSet():
426 # the mainloop is dead, start executing code directly
427 print "Warning: Timeout for mainloop thread exceeded"
428 print "switching to nonthreaded mode (until mainloop wakes up again)"
429 self.worker_ident = None
430 else:
431 completed_ev.wait()
432 return False
433
434 def runcode(self):
435 """Execute a code object.
436
437 Multithreaded wrapper around IPython's runcode()."""
438
439 global CODE_RUN
440
441 # we are in worker thread, stash out the id for runsource()
442 self.worker_ident = thread.get_ident()
443
444 if self._kill:
445 print >>Term.cout, 'Closing threads...',
446 Term.cout.flush()
447 for tokill in self.on_kill:
448 tokill()
449 print >>Term.cout, 'Done.'
450 # allow kill() to return
451 self._kill.set()
452 return True
453
454 # Install sigint handler. We do it every time to ensure that if user
455 # code modifies it, we restore our own handling.
456 try:
457 signal(SIGINT,sigint_handler)
458 except SystemError:
459 # This happens under Windows, which seems to have all sorts
460 # of problems with signal handling. Oh well...
461 pass
462
463 # Flush queue of pending code by calling the run methood of the parent
464 # class with all items which may be in the queue.
465 code_to_run = None
466 while 1:
467 try:
468 code_to_run, completed_ev, received_ev = self.code_queue.get_nowait()
469 except Queue.Empty:
470 break
471 received_ev.set()
472
473 # Exceptions need to be raised differently depending on which
474 # thread is active. This convoluted try/except is only there to
475 # protect against asynchronous exceptions, to ensure that a KBINT
476 # at the wrong time doesn't deadlock everything. The global
477 # CODE_TO_RUN is set to true/false as close as possible to the
478 # runcode() call, so that the KBINT handler is correctly informed.
479 try:
480 try:
481 CODE_RUN = True
482 InteractiveShell.runcode(self,code_to_run)
483 except KeyboardInterrupt:
484 print "Keyboard interrupted in mainloop"
485 while not self.code_queue.empty():
486 code, ev1,ev2 = self.code_queue.get_nowait()
487 ev1.set()
488 ev2.set()
489 break
490 finally:
491 CODE_RUN = False
492 # allow runsource() return from wait
493 completed_ev.set()
494
495
496 # This MUST return true for gtk threading to work
497 return True
498
499 def kill(self):
500 """Kill the thread, returning when it has been shut down."""
501 self._kill = threading.Event()
502 self._kill.wait()
503
504 class MatplotlibShellBase:
505 """Mixin class to provide the necessary modifications to regular IPython
506 shell classes for matplotlib support.
507
508 Given Python's MRO, this should be used as the FIRST class in the
509 inheritance hierarchy, so that it overrides the relevant methods."""
510
511 def _matplotlib_config(self,name,user_ns,user_global_ns=None):
512 """Return items needed to setup the user's shell with matplotlib"""
513
514 # Initialize matplotlib to interactive mode always
515 import matplotlib
516 from matplotlib import backends
517 matplotlib.interactive(True)
518
519 def use(arg):
520 """IPython wrapper for matplotlib's backend switcher.
521
522 In interactive use, we can not allow switching to a different
523 interactive backend, since thread conflicts will most likely crash
524 the python interpreter. This routine does a safety check first,
525 and refuses to perform a dangerous switch. It still allows
526 switching to non-interactive backends."""
527
528 if arg in backends.interactive_bk and arg != self.mpl_backend:
529 m=('invalid matplotlib backend switch.\n'
530 'This script attempted to switch to the interactive '
531 'backend: `%s`\n'
532 'Your current choice of interactive backend is: `%s`\n\n'
533 'Switching interactive matplotlib backends at runtime\n'
534 'would crash the python interpreter, '
535 'and IPython has blocked it.\n\n'
536 'You need to either change your choice of matplotlib backend\n'
537 'by editing your .matplotlibrc file, or run this script as a \n'
538 'standalone file from the command line, not using IPython.\n' %
539 (arg,self.mpl_backend) )
540 raise RuntimeError, m
541 else:
542 self.mpl_use(arg)
543 self.mpl_use._called = True
544
545 self.matplotlib = matplotlib
546 self.mpl_backend = matplotlib.rcParams['backend']
547
548 # we also need to block switching of interactive backends by use()
549 self.mpl_use = matplotlib.use
550 self.mpl_use._called = False
551 # overwrite the original matplotlib.use with our wrapper
552 matplotlib.use = use
553
554 # This must be imported last in the matplotlib series, after
555 # backend/interactivity choices have been made
556 import matplotlib.pylab as pylab
557 self.pylab = pylab
558
559 self.pylab.show._needmain = False
560 # We need to detect at runtime whether show() is called by the user.
561 # For this, we wrap it into a decorator which adds a 'called' flag.
562 self.pylab.draw_if_interactive = flag_calls(self.pylab.draw_if_interactive)
563
564 # Build a user namespace initialized with matplotlib/matlab features.
565 user_ns, user_global_ns = IPython.ipapi.make_user_namespaces(user_ns,
566 user_global_ns)
567
568 # Import numpy as np/pyplot as plt are conventions we're trying to
569 # somewhat standardize on. Making them available to users by default
570 # will greatly help this.
571 exec ("import numpy\n"
572 "import numpy as np\n"
573 "import matplotlib\n"
574 "import matplotlib.pylab as pylab\n"
575 "try:\n"
576 " import matplotlib.pyplot as plt\n"
577 "except ImportError:\n"
578 " pass\n"
579 ) in user_ns
580
581 # Build matplotlib info banner
582 b="""
583 Welcome to pylab, a matplotlib-based Python environment.
584 For more information, type 'help(pylab)'.
585 """
29 """
586 return user_ns,user_global_ns,b
587
588 def mplot_exec(self,fname,*where,**kw):
589 """Execute a matplotlib script.
590
591 This is a call to execfile(), but wrapped in safeties to properly
592 handle interactive rendering and backend switching."""
593
594 #print '*** Matplotlib runner ***' # dbg
595 # turn off rendering until end of script
596 isInteractive = self.matplotlib.rcParams['interactive']
597 self.matplotlib.interactive(False)
598 self.safe_execfile(fname,*where,**kw)
599 self.matplotlib.interactive(isInteractive)
600 # make rendering call now, if the user tried to do it
601 if self.pylab.draw_if_interactive.called:
602 self.pylab.draw()
603 self.pylab.draw_if_interactive.called = False
604
605 # if a backend switch was performed, reverse it now
606 if self.mpl_use._called:
607 self.matplotlib.rcParams['backend'] = self.mpl_backend
608
609 @testdec.skip_doctest
610 def magic_run(self,parameter_s=''):
611 Magic.magic_run(self,parameter_s,runner=self.mplot_exec)
612
613 # Fix the docstring so users see the original as well
614 magic_run.__doc__ = "%s\n%s" % (Magic.magic_run.__doc__,
615 "\n *** Modified %run for Matplotlib,"
616 " with proper interactive handling ***")
617
618 # Now we provide 2 versions of a matplotlib-aware IPython base shells, single
619 # and multithreaded. Note that these are meant for internal use, the IPShell*
620 # classes below are the ones meant for public consumption.
621
622 class MatplotlibShell(MatplotlibShellBase,InteractiveShell):
623 """Single-threaded shell with matplotlib support."""
624
625 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
626 user_ns=None,user_global_ns=None,**kw):
627 user_ns,user_global_ns,b2 = self._matplotlib_config(name,user_ns,user_global_ns)
628 InteractiveShell.__init__(self,name,usage,rc,user_ns,user_global_ns,
629 banner2=b2,**kw)
630
631 class MatplotlibMTShell(MatplotlibShellBase,MTInteractiveShell):
632 """Multi-threaded shell with matplotlib support."""
633
634 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
635 user_ns=None,user_global_ns=None, **kw):
636 user_ns,user_global_ns,b2 = self._matplotlib_config(name,user_ns,user_global_ns)
637 MTInteractiveShell.__init__(self,name,usage,rc,user_ns,user_global_ns,
638 banner2=b2,**kw)
639
30
640 #-----------------------------------------------------------------------------
31 warn(msg, category=DeprecationWarning, stacklevel=1)
641 # Utility functions for the different GUI enabled IPShell* classes.
642
643 def get_tk():
644 """Tries to import Tkinter and returns a withdrawn Tkinter root
645 window. If Tkinter is already imported or not available, this
646 returns None. This function calls `hijack_tk` underneath.
647 """
648 if not USE_TK or sys.modules.has_key('Tkinter'):
649 return None
650 else:
651 try:
652 import Tkinter
653 except ImportError:
654 return None
655 else:
656 hijack_tk()
657 r = Tkinter.Tk()
658 r.withdraw()
659 return r
660
661 def hijack_tk():
662 """Modifies Tkinter's mainloop with a dummy so when a module calls
663 mainloop, it does not block.
664
32
665 """
33 from IPython.core.iplib import InteractiveShell as IPShell
666 def misc_mainloop(self, n=0):
34 from IPython.core.embed import InteractiveShellEmbed as IPShellEmbed
667 pass
668 def tkinter_mainloop(n=0):
669 pass
670
671 import Tkinter
672 Tkinter.Misc.mainloop = misc_mainloop
673 Tkinter.mainloop = tkinter_mainloop
674
35
675 def update_tk(tk):
36 def start(user_ns=None, embedded=False):
676 """Updates the Tkinter event loop. This is typically called from
37 """Return an instance of :class:`InteractiveShell`."""
677 the respective WX or GTK mainloops.
38 if embedded:
678 """
39 return InteractiveShellEmbed(user_ns=user_ns)
679 if tk:
680 tk.update()
681
682 def hijack_wx():
683 """Modifies wxPython's MainLoop with a dummy so user code does not
684 block IPython. The hijacked mainloop function is returned.
685 """
686 def dummy_mainloop(*args, **kw):
687 pass
688
689 try:
690 import wx
691 except ImportError:
692 # For very old versions of WX
693 import wxPython as wx
694
695 ver = wx.__version__
696 orig_mainloop = None
697 if ver[:3] >= '2.5':
698 import wx
699 if hasattr(wx, '_core_'): core = getattr(wx, '_core_')
700 elif hasattr(wx, '_core'): core = getattr(wx, '_core')
701 else: raise AttributeError('Could not find wx core module')
702 orig_mainloop = core.PyApp_MainLoop
703 core.PyApp_MainLoop = dummy_mainloop
704 elif ver[:3] == '2.4':
705 orig_mainloop = wx.wxc.wxPyApp_MainLoop
706 wx.wxc.wxPyApp_MainLoop = dummy_mainloop
707 else:
40 else:
708 warn("Unable to find either wxPython version 2.4 or >= 2.5.")
41 return InteractiveShell(user_ns=user_ns)
709 return orig_mainloop
710
711 def hijack_gtk():
712 """Modifies pyGTK's mainloop with a dummy so user code does not
713 block IPython. This function returns the original `gtk.mainloop`
714 function that has been hijacked.
715 """
716 def dummy_mainloop(*args, **kw):
717 pass
718 import gtk
719 if gtk.pygtk_version >= (2,4,0): orig_mainloop = gtk.main
720 else: orig_mainloop = gtk.mainloop
721 gtk.mainloop = dummy_mainloop
722 gtk.main = dummy_mainloop
723 return orig_mainloop
724
725 def hijack_qt():
726 """Modifies PyQt's mainloop with a dummy so user code does not
727 block IPython. This function returns the original
728 `qt.qApp.exec_loop` function that has been hijacked.
729 """
730 def dummy_mainloop(*args, **kw):
731 pass
732 import qt
733 orig_mainloop = qt.qApp.exec_loop
734 qt.qApp.exec_loop = dummy_mainloop
735 qt.QApplication.exec_loop = dummy_mainloop
736 return orig_mainloop
737
738 def hijack_qt4():
739 """Modifies PyQt4's mainloop with a dummy so user code does not
740 block IPython. This function returns the original
741 `QtGui.qApp.exec_` function that has been hijacked.
742 """
743 def dummy_mainloop(*args, **kw):
744 pass
745 from PyQt4 import QtGui, QtCore
746 orig_mainloop = QtGui.qApp.exec_
747 QtGui.qApp.exec_ = dummy_mainloop
748 QtGui.QApplication.exec_ = dummy_mainloop
749 QtCore.QCoreApplication.exec_ = dummy_mainloop
750 return orig_mainloop
751
752 #-----------------------------------------------------------------------------
753 # The IPShell* classes below are the ones meant to be run by external code as
754 # IPython instances. Note that unless a specific threading strategy is
755 # desired, the factory function start() below should be used instead (it
756 # selects the proper threaded class).
757
758 class IPThread(threading.Thread):
759 def run(self):
760 self.IP.mainloop(self._banner)
761 self.IP.kill()
762
763 class IPShellGTK(IPThread):
764 """Run a gtk mainloop() in a separate thread.
765
766 Python commands can be passed to the thread where they will be executed.
767 This is implemented by periodically checking for passed code using a
768 GTK timeout callback."""
769
770 TIMEOUT = 100 # Millisecond interval between timeouts.
771
772 def __init__(self,argv=None,user_ns=None,user_global_ns=None,
773 debug=1,shell_class=MTInteractiveShell):
774
775 import gtk
776 # Check for set_interactive, coming up in new pygtk.
777 # Disable it so that this code works, but notify
778 # the user that he has a better option as well.
779 # XXX TODO better support when set_interactive is released
780 try:
781 gtk.set_interactive(False)
782 print "Your PyGtk has set_interactive(), so you can use the"
783 print "more stable single-threaded Gtk mode."
784 print "See https://bugs.launchpad.net/ipython/+bug/270856"
785 except AttributeError:
786 pass
787
788 self.gtk = gtk
789 self.gtk_mainloop = hijack_gtk()
790
791 # Allows us to use both Tk and GTK.
792 self.tk = get_tk()
793
794 if gtk.pygtk_version >= (2,4,0): mainquit = self.gtk.main_quit
795 else: mainquit = self.gtk.mainquit
796
797 self.IP = make_IPython(argv,user_ns=user_ns,
798 user_global_ns=user_global_ns,
799 debug=debug,
800 shell_class=shell_class,
801 on_kill=[mainquit])
802
803 # HACK: slot for banner in self; it will be passed to the mainloop
804 # method only and .run() needs it. The actual value will be set by
805 # .mainloop().
806 self._banner = None
807
808 threading.Thread.__init__(self)
809
810 def mainloop(self,sys_exit=0,banner=None):
811
812 self._banner = banner
813
814 if self.gtk.pygtk_version >= (2,4,0):
815 import gobject
816 gobject.idle_add(self.on_timer)
817 else:
818 self.gtk.idle_add(self.on_timer)
819
820 if sys.platform != 'win32':
821 try:
822 if self.gtk.gtk_version[0] >= 2:
823 self.gtk.gdk.threads_init()
824 except AttributeError:
825 pass
826 except RuntimeError:
827 error('Your pyGTK likely has not been compiled with '
828 'threading support.\n'
829 'The exception printout is below.\n'
830 'You can either rebuild pyGTK with threads, or '
831 'try using \n'
832 'matplotlib with a different backend (like Tk or WX).\n'
833 'Note that matplotlib will most likely not work in its '
834 'current state!')
835 self.IP.InteractiveTB()
836
837 self.start()
838 self.gtk.gdk.threads_enter()
839 self.gtk_mainloop()
840 self.gtk.gdk.threads_leave()
841 self.join()
842
843 def on_timer(self):
844 """Called when GTK is idle.
845
846 Must return True always, otherwise GTK stops calling it"""
847
848 update_tk(self.tk)
849 self.IP.runcode()
850 time.sleep(0.01)
851 return True
852
853
854 class IPShellWX(IPThread):
855 """Run a wx mainloop() in a separate thread.
856
857 Python commands can be passed to the thread where they will be executed.
858 This is implemented by periodically checking for passed code using a
859 GTK timeout callback."""
860
861 TIMEOUT = 100 # Millisecond interval between timeouts.
862
863 def __init__(self,argv=None,user_ns=None,user_global_ns=None,
864 debug=1,shell_class=MTInteractiveShell):
865
866 self.IP = make_IPython(argv,user_ns=user_ns,
867 user_global_ns=user_global_ns,
868 debug=debug,
869 shell_class=shell_class,
870 on_kill=[self.wxexit])
871
872 wantedwxversion=self.IP.rc.wxversion
873 if wantedwxversion!="0":
874 try:
875 import wxversion
876 except ImportError:
877 error('The wxversion module is needed for WX version selection')
878 else:
879 try:
880 wxversion.select(wantedwxversion)
881 except:
882 self.IP.InteractiveTB()
883 error('Requested wxPython version %s could not be loaded' %
884 wantedwxversion)
885
886 import wx
887
888 threading.Thread.__init__(self)
889 self.wx = wx
890 self.wx_mainloop = hijack_wx()
891
892 # Allows us to use both Tk and GTK.
893 self.tk = get_tk()
894
895 # HACK: slot for banner in self; it will be passed to the mainloop
896 # method only and .run() needs it. The actual value will be set by
897 # .mainloop().
898 self._banner = None
899
900 self.app = None
901
902 def wxexit(self, *args):
903 if self.app is not None:
904 self.app.agent.timer.Stop()
905 self.app.ExitMainLoop()
906
907 def mainloop(self,sys_exit=0,banner=None):
908
909 self._banner = banner
910
911 self.start()
912
913 class TimerAgent(self.wx.MiniFrame):
914 wx = self.wx
915 IP = self.IP
916 tk = self.tk
917 def __init__(self, parent, interval):
918 style = self.wx.DEFAULT_FRAME_STYLE | self.wx.TINY_CAPTION_HORIZ
919 self.wx.MiniFrame.__init__(self, parent, -1, ' ', pos=(200, 200),
920 size=(100, 100),style=style)
921 self.Show(False)
922 self.interval = interval
923 self.timerId = self.wx.NewId()
924
925 def StartWork(self):
926 self.timer = self.wx.Timer(self, self.timerId)
927 self.wx.EVT_TIMER(self, self.timerId, self.OnTimer)
928 self.timer.Start(self.interval)
929
930 def OnTimer(self, event):
931 update_tk(self.tk)
932 self.IP.runcode()
933
934 class App(self.wx.App):
935 wx = self.wx
936 TIMEOUT = self.TIMEOUT
937 def OnInit(self):
938 'Create the main window and insert the custom frame'
939 self.agent = TimerAgent(None, self.TIMEOUT)
940 self.agent.Show(False)
941 self.agent.StartWork()
942 return True
943
944 self.app = App(redirect=False)
945 self.wx_mainloop(self.app)
946 self.join()
947
948
949 class IPShellQt(IPThread):
950 """Run a Qt event loop in a separate thread.
951
952 Python commands can be passed to the thread where they will be executed.
953 This is implemented by periodically checking for passed code using a
954 Qt timer / slot."""
955
956 TIMEOUT = 100 # Millisecond interval between timeouts.
957
958 def __init__(self, argv=None, user_ns=None, user_global_ns=None,
959 debug=0, shell_class=MTInteractiveShell):
960
961 import qt
962
963 self.exec_loop = hijack_qt()
964
965 # Allows us to use both Tk and QT.
966 self.tk = get_tk()
967
968 self.IP = make_IPython(argv,
969 user_ns=user_ns,
970 user_global_ns=user_global_ns,
971 debug=debug,
972 shell_class=shell_class,
973 on_kill=[qt.qApp.exit])
974
975 # HACK: slot for banner in self; it will be passed to the mainloop
976 # method only and .run() needs it. The actual value will be set by
977 # .mainloop().
978 self._banner = None
979
980 threading.Thread.__init__(self)
981
982 def mainloop(self, sys_exit=0, banner=None):
983
984 import qt
985
986 self._banner = banner
987
988 if qt.QApplication.startingUp():
989 a = qt.QApplication(sys.argv)
990
991 self.timer = qt.QTimer()
992 qt.QObject.connect(self.timer,
993 qt.SIGNAL('timeout()'),
994 self.on_timer)
995
996 self.start()
997 self.timer.start(self.TIMEOUT, True)
998 while True:
999 if self.IP._kill: break
1000 self.exec_loop()
1001 self.join()
1002
1003 def on_timer(self):
1004 update_tk(self.tk)
1005 result = self.IP.runcode()
1006 self.timer.start(self.TIMEOUT, True)
1007 return result
1008
1009
1010 class IPShellQt4(IPThread):
1011 """Run a Qt event loop in a separate thread.
1012
1013 Python commands can be passed to the thread where they will be executed.
1014 This is implemented by periodically checking for passed code using a
1015 Qt timer / slot."""
1016
1017 TIMEOUT = 100 # Millisecond interval between timeouts.
1018
1019 def __init__(self, argv=None, user_ns=None, user_global_ns=None,
1020 debug=0, shell_class=MTInteractiveShell):
1021
1022 from PyQt4 import QtCore, QtGui
1023
1024 try:
1025 # present in PyQt4-4.2.1 or later
1026 QtCore.pyqtRemoveInputHook()
1027 except AttributeError:
1028 pass
1029
1030 if QtCore.PYQT_VERSION_STR == '4.3':
1031 warn('''PyQt4 version 4.3 detected.
1032 If you experience repeated threading warnings, please update PyQt4.
1033 ''')
1034
1035 self.exec_ = hijack_qt4()
1036
1037 # Allows us to use both Tk and QT.
1038 self.tk = get_tk()
1039
1040 self.IP = make_IPython(argv,
1041 user_ns=user_ns,
1042 user_global_ns=user_global_ns,
1043 debug=debug,
1044 shell_class=shell_class,
1045 on_kill=[QtGui.qApp.exit])
1046
1047 # HACK: slot for banner in self; it will be passed to the mainloop
1048 # method only and .run() needs it. The actual value will be set by
1049 # .mainloop().
1050 self._banner = None
1051
1052 threading.Thread.__init__(self)
1053
1054 def mainloop(self, sys_exit=0, banner=None):
1055
1056 from PyQt4 import QtCore, QtGui
1057
1058 self._banner = banner
1059
1060 if QtGui.QApplication.startingUp():
1061 a = QtGui.QApplication(sys.argv)
1062
1063 self.timer = QtCore.QTimer()
1064 QtCore.QObject.connect(self.timer,
1065 QtCore.SIGNAL('timeout()'),
1066 self.on_timer)
1067
1068 self.start()
1069 self.timer.start(self.TIMEOUT)
1070 while True:
1071 if self.IP._kill: break
1072 self.exec_()
1073 self.join()
1074
1075 def on_timer(self):
1076 update_tk(self.tk)
1077 result = self.IP.runcode()
1078 self.timer.start(self.TIMEOUT)
1079 return result
1080
1081
1082 # A set of matplotlib public IPython shell classes, for single-threaded (Tk*
1083 # and FLTK*) and multithreaded (GTK*, WX* and Qt*) backends to use.
1084 def _load_pylab(user_ns):
1085 """Allow users to disable pulling all of pylab into the top-level
1086 namespace.
1087
1088 This little utility must be called AFTER the actual ipython instance is
1089 running, since only then will the options file have been fully parsed."""
1090
1091 ip = IPython.ipapi.get()
1092 if ip.options.pylab_import_all:
1093 ip.ex("from matplotlib.pylab import *")
1094 ip.IP.user_config_ns.update(ip.user_ns)
1095
1096
1097 class IPShellMatplotlib(IPShell):
1098 """Subclass IPShell with MatplotlibShell as the internal shell.
1099
1100 Single-threaded class, meant for the Tk* and FLTK* backends.
1101
1102 Having this on a separate class simplifies the external driver code."""
1103
1104 def __init__(self,argv=None,user_ns=None,user_global_ns=None,debug=1):
1105 IPShell.__init__(self,argv,user_ns,user_global_ns,debug,
1106 shell_class=MatplotlibShell)
1107 _load_pylab(self.IP.user_ns)
1108
1109 class IPShellMatplotlibGTK(IPShellGTK):
1110 """Subclass IPShellGTK with MatplotlibMTShell as the internal shell.
1111
1112 Multi-threaded class, meant for the GTK* backends."""
1113
1114 def __init__(self,argv=None,user_ns=None,user_global_ns=None,debug=1):
1115 IPShellGTK.__init__(self,argv,user_ns,user_global_ns,debug,
1116 shell_class=MatplotlibMTShell)
1117 _load_pylab(self.IP.user_ns)
1118
1119 class IPShellMatplotlibWX(IPShellWX):
1120 """Subclass IPShellWX with MatplotlibMTShell as the internal shell.
1121
1122 Multi-threaded class, meant for the WX* backends."""
1123
1124 def __init__(self,argv=None,user_ns=None,user_global_ns=None,debug=1):
1125 IPShellWX.__init__(self,argv,user_ns,user_global_ns,debug,
1126 shell_class=MatplotlibMTShell)
1127 _load_pylab(self.IP.user_ns)
1128
1129 class IPShellMatplotlibQt(IPShellQt):
1130 """Subclass IPShellQt with MatplotlibMTShell as the internal shell.
1131
1132 Multi-threaded class, meant for the Qt* backends."""
1133
1134 def __init__(self,argv=None,user_ns=None,user_global_ns=None,debug=1):
1135 IPShellQt.__init__(self,argv,user_ns,user_global_ns,debug,
1136 shell_class=MatplotlibMTShell)
1137 _load_pylab(self.IP.user_ns)
1138
1139 class IPShellMatplotlibQt4(IPShellQt4):
1140 """Subclass IPShellQt4 with MatplotlibMTShell as the internal shell.
1141
1142 Multi-threaded class, meant for the Qt4* backends."""
1143
1144 def __init__(self,argv=None,user_ns=None,user_global_ns=None,debug=1):
1145 IPShellQt4.__init__(self,argv,user_ns,user_global_ns,debug,
1146 shell_class=MatplotlibMTShell)
1147 _load_pylab(self.IP.user_ns)
1148
1149 #-----------------------------------------------------------------------------
1150 # Factory functions to actually start the proper thread-aware shell
1151
1152 def _select_shell(argv):
1153 """Select a shell from the given argv vector.
1154
1155 This function implements the threading selection policy, allowing runtime
1156 control of the threading mode, both for general users and for matplotlib.
1157
1158 Return:
1159 Shell class to be instantiated for runtime operation.
1160 """
1161
1162 global USE_TK
1163
1164 mpl_shell = {'gthread' : IPShellMatplotlibGTK,
1165 'wthread' : IPShellMatplotlibWX,
1166 'qthread' : IPShellMatplotlibQt,
1167 'q4thread' : IPShellMatplotlibQt4,
1168 'tkthread' : IPShellMatplotlib, # Tk is built-in
1169 }
1170
1171 th_shell = {'gthread' : IPShellGTK,
1172 'wthread' : IPShellWX,
1173 'qthread' : IPShellQt,
1174 'q4thread' : IPShellQt4,
1175 'tkthread' : IPShell, # Tk is built-in
1176 }
1177
1178 backends = {'gthread' : 'GTKAgg',
1179 'wthread' : 'WXAgg',
1180 'qthread' : 'QtAgg',
1181 'q4thread' :'Qt4Agg',
1182 'tkthread' :'TkAgg',
1183 }
1184
1185 all_opts = set(['tk','pylab','gthread','qthread','q4thread','wthread',
1186 'tkthread'])
1187 user_opts = set([s.replace('-','') for s in argv[:3]])
1188 special_opts = user_opts & all_opts
1189
1190 if 'tk' in special_opts:
1191 USE_TK = True
1192 special_opts.remove('tk')
1193
1194 if 'pylab' in special_opts:
1195
1196 try:
1197 import matplotlib
1198 except ImportError:
1199 error('matplotlib could NOT be imported! Starting normal IPython.')
1200 return IPShell
1201
1202 special_opts.remove('pylab')
1203 # If there's any option left, it means the user wants to force the
1204 # threading backend, else it's auto-selected from the rc file
1205 if special_opts:
1206 th_mode = special_opts.pop()
1207 matplotlib.rcParams['backend'] = backends[th_mode]
1208 else:
1209 backend = matplotlib.rcParams['backend']
1210 if backend.startswith('GTK'):
1211 th_mode = 'gthread'
1212 elif backend.startswith('WX'):
1213 th_mode = 'wthread'
1214 elif backend.startswith('Qt4'):
1215 th_mode = 'q4thread'
1216 elif backend.startswith('Qt'):
1217 th_mode = 'qthread'
1218 else:
1219 # Any other backend, use plain Tk
1220 th_mode = 'tkthread'
1221
1222 return mpl_shell[th_mode]
1223 else:
1224 # No pylab requested, just plain threads
1225 try:
1226 th_mode = special_opts.pop()
1227 except KeyError:
1228 th_mode = 'tkthread'
1229 return th_shell[th_mode]
1230
1231
1232 # This is the one which should be called by external code.
1233 def start(user_ns = None):
1234 """Return a running shell instance, dealing with threading options.
1235
1236 This is a factory function which will instantiate the proper IPython shell
1237 based on the user's threading choice. Such a selector is needed because
1238 different GUI toolkits require different thread handling details."""
1239
1240 shell = _select_shell(sys.argv)
1241 return shell(user_ns = user_ns)
1242
42
1243 # Some aliases for backwards compatibility
1244 IPythonShell = IPShell
1245 IPythonShellEmbed = IPShellEmbed
1246 #************************ End of file <Shell.py> ***************************
@@ -1,72 +1,64 b''
1 # -*- coding: utf-8 -*-
1 #!/usr/bin/env python
2 # encoding: utf-8
2 """
3 """
3 IPython -- An enhanced Interactive Python
4 IPython.
4
5
5 One of Python's nicest features is its interactive interpreter. This allows
6 IPython is a set of tools for interactive and exploratory computing in Python.
6 very fast testing of ideas without the overhead of creating test files as is
7 typical in most programming languages. However, the interpreter supplied with
8 the standard Python distribution is fairly primitive (and IDLE isn't really
9 much better).
10
11 IPython tries to:
12
13 i - provide an efficient environment for interactive work in Python
14 programming. It tries to address what we see as shortcomings of the standard
15 Python prompt, and adds many features to make interactive work much more
16 efficient.
17
18 ii - offer a flexible framework so that it can be used as the base
19 environment for other projects and problems where Python can be the
20 underlying language. Specifically scientific environments like Mathematica,
21 IDL and Mathcad inspired its design, but similar ideas can be useful in many
22 fields. Python is a fabulous language for implementing this kind of system
23 (due to its dynamic and introspective features), and with suitable libraries
24 entire systems could be built leveraging Python's power.
25
26 iii - serve as an embeddable, ready to go interpreter for your own programs.
27
28 IPython requires Python 2.4 or newer.
29 """
7 """
30
8
31 #*****************************************************************************
9 #-----------------------------------------------------------------------------
32 # Copyright (C) 2008-2009 The IPython Development Team
10 # Copyright (C) 2008-2009 The IPython Development Team
33 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
34 #
11 #
35 # Distributed under the terms of the BSD License. The full license is in
12 # Distributed under the terms of the BSD License. The full license is in
36 # the file COPYING, distributed as part of this software.
13 # the file COPYING, distributed as part of this software.
37 #*****************************************************************************
14 #-----------------------------------------------------------------------------
15
16 #-----------------------------------------------------------------------------
17 # Imports
18 #-----------------------------------------------------------------------------
38
19
39 # Enforce proper version requirements
20 import os
40 import sys
21 import sys
22 from IPython.core import release
23
24 #-----------------------------------------------------------------------------
25 # Setup everything
26 #-----------------------------------------------------------------------------
27
41
28
42 if sys.version[0:3] < '2.4':
29 if sys.version[0:3] < '2.4':
43 raise ImportError('Python Version 2.4 or above is required for IPython.')
30 raise ImportError('Python Version 2.4 or above is required for IPython.')
44
31
32
45 # Make it easy to import extensions - they are always directly on pythonpath.
33 # Make it easy to import extensions - they are always directly on pythonpath.
46 # Therefore, non-IPython modules can be added to Extensions directory
34 # Therefore, non-IPython modules can be added to extensions directory
47 import os
35 sys.path.append(os.path.join(os.path.dirname(__file__), "extensions"))
48 sys.path.append(os.path.dirname(__file__) + "/Extensions")
49
36
50 # Define what gets imported with a 'from IPython import *'
37 #-----------------------------------------------------------------------------
51 __all__ = ['ipapi','generics','ipstruct','Release','Shell']
38 # Setup the top level names
39 #-----------------------------------------------------------------------------
52
40
53 # Load __all__ in IPython namespace so that a simple 'import IPython' gives
41 # In some cases, these are causing circular imports.
54 # access to them via IPython.<name>
42 from IPython.core.iplib import InteractiveShell
55 glob,loc = globals(),locals()
43 from IPython.core.embed import embed
56 for name in __all__:
44 from IPython.core.error import TryNext
57 #print 'Importing: ',name # dbg
58 __import__(name,glob,loc,[])
59
45
60 import Shell
46 from IPython.lib import (
47 enable_wx, disable_wx,
48 enable_gtk, disable_gtk,
49 enable_qt4, disable_qt4,
50 enable_tk, disable_tk,
51 set_inputhook, clear_inputhook,
52 current_gui, spin,
53 appstart_qt4, appstart_wx,
54 appstart_gtk, appstart_tk
55 )
61
56
62 # Release data
57 # Release data
63 from IPython import Release # do it explicitly so pydoc can see it - pydoc bug
58 __author__ = ''
64 __author__ = '%s <%s>\n%s <%s>\n%s <%s>' % \
59 for author, email in release.authors.values():
65 ( Release.authors['Fernando'] + Release.authors['Janko'] + \
60 __author__ += author + ' <' + email + '>\n'
66 Release.authors['Nathan'] )
61 __license__ = release.license
67 __license__ = Release.license
62 __version__ = release.version
68 __version__ = Release.version
63 __revision__ = release.revision
69 __revision__ = Release.revision
70
64
71 # Namespace cleanup
72 del name,glob,loc
1 NO CONTENT: file renamed from IPython/UserConfig/__init__.py to IPython/config/default/__init__.py
NO CONTENT: file renamed from IPython/UserConfig/__init__.py to IPython/config/default/__init__.py
1 NO CONTENT: file renamed from IPython/tests/__init__.py to IPython/config/profile/__init__.py
NO CONTENT: file renamed from IPython/tests/__init__.py to IPython/config/profile/__init__.py
1 NO CONTENT: file renamed from IPython/tools/__init__.py to IPython/core/__init__.py
NO CONTENT: file renamed from IPython/tools/__init__.py to IPython/core/__init__.py
@@ -1,639 +1,642 b''
1 """Word completion for IPython.
1 """Word completion for IPython.
2
2
3 This module is a fork of the rlcompleter module in the Python standard
3 This module is a fork of the rlcompleter module in the Python standard
4 library. The original enhancements made to rlcompleter have been sent
4 library. The original enhancements made to rlcompleter have been sent
5 upstream and were accepted as of Python 2.3, but we need a lot more
5 upstream and were accepted as of Python 2.3, but we need a lot more
6 functionality specific to IPython, so this module will continue to live as an
6 functionality specific to IPython, so this module will continue to live as an
7 IPython-specific utility.
7 IPython-specific utility.
8
8
9 Original rlcompleter documentation:
9 Original rlcompleter documentation:
10
10
11 This requires the latest extension to the readline module (the
11 This requires the latest extension to the readline module (the
12 completes keywords, built-ins and globals in __main__; when completing
12 completes keywords, built-ins and globals in __main__; when completing
13 NAME.NAME..., it evaluates (!) the expression up to the last dot and
13 NAME.NAME..., it evaluates (!) the expression up to the last dot and
14 completes its attributes.
14 completes its attributes.
15
15
16 It's very cool to do "import string" type "string.", hit the
16 It's very cool to do "import string" type "string.", hit the
17 completion key (twice), and see the list of names defined by the
17 completion key (twice), and see the list of names defined by the
18 string module!
18 string module!
19
19
20 Tip: to use the tab key as the completion key, call
20 Tip: to use the tab key as the completion key, call
21
21
22 readline.parse_and_bind("tab: complete")
22 readline.parse_and_bind("tab: complete")
23
23
24 Notes:
24 Notes:
25
25
26 - Exceptions raised by the completer function are *ignored* (and
26 - Exceptions raised by the completer function are *ignored* (and
27 generally cause the completion to fail). This is a feature -- since
27 generally cause the completion to fail). This is a feature -- since
28 readline sets the tty device in raw (or cbreak) mode, printing a
28 readline sets the tty device in raw (or cbreak) mode, printing a
29 traceback wouldn't work well without some complicated hoopla to save,
29 traceback wouldn't work well without some complicated hoopla to save,
30 reset and restore the tty state.
30 reset and restore the tty state.
31
31
32 - The evaluation of the NAME.NAME... form may cause arbitrary
32 - The evaluation of the NAME.NAME... form may cause arbitrary
33 application defined code to be executed if an object with a
33 application defined code to be executed if an object with a
34 __getattr__ hook is found. Since it is the responsibility of the
34 __getattr__ hook is found. Since it is the responsibility of the
35 application (or the user) to enable this feature, I consider this an
35 application (or the user) to enable this feature, I consider this an
36 acceptable risk. More complicated expressions (e.g. function calls or
36 acceptable risk. More complicated expressions (e.g. function calls or
37 indexing operations) are *not* evaluated.
37 indexing operations) are *not* evaluated.
38
38
39 - GNU readline is also used by the built-in functions input() and
39 - GNU readline is also used by the built-in functions input() and
40 raw_input(), and thus these also benefit/suffer from the completer
40 raw_input(), and thus these also benefit/suffer from the completer
41 features. Clearly an interactive application can benefit by
41 features. Clearly an interactive application can benefit by
42 specifying its own completer function and using raw_input() for all
42 specifying its own completer function and using raw_input() for all
43 its input.
43 its input.
44
44
45 - When the original stdin is not a tty device, GNU readline is never
45 - When the original stdin is not a tty device, GNU readline is never
46 used, and this module (and the readline module) are silently inactive.
46 used, and this module (and the readline module) are silently inactive.
47
47
48 """
48 """
49
49
50 #*****************************************************************************
50 #*****************************************************************************
51 #
51 #
52 # Since this file is essentially a minimally modified copy of the rlcompleter
52 # Since this file is essentially a minimally modified copy of the rlcompleter
53 # module which is part of the standard Python distribution, I assume that the
53 # module which is part of the standard Python distribution, I assume that the
54 # proper procedure is to maintain its copyright as belonging to the Python
54 # proper procedure is to maintain its copyright as belonging to the Python
55 # Software Foundation (in addition to my own, for all new code).
55 # Software Foundation (in addition to my own, for all new code).
56 #
56 #
57 # Copyright (C) 2001 Python Software Foundation, www.python.org
57 # Copyright (C) 2001 Python Software Foundation, www.python.org
58 # Copyright (C) 2001-2006 Fernando Perez. <fperez@colorado.edu>
58 # Copyright (C) 2001-2006 Fernando Perez. <fperez@colorado.edu>
59 #
59 #
60 # Distributed under the terms of the BSD License. The full license is in
60 # Distributed under the terms of the BSD License. The full license is in
61 # the file COPYING, distributed as part of this software.
61 # the file COPYING, distributed as part of this software.
62 #
62 #
63 #*****************************************************************************
63 #*****************************************************************************
64
64
65 import __builtin__
65 import __builtin__
66 import __main__
66 import __main__
67 import glob
67 import glob
68 import itertools
68 import keyword
69 import keyword
69 import os
70 import os
70 import re
71 import re
71 import shlex
72 import shlex
72 import sys
73 import sys
73 import IPython.rlineimpl as readline
74 import itertools
75 from IPython.ipstruct import Struct
76 from IPython import ipapi
77 from IPython import generics
78 import types
74 import types
79
75
76 from IPython.core.error import TryNext
77 from IPython.core.prefilter import ESC_MAGIC
78
79 import IPython.utils.rlineimpl as readline
80 from IPython.utils.ipstruct import Struct
81 from IPython.utils import generics
82
80 # Python 2.4 offers sets as a builtin
83 # Python 2.4 offers sets as a builtin
81 try:
84 try:
82 set()
85 set()
83 except NameError:
86 except NameError:
84 from sets import Set as set
87 from sets import Set as set
85
88
86 from IPython.genutils import debugx, dir2
89 from IPython.utils.genutils import debugx, dir2
87
90
88 __all__ = ['Completer','IPCompleter']
91 __all__ = ['Completer','IPCompleter']
89
92
90 class Completer:
93 class Completer:
91 def __init__(self,namespace=None,global_namespace=None):
94 def __init__(self,namespace=None,global_namespace=None):
92 """Create a new completer for the command line.
95 """Create a new completer for the command line.
93
96
94 Completer([namespace,global_namespace]) -> completer instance.
97 Completer([namespace,global_namespace]) -> completer instance.
95
98
96 If unspecified, the default namespace where completions are performed
99 If unspecified, the default namespace where completions are performed
97 is __main__ (technically, __main__.__dict__). Namespaces should be
100 is __main__ (technically, __main__.__dict__). Namespaces should be
98 given as dictionaries.
101 given as dictionaries.
99
102
100 An optional second namespace can be given. This allows the completer
103 An optional second namespace can be given. This allows the completer
101 to handle cases where both the local and global scopes need to be
104 to handle cases where both the local and global scopes need to be
102 distinguished.
105 distinguished.
103
106
104 Completer instances should be used as the completion mechanism of
107 Completer instances should be used as the completion mechanism of
105 readline via the set_completer() call:
108 readline via the set_completer() call:
106
109
107 readline.set_completer(Completer(my_namespace).complete)
110 readline.set_completer(Completer(my_namespace).complete)
108 """
111 """
109
112
110 # Don't bind to namespace quite yet, but flag whether the user wants a
113 # Don't bind to namespace quite yet, but flag whether the user wants a
111 # specific namespace or to use __main__.__dict__. This will allow us
114 # specific namespace or to use __main__.__dict__. This will allow us
112 # to bind to __main__.__dict__ at completion time, not now.
115 # to bind to __main__.__dict__ at completion time, not now.
113 if namespace is None:
116 if namespace is None:
114 self.use_main_ns = 1
117 self.use_main_ns = 1
115 else:
118 else:
116 self.use_main_ns = 0
119 self.use_main_ns = 0
117 self.namespace = namespace
120 self.namespace = namespace
118
121
119 # The global namespace, if given, can be bound directly
122 # The global namespace, if given, can be bound directly
120 if global_namespace is None:
123 if global_namespace is None:
121 self.global_namespace = {}
124 self.global_namespace = {}
122 else:
125 else:
123 self.global_namespace = global_namespace
126 self.global_namespace = global_namespace
124
127
125 def complete(self, text, state):
128 def complete(self, text, state):
126 """Return the next possible completion for 'text'.
129 """Return the next possible completion for 'text'.
127
130
128 This is called successively with state == 0, 1, 2, ... until it
131 This is called successively with state == 0, 1, 2, ... until it
129 returns None. The completion should begin with 'text'.
132 returns None. The completion should begin with 'text'.
130
133
131 """
134 """
132 if self.use_main_ns:
135 if self.use_main_ns:
133 self.namespace = __main__.__dict__
136 self.namespace = __main__.__dict__
134
137
135 if state == 0:
138 if state == 0:
136 if "." in text:
139 if "." in text:
137 self.matches = self.attr_matches(text)
140 self.matches = self.attr_matches(text)
138 else:
141 else:
139 self.matches = self.global_matches(text)
142 self.matches = self.global_matches(text)
140 try:
143 try:
141 return self.matches[state]
144 return self.matches[state]
142 except IndexError:
145 except IndexError:
143 return None
146 return None
144
147
145 def global_matches(self, text):
148 def global_matches(self, text):
146 """Compute matches when text is a simple name.
149 """Compute matches when text is a simple name.
147
150
148 Return a list of all keywords, built-in functions and names currently
151 Return a list of all keywords, built-in functions and names currently
149 defined in self.namespace or self.global_namespace that match.
152 defined in self.namespace or self.global_namespace that match.
150
153
151 """
154 """
152 matches = []
155 matches = []
153 match_append = matches.append
156 match_append = matches.append
154 n = len(text)
157 n = len(text)
155 for lst in [keyword.kwlist,
158 for lst in [keyword.kwlist,
156 __builtin__.__dict__.keys(),
159 __builtin__.__dict__.keys(),
157 self.namespace.keys(),
160 self.namespace.keys(),
158 self.global_namespace.keys()]:
161 self.global_namespace.keys()]:
159 for word in lst:
162 for word in lst:
160 if word[:n] == text and word != "__builtins__":
163 if word[:n] == text and word != "__builtins__":
161 match_append(word)
164 match_append(word)
162 return matches
165 return matches
163
166
164 def attr_matches(self, text):
167 def attr_matches(self, text):
165 """Compute matches when text contains a dot.
168 """Compute matches when text contains a dot.
166
169
167 Assuming the text is of the form NAME.NAME....[NAME], and is
170 Assuming the text is of the form NAME.NAME....[NAME], and is
168 evaluatable in self.namespace or self.global_namespace, it will be
171 evaluatable in self.namespace or self.global_namespace, it will be
169 evaluated and its attributes (as revealed by dir()) are used as
172 evaluated and its attributes (as revealed by dir()) are used as
170 possible completions. (For class instances, class members are are
173 possible completions. (For class instances, class members are are
171 also considered.)
174 also considered.)
172
175
173 WARNING: this can still invoke arbitrary C code, if an object
176 WARNING: this can still invoke arbitrary C code, if an object
174 with a __getattr__ hook is evaluated.
177 with a __getattr__ hook is evaluated.
175
178
176 """
179 """
177 import re
180 import re
178
181
179 # Another option, seems to work great. Catches things like ''.<tab>
182 # Another option, seems to work great. Catches things like ''.<tab>
180 m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text)
183 m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text)
181
184
182 if not m:
185 if not m:
183 return []
186 return []
184
187
185 expr, attr = m.group(1, 3)
188 expr, attr = m.group(1, 3)
186 try:
189 try:
187 obj = eval(expr, self.namespace)
190 obj = eval(expr, self.namespace)
188 except:
191 except:
189 try:
192 try:
190 obj = eval(expr, self.global_namespace)
193 obj = eval(expr, self.global_namespace)
191 except:
194 except:
192 return []
195 return []
193
196
194 words = dir2(obj)
197 words = dir2(obj)
195
198
196 try:
199 try:
197 words = generics.complete_object(obj, words)
200 words = generics.complete_object(obj, words)
198 except ipapi.TryNext:
201 except TryNext:
199 pass
202 pass
200 # Build match list to return
203 # Build match list to return
201 n = len(attr)
204 n = len(attr)
202 res = ["%s.%s" % (expr, w) for w in words if w[:n] == attr ]
205 res = ["%s.%s" % (expr, w) for w in words if w[:n] == attr ]
203 return res
206 return res
204
207
205 class IPCompleter(Completer):
208 class IPCompleter(Completer):
206 """Extension of the completer class with IPython-specific features"""
209 """Extension of the completer class with IPython-specific features"""
207
210
208 def __init__(self,shell,namespace=None,global_namespace=None,
211 def __init__(self,shell,namespace=None,global_namespace=None,
209 omit__names=0,alias_table=None):
212 omit__names=0,alias_table=None):
210 """IPCompleter() -> completer
213 """IPCompleter() -> completer
211
214
212 Return a completer object suitable for use by the readline library
215 Return a completer object suitable for use by the readline library
213 via readline.set_completer().
216 via readline.set_completer().
214
217
215 Inputs:
218 Inputs:
216
219
217 - shell: a pointer to the ipython shell itself. This is needed
220 - shell: a pointer to the ipython shell itself. This is needed
218 because this completer knows about magic functions, and those can
221 because this completer knows about magic functions, and those can
219 only be accessed via the ipython instance.
222 only be accessed via the ipython instance.
220
223
221 - namespace: an optional dict where completions are performed.
224 - namespace: an optional dict where completions are performed.
222
225
223 - global_namespace: secondary optional dict for completions, to
226 - global_namespace: secondary optional dict for completions, to
224 handle cases (such as IPython embedded inside functions) where
227 handle cases (such as IPython embedded inside functions) where
225 both Python scopes are visible.
228 both Python scopes are visible.
226
229
227 - The optional omit__names parameter sets the completer to omit the
230 - The optional omit__names parameter sets the completer to omit the
228 'magic' names (__magicname__) for python objects unless the text
231 'magic' names (__magicname__) for python objects unless the text
229 to be completed explicitly starts with one or more underscores.
232 to be completed explicitly starts with one or more underscores.
230
233
231 - If alias_table is supplied, it should be a dictionary of aliases
234 - If alias_table is supplied, it should be a dictionary of aliases
232 to complete. """
235 to complete. """
233
236
234 Completer.__init__(self,namespace,global_namespace)
237 Completer.__init__(self,namespace,global_namespace)
235 self.magic_prefix = shell.name+'.magic_'
238 self.magic_prefix = shell.name+'.magic_'
236 self.magic_escape = shell.ESC_MAGIC
239 self.magic_escape = ESC_MAGIC
237 self.readline = readline
240 self.readline = readline
238 delims = self.readline.get_completer_delims()
241 delims = self.readline.get_completer_delims()
239 delims = delims.replace(self.magic_escape,'')
242 delims = delims.replace(self.magic_escape,'')
240 self.readline.set_completer_delims(delims)
243 self.readline.set_completer_delims(delims)
241 self.get_line_buffer = self.readline.get_line_buffer
244 self.get_line_buffer = self.readline.get_line_buffer
242 self.get_endidx = self.readline.get_endidx
245 self.get_endidx = self.readline.get_endidx
243 self.omit__names = omit__names
246 self.omit__names = omit__names
244 self.merge_completions = shell.rc.readline_merge_completions
247 self.merge_completions = shell.readline_merge_completions
245 if alias_table is None:
248 if alias_table is None:
246 alias_table = {}
249 alias_table = {}
247 self.alias_table = alias_table
250 self.alias_table = alias_table
248 # Regexp to split filenames with spaces in them
251 # Regexp to split filenames with spaces in them
249 self.space_name_re = re.compile(r'([^\\] )')
252 self.space_name_re = re.compile(r'([^\\] )')
250 # Hold a local ref. to glob.glob for speed
253 # Hold a local ref. to glob.glob for speed
251 self.glob = glob.glob
254 self.glob = glob.glob
252
255
253 # Determine if we are running on 'dumb' terminals, like (X)Emacs
256 # Determine if we are running on 'dumb' terminals, like (X)Emacs
254 # buffers, to avoid completion problems.
257 # buffers, to avoid completion problems.
255 term = os.environ.get('TERM','xterm')
258 term = os.environ.get('TERM','xterm')
256 self.dumb_terminal = term in ['dumb','emacs']
259 self.dumb_terminal = term in ['dumb','emacs']
257
260
258 # Special handling of backslashes needed in win32 platforms
261 # Special handling of backslashes needed in win32 platforms
259 if sys.platform == "win32":
262 if sys.platform == "win32":
260 self.clean_glob = self._clean_glob_win32
263 self.clean_glob = self._clean_glob_win32
261 else:
264 else:
262 self.clean_glob = self._clean_glob
265 self.clean_glob = self._clean_glob
263 self.matchers = [self.python_matches,
266 self.matchers = [self.python_matches,
264 self.file_matches,
267 self.file_matches,
265 self.alias_matches,
268 self.alias_matches,
266 self.python_func_kw_matches]
269 self.python_func_kw_matches]
267
270
268
271
269 # Code contributed by Alex Schmolck, for ipython/emacs integration
272 # Code contributed by Alex Schmolck, for ipython/emacs integration
270 def all_completions(self, text):
273 def all_completions(self, text):
271 """Return all possible completions for the benefit of emacs."""
274 """Return all possible completions for the benefit of emacs."""
272
275
273 completions = []
276 completions = []
274 comp_append = completions.append
277 comp_append = completions.append
275 try:
278 try:
276 for i in xrange(sys.maxint):
279 for i in xrange(sys.maxint):
277 res = self.complete(text, i)
280 res = self.complete(text, i)
278
281
279 if not res: break
282 if not res: break
280
283
281 comp_append(res)
284 comp_append(res)
282 #XXX workaround for ``notDefined.<tab>``
285 #XXX workaround for ``notDefined.<tab>``
283 except NameError:
286 except NameError:
284 pass
287 pass
285 return completions
288 return completions
286 # /end Alex Schmolck code.
289 # /end Alex Schmolck code.
287
290
288 def _clean_glob(self,text):
291 def _clean_glob(self,text):
289 return self.glob("%s*" % text)
292 return self.glob("%s*" % text)
290
293
291 def _clean_glob_win32(self,text):
294 def _clean_glob_win32(self,text):
292 return [f.replace("\\","/")
295 return [f.replace("\\","/")
293 for f in self.glob("%s*" % text)]
296 for f in self.glob("%s*" % text)]
294
297
295 def file_matches(self, text):
298 def file_matches(self, text):
296 """Match filenames, expanding ~USER type strings.
299 """Match filenames, expanding ~USER type strings.
297
300
298 Most of the seemingly convoluted logic in this completer is an
301 Most of the seemingly convoluted logic in this completer is an
299 attempt to handle filenames with spaces in them. And yet it's not
302 attempt to handle filenames with spaces in them. And yet it's not
300 quite perfect, because Python's readline doesn't expose all of the
303 quite perfect, because Python's readline doesn't expose all of the
301 GNU readline details needed for this to be done correctly.
304 GNU readline details needed for this to be done correctly.
302
305
303 For a filename with a space in it, the printed completions will be
306 For a filename with a space in it, the printed completions will be
304 only the parts after what's already been typed (instead of the
307 only the parts after what's already been typed (instead of the
305 full completions, as is normally done). I don't think with the
308 full completions, as is normally done). I don't think with the
306 current (as of Python 2.3) Python readline it's possible to do
309 current (as of Python 2.3) Python readline it's possible to do
307 better."""
310 better."""
308
311
309 #print 'Completer->file_matches: <%s>' % text # dbg
312 #print 'Completer->file_matches: <%s>' % text # dbg
310
313
311 # chars that require escaping with backslash - i.e. chars
314 # chars that require escaping with backslash - i.e. chars
312 # that readline treats incorrectly as delimiters, but we
315 # that readline treats incorrectly as delimiters, but we
313 # don't want to treat as delimiters in filename matching
316 # don't want to treat as delimiters in filename matching
314 # when escaped with backslash
317 # when escaped with backslash
315
318
316 if sys.platform == 'win32':
319 if sys.platform == 'win32':
317 protectables = ' '
320 protectables = ' '
318 else:
321 else:
319 protectables = ' ()'
322 protectables = ' ()'
320
323
321 if text.startswith('!'):
324 if text.startswith('!'):
322 text = text[1:]
325 text = text[1:]
323 text_prefix = '!'
326 text_prefix = '!'
324 else:
327 else:
325 text_prefix = ''
328 text_prefix = ''
326
329
327 def protect_filename(s):
330 def protect_filename(s):
328 return "".join([(ch in protectables and '\\' + ch or ch)
331 return "".join([(ch in protectables and '\\' + ch or ch)
329 for ch in s])
332 for ch in s])
330
333
331 def single_dir_expand(matches):
334 def single_dir_expand(matches):
332 "Recursively expand match lists containing a single dir."
335 "Recursively expand match lists containing a single dir."
333
336
334 if len(matches) == 1 and os.path.isdir(matches[0]):
337 if len(matches) == 1 and os.path.isdir(matches[0]):
335 # Takes care of links to directories also. Use '/'
338 # Takes care of links to directories also. Use '/'
336 # explicitly, even under Windows, so that name completions
339 # explicitly, even under Windows, so that name completions
337 # don't end up escaped.
340 # don't end up escaped.
338 d = matches[0]
341 d = matches[0]
339 if d[-1] in ['/','\\']:
342 if d[-1] in ['/','\\']:
340 d = d[:-1]
343 d = d[:-1]
341
344
342 subdirs = os.listdir(d)
345 subdirs = os.listdir(d)
343 if subdirs:
346 if subdirs:
344 matches = [ (d + '/' + p) for p in subdirs]
347 matches = [ (d + '/' + p) for p in subdirs]
345 return single_dir_expand(matches)
348 return single_dir_expand(matches)
346 else:
349 else:
347 return matches
350 return matches
348 else:
351 else:
349 return matches
352 return matches
350
353
351 lbuf = self.lbuf
354 lbuf = self.lbuf
352 open_quotes = 0 # track strings with open quotes
355 open_quotes = 0 # track strings with open quotes
353 try:
356 try:
354 lsplit = shlex.split(lbuf)[-1]
357 lsplit = shlex.split(lbuf)[-1]
355 except ValueError:
358 except ValueError:
356 # typically an unmatched ", or backslash without escaped char.
359 # typically an unmatched ", or backslash without escaped char.
357 if lbuf.count('"')==1:
360 if lbuf.count('"')==1:
358 open_quotes = 1
361 open_quotes = 1
359 lsplit = lbuf.split('"')[-1]
362 lsplit = lbuf.split('"')[-1]
360 elif lbuf.count("'")==1:
363 elif lbuf.count("'")==1:
361 open_quotes = 1
364 open_quotes = 1
362 lsplit = lbuf.split("'")[-1]
365 lsplit = lbuf.split("'")[-1]
363 else:
366 else:
364 return []
367 return []
365 except IndexError:
368 except IndexError:
366 # tab pressed on empty line
369 # tab pressed on empty line
367 lsplit = ""
370 lsplit = ""
368
371
369 if lsplit != protect_filename(lsplit):
372 if lsplit != protect_filename(lsplit):
370 # if protectables are found, do matching on the whole escaped
373 # if protectables are found, do matching on the whole escaped
371 # name
374 # name
372 has_protectables = 1
375 has_protectables = 1
373 text0,text = text,lsplit
376 text0,text = text,lsplit
374 else:
377 else:
375 has_protectables = 0
378 has_protectables = 0
376 text = os.path.expanduser(text)
379 text = os.path.expanduser(text)
377
380
378 if text == "":
381 if text == "":
379 return [text_prefix + protect_filename(f) for f in self.glob("*")]
382 return [text_prefix + protect_filename(f) for f in self.glob("*")]
380
383
381 m0 = self.clean_glob(text.replace('\\',''))
384 m0 = self.clean_glob(text.replace('\\',''))
382 if has_protectables:
385 if has_protectables:
383 # If we had protectables, we need to revert our changes to the
386 # If we had protectables, we need to revert our changes to the
384 # beginning of filename so that we don't double-write the part
387 # beginning of filename so that we don't double-write the part
385 # of the filename we have so far
388 # of the filename we have so far
386 len_lsplit = len(lsplit)
389 len_lsplit = len(lsplit)
387 matches = [text_prefix + text0 +
390 matches = [text_prefix + text0 +
388 protect_filename(f[len_lsplit:]) for f in m0]
391 protect_filename(f[len_lsplit:]) for f in m0]
389 else:
392 else:
390 if open_quotes:
393 if open_quotes:
391 # if we have a string with an open quote, we don't need to
394 # if we have a string with an open quote, we don't need to
392 # protect the names at all (and we _shouldn't_, as it
395 # protect the names at all (and we _shouldn't_, as it
393 # would cause bugs when the filesystem call is made).
396 # would cause bugs when the filesystem call is made).
394 matches = m0
397 matches = m0
395 else:
398 else:
396 matches = [text_prefix +
399 matches = [text_prefix +
397 protect_filename(f) for f in m0]
400 protect_filename(f) for f in m0]
398
401
399 #print 'mm',matches # dbg
402 #print 'mm',matches # dbg
400 return single_dir_expand(matches)
403 return single_dir_expand(matches)
401
404
402 def alias_matches(self, text):
405 def alias_matches(self, text):
403 """Match internal system aliases"""
406 """Match internal system aliases"""
404 #print 'Completer->alias_matches:',text,'lb',self.lbuf # dbg
407 #print 'Completer->alias_matches:',text,'lb',self.lbuf # dbg
405
408
406 # if we are not in the first 'item', alias matching
409 # if we are not in the first 'item', alias matching
407 # doesn't make sense - unless we are starting with 'sudo' command.
410 # doesn't make sense - unless we are starting with 'sudo' command.
408 if ' ' in self.lbuf.lstrip() and not self.lbuf.lstrip().startswith('sudo'):
411 if ' ' in self.lbuf.lstrip() and not self.lbuf.lstrip().startswith('sudo'):
409 return []
412 return []
410 text = os.path.expanduser(text)
413 text = os.path.expanduser(text)
411 aliases = self.alias_table.keys()
414 aliases = self.alias_table.keys()
412 if text == "":
415 if text == "":
413 return aliases
416 return aliases
414 else:
417 else:
415 return [alias for alias in aliases if alias.startswith(text)]
418 return [alias for alias in aliases if alias.startswith(text)]
416
419
417 def python_matches(self,text):
420 def python_matches(self,text):
418 """Match attributes or global python names"""
421 """Match attributes or global python names"""
419
422
420 #print 'Completer->python_matches, txt=<%s>' % text # dbg
423 #print 'Completer->python_matches, txt=<%s>' % text # dbg
421 if "." in text:
424 if "." in text:
422 try:
425 try:
423 matches = self.attr_matches(text)
426 matches = self.attr_matches(text)
424 if text.endswith('.') and self.omit__names:
427 if text.endswith('.') and self.omit__names:
425 if self.omit__names == 1:
428 if self.omit__names == 1:
426 # true if txt is _not_ a __ name, false otherwise:
429 # true if txt is _not_ a __ name, false otherwise:
427 no__name = (lambda txt:
430 no__name = (lambda txt:
428 re.match(r'.*\.__.*?__',txt) is None)
431 re.match(r'.*\.__.*?__',txt) is None)
429 else:
432 else:
430 # true if txt is _not_ a _ name, false otherwise:
433 # true if txt is _not_ a _ name, false otherwise:
431 no__name = (lambda txt:
434 no__name = (lambda txt:
432 re.match(r'.*\._.*?',txt) is None)
435 re.match(r'.*\._.*?',txt) is None)
433 matches = filter(no__name, matches)
436 matches = filter(no__name, matches)
434 except NameError:
437 except NameError:
435 # catches <undefined attributes>.<tab>
438 # catches <undefined attributes>.<tab>
436 matches = []
439 matches = []
437 else:
440 else:
438 matches = self.global_matches(text)
441 matches = self.global_matches(text)
439 # this is so completion finds magics when automagic is on:
442 # this is so completion finds magics when automagic is on:
440 if (matches == [] and
443 if (matches == [] and
441 not text.startswith(os.sep) and
444 not text.startswith(os.sep) and
442 not ' ' in self.lbuf):
445 not ' ' in self.lbuf):
443 matches = self.attr_matches(self.magic_prefix+text)
446 matches = self.attr_matches(self.magic_prefix+text)
444 return matches
447 return matches
445
448
446 def _default_arguments(self, obj):
449 def _default_arguments(self, obj):
447 """Return the list of default arguments of obj if it is callable,
450 """Return the list of default arguments of obj if it is callable,
448 or empty list otherwise."""
451 or empty list otherwise."""
449
452
450 if not (inspect.isfunction(obj) or inspect.ismethod(obj)):
453 if not (inspect.isfunction(obj) or inspect.ismethod(obj)):
451 # for classes, check for __init__,__new__
454 # for classes, check for __init__,__new__
452 if inspect.isclass(obj):
455 if inspect.isclass(obj):
453 obj = (getattr(obj,'__init__',None) or
456 obj = (getattr(obj,'__init__',None) or
454 getattr(obj,'__new__',None))
457 getattr(obj,'__new__',None))
455 # for all others, check if they are __call__able
458 # for all others, check if they are __call__able
456 elif hasattr(obj, '__call__'):
459 elif hasattr(obj, '__call__'):
457 obj = obj.__call__
460 obj = obj.__call__
458 # XXX: is there a way to handle the builtins ?
461 # XXX: is there a way to handle the builtins ?
459 try:
462 try:
460 args,_,_1,defaults = inspect.getargspec(obj)
463 args,_,_1,defaults = inspect.getargspec(obj)
461 if defaults:
464 if defaults:
462 return args[-len(defaults):]
465 return args[-len(defaults):]
463 except TypeError: pass
466 except TypeError: pass
464 return []
467 return []
465
468
466 def python_func_kw_matches(self,text):
469 def python_func_kw_matches(self,text):
467 """Match named parameters (kwargs) of the last open function"""
470 """Match named parameters (kwargs) of the last open function"""
468
471
469 if "." in text: # a parameter cannot be dotted
472 if "." in text: # a parameter cannot be dotted
470 return []
473 return []
471 try: regexp = self.__funcParamsRegex
474 try: regexp = self.__funcParamsRegex
472 except AttributeError:
475 except AttributeError:
473 regexp = self.__funcParamsRegex = re.compile(r'''
476 regexp = self.__funcParamsRegex = re.compile(r'''
474 '.*?' | # single quoted strings or
477 '.*?' | # single quoted strings or
475 ".*?" | # double quoted strings or
478 ".*?" | # double quoted strings or
476 \w+ | # identifier
479 \w+ | # identifier
477 \S # other characters
480 \S # other characters
478 ''', re.VERBOSE | re.DOTALL)
481 ''', re.VERBOSE | re.DOTALL)
479 # 1. find the nearest identifier that comes before an unclosed
482 # 1. find the nearest identifier that comes before an unclosed
480 # parenthesis e.g. for "foo (1+bar(x), pa", the candidate is "foo"
483 # parenthesis e.g. for "foo (1+bar(x), pa", the candidate is "foo"
481 tokens = regexp.findall(self.get_line_buffer())
484 tokens = regexp.findall(self.get_line_buffer())
482 tokens.reverse()
485 tokens.reverse()
483 iterTokens = iter(tokens); openPar = 0
486 iterTokens = iter(tokens); openPar = 0
484 for token in iterTokens:
487 for token in iterTokens:
485 if token == ')':
488 if token == ')':
486 openPar -= 1
489 openPar -= 1
487 elif token == '(':
490 elif token == '(':
488 openPar += 1
491 openPar += 1
489 if openPar > 0:
492 if openPar > 0:
490 # found the last unclosed parenthesis
493 # found the last unclosed parenthesis
491 break
494 break
492 else:
495 else:
493 return []
496 return []
494 # 2. Concatenate dotted names ("foo.bar" for "foo.bar(x, pa" )
497 # 2. Concatenate dotted names ("foo.bar" for "foo.bar(x, pa" )
495 ids = []
498 ids = []
496 isId = re.compile(r'\w+$').match
499 isId = re.compile(r'\w+$').match
497 while True:
500 while True:
498 try:
501 try:
499 ids.append(iterTokens.next())
502 ids.append(iterTokens.next())
500 if not isId(ids[-1]):
503 if not isId(ids[-1]):
501 ids.pop(); break
504 ids.pop(); break
502 if not iterTokens.next() == '.':
505 if not iterTokens.next() == '.':
503 break
506 break
504 except StopIteration:
507 except StopIteration:
505 break
508 break
506 # lookup the candidate callable matches either using global_matches
509 # lookup the candidate callable matches either using global_matches
507 # or attr_matches for dotted names
510 # or attr_matches for dotted names
508 if len(ids) == 1:
511 if len(ids) == 1:
509 callableMatches = self.global_matches(ids[0])
512 callableMatches = self.global_matches(ids[0])
510 else:
513 else:
511 callableMatches = self.attr_matches('.'.join(ids[::-1]))
514 callableMatches = self.attr_matches('.'.join(ids[::-1]))
512 argMatches = []
515 argMatches = []
513 for callableMatch in callableMatches:
516 for callableMatch in callableMatches:
514 try: namedArgs = self._default_arguments(eval(callableMatch,
517 try: namedArgs = self._default_arguments(eval(callableMatch,
515 self.namespace))
518 self.namespace))
516 except: continue
519 except: continue
517 for namedArg in namedArgs:
520 for namedArg in namedArgs:
518 if namedArg.startswith(text):
521 if namedArg.startswith(text):
519 argMatches.append("%s=" %namedArg)
522 argMatches.append("%s=" %namedArg)
520 return argMatches
523 return argMatches
521
524
522 def dispatch_custom_completer(self,text):
525 def dispatch_custom_completer(self,text):
523 #print "Custom! '%s' %s" % (text, self.custom_completers) # dbg
526 #print "Custom! '%s' %s" % (text, self.custom_completers) # dbg
524 line = self.full_lbuf
527 line = self.full_lbuf
525 if not line.strip():
528 if not line.strip():
526 return None
529 return None
527
530
528 event = Struct()
531 event = Struct()
529 event.line = line
532 event.line = line
530 event.symbol = text
533 event.symbol = text
531 cmd = line.split(None,1)[0]
534 cmd = line.split(None,1)[0]
532 event.command = cmd
535 event.command = cmd
533 #print "\ncustom:{%s]\n" % event # dbg
536 #print "\ncustom:{%s]\n" % event # dbg
534
537
535 # for foo etc, try also to find completer for %foo
538 # for foo etc, try also to find completer for %foo
536 if not cmd.startswith(self.magic_escape):
539 if not cmd.startswith(self.magic_escape):
537 try_magic = self.custom_completers.s_matches(
540 try_magic = self.custom_completers.s_matches(
538 self.magic_escape + cmd)
541 self.magic_escape + cmd)
539 else:
542 else:
540 try_magic = []
543 try_magic = []
541
544
542
545
543 for c in itertools.chain(
546 for c in itertools.chain(
544 self.custom_completers.s_matches(cmd),
547 self.custom_completers.s_matches(cmd),
545 try_magic,
548 try_magic,
546 self.custom_completers.flat_matches(self.lbuf)):
549 self.custom_completers.flat_matches(self.lbuf)):
547 #print "try",c # dbg
550 #print "try",c # dbg
548 try:
551 try:
549 res = c(event)
552 res = c(event)
550 # first, try case sensitive match
553 # first, try case sensitive match
551 withcase = [r for r in res if r.startswith(text)]
554 withcase = [r for r in res if r.startswith(text)]
552 if withcase:
555 if withcase:
553 return withcase
556 return withcase
554 # if none, then case insensitive ones are ok too
557 # if none, then case insensitive ones are ok too
555 return [r for r in res if r.lower().startswith(text.lower())]
558 return [r for r in res if r.lower().startswith(text.lower())]
556 except ipapi.TryNext:
559 except TryNext:
557 pass
560 pass
558
561
559 return None
562 return None
560
563
561 def complete(self, text, state,line_buffer=None):
564 def complete(self, text, state,line_buffer=None):
562 """Return the next possible completion for 'text'.
565 """Return the next possible completion for 'text'.
563
566
564 This is called successively with state == 0, 1, 2, ... until it
567 This is called successively with state == 0, 1, 2, ... until it
565 returns None. The completion should begin with 'text'.
568 returns None. The completion should begin with 'text'.
566
569
567 :Keywords:
570 :Keywords:
568 - line_buffer: string
571 - line_buffer: string
569 If not given, the completer attempts to obtain the current line buffer
572 If not given, the completer attempts to obtain the current line buffer
570 via readline. This keyword allows clients which are requesting for
573 via readline. This keyword allows clients which are requesting for
571 text completions in non-readline contexts to inform the completer of
574 text completions in non-readline contexts to inform the completer of
572 the entire text.
575 the entire text.
573 """
576 """
574
577
575 #print '\n*** COMPLETE: <%s> (%s)' % (text,state) # dbg
578 #print '\n*** COMPLETE: <%s> (%s)' % (text,state) # dbg
576
579
577 # if there is only a tab on a line with only whitespace, instead
580 # if there is only a tab on a line with only whitespace, instead
578 # of the mostly useless 'do you want to see all million
581 # of the mostly useless 'do you want to see all million
579 # completions' message, just do the right thing and give the user
582 # completions' message, just do the right thing and give the user
580 # his tab! Incidentally, this enables pasting of tabbed text from
583 # his tab! Incidentally, this enables pasting of tabbed text from
581 # an editor (as long as autoindent is off).
584 # an editor (as long as autoindent is off).
582
585
583 # It should be noted that at least pyreadline still shows
586 # It should be noted that at least pyreadline still shows
584 # file completions - is there a way around it?
587 # file completions - is there a way around it?
585
588
586 # don't apply this on 'dumb' terminals, such as emacs buffers, so we
589 # don't apply this on 'dumb' terminals, such as emacs buffers, so we
587 # don't interfere with their own tab-completion mechanism.
590 # don't interfere with their own tab-completion mechanism.
588 if line_buffer is None:
591 if line_buffer is None:
589 self.full_lbuf = self.get_line_buffer()
592 self.full_lbuf = self.get_line_buffer()
590 else:
593 else:
591 self.full_lbuf = line_buffer
594 self.full_lbuf = line_buffer
592
595
593 if not (self.dumb_terminal or self.full_lbuf.strip()):
596 if not (self.dumb_terminal or self.full_lbuf.strip()):
594 self.readline.insert_text('\t')
597 self.readline.insert_text('\t')
595 return None
598 return None
596
599
597 magic_escape = self.magic_escape
600 magic_escape = self.magic_escape
598 magic_prefix = self.magic_prefix
601 magic_prefix = self.magic_prefix
599
602
600 self.lbuf = self.full_lbuf[:self.get_endidx()]
603 self.lbuf = self.full_lbuf[:self.get_endidx()]
601
604
602 try:
605 try:
603 if text.startswith(magic_escape):
606 if text.startswith(magic_escape):
604 text = text.replace(magic_escape,magic_prefix)
607 text = text.replace(magic_escape,magic_prefix)
605 elif text.startswith('~'):
608 elif text.startswith('~'):
606 text = os.path.expanduser(text)
609 text = os.path.expanduser(text)
607 if state == 0:
610 if state == 0:
608 custom_res = self.dispatch_custom_completer(text)
611 custom_res = self.dispatch_custom_completer(text)
609 if custom_res is not None:
612 if custom_res is not None:
610 # did custom completers produce something?
613 # did custom completers produce something?
611 self.matches = custom_res
614 self.matches = custom_res
612 else:
615 else:
613 # Extend the list of completions with the results of each
616 # Extend the list of completions with the results of each
614 # matcher, so we return results to the user from all
617 # matcher, so we return results to the user from all
615 # namespaces.
618 # namespaces.
616 if self.merge_completions:
619 if self.merge_completions:
617 self.matches = []
620 self.matches = []
618 for matcher in self.matchers:
621 for matcher in self.matchers:
619 self.matches.extend(matcher(text))
622 self.matches.extend(matcher(text))
620 else:
623 else:
621 for matcher in self.matchers:
624 for matcher in self.matchers:
622 self.matches = matcher(text)
625 self.matches = matcher(text)
623 if self.matches:
626 if self.matches:
624 break
627 break
625 def uniq(alist):
628 def uniq(alist):
626 set = {}
629 set = {}
627 return [set.setdefault(e,e) for e in alist if e not in set]
630 return [set.setdefault(e,e) for e in alist if e not in set]
628 self.matches = uniq(self.matches)
631 self.matches = uniq(self.matches)
629 try:
632 try:
630 ret = self.matches[state].replace(magic_prefix,magic_escape)
633 ret = self.matches[state].replace(magic_prefix,magic_escape)
631 return ret
634 return ret
632 except IndexError:
635 except IndexError:
633 return None
636 return None
634 except:
637 except:
635 #from IPython.ultraTB import AutoFormattedTB; # dbg
638 #from IPython.core.ultratb import AutoFormattedTB; # dbg
636 #tb=AutoFormattedTB('Verbose');tb() #dbg
639 #tb=AutoFormattedTB('Verbose');tb() #dbg
637
640
638 # If completion fails, don't annoy the user.
641 # If completion fails, don't annoy the user.
639 return None
642 return None
@@ -1,230 +1,229 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """sys.excepthook for IPython itself, leaves a detailed report on disk.
2 """sys.excepthook for IPython itself, leaves a detailed report on disk.
3
3
4
4
5 Authors
5 Authors
6 -------
6 -------
7 - Fernando Perez <Fernando.Perez@berkeley.edu>
7 - Fernando Perez <Fernando.Perez@berkeley.edu>
8 """
8 """
9
9
10 #*****************************************************************************
10 #*****************************************************************************
11 # Copyright (C) 2008-2009 The IPython Development Team
11 # Copyright (C) 2008-2009 The IPython Development Team
12 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
12 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
13 #
13 #
14 # Distributed under the terms of the BSD License. The full license is in
14 # Distributed under the terms of the BSD License. The full license is in
15 # the file COPYING, distributed as part of this software.
15 # the file COPYING, distributed as part of this software.
16 #*****************************************************************************
16 #*****************************************************************************
17
17
18 #****************************************************************************
18 #****************************************************************************
19 # Required modules
19 # Required modules
20
20
21 # From the standard library
21 # From the standard library
22 import os
22 import os
23 import sys
23 import sys
24 from pprint import pprint,pformat
24 from pprint import pformat
25
25
26 # Our own
26 # Our own
27 from IPython import Release
27 from IPython.core import release
28 from IPython import ultraTB
28 from IPython.core import ultratb
29 from IPython.ColorANSI import ColorScheme,ColorSchemeTable # too long names
29 from IPython.external.Itpl import itpl
30 from IPython.Itpl import Itpl,itpl,printpl
31
30
32 from IPython.genutils import *
31 from IPython.utils.genutils import *
33
32
34 #****************************************************************************
33 #****************************************************************************
35 class CrashHandler:
34 class CrashHandler:
36 """Customizable crash handlers for IPython-based systems.
35 """Customizable crash handlers for IPython-based systems.
37
36
38 Instances of this class provide a __call__ method which can be used as a
37 Instances of this class provide a __call__ method which can be used as a
39 sys.excepthook, i.e., the __call__ signature is:
38 sys.excepthook, i.e., the __call__ signature is:
40
39
41 def __call__(self,etype, evalue, etb)
40 def __call__(self,etype, evalue, etb)
42
41
43 """
42 """
44
43
45 def __init__(self,IP,app_name,contact_name,contact_email,
44 def __init__(self,IP,app_name,contact_name,contact_email,
46 bug_tracker,crash_report_fname,
45 bug_tracker,crash_report_fname,
47 show_crash_traceback=True):
46 show_crash_traceback=True):
48 """New crash handler.
47 """New crash handler.
49
48
50 Inputs:
49 Inputs:
51
50
52 - IP: a running IPython instance, which will be queried at crash time
51 - IP: a running IPython instance, which will be queried at crash time
53 for internal information.
52 for internal information.
54
53
55 - app_name: a string containing the name of your application.
54 - app_name: a string containing the name of your application.
56
55
57 - contact_name: a string with the name of the person to contact.
56 - contact_name: a string with the name of the person to contact.
58
57
59 - contact_email: a string with the email address of the contact.
58 - contact_email: a string with the email address of the contact.
60
59
61 - bug_tracker: a string with the URL for your project's bug tracker.
60 - bug_tracker: a string with the URL for your project's bug tracker.
62
61
63 - crash_report_fname: a string with the filename for the crash report
62 - crash_report_fname: a string with the filename for the crash report
64 to be saved in. These reports are left in the ipython user directory
63 to be saved in. These reports are left in the ipython user directory
65 as determined by the running IPython instance.
64 as determined by the running IPython instance.
66
65
67 Optional inputs:
66 Optional inputs:
68
67
69 - show_crash_traceback(True): if false, don't print the crash
68 - show_crash_traceback(True): if false, don't print the crash
70 traceback on stderr, only generate the on-disk report
69 traceback on stderr, only generate the on-disk report
71
70
72
71
73 Non-argument instance attributes:
72 Non-argument instance attributes:
74
73
75 These instances contain some non-argument attributes which allow for
74 These instances contain some non-argument attributes which allow for
76 further customization of the crash handler's behavior. Please see the
75 further customization of the crash handler's behavior. Please see the
77 source for further details.
76 source for further details.
78 """
77 """
79
78
80 # apply args into instance
79 # apply args into instance
81 self.IP = IP # IPython instance
80 self.IP = IP # IPython instance
82 self.app_name = app_name
81 self.app_name = app_name
83 self.contact_name = contact_name
82 self.contact_name = contact_name
84 self.contact_email = contact_email
83 self.contact_email = contact_email
85 self.bug_tracker = bug_tracker
84 self.bug_tracker = bug_tracker
86 self.crash_report_fname = crash_report_fname
85 self.crash_report_fname = crash_report_fname
87 self.show_crash_traceback = show_crash_traceback
86 self.show_crash_traceback = show_crash_traceback
88
87
89 # Hardcoded defaults, which can be overridden either by subclasses or
88 # Hardcoded defaults, which can be overridden either by subclasses or
90 # at runtime for the instance.
89 # at runtime for the instance.
91
90
92 # Template for the user message. Subclasses which completely override
91 # Template for the user message. Subclasses which completely override
93 # this, or user apps, can modify it to suit their tastes. It gets
92 # this, or user apps, can modify it to suit their tastes. It gets
94 # expanded using itpl, so calls of the kind $self.foo are valid.
93 # expanded using itpl, so calls of the kind $self.foo are valid.
95 self.user_message_template = """
94 self.user_message_template = """
96 Oops, $self.app_name crashed. We do our best to make it stable, but...
95 Oops, $self.app_name crashed. We do our best to make it stable, but...
97
96
98 A crash report was automatically generated with the following information:
97 A crash report was automatically generated with the following information:
99 - A verbatim copy of the crash traceback.
98 - A verbatim copy of the crash traceback.
100 - A copy of your input history during this session.
99 - A copy of your input history during this session.
101 - Data on your current $self.app_name configuration.
100 - Data on your current $self.app_name configuration.
102
101
103 It was left in the file named:
102 It was left in the file named:
104 \t'$self.crash_report_fname'
103 \t'$self.crash_report_fname'
105 If you can email this file to the developers, the information in it will help
104 If you can email this file to the developers, the information in it will help
106 them in understanding and correcting the problem.
105 them in understanding and correcting the problem.
107
106
108 You can mail it to: $self.contact_name at $self.contact_email
107 You can mail it to: $self.contact_name at $self.contact_email
109 with the subject '$self.app_name Crash Report'.
108 with the subject '$self.app_name Crash Report'.
110
109
111 If you want to do it now, the following command will work (under Unix):
110 If you want to do it now, the following command will work (under Unix):
112 mail -s '$self.app_name Crash Report' $self.contact_email < $self.crash_report_fname
111 mail -s '$self.app_name Crash Report' $self.contact_email < $self.crash_report_fname
113
112
114 To ensure accurate tracking of this issue, please file a report about it at:
113 To ensure accurate tracking of this issue, please file a report about it at:
115 $self.bug_tracker
114 $self.bug_tracker
116 """
115 """
117
116
118 def __call__(self,etype, evalue, etb):
117 def __call__(self,etype, evalue, etb):
119 """Handle an exception, call for compatible with sys.excepthook"""
118 """Handle an exception, call for compatible with sys.excepthook"""
120
119
121 # Report tracebacks shouldn't use color in general (safer for users)
120 # Report tracebacks shouldn't use color in general (safer for users)
122 color_scheme = 'NoColor'
121 color_scheme = 'NoColor'
123
122
124 # Use this ONLY for developer debugging (keep commented out for release)
123 # Use this ONLY for developer debugging (keep commented out for release)
125 #color_scheme = 'Linux' # dbg
124 #color_scheme = 'Linux' # dbg
126
125
127 try:
126 try:
128 rptdir = self.IP.rc.ipythondir
127 rptdir = self.IP.ipython_dir
129 except:
128 except:
130 rptdir = os.getcwd()
129 rptdir = os.getcwd()
131 if not os.path.isdir(rptdir):
130 if not os.path.isdir(rptdir):
132 rptdir = os.getcwd()
131 rptdir = os.getcwd()
133 report_name = os.path.join(rptdir,self.crash_report_fname)
132 report_name = os.path.join(rptdir,self.crash_report_fname)
134 # write the report filename into the instance dict so it can get
133 # write the report filename into the instance dict so it can get
135 # properly expanded out in the user message template
134 # properly expanded out in the user message template
136 self.crash_report_fname = report_name
135 self.crash_report_fname = report_name
137 TBhandler = ultraTB.VerboseTB(color_scheme=color_scheme,
136 TBhandler = ultratb.VerboseTB(color_scheme=color_scheme,
138 long_header=1)
137 long_header=1)
139 traceback = TBhandler.text(etype,evalue,etb,context=31)
138 traceback = TBhandler.text(etype,evalue,etb,context=31)
140
139
141 # print traceback to screen
140 # print traceback to screen
142 if self.show_crash_traceback:
141 if self.show_crash_traceback:
143 print >> sys.stderr, traceback
142 print >> sys.stderr, traceback
144
143
145 # and generate a complete report on disk
144 # and generate a complete report on disk
146 try:
145 try:
147 report = open(report_name,'w')
146 report = open(report_name,'w')
148 except:
147 except:
149 print >> sys.stderr, 'Could not create crash report on disk.'
148 print >> sys.stderr, 'Could not create crash report on disk.'
150 return
149 return
151
150
152 # Inform user on stderr of what happened
151 # Inform user on stderr of what happened
153 msg = itpl('\n'+'*'*70+'\n'+self.user_message_template)
152 msg = itpl('\n'+'*'*70+'\n'+self.user_message_template)
154 print >> sys.stderr, msg
153 print >> sys.stderr, msg
155
154
156 # Construct report on disk
155 # Construct report on disk
157 report.write(self.make_report(traceback))
156 report.write(self.make_report(traceback))
158 report.close()
157 report.close()
159 raw_input("Press enter to exit:")
158 raw_input("Press enter to exit:")
160
159
161 def make_report(self,traceback):
160 def make_report(self,traceback):
162 """Return a string containing a crash report."""
161 """Return a string containing a crash report."""
163
162
164 sec_sep = '\n\n'+'*'*75+'\n\n'
163 sec_sep = '\n\n'+'*'*75+'\n\n'
165
164
166 report = []
165 report = []
167 rpt_add = report.append
166 rpt_add = report.append
168
167
169 rpt_add('*'*75+'\n\n'+'IPython post-mortem report\n\n')
168 rpt_add('*'*75+'\n\n'+'IPython post-mortem report\n\n')
170 rpt_add('IPython version: %s \n\n' % Release.version)
169 rpt_add('IPython version: %s \n\n' % release.version)
171 rpt_add('BZR revision : %s \n\n' % Release.revision)
170 rpt_add('BZR revision : %s \n\n' % release.revision)
172 rpt_add('Platform info : os.name -> %s, sys.platform -> %s' %
171 rpt_add('Platform info : os.name -> %s, sys.platform -> %s' %
173 (os.name,sys.platform) )
172 (os.name,sys.platform) )
174 rpt_add(sec_sep+'Current user configuration structure:\n\n')
173 rpt_add(sec_sep+'Current user configuration structure:\n\n')
175 rpt_add(pformat(self.IP.rc.dict()))
174 rpt_add(pformat(self.IP.dict()))
176 rpt_add(sec_sep+'Crash traceback:\n\n' + traceback)
175 rpt_add(sec_sep+'Crash traceback:\n\n' + traceback)
177 try:
176 try:
178 rpt_add(sec_sep+"History of session input:")
177 rpt_add(sec_sep+"History of session input:")
179 for line in self.IP.user_ns['_ih']:
178 for line in self.IP.user_ns['_ih']:
180 rpt_add(line)
179 rpt_add(line)
181 rpt_add('\n*** Last line of input (may not be in above history):\n')
180 rpt_add('\n*** Last line of input (may not be in above history):\n')
182 rpt_add(self.IP._last_input_line+'\n')
181 rpt_add(self.IP._last_input_line+'\n')
183 except:
182 except:
184 pass
183 pass
185
184
186 return ''.join(report)
185 return ''.join(report)
187
186
188 class IPythonCrashHandler(CrashHandler):
187 class IPythonCrashHandler(CrashHandler):
189 """sys.excepthook for IPython itself, leaves a detailed report on disk."""
188 """sys.excepthook for IPython itself, leaves a detailed report on disk."""
190
189
191 def __init__(self,IP):
190 def __init__(self,IP):
192
191
193 # Set here which of the IPython authors should be listed as contact
192 # Set here which of the IPython authors should be listed as contact
194 AUTHOR_CONTACT = 'Ville'
193 AUTHOR_CONTACT = 'Fernando'
195
194
196 # Set argument defaults
195 # Set argument defaults
197 app_name = 'IPython'
196 app_name = 'IPython'
198 bug_tracker = 'https://bugs.launchpad.net/ipython/+filebug'
197 bug_tracker = 'https://bugs.launchpad.net/ipython/+filebug'
199 contact_name,contact_email = Release.authors[AUTHOR_CONTACT][:2]
198 contact_name,contact_email = release.authors[AUTHOR_CONTACT][:2]
200 crash_report_fname = 'IPython_crash_report.txt'
199 crash_report_fname = 'IPython_crash_report.txt'
201 # Call parent constructor
200 # Call parent constructor
202 CrashHandler.__init__(self,IP,app_name,contact_name,contact_email,
201 CrashHandler.__init__(self,IP,app_name,contact_name,contact_email,
203 bug_tracker,crash_report_fname)
202 bug_tracker,crash_report_fname)
204
203
205 def make_report(self,traceback):
204 def make_report(self,traceback):
206 """Return a string containing a crash report."""
205 """Return a string containing a crash report."""
207
206
208 sec_sep = '\n\n'+'*'*75+'\n\n'
207 sec_sep = '\n\n'+'*'*75+'\n\n'
209
208
210 report = []
209 report = []
211 rpt_add = report.append
210 rpt_add = report.append
212
211
213 rpt_add('*'*75+'\n\n'+'IPython post-mortem report\n\n')
212 rpt_add('*'*75+'\n\n'+'IPython post-mortem report\n\n')
214 rpt_add('IPython version: %s \n\n' % Release.version)
213 rpt_add('IPython version: %s \n\n' % release.version)
215 rpt_add('BZR revision : %s \n\n' % Release.revision)
214 rpt_add('BZR revision : %s \n\n' % release.revision)
216 rpt_add('Platform info : os.name -> %s, sys.platform -> %s' %
215 rpt_add('Platform info : os.name -> %s, sys.platform -> %s' %
217 (os.name,sys.platform) )
216 (os.name,sys.platform) )
218 rpt_add(sec_sep+'Current user configuration structure:\n\n')
217 rpt_add(sec_sep+'Current user configuration structure:\n\n')
219 rpt_add(pformat(self.IP.rc.dict()))
218 # rpt_add(pformat(self.IP.dict()))
220 rpt_add(sec_sep+'Crash traceback:\n\n' + traceback)
219 rpt_add(sec_sep+'Crash traceback:\n\n' + traceback)
221 try:
220 try:
222 rpt_add(sec_sep+"History of session input:")
221 rpt_add(sec_sep+"History of session input:")
223 for line in self.IP.user_ns['_ih']:
222 for line in self.IP.user_ns['_ih']:
224 rpt_add(line)
223 rpt_add(line)
225 rpt_add('\n*** Last line of input (may not be in above history):\n')
224 rpt_add('\n*** Last line of input (may not be in above history):\n')
226 rpt_add(self.IP._last_input_line+'\n')
225 rpt_add(self.IP._last_input_line+'\n')
227 except:
226 except:
228 pass
227 pass
229
228
230 return ''.join(report)
229 return ''.join(report)
@@ -1,522 +1,479 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 Pdb debugger class.
3 Pdb debugger class.
4
4
5 Modified from the standard pdb.Pdb class to avoid including readline, so that
5 Modified from the standard pdb.Pdb class to avoid including readline, so that
6 the command line completion of other programs which include this isn't
6 the command line completion of other programs which include this isn't
7 damaged.
7 damaged.
8
8
9 In the future, this class will be expanded with improvements over the standard
9 In the future, this class will be expanded with improvements over the standard
10 pdb.
10 pdb.
11
11
12 The code in this file is mainly lifted out of cmd.py in Python 2.2, with minor
12 The code in this file is mainly lifted out of cmd.py in Python 2.2, with minor
13 changes. Licensing should therefore be under the standard Python terms. For
13 changes. Licensing should therefore be under the standard Python terms. For
14 details on the PSF (Python Software Foundation) standard license, see:
14 details on the PSF (Python Software Foundation) standard license, see:
15
15
16 http://www.python.org/2.2.3/license.html"""
16 http://www.python.org/2.2.3/license.html"""
17
17
18 #*****************************************************************************
18 #*****************************************************************************
19 #
19 #
20 # This file is licensed under the PSF license.
20 # This file is licensed under the PSF license.
21 #
21 #
22 # Copyright (C) 2001 Python Software Foundation, www.python.org
22 # Copyright (C) 2001 Python Software Foundation, www.python.org
23 # Copyright (C) 2005-2006 Fernando Perez. <fperez@colorado.edu>
23 # Copyright (C) 2005-2006 Fernando Perez. <fperez@colorado.edu>
24 #
24 #
25 #
25 #
26 #*****************************************************************************
26 #*****************************************************************************
27
27
28 import bdb
28 import bdb
29 import cmd
29 import cmd
30 import linecache
30 import linecache
31 import os
31 import os
32 import sys
32 import sys
33
33
34 from IPython import PyColorize, ColorANSI, ipapi
34 from IPython.utils import PyColorize
35 from IPython.genutils import Term
35 from IPython.core import ipapi
36 from IPython.excolors import exception_colors
36 from IPython.utils import coloransi
37 from IPython.utils.genutils import Term
38 from IPython.core.excolors import exception_colors
37
39
38 # See if we can use pydb.
40 # See if we can use pydb.
39 has_pydb = False
41 has_pydb = False
40 prompt = 'ipdb> '
42 prompt = 'ipdb> '
41 #We have to check this directly from sys.argv, config struct not yet available
43 #We have to check this directly from sys.argv, config struct not yet available
42 if '-pydb' in sys.argv:
44 if '-pydb' in sys.argv:
43 try:
45 try:
44 import pydb
46 import pydb
45 if hasattr(pydb.pydb, "runl") and pydb.version>'1.17':
47 if hasattr(pydb.pydb, "runl") and pydb.version>'1.17':
46 # Version 1.17 is broken, and that's what ships with Ubuntu Edgy, so we
48 # Version 1.17 is broken, and that's what ships with Ubuntu Edgy, so we
47 # better protect against it.
49 # better protect against it.
48 has_pydb = True
50 has_pydb = True
49 except ImportError:
51 except ImportError:
50 print "Pydb (http://bashdb.sourceforge.net/pydb/) does not seem to be available"
52 print "Pydb (http://bashdb.sourceforge.net/pydb/) does not seem to be available"
51
53
52 if has_pydb:
54 if has_pydb:
53 from pydb import Pdb as OldPdb
55 from pydb import Pdb as OldPdb
54 #print "Using pydb for %run -d and post-mortem" #dbg
56 #print "Using pydb for %run -d and post-mortem" #dbg
55 prompt = 'ipydb> '
57 prompt = 'ipydb> '
56 else:
58 else:
57 from pdb import Pdb as OldPdb
59 from pdb import Pdb as OldPdb
58
60
59 # Allow the set_trace code to operate outside of an ipython instance, even if
61 # Allow the set_trace code to operate outside of an ipython instance, even if
60 # it does so with some limitations. The rest of this support is implemented in
62 # it does so with some limitations. The rest of this support is implemented in
61 # the Tracer constructor.
63 # the Tracer constructor.
62 def BdbQuit_excepthook(et,ev,tb):
64 def BdbQuit_excepthook(et,ev,tb):
63 if et==bdb.BdbQuit:
65 if et==bdb.BdbQuit:
64 print 'Exiting Debugger.'
66 print 'Exiting Debugger.'
65 else:
67 else:
66 BdbQuit_excepthook.excepthook_ori(et,ev,tb)
68 BdbQuit_excepthook.excepthook_ori(et,ev,tb)
67
69
68 def BdbQuit_IPython_excepthook(self,et,ev,tb):
70 def BdbQuit_IPython_excepthook(self,et,ev,tb):
69 print 'Exiting Debugger.'
71 print 'Exiting Debugger.'
70
72
73
71 class Tracer(object):
74 class Tracer(object):
72 """Class for local debugging, similar to pdb.set_trace.
75 """Class for local debugging, similar to pdb.set_trace.
73
76
74 Instances of this class, when called, behave like pdb.set_trace, but
77 Instances of this class, when called, behave like pdb.set_trace, but
75 providing IPython's enhanced capabilities.
78 providing IPython's enhanced capabilities.
76
79
77 This is implemented as a class which must be initialized in your own code
80 This is implemented as a class which must be initialized in your own code
78 and not as a standalone function because we need to detect at runtime
81 and not as a standalone function because we need to detect at runtime
79 whether IPython is already active or not. That detection is done in the
82 whether IPython is already active or not. That detection is done in the
80 constructor, ensuring that this code plays nicely with a running IPython,
83 constructor, ensuring that this code plays nicely with a running IPython,
81 while functioning acceptably (though with limitations) if outside of it.
84 while functioning acceptably (though with limitations) if outside of it.
82 """
85 """
83
86
84 def __init__(self,colors=None):
87 def __init__(self,colors=None):
85 """Create a local debugger instance.
88 """Create a local debugger instance.
86
89
87 :Parameters:
90 :Parameters:
88
91
89 - `colors` (None): a string containing the name of the color scheme to
92 - `colors` (None): a string containing the name of the color scheme to
90 use, it must be one of IPython's valid color schemes. If not given, the
93 use, it must be one of IPython's valid color schemes. If not given, the
91 function will default to the current IPython scheme when running inside
94 function will default to the current IPython scheme when running inside
92 IPython, and to 'NoColor' otherwise.
95 IPython, and to 'NoColor' otherwise.
93
96
94 Usage example:
97 Usage example:
95
98
96 from IPython.Debugger import Tracer; debug_here = Tracer()
99 from IPython.core.debugger import Tracer; debug_here = Tracer()
97
100
98 ... later in your code
101 ... later in your code
99 debug_here() # -> will open up the debugger at that point.
102 debug_here() # -> will open up the debugger at that point.
100
103
101 Once the debugger activates, you can use all of its regular commands to
104 Once the debugger activates, you can use all of its regular commands to
102 step through code, set breakpoints, etc. See the pdb documentation
105 step through code, set breakpoints, etc. See the pdb documentation
103 from the Python standard library for usage details.
106 from the Python standard library for usage details.
104 """
107 """
105
108
106 global __IPYTHON__
107 try:
109 try:
108 __IPYTHON__
110 ip = ipapi.get()
109 except NameError:
111 except:
110 # Outside of ipython, we set our own exception hook manually
112 # Outside of ipython, we set our own exception hook manually
111 __IPYTHON__ = ipapi.get(True,False)
112 BdbQuit_excepthook.excepthook_ori = sys.excepthook
113 BdbQuit_excepthook.excepthook_ori = sys.excepthook
113 sys.excepthook = BdbQuit_excepthook
114 sys.excepthook = BdbQuit_excepthook
114 def_colors = 'NoColor'
115 def_colors = 'NoColor'
115 try:
116 try:
116 # Limited tab completion support
117 # Limited tab completion support
117 import rlcompleter,readline
118 import readline
118 readline.parse_and_bind('tab: complete')
119 readline.parse_and_bind('tab: complete')
119 except ImportError:
120 except ImportError:
120 pass
121 pass
121 else:
122 else:
122 # In ipython, we use its custom exception handler mechanism
123 # In ipython, we use its custom exception handler mechanism
123 ip = ipapi.get()
124 def_colors = ip.colors
124 def_colors = ip.options.colors
125 ip.set_custom_exc((bdb.BdbQuit,), BdbQuit_IPython_excepthook)
125 ip.set_custom_exc((bdb.BdbQuit,),BdbQuit_IPython_excepthook)
126
126
127 if colors is None:
127 if colors is None:
128 colors = def_colors
128 colors = def_colors
129 self.debugger = Pdb(colors)
129 self.debugger = Pdb(colors)
130
130
131 def __call__(self):
131 def __call__(self):
132 """Starts an interactive debugger at the point where called.
132 """Starts an interactive debugger at the point where called.
133
133
134 This is similar to the pdb.set_trace() function from the std lib, but
134 This is similar to the pdb.set_trace() function from the std lib, but
135 using IPython's enhanced debugger."""
135 using IPython's enhanced debugger."""
136
136
137 self.debugger.set_trace(sys._getframe().f_back)
137 self.debugger.set_trace(sys._getframe().f_back)
138
138
139
139 def decorate_fn_with_doc(new_fn, old_fn, additional_text=""):
140 def decorate_fn_with_doc(new_fn, old_fn, additional_text=""):
140 """Make new_fn have old_fn's doc string. This is particularly useful
141 """Make new_fn have old_fn's doc string. This is particularly useful
141 for the do_... commands that hook into the help system.
142 for the do_... commands that hook into the help system.
142 Adapted from from a comp.lang.python posting
143 Adapted from from a comp.lang.python posting
143 by Duncan Booth."""
144 by Duncan Booth."""
144 def wrapper(*args, **kw):
145 def wrapper(*args, **kw):
145 return new_fn(*args, **kw)
146 return new_fn(*args, **kw)
146 if old_fn.__doc__:
147 if old_fn.__doc__:
147 wrapper.__doc__ = old_fn.__doc__ + additional_text
148 wrapper.__doc__ = old_fn.__doc__ + additional_text
148 return wrapper
149 return wrapper
149
150
151
150 def _file_lines(fname):
152 def _file_lines(fname):
151 """Return the contents of a named file as a list of lines.
153 """Return the contents of a named file as a list of lines.
152
154
153 This function never raises an IOError exception: if the file can't be
155 This function never raises an IOError exception: if the file can't be
154 read, it simply returns an empty list."""
156 read, it simply returns an empty list."""
155
157
156 try:
158 try:
157 outfile = open(fname)
159 outfile = open(fname)
158 except IOError:
160 except IOError:
159 return []
161 return []
160 else:
162 else:
161 out = outfile.readlines()
163 out = outfile.readlines()
162 outfile.close()
164 outfile.close()
163 return out
165 return out
164
166
167
165 class Pdb(OldPdb):
168 class Pdb(OldPdb):
166 """Modified Pdb class, does not load readline."""
169 """Modified Pdb class, does not load readline."""
167
170
168 if sys.version[:3] >= '2.5' or has_pydb:
171 def __init__(self,color_scheme='NoColor',completekey=None,
169 def __init__(self,color_scheme='NoColor',completekey=None,
172 stdin=None, stdout=None):
170 stdin=None, stdout=None):
171
173
172 # Parent constructor:
174 # Parent constructor:
173 if has_pydb and completekey is None:
175 if has_pydb and completekey is None:
174 OldPdb.__init__(self,stdin=stdin,stdout=Term.cout)
176 OldPdb.__init__(self,stdin=stdin,stdout=Term.cout)
175 else:
177 else:
176 OldPdb.__init__(self,completekey,stdin,stdout)
178 OldPdb.__init__(self,completekey,stdin,stdout)
177
178 self.prompt = prompt # The default prompt is '(Pdb)'
179
179
180 # IPython changes...
180 self.prompt = prompt # The default prompt is '(Pdb)'
181 self.is_pydb = has_pydb
181
182
182 # IPython changes...
183 if self.is_pydb:
183 self.is_pydb = has_pydb
184
185 # iplib.py's ipalias seems to want pdb's checkline
186 # which located in pydb.fn
187 import pydb.fns
188 self.checkline = lambda filename, lineno: \
189 pydb.fns.checkline(self, filename, lineno)
190
191 self.curframe = None
192 self.do_restart = self.new_do_restart
193
194 self.old_all_completions = __IPYTHON__.Completer.all_completions
195 __IPYTHON__.Completer.all_completions=self.all_completions
196
197 self.do_list = decorate_fn_with_doc(self.list_command_pydb,
198 OldPdb.do_list)
199 self.do_l = self.do_list
200 self.do_frame = decorate_fn_with_doc(self.new_do_frame,
201 OldPdb.do_frame)
202
203 self.aliases = {}
204
205 # Create color table: we copy the default one from the traceback
206 # module and add a few attributes needed for debugging
207 self.color_scheme_table = exception_colors()
208
184
209 # shorthands
185 self.shell = ipapi.get()
210 C = ColorANSI.TermColors
211 cst = self.color_scheme_table
212
186
213 cst['NoColor'].colors.breakpoint_enabled = C.NoColor
187 if self.is_pydb:
214 cst['NoColor'].colors.breakpoint_disabled = C.NoColor
215
188
216 cst['Linux'].colors.breakpoint_enabled = C.LightRed
189 # iplib.py's ipalias seems to want pdb's checkline
217 cst['Linux'].colors.breakpoint_disabled = C.Red
190 # which located in pydb.fn
191 import pydb.fns
192 self.checkline = lambda filename, lineno: \
193 pydb.fns.checkline(self, filename, lineno)
218
194
219 cst['LightBG'].colors.breakpoint_enabled = C.LightRed
195 self.curframe = None
220 cst['LightBG'].colors.breakpoint_disabled = C.Red
196 self.do_restart = self.new_do_restart
221
197
222 self.set_colors(color_scheme)
198 self.old_all_completions = self.shell.Completer.all_completions
199 self.shell.Completer.all_completions=self.all_completions
223
200
224 # Add a python parser so we can syntax highlight source while
201 self.do_list = decorate_fn_with_doc(self.list_command_pydb,
225 # debugging.
202 OldPdb.do_list)
226 self.parser = PyColorize.Parser()
203 self.do_l = self.do_list
204 self.do_frame = decorate_fn_with_doc(self.new_do_frame,
205 OldPdb.do_frame)
227
206
207 self.aliases = {}
228
208
229 else:
209 # Create color table: we copy the default one from the traceback
230 # Ugly hack: for Python 2.3-2.4, we can't call the parent constructor,
210 # module and add a few attributes needed for debugging
231 # because it binds readline and breaks tab-completion. This means we
211 self.color_scheme_table = exception_colors()
232 # have to COPY the constructor here.
233 def __init__(self,color_scheme='NoColor'):
234 bdb.Bdb.__init__(self)
235 cmd.Cmd.__init__(self,completekey=None) # don't load readline
236 self.prompt = 'ipdb> ' # The default prompt is '(Pdb)'
237 self.aliases = {}
238
239 # These two lines are part of the py2.4 constructor, let's put them
240 # unconditionally here as they won't cause any problems in 2.3.
241 self.mainpyfile = ''
242 self._wait_for_mainpyfile = 0
243
244 # Read $HOME/.pdbrc and ./.pdbrc
245 try:
246 self.rcLines = _file_lines(os.path.join(os.environ['HOME'],
247 ".pdbrc"))
248 except KeyError:
249 self.rcLines = []
250 self.rcLines.extend(_file_lines(".pdbrc"))
251
212
252 # Create color table: we copy the default one from the traceback
213 # shorthands
253 # module and add a few attributes needed for debugging
214 C = coloransi.TermColors
254 self.color_scheme_table = exception_colors()
215 cst = self.color_scheme_table
255
216
256 # shorthands
217 cst['NoColor'].colors.breakpoint_enabled = C.NoColor
257 C = ColorANSI.TermColors
218 cst['NoColor'].colors.breakpoint_disabled = C.NoColor
258 cst = self.color_scheme_table
259
219
260 cst['NoColor'].colors.breakpoint_enabled = C.NoColor
220 cst['Linux'].colors.breakpoint_enabled = C.LightRed
261 cst['NoColor'].colors.breakpoint_disabled = C.NoColor
221 cst['Linux'].colors.breakpoint_disabled = C.Red
262
222
263 cst['Linux'].colors.breakpoint_enabled = C.LightRed
223 cst['LightBG'].colors.breakpoint_enabled = C.LightRed
264 cst['Linux'].colors.breakpoint_disabled = C.Red
224 cst['LightBG'].colors.breakpoint_disabled = C.Red
265
225
266 cst['LightBG'].colors.breakpoint_enabled = C.LightRed
226 self.set_colors(color_scheme)
267 cst['LightBG'].colors.breakpoint_disabled = C.Red
268
227
269 self.set_colors(color_scheme)
228 # Add a python parser so we can syntax highlight source while
229 # debugging.
230 self.parser = PyColorize.Parser()
270
231
271 # Add a python parser so we can syntax highlight source while
272 # debugging.
273 self.parser = PyColorize.Parser()
274
275 def set_colors(self, scheme):
232 def set_colors(self, scheme):
276 """Shorthand access to the color table scheme selector method."""
233 """Shorthand access to the color table scheme selector method."""
277 self.color_scheme_table.set_active_scheme(scheme)
234 self.color_scheme_table.set_active_scheme(scheme)
278
235
279 def interaction(self, frame, traceback):
236 def interaction(self, frame, traceback):
280 __IPYTHON__.set_completer_frame(frame)
237 self.shell.set_completer_frame(frame)
281 OldPdb.interaction(self, frame, traceback)
238 OldPdb.interaction(self, frame, traceback)
282
239
283 def new_do_up(self, arg):
240 def new_do_up(self, arg):
284 OldPdb.do_up(self, arg)
241 OldPdb.do_up(self, arg)
285 __IPYTHON__.set_completer_frame(self.curframe)
242 self.shell.set_completer_frame(self.curframe)
286 do_u = do_up = decorate_fn_with_doc(new_do_up, OldPdb.do_up)
243 do_u = do_up = decorate_fn_with_doc(new_do_up, OldPdb.do_up)
287
244
288 def new_do_down(self, arg):
245 def new_do_down(self, arg):
289 OldPdb.do_down(self, arg)
246 OldPdb.do_down(self, arg)
290 __IPYTHON__.set_completer_frame(self.curframe)
247 self.shell.set_completer_frame(self.curframe)
291
248
292 do_d = do_down = decorate_fn_with_doc(new_do_down, OldPdb.do_down)
249 do_d = do_down = decorate_fn_with_doc(new_do_down, OldPdb.do_down)
293
250
294 def new_do_frame(self, arg):
251 def new_do_frame(self, arg):
295 OldPdb.do_frame(self, arg)
252 OldPdb.do_frame(self, arg)
296 __IPYTHON__.set_completer_frame(self.curframe)
253 self.shell.set_completer_frame(self.curframe)
297
254
298 def new_do_quit(self, arg):
255 def new_do_quit(self, arg):
299
256
300 if hasattr(self, 'old_all_completions'):
257 if hasattr(self, 'old_all_completions'):
301 __IPYTHON__.Completer.all_completions=self.old_all_completions
258 self.shell.Completer.all_completions=self.old_all_completions
302
259
303
260
304 return OldPdb.do_quit(self, arg)
261 return OldPdb.do_quit(self, arg)
305
262
306 do_q = do_quit = decorate_fn_with_doc(new_do_quit, OldPdb.do_quit)
263 do_q = do_quit = decorate_fn_with_doc(new_do_quit, OldPdb.do_quit)
307
264
308 def new_do_restart(self, arg):
265 def new_do_restart(self, arg):
309 """Restart command. In the context of ipython this is exactly the same
266 """Restart command. In the context of ipython this is exactly the same
310 thing as 'quit'."""
267 thing as 'quit'."""
311 self.msg("Restart doesn't make sense here. Using 'quit' instead.")
268 self.msg("Restart doesn't make sense here. Using 'quit' instead.")
312 return self.do_quit(arg)
269 return self.do_quit(arg)
313
270
314 def postloop(self):
271 def postloop(self):
315 __IPYTHON__.set_completer_frame(None)
272 self.shell.set_completer_frame(None)
316
273
317 def print_stack_trace(self):
274 def print_stack_trace(self):
318 try:
275 try:
319 for frame_lineno in self.stack:
276 for frame_lineno in self.stack:
320 self.print_stack_entry(frame_lineno, context = 5)
277 self.print_stack_entry(frame_lineno, context = 5)
321 except KeyboardInterrupt:
278 except KeyboardInterrupt:
322 pass
279 pass
323
280
324 def print_stack_entry(self,frame_lineno,prompt_prefix='\n-> ',
281 def print_stack_entry(self,frame_lineno,prompt_prefix='\n-> ',
325 context = 3):
282 context = 3):
326 #frame, lineno = frame_lineno
283 #frame, lineno = frame_lineno
327 print >>Term.cout, self.format_stack_entry(frame_lineno, '', context)
284 print >>Term.cout, self.format_stack_entry(frame_lineno, '', context)
328
285
329 # vds: >>
286 # vds: >>
330 frame, lineno = frame_lineno
287 frame, lineno = frame_lineno
331 filename = frame.f_code.co_filename
288 filename = frame.f_code.co_filename
332 __IPYTHON__.hooks.synchronize_with_editor(filename, lineno, 0)
289 self.shell.hooks.synchronize_with_editor(filename, lineno, 0)
333 # vds: <<
290 # vds: <<
334
291
335 def format_stack_entry(self, frame_lineno, lprefix=': ', context = 3):
292 def format_stack_entry(self, frame_lineno, lprefix=': ', context = 3):
336 import linecache, repr
293 import linecache, repr
337
294
338 ret = []
295 ret = []
339
296
340 Colors = self.color_scheme_table.active_colors
297 Colors = self.color_scheme_table.active_colors
341 ColorsNormal = Colors.Normal
298 ColorsNormal = Colors.Normal
342 tpl_link = '%s%%s%s' % (Colors.filenameEm, ColorsNormal)
299 tpl_link = '%s%%s%s' % (Colors.filenameEm, ColorsNormal)
343 tpl_call = '%s%%s%s%%s%s' % (Colors.vName, Colors.valEm, ColorsNormal)
300 tpl_call = '%s%%s%s%%s%s' % (Colors.vName, Colors.valEm, ColorsNormal)
344 tpl_line = '%%s%s%%s %s%%s' % (Colors.lineno, ColorsNormal)
301 tpl_line = '%%s%s%%s %s%%s' % (Colors.lineno, ColorsNormal)
345 tpl_line_em = '%%s%s%%s %s%%s%s' % (Colors.linenoEm, Colors.line,
302 tpl_line_em = '%%s%s%%s %s%%s%s' % (Colors.linenoEm, Colors.line,
346 ColorsNormal)
303 ColorsNormal)
347
304
348 frame, lineno = frame_lineno
305 frame, lineno = frame_lineno
349
306
350 return_value = ''
307 return_value = ''
351 if '__return__' in frame.f_locals:
308 if '__return__' in frame.f_locals:
352 rv = frame.f_locals['__return__']
309 rv = frame.f_locals['__return__']
353 #return_value += '->'
310 #return_value += '->'
354 return_value += repr.repr(rv) + '\n'
311 return_value += repr.repr(rv) + '\n'
355 ret.append(return_value)
312 ret.append(return_value)
356
313
357 #s = filename + '(' + `lineno` + ')'
314 #s = filename + '(' + `lineno` + ')'
358 filename = self.canonic(frame.f_code.co_filename)
315 filename = self.canonic(frame.f_code.co_filename)
359 link = tpl_link % filename
316 link = tpl_link % filename
360
317
361 if frame.f_code.co_name:
318 if frame.f_code.co_name:
362 func = frame.f_code.co_name
319 func = frame.f_code.co_name
363 else:
320 else:
364 func = "<lambda>"
321 func = "<lambda>"
365
322
366 call = ''
323 call = ''
367 if func != '?':
324 if func != '?':
368 if '__args__' in frame.f_locals:
325 if '__args__' in frame.f_locals:
369 args = repr.repr(frame.f_locals['__args__'])
326 args = repr.repr(frame.f_locals['__args__'])
370 else:
327 else:
371 args = '()'
328 args = '()'
372 call = tpl_call % (func, args)
329 call = tpl_call % (func, args)
373
330
374 # The level info should be generated in the same format pdb uses, to
331 # The level info should be generated in the same format pdb uses, to
375 # avoid breaking the pdbtrack functionality of python-mode in *emacs.
332 # avoid breaking the pdbtrack functionality of python-mode in *emacs.
376 if frame is self.curframe:
333 if frame is self.curframe:
377 ret.append('> ')
334 ret.append('> ')
378 else:
335 else:
379 ret.append(' ')
336 ret.append(' ')
380 ret.append('%s(%s)%s\n' % (link,lineno,call))
337 ret.append('%s(%s)%s\n' % (link,lineno,call))
381
338
382 start = lineno - 1 - context//2
339 start = lineno - 1 - context//2
383 lines = linecache.getlines(filename)
340 lines = linecache.getlines(filename)
384 start = max(start, 0)
341 start = max(start, 0)
385 start = min(start, len(lines) - context)
342 start = min(start, len(lines) - context)
386 lines = lines[start : start + context]
343 lines = lines[start : start + context]
387
344
388 for i,line in enumerate(lines):
345 for i,line in enumerate(lines):
389 show_arrow = (start + 1 + i == lineno)
346 show_arrow = (start + 1 + i == lineno)
390 linetpl = (frame is self.curframe or show_arrow) \
347 linetpl = (frame is self.curframe or show_arrow) \
391 and tpl_line_em \
348 and tpl_line_em \
392 or tpl_line
349 or tpl_line
393 ret.append(self.__format_line(linetpl, filename,
350 ret.append(self.__format_line(linetpl, filename,
394 start + 1 + i, line,
351 start + 1 + i, line,
395 arrow = show_arrow) )
352 arrow = show_arrow) )
396
353
397 return ''.join(ret)
354 return ''.join(ret)
398
355
399 def __format_line(self, tpl_line, filename, lineno, line, arrow = False):
356 def __format_line(self, tpl_line, filename, lineno, line, arrow = False):
400 bp_mark = ""
357 bp_mark = ""
401 bp_mark_color = ""
358 bp_mark_color = ""
402
359
403 scheme = self.color_scheme_table.active_scheme_name
360 scheme = self.color_scheme_table.active_scheme_name
404 new_line, err = self.parser.format2(line, 'str', scheme)
361 new_line, err = self.parser.format2(line, 'str', scheme)
405 if not err: line = new_line
362 if not err: line = new_line
406
363
407 bp = None
364 bp = None
408 if lineno in self.get_file_breaks(filename):
365 if lineno in self.get_file_breaks(filename):
409 bps = self.get_breaks(filename, lineno)
366 bps = self.get_breaks(filename, lineno)
410 bp = bps[-1]
367 bp = bps[-1]
411
368
412 if bp:
369 if bp:
413 Colors = self.color_scheme_table.active_colors
370 Colors = self.color_scheme_table.active_colors
414 bp_mark = str(bp.number)
371 bp_mark = str(bp.number)
415 bp_mark_color = Colors.breakpoint_enabled
372 bp_mark_color = Colors.breakpoint_enabled
416 if not bp.enabled:
373 if not bp.enabled:
417 bp_mark_color = Colors.breakpoint_disabled
374 bp_mark_color = Colors.breakpoint_disabled
418
375
419 numbers_width = 7
376 numbers_width = 7
420 if arrow:
377 if arrow:
421 # This is the line with the error
378 # This is the line with the error
422 pad = numbers_width - len(str(lineno)) - len(bp_mark)
379 pad = numbers_width - len(str(lineno)) - len(bp_mark)
423 if pad >= 3:
380 if pad >= 3:
424 marker = '-'*(pad-3) + '-> '
381 marker = '-'*(pad-3) + '-> '
425 elif pad == 2:
382 elif pad == 2:
426 marker = '> '
383 marker = '> '
427 elif pad == 1:
384 elif pad == 1:
428 marker = '>'
385 marker = '>'
429 else:
386 else:
430 marker = ''
387 marker = ''
431 num = '%s%s' % (marker, str(lineno))
388 num = '%s%s' % (marker, str(lineno))
432 line = tpl_line % (bp_mark_color + bp_mark, num, line)
389 line = tpl_line % (bp_mark_color + bp_mark, num, line)
433 else:
390 else:
434 num = '%*s' % (numbers_width - len(bp_mark), str(lineno))
391 num = '%*s' % (numbers_width - len(bp_mark), str(lineno))
435 line = tpl_line % (bp_mark_color + bp_mark, num, line)
392 line = tpl_line % (bp_mark_color + bp_mark, num, line)
436
393
437 return line
394 return line
438
395
439 def list_command_pydb(self, arg):
396 def list_command_pydb(self, arg):
440 """List command to use if we have a newer pydb installed"""
397 """List command to use if we have a newer pydb installed"""
441 filename, first, last = OldPdb.parse_list_cmd(self, arg)
398 filename, first, last = OldPdb.parse_list_cmd(self, arg)
442 if filename is not None:
399 if filename is not None:
443 self.print_list_lines(filename, first, last)
400 self.print_list_lines(filename, first, last)
444
401
445 def print_list_lines(self, filename, first, last):
402 def print_list_lines(self, filename, first, last):
446 """The printing (as opposed to the parsing part of a 'list'
403 """The printing (as opposed to the parsing part of a 'list'
447 command."""
404 command."""
448 try:
405 try:
449 Colors = self.color_scheme_table.active_colors
406 Colors = self.color_scheme_table.active_colors
450 ColorsNormal = Colors.Normal
407 ColorsNormal = Colors.Normal
451 tpl_line = '%%s%s%%s %s%%s' % (Colors.lineno, ColorsNormal)
408 tpl_line = '%%s%s%%s %s%%s' % (Colors.lineno, ColorsNormal)
452 tpl_line_em = '%%s%s%%s %s%%s%s' % (Colors.linenoEm, Colors.line, ColorsNormal)
409 tpl_line_em = '%%s%s%%s %s%%s%s' % (Colors.linenoEm, Colors.line, ColorsNormal)
453 src = []
410 src = []
454 for lineno in range(first, last+1):
411 for lineno in range(first, last+1):
455 line = linecache.getline(filename, lineno)
412 line = linecache.getline(filename, lineno)
456 if not line:
413 if not line:
457 break
414 break
458
415
459 if lineno == self.curframe.f_lineno:
416 if lineno == self.curframe.f_lineno:
460 line = self.__format_line(tpl_line_em, filename, lineno, line, arrow = True)
417 line = self.__format_line(tpl_line_em, filename, lineno, line, arrow = True)
461 else:
418 else:
462 line = self.__format_line(tpl_line, filename, lineno, line, arrow = False)
419 line = self.__format_line(tpl_line, filename, lineno, line, arrow = False)
463
420
464 src.append(line)
421 src.append(line)
465 self.lineno = lineno
422 self.lineno = lineno
466
423
467 print >>Term.cout, ''.join(src)
424 print >>Term.cout, ''.join(src)
468
425
469 except KeyboardInterrupt:
426 except KeyboardInterrupt:
470 pass
427 pass
471
428
472 def do_list(self, arg):
429 def do_list(self, arg):
473 self.lastcmd = 'list'
430 self.lastcmd = 'list'
474 last = None
431 last = None
475 if arg:
432 if arg:
476 try:
433 try:
477 x = eval(arg, {}, {})
434 x = eval(arg, {}, {})
478 if type(x) == type(()):
435 if type(x) == type(()):
479 first, last = x
436 first, last = x
480 first = int(first)
437 first = int(first)
481 last = int(last)
438 last = int(last)
482 if last < first:
439 if last < first:
483 # Assume it's a count
440 # Assume it's a count
484 last = first + last
441 last = first + last
485 else:
442 else:
486 first = max(1, int(x) - 5)
443 first = max(1, int(x) - 5)
487 except:
444 except:
488 print '*** Error in argument:', `arg`
445 print '*** Error in argument:', `arg`
489 return
446 return
490 elif self.lineno is None:
447 elif self.lineno is None:
491 first = max(1, self.curframe.f_lineno - 5)
448 first = max(1, self.curframe.f_lineno - 5)
492 else:
449 else:
493 first = self.lineno + 1
450 first = self.lineno + 1
494 if last is None:
451 if last is None:
495 last = first + 10
452 last = first + 10
496 self.print_list_lines(self.curframe.f_code.co_filename, first, last)
453 self.print_list_lines(self.curframe.f_code.co_filename, first, last)
497
454
498 # vds: >>
455 # vds: >>
499 lineno = first
456 lineno = first
500 filename = self.curframe.f_code.co_filename
457 filename = self.curframe.f_code.co_filename
501 __IPYTHON__.hooks.synchronize_with_editor(filename, lineno, 0)
458 self.shell.hooks.synchronize_with_editor(filename, lineno, 0)
502 # vds: <<
459 # vds: <<
503
460
504 do_l = do_list
461 do_l = do_list
505
462
506 def do_pdef(self, arg):
463 def do_pdef(self, arg):
507 """The debugger interface to magic_pdef"""
464 """The debugger interface to magic_pdef"""
508 namespaces = [('Locals', self.curframe.f_locals),
465 namespaces = [('Locals', self.curframe.f_locals),
509 ('Globals', self.curframe.f_globals)]
466 ('Globals', self.curframe.f_globals)]
510 __IPYTHON__.magic_pdef(arg, namespaces=namespaces)
467 self.shell.magic_pdef(arg, namespaces=namespaces)
511
468
512 def do_pdoc(self, arg):
469 def do_pdoc(self, arg):
513 """The debugger interface to magic_pdoc"""
470 """The debugger interface to magic_pdoc"""
514 namespaces = [('Locals', self.curframe.f_locals),
471 namespaces = [('Locals', self.curframe.f_locals),
515 ('Globals', self.curframe.f_globals)]
472 ('Globals', self.curframe.f_globals)]
516 __IPYTHON__.magic_pdoc(arg, namespaces=namespaces)
473 self.shell.magic_pdoc(arg, namespaces=namespaces)
517
474
518 def do_pinfo(self, arg):
475 def do_pinfo(self, arg):
519 """The debugger equivalant of ?obj"""
476 """The debugger equivalant of ?obj"""
520 namespaces = [('Locals', self.curframe.f_locals),
477 namespaces = [('Locals', self.curframe.f_locals),
521 ('Globals', self.curframe.f_globals)]
478 ('Globals', self.curframe.f_globals)]
522 __IPYTHON__.magic_pinfo("pinfo %s" % arg, namespaces=namespaces)
479 self.shell.magic_pinfo("pinfo %s" % arg, namespaces=namespaces)
@@ -1,137 +1,137 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 Color schemes for exception handling code in IPython.
3 Color schemes for exception handling code in IPython.
4 """
4 """
5
5
6 #*****************************************************************************
6 #*****************************************************************************
7 # Copyright (C) 2005-2006 Fernando Perez <fperez@colorado.edu>
7 # Copyright (C) 2005-2006 Fernando Perez <fperez@colorado.edu>
8 #
8 #
9 # Distributed under the terms of the BSD License. The full license is in
9 # Distributed under the terms of the BSD License. The full license is in
10 # the file COPYING, distributed as part of this software.
10 # the file COPYING, distributed as part of this software.
11 #*****************************************************************************
11 #*****************************************************************************
12
12
13 #****************************************************************************
13 #****************************************************************************
14 # Required modules
14 # Required modules
15 from IPython.ColorANSI import ColorSchemeTable, TermColors, ColorScheme
15 from IPython.utils.coloransi import ColorSchemeTable, TermColors, ColorScheme
16
16
17 def exception_colors():
17 def exception_colors():
18 """Return a color table with fields for exception reporting.
18 """Return a color table with fields for exception reporting.
19
19
20 The table is an instance of ColorSchemeTable with schemes added for
20 The table is an instance of ColorSchemeTable with schemes added for
21 'Linux', 'LightBG' and 'NoColor' and fields for exception handling filled
21 'Linux', 'LightBG' and 'NoColor' and fields for exception handling filled
22 in.
22 in.
23
23
24 Examples:
24 Examples:
25
25
26 >>> ec = exception_colors()
26 >>> ec = exception_colors()
27 >>> ec.active_scheme_name
27 >>> ec.active_scheme_name
28 ''
28 ''
29 >>> print ec.active_colors
29 >>> print ec.active_colors
30 None
30 None
31
31
32 Now we activate a color scheme:
32 Now we activate a color scheme:
33 >>> ec.set_active_scheme('NoColor')
33 >>> ec.set_active_scheme('NoColor')
34 >>> ec.active_scheme_name
34 >>> ec.active_scheme_name
35 'NoColor'
35 'NoColor'
36 >>> ec.active_colors.keys()
36 >>> ec.active_colors.keys()
37 ['em', 'caret', '__allownew', 'name', 'val', 'vName', 'Normal', 'normalEm',
37 ['em', 'filenameEm', 'excName', 'valEm', 'nameEm', 'line', 'topline',
38 'filename', 'linenoEm', 'excName', 'lineno', 'valEm', 'filenameEm',
38 'name', 'caret', 'val', 'vName', 'Normal', 'filename', 'linenoEm',
39 'nameEm', 'line', 'topline']
39 'lineno', 'normalEm']
40 """
40 """
41
41
42 ex_colors = ColorSchemeTable()
42 ex_colors = ColorSchemeTable()
43
43
44 # Populate it with color schemes
44 # Populate it with color schemes
45 C = TermColors # shorthand and local lookup
45 C = TermColors # shorthand and local lookup
46 ex_colors.add_scheme(ColorScheme(
46 ex_colors.add_scheme(ColorScheme(
47 'NoColor',
47 'NoColor',
48 # The color to be used for the top line
48 # The color to be used for the top line
49 topline = C.NoColor,
49 topline = C.NoColor,
50
50
51 # The colors to be used in the traceback
51 # The colors to be used in the traceback
52 filename = C.NoColor,
52 filename = C.NoColor,
53 lineno = C.NoColor,
53 lineno = C.NoColor,
54 name = C.NoColor,
54 name = C.NoColor,
55 vName = C.NoColor,
55 vName = C.NoColor,
56 val = C.NoColor,
56 val = C.NoColor,
57 em = C.NoColor,
57 em = C.NoColor,
58
58
59 # Emphasized colors for the last frame of the traceback
59 # Emphasized colors for the last frame of the traceback
60 normalEm = C.NoColor,
60 normalEm = C.NoColor,
61 filenameEm = C.NoColor,
61 filenameEm = C.NoColor,
62 linenoEm = C.NoColor,
62 linenoEm = C.NoColor,
63 nameEm = C.NoColor,
63 nameEm = C.NoColor,
64 valEm = C.NoColor,
64 valEm = C.NoColor,
65
65
66 # Colors for printing the exception
66 # Colors for printing the exception
67 excName = C.NoColor,
67 excName = C.NoColor,
68 line = C.NoColor,
68 line = C.NoColor,
69 caret = C.NoColor,
69 caret = C.NoColor,
70 Normal = C.NoColor
70 Normal = C.NoColor
71 ))
71 ))
72
72
73 # make some schemes as instances so we can copy them for modification easily
73 # make some schemes as instances so we can copy them for modification easily
74 ex_colors.add_scheme(ColorScheme(
74 ex_colors.add_scheme(ColorScheme(
75 'Linux',
75 'Linux',
76 # The color to be used for the top line
76 # The color to be used for the top line
77 topline = C.LightRed,
77 topline = C.LightRed,
78
78
79 # The colors to be used in the traceback
79 # The colors to be used in the traceback
80 filename = C.Green,
80 filename = C.Green,
81 lineno = C.Green,
81 lineno = C.Green,
82 name = C.Purple,
82 name = C.Purple,
83 vName = C.Cyan,
83 vName = C.Cyan,
84 val = C.Green,
84 val = C.Green,
85 em = C.LightCyan,
85 em = C.LightCyan,
86
86
87 # Emphasized colors for the last frame of the traceback
87 # Emphasized colors for the last frame of the traceback
88 normalEm = C.LightCyan,
88 normalEm = C.LightCyan,
89 filenameEm = C.LightGreen,
89 filenameEm = C.LightGreen,
90 linenoEm = C.LightGreen,
90 linenoEm = C.LightGreen,
91 nameEm = C.LightPurple,
91 nameEm = C.LightPurple,
92 valEm = C.LightBlue,
92 valEm = C.LightBlue,
93
93
94 # Colors for printing the exception
94 # Colors for printing the exception
95 excName = C.LightRed,
95 excName = C.LightRed,
96 line = C.Yellow,
96 line = C.Yellow,
97 caret = C.White,
97 caret = C.White,
98 Normal = C.Normal
98 Normal = C.Normal
99 ))
99 ))
100
100
101 # For light backgrounds, swap dark/light colors
101 # For light backgrounds, swap dark/light colors
102 ex_colors.add_scheme(ColorScheme(
102 ex_colors.add_scheme(ColorScheme(
103 'LightBG',
103 'LightBG',
104 # The color to be used for the top line
104 # The color to be used for the top line
105 topline = C.Red,
105 topline = C.Red,
106
106
107 # The colors to be used in the traceback
107 # The colors to be used in the traceback
108 filename = C.LightGreen,
108 filename = C.LightGreen,
109 lineno = C.LightGreen,
109 lineno = C.LightGreen,
110 name = C.LightPurple,
110 name = C.LightPurple,
111 vName = C.Cyan,
111 vName = C.Cyan,
112 val = C.LightGreen,
112 val = C.LightGreen,
113 em = C.Cyan,
113 em = C.Cyan,
114
114
115 # Emphasized colors for the last frame of the traceback
115 # Emphasized colors for the last frame of the traceback
116 normalEm = C.Cyan,
116 normalEm = C.Cyan,
117 filenameEm = C.Green,
117 filenameEm = C.Green,
118 linenoEm = C.Green,
118 linenoEm = C.Green,
119 nameEm = C.Purple,
119 nameEm = C.Purple,
120 valEm = C.Blue,
120 valEm = C.Blue,
121
121
122 # Colors for printing the exception
122 # Colors for printing the exception
123 excName = C.Red,
123 excName = C.Red,
124 #line = C.Brown, # brown often is displayed as yellow
124 #line = C.Brown, # brown often is displayed as yellow
125 line = C.Red,
125 line = C.Red,
126 caret = C.Normal,
126 caret = C.Normal,
127 Normal = C.Normal,
127 Normal = C.Normal,
128 ))
128 ))
129
129
130 return ex_colors
130 return ex_colors
131
131
132
132
133 # For backwards compatibility, keep around a single global object. Note that
133 # For backwards compatibility, keep around a single global object. Note that
134 # this should NOT be used, the factory function should be used instead, since
134 # this should NOT be used, the factory function should be used instead, since
135 # these objects are stateful and it's very easy to get strange bugs if any code
135 # these objects are stateful and it's very easy to get strange bugs if any code
136 # modifies the module-level object's state.
136 # modifies the module-level object's state.
137 ExceptionColors = exception_colors()
137 ExceptionColors = exception_colors()
1 NO CONTENT: file renamed from IPython/FakeModule.py to IPython/core/fakemodule.py
NO CONTENT: file renamed from IPython/FakeModule.py to IPython/core/fakemodule.py
@@ -1,258 +1,254 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """ History related magics and functionality """
2 """ History related magics and functionality """
3
3
4 # Stdlib imports
4 # Stdlib imports
5 import fnmatch
5 import fnmatch
6 import os
6 import os
7
7
8 # IPython imports
8 from IPython.utils.genutils import Term, ask_yes_no, warn
9 from IPython.genutils import Term, ask_yes_no, warn
9 from IPython.core import ipapi
10 import IPython.ipapi
11
10
12 def magic_history(self, parameter_s = ''):
11 def magic_history(self, parameter_s = ''):
13 """Print input history (_i<n> variables), with most recent last.
12 """Print input history (_i<n> variables), with most recent last.
14
13
15 %history -> print at most 40 inputs (some may be multi-line)\\
14 %history -> print at most 40 inputs (some may be multi-line)\\
16 %history n -> print at most n inputs\\
15 %history n -> print at most n inputs\\
17 %history n1 n2 -> print inputs between n1 and n2 (n2 not included)\\
16 %history n1 n2 -> print inputs between n1 and n2 (n2 not included)\\
18
17
19 Each input's number <n> is shown, and is accessible as the
18 Each input's number <n> is shown, and is accessible as the
20 automatically generated variable _i<n>. Multi-line statements are
19 automatically generated variable _i<n>. Multi-line statements are
21 printed starting at a new line for easy copy/paste.
20 printed starting at a new line for easy copy/paste.
22
21
23
22
24 Options:
23 Options:
25
24
26 -n: do NOT print line numbers. This is useful if you want to get a
25 -n: do NOT print line numbers. This is useful if you want to get a
27 printout of many lines which can be directly pasted into a text
26 printout of many lines which can be directly pasted into a text
28 editor.
27 editor.
29
28
30 This feature is only available if numbered prompts are in use.
29 This feature is only available if numbered prompts are in use.
31
30
32 -t: (default) print the 'translated' history, as IPython understands it.
31 -t: (default) print the 'translated' history, as IPython understands it.
33 IPython filters your input and converts it all into valid Python source
32 IPython filters your input and converts it all into valid Python source
34 before executing it (things like magics or aliases are turned into
33 before executing it (things like magics or aliases are turned into
35 function calls, for example). With this option, you'll see the native
34 function calls, for example). With this option, you'll see the native
36 history instead of the user-entered version: '%cd /' will be seen as
35 history instead of the user-entered version: '%cd /' will be seen as
37 '_ip.magic("%cd /")' instead of '%cd /'.
36 '_ip.magic("%cd /")' instead of '%cd /'.
38
37
39 -r: print the 'raw' history, i.e. the actual commands you typed.
38 -r: print the 'raw' history, i.e. the actual commands you typed.
40
39
41 -g: treat the arg as a pattern to grep for in (full) history.
40 -g: treat the arg as a pattern to grep for in (full) history.
42 This includes the "shadow history" (almost all commands ever written).
41 This includes the "shadow history" (almost all commands ever written).
43 Use '%hist -g' to show full shadow history (may be very long).
42 Use '%hist -g' to show full shadow history (may be very long).
44 In shadow history, every index nuwber starts with 0.
43 In shadow history, every index nuwber starts with 0.
45
44
46 -f FILENAME: instead of printing the output to the screen, redirect it to
45 -f FILENAME: instead of printing the output to the screen, redirect it to
47 the given file. The file is always overwritten, though IPython asks for
46 the given file. The file is always overwritten, though IPython asks for
48 confirmation first if it already exists.
47 confirmation first if it already exists.
49 """
48 """
50
49
51 ip = self.api
50 if not self.outputcache.do_full_cache:
52 shell = self.shell
53 if not shell.outputcache.do_full_cache:
54 print 'This feature is only available if numbered prompts are in use.'
51 print 'This feature is only available if numbered prompts are in use.'
55 return
52 return
56 opts,args = self.parse_options(parameter_s,'gntsrf:',mode='list')
53 opts,args = self.parse_options(parameter_s,'gntsrf:',mode='list')
57
54
58 # Check if output to specific file was requested.
55 # Check if output to specific file was requested.
59 try:
56 try:
60 outfname = opts['f']
57 outfname = opts['f']
61 except KeyError:
58 except KeyError:
62 outfile = Term.cout # default
59 outfile = Term.cout # default
63 # We don't want to close stdout at the end!
60 # We don't want to close stdout at the end!
64 close_at_end = False
61 close_at_end = False
65 else:
62 else:
66 if os.path.exists(outfname):
63 if os.path.exists(outfname):
67 if not ask_yes_no("File %r exists. Overwrite?" % outfname):
64 if not ask_yes_no("File %r exists. Overwrite?" % outfname):
68 print 'Aborting.'
65 print 'Aborting.'
69 return
66 return
70
67
71 outfile = open(outfname,'w')
68 outfile = open(outfname,'w')
72 close_at_end = True
69 close_at_end = True
73
70
74 if 't' in opts:
71 if 't' in opts:
75 input_hist = shell.input_hist
72 input_hist = self.input_hist
76 elif 'r' in opts:
73 elif 'r' in opts:
77 input_hist = shell.input_hist_raw
74 input_hist = self.input_hist_raw
78 else:
75 else:
79 input_hist = shell.input_hist
76 input_hist = self.input_hist
80
77
81 default_length = 40
78 default_length = 40
82 pattern = None
79 pattern = None
83 if 'g' in opts:
80 if 'g' in opts:
84 init = 1
81 init = 1
85 final = len(input_hist)
82 final = len(input_hist)
86 parts = parameter_s.split(None,1)
83 parts = parameter_s.split(None,1)
87 if len(parts) == 1:
84 if len(parts) == 1:
88 parts += '*'
85 parts += '*'
89 head, pattern = parts
86 head, pattern = parts
90 pattern = "*" + pattern + "*"
87 pattern = "*" + pattern + "*"
91 elif len(args) == 0:
88 elif len(args) == 0:
92 final = len(input_hist)
89 final = len(input_hist)
93 init = max(1,final-default_length)
90 init = max(1,final-default_length)
94 elif len(args) == 1:
91 elif len(args) == 1:
95 final = len(input_hist)
92 final = len(input_hist)
96 init = max(1,final-int(args[0]))
93 init = max(1,final-int(args[0]))
97 elif len(args) == 2:
94 elif len(args) == 2:
98 init,final = map(int,args)
95 init,final = map(int,args)
99 else:
96 else:
100 warn('%hist takes 0, 1 or 2 arguments separated by spaces.')
97 warn('%hist takes 0, 1 or 2 arguments separated by spaces.')
101 print self.magic_hist.__doc__
98 print self.magic_hist.__doc__
102 return
99 return
103 width = len(str(final))
100 width = len(str(final))
104 line_sep = ['','\n']
101 line_sep = ['','\n']
105 print_nums = not opts.has_key('n')
102 print_nums = not opts.has_key('n')
106
103
107 found = False
104 found = False
108 if pattern is not None:
105 if pattern is not None:
109 sh = ip.IP.shadowhist.all()
106 sh = self.shadowhist.all()
110 for idx, s in sh:
107 for idx, s in sh:
111 if fnmatch.fnmatch(s, pattern):
108 if fnmatch.fnmatch(s, pattern):
112 print "0%d: %s" %(idx, s)
109 print "0%d: %s" %(idx, s)
113 found = True
110 found = True
114
111
115 if found:
112 if found:
116 print "==="
113 print "==="
117 print "shadow history ends, fetch by %rep <number> (must start with 0)"
114 print "shadow history ends, fetch by %rep <number> (must start with 0)"
118 print "=== start of normal history ==="
115 print "=== start of normal history ==="
119
116
120 for in_num in range(init,final):
117 for in_num in range(init,final):
121 inline = input_hist[in_num]
118 inline = input_hist[in_num]
122 if pattern is not None and not fnmatch.fnmatch(inline, pattern):
119 if pattern is not None and not fnmatch.fnmatch(inline, pattern):
123 continue
120 continue
124
121
125 multiline = int(inline.count('\n') > 1)
122 multiline = int(inline.count('\n') > 1)
126 if print_nums:
123 if print_nums:
127 print >> outfile, \
124 print >> outfile, \
128 '%s:%s' % (str(in_num).ljust(width),line_sep[multiline]),
125 '%s:%s' % (str(in_num).ljust(width),line_sep[multiline]),
129 print >> outfile, inline,
126 print >> outfile, inline,
130
127
131 if close_at_end:
128 if close_at_end:
132 outfile.close()
129 outfile.close()
133
130
134
131
135 def magic_hist(self, parameter_s=''):
132 def magic_hist(self, parameter_s=''):
136 """Alternate name for %history."""
133 """Alternate name for %history."""
137 return self.magic_history(parameter_s)
134 return self.magic_history(parameter_s)
138
135
139
136
140 def rep_f(self, arg):
137 def rep_f(self, arg):
141 r""" Repeat a command, or get command to input line for editing
138 r""" Repeat a command, or get command to input line for editing
142
139
143 - %rep (no arguments):
140 - %rep (no arguments):
144
141
145 Place a string version of last computation result (stored in the special '_'
142 Place a string version of last computation result (stored in the special '_'
146 variable) to the next input prompt. Allows you to create elaborate command
143 variable) to the next input prompt. Allows you to create elaborate command
147 lines without using copy-paste::
144 lines without using copy-paste::
148
145
149 $ l = ["hei", "vaan"]
146 $ l = ["hei", "vaan"]
150 $ "".join(l)
147 $ "".join(l)
151 ==> heivaan
148 ==> heivaan
152 $ %rep
149 $ %rep
153 $ heivaan_ <== cursor blinking
150 $ heivaan_ <== cursor blinking
154
151
155 %rep 45
152 %rep 45
156
153
157 Place history line 45 to next input prompt. Use %hist to find out the
154 Place history line 45 to next input prompt. Use %hist to find out the
158 number.
155 number.
159
156
160 %rep 1-4 6-7 3
157 %rep 1-4 6-7 3
161
158
162 Repeat the specified lines immediately. Input slice syntax is the same as
159 Repeat the specified lines immediately. Input slice syntax is the same as
163 in %macro and %save.
160 in %macro and %save.
164
161
165 %rep foo
162 %rep foo
166
163
167 Place the most recent line that has the substring "foo" to next input.
164 Place the most recent line that has the substring "foo" to next input.
168 (e.g. 'svn ci -m foobar').
165 (e.g. 'svn ci -m foobar').
169 """
166 """
170
167
171 opts,args = self.parse_options(arg,'',mode='list')
168 opts,args = self.parse_options(arg,'',mode='list')
172 ip = self.api
173 if not args:
169 if not args:
174 ip.set_next_input(str(ip.user_ns["_"]))
170 self.set_next_input(str(self.user_ns["_"]))
175 return
171 return
176
172
177 if len(args) == 1 and not '-' in args[0]:
173 if len(args) == 1 and not '-' in args[0]:
178 arg = args[0]
174 arg = args[0]
179 if len(arg) > 1 and arg.startswith('0'):
175 if len(arg) > 1 and arg.startswith('0'):
180 # get from shadow hist
176 # get from shadow hist
181 num = int(arg[1:])
177 num = int(arg[1:])
182 line = self.shadowhist.get(num)
178 line = self.shadowhist.get(num)
183 ip.set_next_input(str(line))
179 self.set_next_input(str(line))
184 return
180 return
185 try:
181 try:
186 num = int(args[0])
182 num = int(args[0])
187 ip.set_next_input(str(ip.IP.input_hist_raw[num]).rstrip())
183 self.set_next_input(str(self.input_hist_raw[num]).rstrip())
188 return
184 return
189 except ValueError:
185 except ValueError:
190 pass
186 pass
191
187
192 for h in reversed(self.shell.input_hist_raw):
188 for h in reversed(self.input_hist_raw):
193 if 'rep' in h:
189 if 'rep' in h:
194 continue
190 continue
195 if fnmatch.fnmatch(h,'*' + arg + '*'):
191 if fnmatch.fnmatch(h,'*' + arg + '*'):
196 ip.set_next_input(str(h).rstrip())
192 self.set_next_input(str(h).rstrip())
197 return
193 return
198
194
199 try:
195 try:
200 lines = self.extract_input_slices(args, True)
196 lines = self.extract_input_slices(args, True)
201 print "lines",lines
197 print "lines",lines
202 ip.runlines(lines)
198 self.runlines(lines)
203 except ValueError:
199 except ValueError:
204 print "Not found in recent history:", args
200 print "Not found in recent history:", args
205
201
206
202
207 _sentinel = object()
203 _sentinel = object()
208
204
209 class ShadowHist:
205 class ShadowHist(object):
210 def __init__(self,db):
206 def __init__(self,db):
211 # cmd => idx mapping
207 # cmd => idx mapping
212 self.curidx = 0
208 self.curidx = 0
213 self.db = db
209 self.db = db
214 self.disabled = False
210 self.disabled = False
215
211
216 def inc_idx(self):
212 def inc_idx(self):
217 idx = self.db.get('shadowhist_idx', 1)
213 idx = self.db.get('shadowhist_idx', 1)
218 self.db['shadowhist_idx'] = idx + 1
214 self.db['shadowhist_idx'] = idx + 1
219 return idx
215 return idx
220
216
221 def add(self, ent):
217 def add(self, ent):
222 if self.disabled:
218 if self.disabled:
223 return
219 return
224 try:
220 try:
225 old = self.db.hget('shadowhist', ent, _sentinel)
221 old = self.db.hget('shadowhist', ent, _sentinel)
226 if old is not _sentinel:
222 if old is not _sentinel:
227 return
223 return
228 newidx = self.inc_idx()
224 newidx = self.inc_idx()
229 #print "new",newidx # dbg
225 #print "new",newidx # dbg
230 self.db.hset('shadowhist',ent, newidx)
226 self.db.hset('shadowhist',ent, newidx)
231 except:
227 except:
232 IPython.ipapi.get().IP.showtraceback()
228 ipapi.get().showtraceback()
233 print "WARNING: disabling shadow history"
229 print "WARNING: disabling shadow history"
234 self.disabled = True
230 self.disabled = True
235
231
236 def all(self):
232 def all(self):
237 d = self.db.hdict('shadowhist')
233 d = self.db.hdict('shadowhist')
238 items = [(i,s) for (s,i) in d.items()]
234 items = [(i,s) for (s,i) in d.items()]
239 items.sort()
235 items.sort()
240 return items
236 return items
241
237
242 def get(self, idx):
238 def get(self, idx):
243 all = self.all()
239 all = self.all()
244
240
245 for k, v in all:
241 for k, v in all:
246 #print k,v
242 #print k,v
247 if k == idx:
243 if k == idx:
248 return v
244 return v
249
245
250
246
251 def init_ipython(ip):
247 def init_ipython(ip):
252 import ipy_completers
248 import ipy_completers
253
249
254 ip.expose_magic("rep",rep_f)
250 ip.define_magic("rep",rep_f)
255 ip.expose_magic("hist",magic_hist)
251 ip.define_magic("hist",magic_hist)
256 ip.expose_magic("history",magic_history)
252 ip.define_magic("history",magic_history)
257
253
258 ipy_completers.quick_completer('%hist' ,'-g -t -r -n')
254 ipy_completers.quick_completer('%hist' ,'-g -t -r -n')
@@ -1,264 +1,274 b''
1 """hooks for IPython.
1 """hooks for IPython.
2
2
3 In Python, it is possible to overwrite any method of any object if you really
3 In Python, it is possible to overwrite any method of any object if you really
4 want to. But IPython exposes a few 'hooks', methods which are _designed_ to
4 want to. But IPython exposes a few 'hooks', methods which are _designed_ to
5 be overwritten by users for customization purposes. This module defines the
5 be overwritten by users for customization purposes. This module defines the
6 default versions of all such hooks, which get used by IPython if not
6 default versions of all such hooks, which get used by IPython if not
7 overridden by the user.
7 overridden by the user.
8
8
9 hooks are simple functions, but they should be declared with 'self' as their
9 hooks are simple functions, but they should be declared with 'self' as their
10 first argument, because when activated they are registered into IPython as
10 first argument, because when activated they are registered into IPython as
11 instance methods. The self argument will be the IPython running instance
11 instance methods. The self argument will be the IPython running instance
12 itself, so hooks have full access to the entire IPython object.
12 itself, so hooks have full access to the entire IPython object.
13
13
14 If you wish to define a new hook and activate it, you need to put the
14 If you wish to define a new hook and activate it, you need to put the
15 necessary code into a python file which can be either imported or execfile()'d
15 necessary code into a python file which can be either imported or execfile()'d
16 from within your ipythonrc configuration.
16 from within your ipythonrc configuration.
17
17
18 For example, suppose that you have a module called 'myiphooks' in your
18 For example, suppose that you have a module called 'myiphooks' in your
19 PYTHONPATH, which contains the following definition:
19 PYTHONPATH, which contains the following definition:
20
20
21 import os
21 import os
22 import IPython.ipapi
22 from IPython.core import ipapi
23 ip = IPython.ipapi.get()
23 ip = ipapi.get()
24
24
25 def calljed(self,filename, linenum):
25 def calljed(self,filename, linenum):
26 "My editor hook calls the jed editor directly."
26 "My editor hook calls the jed editor directly."
27 print "Calling my own editor, jed ..."
27 print "Calling my own editor, jed ..."
28 if os.system('jed +%d %s' % (linenum,filename)) != 0:
28 if os.system('jed +%d %s' % (linenum,filename)) != 0:
29 raise ipapi.TryNext()
29 raise TryNext()
30
30
31 ip.set_hook('editor', calljed)
31 ip.set_hook('editor', calljed)
32
32
33 You can then enable the functionality by doing 'import myiphooks'
33 You can then enable the functionality by doing 'import myiphooks'
34 somewhere in your configuration files or ipython command line.
34 somewhere in your configuration files or ipython command line.
35 """
35 """
36
36
37 #*****************************************************************************
37 #*****************************************************************************
38 # Copyright (C) 2005 Fernando Perez. <fperez@colorado.edu>
38 # Copyright (C) 2005 Fernando Perez. <fperez@colorado.edu>
39 #
39 #
40 # Distributed under the terms of the BSD License. The full license is in
40 # Distributed under the terms of the BSD License. The full license is in
41 # the file COPYING, distributed as part of this software.
41 # the file COPYING, distributed as part of this software.
42 #*****************************************************************************
42 #*****************************************************************************
43
43
44 from IPython import ipapi
44 import os, bisect
45
46 import os,bisect
47 import sys
45 import sys
48 from genutils import Term,shell
46 from IPython.utils.genutils import Term, shell
49 from pprint import PrettyPrinter
47 from pprint import PrettyPrinter
50
48
49 from IPython.core.error import TryNext
50
51 # List here all the default hooks. For now it's just the editor functions
51 # List here all the default hooks. For now it's just the editor functions
52 # but over time we'll move here all the public API for user-accessible things.
52 # but over time we'll move here all the public API for user-accessible things.
53 # vds: >>
53
54 __all__ = ['editor', 'fix_error_editor', 'synchronize_with_editor', 'result_display',
54 __all__ = ['editor', 'fix_error_editor', 'synchronize_with_editor', 'result_display',
55 'input_prefilter', 'shutdown_hook', 'late_startup_hook',
55 'input_prefilter', 'shutdown_hook', 'late_startup_hook',
56 'generate_prompt', 'generate_output_prompt','shell_hook',
56 'generate_prompt', 'generate_output_prompt','shell_hook',
57 'show_in_pager','pre_prompt_hook', 'pre_runcode_hook',
57 'show_in_pager','pre_prompt_hook', 'pre_runcode_hook',
58 'clipboard_get']
58 'clipboard_get']
59 # vds: <<
60
59
61 pformat = PrettyPrinter().pformat
60 pformat = PrettyPrinter().pformat
62
61
63 def editor(self,filename, linenum=None):
62 def editor(self,filename, linenum=None):
64 """Open the default editor at the given filename and linenumber.
63 """Open the default editor at the given filename and linenumber.
65
64
66 This is IPython's default editor hook, you can use it as an example to
65 This is IPython's default editor hook, you can use it as an example to
67 write your own modified one. To set your own editor function as the
66 write your own modified one. To set your own editor function as the
68 new editor hook, call ip.set_hook('editor',yourfunc)."""
67 new editor hook, call ip.set_hook('editor',yourfunc)."""
69
68
70 # IPython configures a default editor at startup by reading $EDITOR from
69 # IPython configures a default editor at startup by reading $EDITOR from
71 # the environment, and falling back on vi (unix) or notepad (win32).
70 # the environment, and falling back on vi (unix) or notepad (win32).
72 editor = self.rc.editor
71 editor = self.editor
73
72
74 # marker for at which line to open the file (for existing objects)
73 # marker for at which line to open the file (for existing objects)
75 if linenum is None or editor=='notepad':
74 if linenum is None or editor=='notepad':
76 linemark = ''
75 linemark = ''
77 else:
76 else:
78 linemark = '+%d' % int(linenum)
77 linemark = '+%d' % int(linenum)
79
78
80 # Enclose in quotes if necessary and legal
79 # Enclose in quotes if necessary and legal
81 if ' ' in editor and os.path.isfile(editor) and editor[0] != '"':
80 if ' ' in editor and os.path.isfile(editor) and editor[0] != '"':
82 editor = '"%s"' % editor
81 editor = '"%s"' % editor
83
82
84 # Call the actual editor
83 # Call the actual editor
85 if os.system('%s %s %s' % (editor,linemark,filename)) != 0:
84 if os.system('%s %s %s' % (editor,linemark,filename)) != 0:
86 raise ipapi.TryNext()
85 raise TryNext()
87
86
88 import tempfile
87 import tempfile
89 def fix_error_editor(self,filename,linenum,column,msg):
88 def fix_error_editor(self,filename,linenum,column,msg):
90 """Open the editor at the given filename, linenumber, column and
89 """Open the editor at the given filename, linenumber, column and
91 show an error message. This is used for correcting syntax errors.
90 show an error message. This is used for correcting syntax errors.
92 The current implementation only has special support for the VIM editor,
91 The current implementation only has special support for the VIM editor,
93 and falls back on the 'editor' hook if VIM is not used.
92 and falls back on the 'editor' hook if VIM is not used.
94
93
95 Call ip.set_hook('fix_error_editor',youfunc) to use your own function,
94 Call ip.set_hook('fix_error_editor',youfunc) to use your own function,
96 """
95 """
97 def vim_quickfix_file():
96 def vim_quickfix_file():
98 t = tempfile.NamedTemporaryFile()
97 t = tempfile.NamedTemporaryFile()
99 t.write('%s:%d:%d:%s\n' % (filename,linenum,column,msg))
98 t.write('%s:%d:%d:%s\n' % (filename,linenum,column,msg))
100 t.flush()
99 t.flush()
101 return t
100 return t
102 if os.path.basename(self.rc.editor) != 'vim':
101 if os.path.basename(self.editor) != 'vim':
103 self.hooks.editor(filename,linenum)
102 self.hooks.editor(filename,linenum)
104 return
103 return
105 t = vim_quickfix_file()
104 t = vim_quickfix_file()
106 try:
105 try:
107 if os.system('vim --cmd "set errorformat=%f:%l:%c:%m" -q ' + t.name):
106 if os.system('vim --cmd "set errorformat=%f:%l:%c:%m" -q ' + t.name):
108 raise ipapi.TryNext()
107 raise TryNext()
109 finally:
108 finally:
110 t.close()
109 t.close()
111
110
112 # vds: >>
111
113 def synchronize_with_editor(self, filename, linenum, column):
112 def synchronize_with_editor(self, filename, linenum, column):
114 pass
113 pass
115 # vds: <<
114
116
115
117 class CommandChainDispatcher:
116 class CommandChainDispatcher:
118 """ Dispatch calls to a chain of commands until some func can handle it
117 """ Dispatch calls to a chain of commands until some func can handle it
119
118
120 Usage: instantiate, execute "add" to add commands (with optional
119 Usage: instantiate, execute "add" to add commands (with optional
121 priority), execute normally via f() calling mechanism.
120 priority), execute normally via f() calling mechanism.
122
121
123 """
122 """
124 def __init__(self,commands=None):
123 def __init__(self,commands=None):
125 if commands is None:
124 if commands is None:
126 self.chain = []
125 self.chain = []
127 else:
126 else:
128 self.chain = commands
127 self.chain = commands
129
128
130
129
131 def __call__(self,*args, **kw):
130 def __call__(self,*args, **kw):
132 """ Command chain is called just like normal func.
131 """ Command chain is called just like normal func.
133
132
134 This will call all funcs in chain with the same args as were given to this
133 This will call all funcs in chain with the same args as were given to this
135 function, and return the result of first func that didn't raise
134 function, and return the result of first func that didn't raise
136 TryNext """
135 TryNext """
137
136
138 for prio,cmd in self.chain:
137 for prio,cmd in self.chain:
139 #print "prio",prio,"cmd",cmd #dbg
138 #print "prio",prio,"cmd",cmd #dbg
140 try:
139 try:
141 ret = cmd(*args, **kw)
140 ret = cmd(*args, **kw)
142 return ret
141 return ret
143 except ipapi.TryNext, exc:
142 except TryNext, exc:
144 if exc.args or exc.kwargs:
143 if exc.args or exc.kwargs:
145 args = exc.args
144 args = exc.args
146 kw = exc.kwargs
145 kw = exc.kwargs
147 # if no function will accept it, raise TryNext up to the caller
146 # if no function will accept it, raise TryNext up to the caller
148 raise ipapi.TryNext
147 raise TryNext
149
148
150 def __str__(self):
149 def __str__(self):
151 return str(self.chain)
150 return str(self.chain)
152
151
153 def add(self, func, priority=0):
152 def add(self, func, priority=0):
154 """ Add a func to the cmd chain with given priority """
153 """ Add a func to the cmd chain with given priority """
155 bisect.insort(self.chain,(priority,func))
154 bisect.insort(self.chain,(priority,func))
156
155
157 def __iter__(self):
156 def __iter__(self):
158 """ Return all objects in chain.
157 """ Return all objects in chain.
159
158
160 Handy if the objects are not callable.
159 Handy if the objects are not callable.
161 """
160 """
162 return iter(self.chain)
161 return iter(self.chain)
163
162
163
164 def result_display(self,arg):
164 def result_display(self,arg):
165 """ Default display hook.
165 """ Default display hook.
166
166
167 Called for displaying the result to the user.
167 Called for displaying the result to the user.
168 """
168 """
169
169
170 if self.rc.pprint:
170 if self.pprint:
171 out = pformat(arg)
171 out = pformat(arg)
172 if '\n' in out:
172 if '\n' in out:
173 # So that multi-line strings line up with the left column of
173 # So that multi-line strings line up with the left column of
174 # the screen, instead of having the output prompt mess up
174 # the screen, instead of having the output prompt mess up
175 # their first line.
175 # their first line.
176 Term.cout.write('\n')
176 Term.cout.write('\n')
177 print >>Term.cout, out
177 print >>Term.cout, out
178 else:
178 else:
179 # By default, the interactive prompt uses repr() to display results,
179 # By default, the interactive prompt uses repr() to display results,
180 # so we should honor this. Users who'd rather use a different
180 # so we should honor this. Users who'd rather use a different
181 # mechanism can easily override this hook.
181 # mechanism can easily override this hook.
182 print >>Term.cout, repr(arg)
182 print >>Term.cout, repr(arg)
183 # the default display hook doesn't manipulate the value to put in history
183 # the default display hook doesn't manipulate the value to put in history
184 return None
184 return None
185
185
186
186 def input_prefilter(self,line):
187 def input_prefilter(self,line):
187 """ Default input prefilter
188 """ Default input prefilter
188
189
189 This returns the line as unchanged, so that the interpreter
190 This returns the line as unchanged, so that the interpreter
190 knows that nothing was done and proceeds with "classic" prefiltering
191 knows that nothing was done and proceeds with "classic" prefiltering
191 (%magics, !shell commands etc.).
192 (%magics, !shell commands etc.).
192
193
193 Note that leading whitespace is not passed to this hook. Prefilter
194 Note that leading whitespace is not passed to this hook. Prefilter
194 can't alter indentation.
195 can't alter indentation.
195
196
196 """
197 """
197 #print "attempt to rewrite",line #dbg
198 #print "attempt to rewrite",line #dbg
198 return line
199 return line
199
200
201
200 def shutdown_hook(self):
202 def shutdown_hook(self):
201 """ default shutdown hook
203 """ default shutdown hook
202
204
203 Typically, shotdown hooks should raise TryNext so all shutdown ops are done
205 Typically, shotdown hooks should raise TryNext so all shutdown ops are done
204 """
206 """
205
207
206 #print "default shutdown hook ok" # dbg
208 #print "default shutdown hook ok" # dbg
207 return
209 return
208
210
211
209 def late_startup_hook(self):
212 def late_startup_hook(self):
210 """ Executed after ipython has been constructed and configured
213 """ Executed after ipython has been constructed and configured
211
214
212 """
215 """
213 #print "default startup hook ok" # dbg
216 #print "default startup hook ok" # dbg
214
217
218
215 def generate_prompt(self, is_continuation):
219 def generate_prompt(self, is_continuation):
216 """ calculate and return a string with the prompt to display """
220 """ calculate and return a string with the prompt to display """
217 ip = self.api
218 if is_continuation:
221 if is_continuation:
219 return str(ip.IP.outputcache.prompt2)
222 return str(self.outputcache.prompt2)
220 return str(ip.IP.outputcache.prompt1)
223 return str(self.outputcache.prompt1)
224
221
225
222 def generate_output_prompt(self):
226 def generate_output_prompt(self):
223 ip = self.api
227 return str(self.outputcache.prompt_out)
224 return str(ip.IP.outputcache.prompt_out)
228
225
229
226 def shell_hook(self,cmd):
230 def shell_hook(self,cmd):
227 """ Run system/shell command a'la os.system() """
231 """ Run system/shell command a'la os.system() """
228
232
229 shell(cmd, header=self.rc.system_header, verbose=self.rc.system_verbose)
233 shell(cmd, header=self.system_header, verbose=self.system_verbose)
234
230
235
231 def show_in_pager(self,s):
236 def show_in_pager(self,s):
232 """ Run a string through pager """
237 """ Run a string through pager """
233 # raising TryNext here will use the default paging functionality
238 # raising TryNext here will use the default paging functionality
234 raise ipapi.TryNext
239 raise TryNext
240
235
241
236 def pre_prompt_hook(self):
242 def pre_prompt_hook(self):
237 """ Run before displaying the next prompt
243 """ Run before displaying the next prompt
238
244
239 Use this e.g. to display output from asynchronous operations (in order
245 Use this e.g. to display output from asynchronous operations (in order
240 to not mess up text entry)
246 to not mess up text entry)
241 """
247 """
242
248
243 return None
249 return None
244
250
251
245 def pre_runcode_hook(self):
252 def pre_runcode_hook(self):
246 """ Executed before running the (prefiltered) code in IPython """
253 """ Executed before running the (prefiltered) code in IPython """
247 return None
254 return None
248
255
256
249 def clipboard_get(self):
257 def clipboard_get(self):
250 """ Get text from the clipboard.
258 """ Get text from the clipboard.
251 """
259 """
252 from IPython.clipboard import (osx_clipboard_get, tkinter_clipboard_get,
260 from IPython.lib.clipboard import (
253 win32_clipboard_get)
261 osx_clipboard_get, tkinter_clipboard_get,
262 win32_clipboard_get
263 )
254 if sys.platform == 'win32':
264 if sys.platform == 'win32':
255 chain = [win32_clipboard_get, tkinter_clipboard_get]
265 chain = [win32_clipboard_get, tkinter_clipboard_get]
256 elif sys.platform == 'darwin':
266 elif sys.platform == 'darwin':
257 chain = [osx_clipboard_get, tkinter_clipboard_get]
267 chain = [osx_clipboard_get, tkinter_clipboard_get]
258 else:
268 else:
259 chain = [tkinter_clipboard_get]
269 chain = [tkinter_clipboard_get]
260 dispatcher = CommandChainDispatcher()
270 dispatcher = CommandChainDispatcher()
261 for func in chain:
271 for func in chain:
262 dispatcher.add(func)
272 dispatcher.add(func)
263 text = dispatcher()
273 text = dispatcher()
264 return text
274 return text
1 NO CONTENT: file renamed from IPython/Logger.py to IPython/core/logger.py
NO CONTENT: file renamed from IPython/Logger.py to IPython/core/logger.py
@@ -1,43 +1,41 b''
1 """Support for interactive macros in IPython"""
1 """Support for interactive macros in IPython"""
2
2
3 #*****************************************************************************
3 #*****************************************************************************
4 # Copyright (C) 2001-2005 Fernando Perez <fperez@colorado.edu>
4 # Copyright (C) 2001-2005 Fernando Perez <fperez@colorado.edu>
5 #
5 #
6 # Distributed under the terms of the BSD License. The full license is in
6 # Distributed under the terms of the BSD License. The full license is in
7 # the file COPYING, distributed as part of this software.
7 # the file COPYING, distributed as part of this software.
8 #*****************************************************************************
8 #*****************************************************************************
9
9
10 import IPython.ipapi
10 from IPython.utils.genutils import Term
11
11 from IPython.core.autocall import IPyAutocall
12 from IPython.genutils import Term
13 from IPython.ipapi import IPyAutocall
14
12
15 class Macro(IPyAutocall):
13 class Macro(IPyAutocall):
16 """Simple class to store the value of macros as strings.
14 """Simple class to store the value of macros as strings.
17
15
18 Macro is just a callable that executes a string of IPython
16 Macro is just a callable that executes a string of IPython
19 input when called.
17 input when called.
20
18
21 Args to macro are available in _margv list if you need them.
19 Args to macro are available in _margv list if you need them.
22 """
20 """
23
21
24 def __init__(self,data):
22 def __init__(self,data):
25
23
26 # store the macro value, as a single string which can be evaluated by
24 # store the macro value, as a single string which can be evaluated by
27 # runlines()
25 # runlines()
28 self.value = ''.join(data).rstrip()+'\n'
26 self.value = ''.join(data).rstrip()+'\n'
29
27
30 def __str__(self):
28 def __str__(self):
31 return self.value
29 return self.value
32
30
33 def __repr__(self):
31 def __repr__(self):
34 return 'IPython.macro.Macro(%s)' % repr(self.value)
32 return 'IPython.macro.Macro(%s)' % repr(self.value)
35
33
36 def __call__(self,*args):
34 def __call__(self,*args):
37 Term.cout.flush()
35 Term.cout.flush()
38 self._ip.user_ns['_margv'] = args
36 self._ip.user_ns['_margv'] = args
39 self._ip.runlines(self.value)
37 self._ip.runlines(self.value)
40
38
41 def __getstate__(self):
39 def __getstate__(self):
42 """ needed for safe pickling via %store """
40 """ needed for safe pickling via %store """
43 return {'value': self.value}
41 return {'value': self.value}
1 NO CONTENT: file renamed from IPython/Magic.py to IPython/core/magic.py
NO CONTENT: file renamed from IPython/Magic.py to IPython/core/magic.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/OInspect.py to IPython/core/oinspect.py
NO CONTENT: file renamed from IPython/OInspect.py to IPython/core/oinspect.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/OutputTrap.py to IPython/core/outputtrap.py
NO CONTENT: file renamed from IPython/OutputTrap.py to IPython/core/outputtrap.py
1 NO CONTENT: file renamed from IPython/Prompts.py to IPython/core/prompts.py
NO CONTENT: file renamed from IPython/Prompts.py to IPython/core/prompts.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/Release.py to IPython/core/release.py
NO CONTENT: file renamed from IPython/Release.py to IPython/core/release.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/shadowns.py to IPython/core/shadowns.py
NO CONTENT: file renamed from IPython/shadowns.py to IPython/core/shadowns.py
1 NO CONTENT: file renamed from IPython/tools/tests/__init__.py to IPython/core/tests/__init__.py
NO CONTENT: file renamed from IPython/tools/tests/__init__.py to IPython/core/tests/__init__.py
1 NO CONTENT: file renamed from IPython/tests/obj_del.py to IPython/core/tests/obj_del.py
NO CONTENT: file renamed from IPython/tests/obj_del.py to IPython/core/tests/obj_del.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/tests/refbug.py to IPython/core/tests/refbug.py
NO CONTENT: file renamed from IPython/tests/refbug.py to IPython/core/tests/refbug.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/tests/tclass.py to IPython/core/tests/tclass.py
NO CONTENT: file renamed from IPython/tests/tclass.py to IPython/core/tests/tclass.py
1 NO CONTENT: file renamed from IPython/tests/test_fakemodule.py to IPython/core/tests/test_fakemodule.py
NO CONTENT: file renamed from IPython/tests/test_fakemodule.py to IPython/core/tests/test_fakemodule.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/tests/test_iplib.py to IPython/core/tests/test_iplib.py
NO CONTENT: file renamed from IPython/tests/test_iplib.py to IPython/core/tests/test_iplib.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/tests/test_magic.py to IPython/core/tests/test_magic.py
NO CONTENT: file renamed from IPython/tests/test_magic.py to IPython/core/tests/test_magic.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/kernel/core/ultraTB.py to IPython/core/ultratb.py
NO CONTENT: file renamed from IPython/kernel/core/ultraTB.py to IPython/core/ultratb.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/usage.py to IPython/core/usage.py
NO CONTENT: file renamed from IPython/usage.py to IPython/core/usage.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/Gnuplot2.py to IPython/deathrow/Gnuplot2.py
NO CONTENT: file renamed from IPython/Gnuplot2.py to IPython/deathrow/Gnuplot2.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/GnuplotInteractive.py to IPython/deathrow/GnuplotInteractive.py
NO CONTENT: file renamed from IPython/GnuplotInteractive.py to IPython/deathrow/GnuplotInteractive.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/GnuplotRuntime.py to IPython/deathrow/GnuplotRuntime.py
NO CONTENT: file renamed from IPython/GnuplotRuntime.py to IPython/deathrow/GnuplotRuntime.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/Itpl.py to IPython/deathrow/Itpl.py
NO CONTENT: file renamed from IPython/Itpl.py to IPython/deathrow/Itpl.py
1 NO CONTENT: file renamed from IPython/Extensions/PhysicalQInput.py to IPython/deathrow/PhysicalQInput.py
NO CONTENT: file renamed from IPython/Extensions/PhysicalQInput.py to IPython/deathrow/PhysicalQInput.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/Extensions/PhysicalQInteractive.py to IPython/deathrow/PhysicalQInteractive.py
NO CONTENT: file renamed from IPython/Extensions/PhysicalQInteractive.py to IPython/deathrow/PhysicalQInteractive.py
1 NO CONTENT: file renamed from IPython/Extensions/astyle.py to IPython/deathrow/astyle.py
NO CONTENT: file renamed from IPython/Extensions/astyle.py to IPython/deathrow/astyle.py
1 NO CONTENT: file renamed from IPython/dtutils.py to IPython/deathrow/dtutils.py
NO CONTENT: file renamed from IPython/dtutils.py to IPython/deathrow/dtutils.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/Extensions/ibrowse.py to IPython/deathrow/ibrowse.py
NO CONTENT: file renamed from IPython/Extensions/ibrowse.py to IPython/deathrow/ibrowse.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/Extensions/igrid.py to IPython/deathrow/igrid.py
NO CONTENT: file renamed from IPython/Extensions/igrid.py to IPython/deathrow/igrid.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/Extensions/igrid_help.css to IPython/deathrow/igrid_help.css
NO CONTENT: file renamed from IPython/Extensions/igrid_help.css to IPython/deathrow/igrid_help.css
1 NO CONTENT: file renamed from IPython/Extensions/igrid_help.html to IPython/deathrow/igrid_help.html
NO CONTENT: file renamed from IPython/Extensions/igrid_help.html to IPython/deathrow/igrid_help.html
1 NO CONTENT: file renamed from IPython/Extensions/ipipe.py to IPython/deathrow/ipipe.py
NO CONTENT: file renamed from IPython/Extensions/ipipe.py to IPython/deathrow/ipipe.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/Extensions/ipy_constants.py to IPython/deathrow/ipy_constants.py
NO CONTENT: file renamed from IPython/Extensions/ipy_constants.py to IPython/deathrow/ipy_constants.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/Extensions/ipy_defaults.py to IPython/deathrow/ipy_defaults.py
NO CONTENT: file renamed from IPython/Extensions/ipy_defaults.py to IPython/deathrow/ipy_defaults.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/Extensions/ipy_kitcfg.py to IPython/deathrow/ipy_kitcfg.py
NO CONTENT: file renamed from IPython/Extensions/ipy_kitcfg.py to IPython/deathrow/ipy_kitcfg.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/Extensions/ipy_legacy.py to IPython/deathrow/ipy_legacy.py
NO CONTENT: file renamed from IPython/Extensions/ipy_legacy.py to IPython/deathrow/ipy_legacy.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/Extensions/ipy_p4.py to IPython/deathrow/ipy_p4.py
NO CONTENT: file renamed from IPython/Extensions/ipy_p4.py to IPython/deathrow/ipy_p4.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/Extensions/ipy_profile_none.py to IPython/deathrow/ipy_profile_none.py
NO CONTENT: file renamed from IPython/Extensions/ipy_profile_none.py to IPython/deathrow/ipy_profile_none.py
1 NO CONTENT: file renamed from IPython/Extensions/ipy_profile_numpy.py to IPython/deathrow/ipy_profile_numpy.py
NO CONTENT: file renamed from IPython/Extensions/ipy_profile_numpy.py to IPython/deathrow/ipy_profile_numpy.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/Extensions/ipy_profile_scipy.py to IPython/deathrow/ipy_profile_scipy.py
NO CONTENT: file renamed from IPython/Extensions/ipy_profile_scipy.py to IPython/deathrow/ipy_profile_scipy.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/Extensions/ipy_profile_sh.py to IPython/deathrow/ipy_profile_sh.py
NO CONTENT: file renamed from IPython/Extensions/ipy_profile_sh.py to IPython/deathrow/ipy_profile_sh.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/Extensions/ipy_profile_zope.py to IPython/deathrow/ipy_profile_zope.py
NO CONTENT: file renamed from IPython/Extensions/ipy_profile_zope.py to IPython/deathrow/ipy_profile_zope.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/Extensions/ipy_traits_completer.py to IPython/deathrow/ipy_traits_completer.py
NO CONTENT: file renamed from IPython/Extensions/ipy_traits_completer.py to IPython/deathrow/ipy_traits_completer.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/Extensions/ipy_vimserver.py to IPython/deathrow/ipy_vimserver.py
NO CONTENT: file renamed from IPython/Extensions/ipy_vimserver.py to IPython/deathrow/ipy_vimserver.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/Extensions/numeric_formats.py to IPython/deathrow/numeric_formats.py
NO CONTENT: file renamed from IPython/Extensions/numeric_formats.py to IPython/deathrow/numeric_formats.py
1 NO CONTENT: file renamed from IPython/numutils.py to IPython/deathrow/numutils.py
NO CONTENT: file renamed from IPython/numutils.py to IPython/deathrow/numutils.py
1 NO CONTENT: file renamed from IPython/Extensions/scitedirector.py to IPython/deathrow/scitedirector.py
NO CONTENT: file renamed from IPython/Extensions/scitedirector.py to IPython/deathrow/scitedirector.py
1 NO CONTENT: file renamed from IPython/twshell.py to IPython/deathrow/twshell.py
NO CONTENT: file renamed from IPython/twshell.py to IPython/deathrow/twshell.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/Extensions/__init__.py to IPython/extensions/__init__.py
NO CONTENT: file renamed from IPython/Extensions/__init__.py to IPython/extensions/__init__.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file chmod 100755 => 100644
NO CONTENT: modified file chmod 100755 => 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/background_jobs.py to IPython/lib/backgroundjobs.py
NO CONTENT: file renamed from IPython/background_jobs.py to IPython/lib/backgroundjobs.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/clipboard.py to IPython/lib/clipboard.py
NO CONTENT: file renamed from IPython/clipboard.py to IPython/lib/clipboard.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/deep_reload.py to IPython/lib/deepreload.py
NO CONTENT: file renamed from IPython/deep_reload.py to IPython/lib/deepreload.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/demo.py to IPython/lib/demo.py
NO CONTENT: file renamed from IPython/demo.py to IPython/lib/demo.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/irunner.py to IPython/lib/irunner.py
NO CONTENT: file renamed from IPython/irunner.py to IPython/lib/irunner.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/Extensions/InterpreterExec.py to IPython/quarantine/InterpreterExec.py
NO CONTENT: file renamed from IPython/Extensions/InterpreterExec.py to IPython/quarantine/InterpreterExec.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/Extensions/InterpreterPasteInput.py to IPython/quarantine/InterpreterPasteInput.py
NO CONTENT: file renamed from IPython/Extensions/InterpreterPasteInput.py to IPython/quarantine/InterpreterPasteInput.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/Extensions/clearcmd.py to IPython/quarantine/clearcmd.py
NO CONTENT: file renamed from IPython/Extensions/clearcmd.py to IPython/quarantine/clearcmd.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/Extensions/envpersist.py to IPython/quarantine/envpersist.py
NO CONTENT: file renamed from IPython/Extensions/envpersist.py to IPython/quarantine/envpersist.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/Extensions/ext_rescapture.py to IPython/quarantine/ext_rescapture.py
NO CONTENT: file renamed from IPython/Extensions/ext_rescapture.py to IPython/quarantine/ext_rescapture.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/Extensions/ipy_app_completers.py to IPython/quarantine/ipy_app_completers.py
NO CONTENT: file renamed from IPython/Extensions/ipy_app_completers.py to IPython/quarantine/ipy_app_completers.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/Extensions/ipy_autoreload.py to IPython/quarantine/ipy_autoreload.py
NO CONTENT: file renamed from IPython/Extensions/ipy_autoreload.py to IPython/quarantine/ipy_autoreload.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/Extensions/ipy_bzr.py to IPython/quarantine/ipy_bzr.py
NO CONTENT: file renamed from IPython/Extensions/ipy_bzr.py to IPython/quarantine/ipy_bzr.py
1 NO CONTENT: file renamed from IPython/Extensions/ipy_completers.py to IPython/quarantine/ipy_completers.py
NO CONTENT: file renamed from IPython/Extensions/ipy_completers.py to IPython/quarantine/ipy_completers.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/Extensions/ipy_editors.py to IPython/quarantine/ipy_editors.py
NO CONTENT: file renamed from IPython/Extensions/ipy_editors.py to IPython/quarantine/ipy_editors.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/Extensions/ipy_exportdb.py to IPython/quarantine/ipy_exportdb.py
NO CONTENT: file renamed from IPython/Extensions/ipy_exportdb.py to IPython/quarantine/ipy_exportdb.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/Extensions/ipy_extutil.py to IPython/quarantine/ipy_extutil.py
NO CONTENT: file renamed from IPython/Extensions/ipy_extutil.py to IPython/quarantine/ipy_extutil.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/Extensions/ipy_fsops.py to IPython/quarantine/ipy_fsops.py
NO CONTENT: file renamed from IPython/Extensions/ipy_fsops.py to IPython/quarantine/ipy_fsops.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/Extensions/ipy_gnuglobal.py to IPython/quarantine/ipy_gnuglobal.py
NO CONTENT: file renamed from IPython/Extensions/ipy_gnuglobal.py to IPython/quarantine/ipy_gnuglobal.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/Extensions/ipy_greedycompleter.py to IPython/quarantine/ipy_greedycompleter.py
NO CONTENT: file renamed from IPython/Extensions/ipy_greedycompleter.py to IPython/quarantine/ipy_greedycompleter.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/Extensions/ipy_jot.py to IPython/quarantine/ipy_jot.py
NO CONTENT: file renamed from IPython/Extensions/ipy_jot.py to IPython/quarantine/ipy_jot.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/Extensions/ipy_lookfor.py to IPython/quarantine/ipy_lookfor.py
NO CONTENT: file renamed from IPython/Extensions/ipy_lookfor.py to IPython/quarantine/ipy_lookfor.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/Extensions/ipy_profile_doctest.py to IPython/quarantine/ipy_profile_doctest.py
NO CONTENT: file renamed from IPython/Extensions/ipy_profile_doctest.py to IPython/quarantine/ipy_profile_doctest.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/Extensions/ipy_pydb.py to IPython/quarantine/ipy_pydb.py
NO CONTENT: file renamed from IPython/Extensions/ipy_pydb.py to IPython/quarantine/ipy_pydb.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/Extensions/ipy_rehashdir.py to IPython/quarantine/ipy_rehashdir.py
NO CONTENT: file renamed from IPython/Extensions/ipy_rehashdir.py to IPython/quarantine/ipy_rehashdir.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/Extensions/ipy_render.py to IPython/quarantine/ipy_render.py
NO CONTENT: file renamed from IPython/Extensions/ipy_render.py to IPython/quarantine/ipy_render.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/Extensions/ipy_server.py to IPython/quarantine/ipy_server.py
NO CONTENT: file renamed from IPython/Extensions/ipy_server.py to IPython/quarantine/ipy_server.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/Extensions/ipy_signals.py to IPython/quarantine/ipy_signals.py
NO CONTENT: file renamed from IPython/Extensions/ipy_signals.py to IPython/quarantine/ipy_signals.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/Extensions/ipy_stock_completers.py to IPython/quarantine/ipy_stock_completers.py
NO CONTENT: file renamed from IPython/Extensions/ipy_stock_completers.py to IPython/quarantine/ipy_stock_completers.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/Extensions/ipy_synchronize_with.py to IPython/quarantine/ipy_synchronize_with.py
NO CONTENT: file renamed from IPython/Extensions/ipy_synchronize_with.py to IPython/quarantine/ipy_synchronize_with.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/Extensions/ipy_system_conf.py to IPython/quarantine/ipy_system_conf.py
NO CONTENT: file renamed from IPython/Extensions/ipy_system_conf.py to IPython/quarantine/ipy_system_conf.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/Extensions/ipy_which.py to IPython/quarantine/ipy_which.py
NO CONTENT: file renamed from IPython/Extensions/ipy_which.py to IPython/quarantine/ipy_which.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/Extensions/ipy_winpdb.py to IPython/quarantine/ipy_winpdb.py
NO CONTENT: file renamed from IPython/Extensions/ipy_winpdb.py to IPython/quarantine/ipy_winpdb.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/Extensions/ipy_workdir.py to IPython/quarantine/ipy_workdir.py
NO CONTENT: file renamed from IPython/Extensions/ipy_workdir.py to IPython/quarantine/ipy_workdir.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/Extensions/jobctrl.py to IPython/quarantine/jobctrl.py
NO CONTENT: file renamed from IPython/Extensions/jobctrl.py to IPython/quarantine/jobctrl.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/Extensions/ledit.py to IPython/quarantine/ledit.py
NO CONTENT: file renamed from IPython/Extensions/ledit.py to IPython/quarantine/ledit.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/Extensions/pspersistence.py to IPython/quarantine/pspersistence.py
NO CONTENT: file renamed from IPython/Extensions/pspersistence.py to IPython/quarantine/pspersistence.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/Extensions/win32clip.py to IPython/quarantine/win32clip.py
NO CONTENT: file renamed from IPython/Extensions/win32clip.py to IPython/quarantine/win32clip.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from scripts/iptest to IPython/scripts/iptest
NO CONTENT: file renamed from scripts/iptest to IPython/scripts/iptest
1 NO CONTENT: file renamed from scripts/ipython-wx to IPython/scripts/ipython-wx
NO CONTENT: file renamed from scripts/ipython-wx to IPython/scripts/ipython-wx
1 NO CONTENT: file renamed from scripts/ipythonx to IPython/scripts/ipythonx
NO CONTENT: file renamed from scripts/ipythonx to IPython/scripts/ipythonx
1 NO CONTENT: file renamed from scripts/irunner to IPython/scripts/irunner
NO CONTENT: file renamed from scripts/irunner to IPython/scripts/irunner
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from scripts/pycolor to IPython/scripts/pycolor
NO CONTENT: file renamed from scripts/pycolor to IPython/scripts/pycolor
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/DPyGetOpt.py to IPython/utils/DPyGetOpt.py
NO CONTENT: file renamed from IPython/DPyGetOpt.py to IPython/utils/DPyGetOpt.py
1 NO CONTENT: file renamed from IPython/PyColorize.py to IPython/utils/PyColorize.py
NO CONTENT: file renamed from IPython/PyColorize.py to IPython/utils/PyColorize.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/ColorANSI.py to IPython/utils/coloransi.py
NO CONTENT: file renamed from IPython/ColorANSI.py to IPython/utils/coloransi.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/genutils.py to IPython/utils/genutils.py
NO CONTENT: file renamed from IPython/genutils.py to IPython/utils/genutils.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/tools/growl.py to IPython/utils/growl.py
NO CONTENT: file renamed from IPython/tools/growl.py to IPython/utils/growl.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/Extensions/pickleshare.py to IPython/utils/pickleshare.py
NO CONTENT: file renamed from IPython/Extensions/pickleshare.py to IPython/utils/pickleshare.py
1 NO CONTENT: file renamed from IPython/platutils.py to IPython/utils/platutils.py
NO CONTENT: file renamed from IPython/platutils.py to IPython/utils/platutils.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/platutils_dummy.py to IPython/utils/platutils_dummy.py
NO CONTENT: file renamed from IPython/platutils_dummy.py to IPython/utils/platutils_dummy.py
1 NO CONTENT: file renamed from IPython/platutils_posix.py to IPython/utils/platutils_posix.py
NO CONTENT: file renamed from IPython/platutils_posix.py to IPython/utils/platutils_posix.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/platutils_win32.py to IPython/utils/platutils_win32.py
NO CONTENT: file renamed from IPython/platutils_win32.py to IPython/utils/platutils_win32.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/rlineimpl.py to IPython/utils/rlineimpl.py
NO CONTENT: file renamed from IPython/rlineimpl.py to IPython/utils/rlineimpl.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/strdispatch.py to IPython/utils/strdispatch.py
NO CONTENT: file renamed from IPython/strdispatch.py to IPython/utils/strdispatch.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/tests/test_genutils.py to IPython/utils/tests/test_genutils.py
NO CONTENT: file renamed from IPython/tests/test_genutils.py to IPython/utils/tests/test_genutils.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/kernel/core/tests/test_notification.py to IPython/utils/tests/test_notification.py
NO CONTENT: file renamed from IPython/kernel/core/tests/test_notification.py to IPython/utils/tests/test_notification.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/tests/test_platutils.py to IPython/utils/tests/test_platutils.py
NO CONTENT: file renamed from IPython/tests/test_platutils.py to IPython/utils/tests/test_platutils.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/upgrade_dir.py to IPython/utils/upgradedir.py
NO CONTENT: file renamed from IPython/upgrade_dir.py to IPython/utils/upgradedir.py
1 NO CONTENT: file renamed from IPython/wildcard.py to IPython/utils/wildcard.py
NO CONTENT: file renamed from IPython/wildcard.py to IPython/utils/wildcard.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/winconsole.py to IPython/utils/winconsole.py
NO CONTENT: file renamed from IPython/winconsole.py to IPython/utils/winconsole.py
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from docs/source/history.txt to docs/source/about/history.txt
NO CONTENT: file renamed from docs/source/history.txt to docs/source/about/history.txt
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from docs/source/license_and_copyright.txt to docs/source/about/license_and_copyright.txt
NO CONTENT: file renamed from docs/source/license_and_copyright.txt to docs/source/about/license_and_copyright.txt
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from docs/source/config/initial_config.txt to docs/source/config/old.txt
NO CONTENT: file renamed from docs/source/config/initial_config.txt to docs/source/config/old.txt
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from docs/source/changes.txt to docs/source/whatsnew/version0.9.txt
NO CONTENT: file renamed from docs/source/changes.txt to docs/source/whatsnew/version0.9.txt
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
This diff has been collapsed as it changes many lines, (631 lines changed) Show them Hide them
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed, binary diff hidden
NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
General Comments 0
You need to be logged in to leave comments. Login now