|
@@
-1,2126
+1,2127
|
|
1
|
# -*- coding: utf-8 -*-
|
|
1
|
# -*- coding: utf-8 -*-
|
|
2
|
"""Main IPython class."""
|
|
2
|
"""Main IPython class."""
|
|
3
|
|
|
3
|
|
|
4
|
#-----------------------------------------------------------------------------
|
|
4
|
#-----------------------------------------------------------------------------
|
|
5
|
# Copyright (C) 2001 Janko Hauser <jhauser@zscout.de>
|
|
5
|
# Copyright (C) 2001 Janko Hauser <jhauser@zscout.de>
|
|
6
|
# Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
|
|
6
|
# Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
|
|
7
|
# Copyright (C) 2008-2010 The IPython Development Team
|
|
7
|
# Copyright (C) 2008-2010 The IPython Development Team
|
|
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
|
# Imports
|
|
14
|
# Imports
|
|
15
|
#-----------------------------------------------------------------------------
|
|
15
|
#-----------------------------------------------------------------------------
|
|
16
|
|
|
16
|
|
|
17
|
from __future__ import with_statement
|
|
17
|
from __future__ import with_statement
|
|
18
|
from __future__ import absolute_import
|
|
18
|
from __future__ import absolute_import
|
|
19
|
|
|
19
|
|
|
20
|
import __builtin__
|
|
20
|
import __builtin__
|
|
21
|
import abc
|
|
21
|
import abc
|
|
22
|
import codeop
|
|
22
|
import codeop
|
|
23
|
import exceptions
|
|
23
|
import exceptions
|
|
24
|
import new
|
|
24
|
import new
|
|
25
|
import os
|
|
25
|
import os
|
|
26
|
import re
|
|
26
|
import re
|
|
27
|
import string
|
|
27
|
import string
|
|
28
|
import sys
|
|
28
|
import sys
|
|
29
|
import tempfile
|
|
29
|
import tempfile
|
|
30
|
from contextlib import nested
|
|
30
|
from contextlib import nested
|
|
31
|
|
|
31
|
|
|
32
|
from IPython.core import debugger, oinspect
|
|
32
|
from IPython.core import debugger, oinspect
|
|
33
|
from IPython.core import history as ipcorehist
|
|
33
|
from IPython.core import history as ipcorehist
|
|
34
|
from IPython.core import prefilter
|
|
34
|
from IPython.core import prefilter
|
|
35
|
from IPython.core import shadowns
|
|
35
|
from IPython.core import shadowns
|
|
36
|
from IPython.core import ultratb
|
|
36
|
from IPython.core import ultratb
|
|
37
|
from IPython.core.alias import AliasManager
|
|
37
|
from IPython.core.alias import AliasManager
|
|
38
|
from IPython.core.builtin_trap import BuiltinTrap
|
|
38
|
from IPython.core.builtin_trap import BuiltinTrap
|
|
39
|
from IPython.config.configurable import Configurable
|
|
39
|
from IPython.config.configurable import Configurable
|
|
40
|
from IPython.core.display_trap import DisplayTrap
|
|
40
|
from IPython.core.display_trap import DisplayTrap
|
|
41
|
from IPython.core.error import UsageError
|
|
41
|
from IPython.core.error import UsageError
|
|
42
|
from IPython.core.extensions import ExtensionManager
|
|
42
|
from IPython.core.extensions import ExtensionManager
|
|
43
|
from IPython.core.fakemodule import FakeModule, init_fakemod_dict
|
|
43
|
from IPython.core.fakemodule import FakeModule, init_fakemod_dict
|
|
44
|
from IPython.core.inputlist import InputList
|
|
44
|
from IPython.core.inputlist import InputList
|
|
45
|
from IPython.core.logger import Logger
|
|
45
|
from IPython.core.logger import Logger
|
|
46
|
from IPython.core.magic import Magic
|
|
46
|
from IPython.core.magic import Magic
|
|
|
|
|
47
|
from IPython.core.payload import PayloadManager
|
|
47
|
from IPython.core.plugin import PluginManager
|
|
48
|
from IPython.core.plugin import PluginManager
|
|
48
|
from IPython.core.prefilter import PrefilterManager
|
|
49
|
from IPython.core.prefilter import PrefilterManager
|
|
49
|
from IPython.core.displayhook import DisplayHook
|
|
50
|
from IPython.core.displayhook import DisplayHook
|
|
50
|
import IPython.core.hooks
|
|
51
|
import IPython.core.hooks
|
|
51
|
from IPython.external.Itpl import ItplNS
|
|
52
|
from IPython.external.Itpl import ItplNS
|
|
52
|
from IPython.utils import PyColorize
|
|
53
|
from IPython.utils import PyColorize
|
|
53
|
from IPython.utils import pickleshare
|
|
54
|
from IPython.utils import pickleshare
|
|
54
|
from IPython.utils.doctestreload import doctest_reload
|
|
55
|
from IPython.utils.doctestreload import doctest_reload
|
|
55
|
from IPython.utils.ipstruct import Struct
|
|
56
|
from IPython.utils.ipstruct import Struct
|
|
56
|
import IPython.utils.io
|
|
57
|
import IPython.utils.io
|
|
57
|
from IPython.utils.io import ask_yes_no
|
|
58
|
from IPython.utils.io import ask_yes_no
|
|
58
|
from IPython.utils.path import get_home_dir, get_ipython_dir, HomeDirError
|
|
59
|
from IPython.utils.path import get_home_dir, get_ipython_dir, HomeDirError
|
|
59
|
from IPython.utils.process import getoutput, getoutputerror
|
|
60
|
from IPython.utils.process import getoutput, getoutputerror
|
|
60
|
from IPython.utils.strdispatch import StrDispatch
|
|
61
|
from IPython.utils.strdispatch import StrDispatch
|
|
61
|
from IPython.utils.syspathcontext import prepended_to_syspath
|
|
62
|
from IPython.utils.syspathcontext import prepended_to_syspath
|
|
62
|
from IPython.utils.text import num_ini_spaces
|
|
63
|
from IPython.utils.text import num_ini_spaces
|
|
63
|
from IPython.utils.warn import warn, error, fatal
|
|
64
|
from IPython.utils.warn import warn, error, fatal
|
|
64
|
from IPython.utils.traitlets import (
|
|
65
|
from IPython.utils.traitlets import (
|
|
65
|
Int, Str, CBool, CaselessStrEnum, Enum, List, Unicode, Instance, Type
|
|
66
|
Int, Str, CBool, CaselessStrEnum, Enum, List, Unicode, Instance, Type
|
|
66
|
)
|
|
67
|
)
|
|
67
|
|
|
68
|
|
|
68
|
# from IPython.utils import growl
|
|
69
|
# from IPython.utils import growl
|
|
69
|
# growl.start("IPython")
|
|
70
|
# growl.start("IPython")
|
|
70
|
|
|
71
|
|
|
71
|
#-----------------------------------------------------------------------------
|
|
72
|
#-----------------------------------------------------------------------------
|
|
72
|
# Globals
|
|
73
|
# Globals
|
|
73
|
#-----------------------------------------------------------------------------
|
|
74
|
#-----------------------------------------------------------------------------
|
|
74
|
|
|
75
|
|
|
75
|
# compiled regexps for autoindent management
|
|
76
|
# compiled regexps for autoindent management
|
|
76
|
dedent_re = re.compile(r'^\s+raise|^\s+return|^\s+pass')
|
|
77
|
dedent_re = re.compile(r'^\s+raise|^\s+return|^\s+pass')
|
|
77
|
|
|
78
|
|
|
78
|
#-----------------------------------------------------------------------------
|
|
79
|
#-----------------------------------------------------------------------------
|
|
79
|
# Utilities
|
|
80
|
# Utilities
|
|
80
|
#-----------------------------------------------------------------------------
|
|
81
|
#-----------------------------------------------------------------------------
|
|
81
|
|
|
82
|
|
|
82
|
# store the builtin raw_input globally, and use this always, in case user code
|
|
83
|
# store the builtin raw_input globally, and use this always, in case user code
|
|
83
|
# overwrites it (like wx.py.PyShell does)
|
|
84
|
# overwrites it (like wx.py.PyShell does)
|
|
84
|
raw_input_original = raw_input
|
|
85
|
raw_input_original = raw_input
|
|
85
|
|
|
86
|
|
|
86
|
def softspace(file, newvalue):
|
|
87
|
def softspace(file, newvalue):
|
|
87
|
"""Copied from code.py, to remove the dependency"""
|
|
88
|
"""Copied from code.py, to remove the dependency"""
|
|
88
|
|
|
89
|
|
|
89
|
oldvalue = 0
|
|
90
|
oldvalue = 0
|
|
90
|
try:
|
|
91
|
try:
|
|
91
|
oldvalue = file.softspace
|
|
92
|
oldvalue = file.softspace
|
|
92
|
except AttributeError:
|
|
93
|
except AttributeError:
|
|
93
|
pass
|
|
94
|
pass
|
|
94
|
try:
|
|
95
|
try:
|
|
95
|
file.softspace = newvalue
|
|
96
|
file.softspace = newvalue
|
|
96
|
except (AttributeError, TypeError):
|
|
97
|
except (AttributeError, TypeError):
|
|
97
|
# "attribute-less object" or "read-only attributes"
|
|
98
|
# "attribute-less object" or "read-only attributes"
|
|
98
|
pass
|
|
99
|
pass
|
|
99
|
return oldvalue
|
|
100
|
return oldvalue
|
|
100
|
|
|
101
|
|
|
101
|
|
|
102
|
|
|
102
|
def no_op(*a, **kw): pass
|
|
103
|
def no_op(*a, **kw): pass
|
|
103
|
|
|
104
|
|
|
104
|
class SpaceInInput(exceptions.Exception): pass
|
|
105
|
class SpaceInInput(exceptions.Exception): pass
|
|
105
|
|
|
106
|
|
|
106
|
class Bunch: pass
|
|
107
|
class Bunch: pass
|
|
107
|
|
|
108
|
|
|
108
|
|
|
109
|
|
|
109
|
def get_default_colors():
|
|
110
|
def get_default_colors():
|
|
110
|
if sys.platform=='darwin':
|
|
111
|
if sys.platform=='darwin':
|
|
111
|
return "LightBG"
|
|
112
|
return "LightBG"
|
|
112
|
elif os.name=='nt':
|
|
113
|
elif os.name=='nt':
|
|
113
|
return 'Linux'
|
|
114
|
return 'Linux'
|
|
114
|
else:
|
|
115
|
else:
|
|
115
|
return 'Linux'
|
|
116
|
return 'Linux'
|
|
116
|
|
|
117
|
|
|
117
|
|
|
118
|
|
|
118
|
class SeparateStr(Str):
|
|
119
|
class SeparateStr(Str):
|
|
119
|
"""A Str subclass to validate separate_in, separate_out, etc.
|
|
120
|
"""A Str subclass to validate separate_in, separate_out, etc.
|
|
120
|
|
|
121
|
|
|
121
|
This is a Str based trait that converts '0'->'' and '\\n'->'\n'.
|
|
122
|
This is a Str based trait that converts '0'->'' and '\\n'->'\n'.
|
|
122
|
"""
|
|
123
|
"""
|
|
123
|
|
|
124
|
|
|
124
|
def validate(self, obj, value):
|
|
125
|
def validate(self, obj, value):
|
|
125
|
if value == '0': value = ''
|
|
126
|
if value == '0': value = ''
|
|
126
|
value = value.replace('\\n','\n')
|
|
127
|
value = value.replace('\\n','\n')
|
|
127
|
return super(SeparateStr, self).validate(obj, value)
|
|
128
|
return super(SeparateStr, self).validate(obj, value)
|
|
128
|
|
|
129
|
|
|
129
|
class MultipleInstanceError(Exception):
|
|
130
|
class MultipleInstanceError(Exception):
|
|
130
|
pass
|
|
131
|
pass
|
|
131
|
|
|
132
|
|
|
132
|
|
|
133
|
|
|
133
|
#-----------------------------------------------------------------------------
|
|
134
|
#-----------------------------------------------------------------------------
|
|
134
|
# Main IPython class
|
|
135
|
# Main IPython class
|
|
135
|
#-----------------------------------------------------------------------------
|
|
136
|
#-----------------------------------------------------------------------------
|
|
136
|
|
|
137
|
|
|
137
|
|
|
138
|
|
|
138
|
class InteractiveShell(Configurable, Magic):
|
|
139
|
class InteractiveShell(Configurable, Magic):
|
|
139
|
"""An enhanced, interactive shell for Python."""
|
|
140
|
"""An enhanced, interactive shell for Python."""
|
|
140
|
|
|
141
|
|
|
141
|
_instance = None
|
|
142
|
_instance = None
|
|
142
|
autocall = Enum((0,1,2), default_value=1, config=True)
|
|
143
|
autocall = Enum((0,1,2), default_value=1, config=True)
|
|
143
|
# TODO: remove all autoindent logic and put into frontends.
|
|
144
|
# TODO: remove all autoindent logic and put into frontends.
|
|
144
|
# We can't do this yet because even runlines uses the autoindent.
|
|
145
|
# We can't do this yet because even runlines uses the autoindent.
|
|
145
|
autoindent = CBool(True, config=True)
|
|
146
|
autoindent = CBool(True, config=True)
|
|
146
|
automagic = CBool(True, config=True)
|
|
147
|
automagic = CBool(True, config=True)
|
|
147
|
cache_size = Int(1000, config=True)
|
|
148
|
cache_size = Int(1000, config=True)
|
|
148
|
color_info = CBool(True, config=True)
|
|
149
|
color_info = CBool(True, config=True)
|
|
149
|
colors = CaselessStrEnum(('NoColor','LightBG','Linux'),
|
|
150
|
colors = CaselessStrEnum(('NoColor','LightBG','Linux'),
|
|
150
|
default_value=get_default_colors(), config=True)
|
|
151
|
default_value=get_default_colors(), config=True)
|
|
151
|
debug = CBool(False, config=True)
|
|
152
|
debug = CBool(False, config=True)
|
|
152
|
deep_reload = CBool(False, config=True)
|
|
153
|
deep_reload = CBool(False, config=True)
|
|
153
|
displayhook_class = Type(DisplayHook)
|
|
154
|
displayhook_class = Type(DisplayHook)
|
|
154
|
filename = Str("<ipython console>")
|
|
155
|
filename = Str("<ipython console>")
|
|
155
|
ipython_dir= Unicode('', config=True) # Set to get_ipython_dir() in __init__
|
|
156
|
ipython_dir= Unicode('', config=True) # Set to get_ipython_dir() in __init__
|
|
156
|
logstart = CBool(False, config=True)
|
|
157
|
logstart = CBool(False, config=True)
|
|
157
|
logfile = Str('', config=True)
|
|
158
|
logfile = Str('', config=True)
|
|
158
|
logappend = Str('', config=True)
|
|
159
|
logappend = Str('', config=True)
|
|
159
|
object_info_string_level = Enum((0,1,2), default_value=0,
|
|
160
|
object_info_string_level = Enum((0,1,2), default_value=0,
|
|
160
|
config=True)
|
|
161
|
config=True)
|
|
161
|
pdb = CBool(False, config=True)
|
|
162
|
pdb = CBool(False, config=True)
|
|
162
|
pprint = CBool(True, config=True)
|
|
163
|
pprint = CBool(True, config=True)
|
|
163
|
profile = Str('', config=True)
|
|
164
|
profile = Str('', config=True)
|
|
164
|
prompt_in1 = Str('In [\\#]: ', config=True)
|
|
165
|
prompt_in1 = Str('In [\\#]: ', config=True)
|
|
165
|
prompt_in2 = Str(' .\\D.: ', config=True)
|
|
166
|
prompt_in2 = Str(' .\\D.: ', config=True)
|
|
166
|
prompt_out = Str('Out[\\#]: ', config=True)
|
|
167
|
prompt_out = Str('Out[\\#]: ', config=True)
|
|
167
|
prompts_pad_left = CBool(True, config=True)
|
|
168
|
prompts_pad_left = CBool(True, config=True)
|
|
168
|
quiet = CBool(False, config=True)
|
|
169
|
quiet = CBool(False, config=True)
|
|
169
|
|
|
170
|
|
|
170
|
# The readline stuff will eventually be moved to the terminal subclass
|
|
171
|
# The readline stuff will eventually be moved to the terminal subclass
|
|
171
|
# but for now, we can't do that as readline is welded in everywhere.
|
|
172
|
# but for now, we can't do that as readline is welded in everywhere.
|
|
172
|
readline_use = CBool(True, config=True)
|
|
173
|
readline_use = CBool(True, config=True)
|
|
173
|
readline_merge_completions = CBool(True, config=True)
|
|
174
|
readline_merge_completions = CBool(True, config=True)
|
|
174
|
readline_omit__names = Enum((0,1,2), default_value=0, config=True)
|
|
175
|
readline_omit__names = Enum((0,1,2), default_value=0, config=True)
|
|
175
|
readline_remove_delims = Str('-/~', config=True)
|
|
176
|
readline_remove_delims = Str('-/~', config=True)
|
|
176
|
readline_parse_and_bind = List([
|
|
177
|
readline_parse_and_bind = List([
|
|
177
|
'tab: complete',
|
|
178
|
'tab: complete',
|
|
178
|
'"\C-l": clear-screen',
|
|
179
|
'"\C-l": clear-screen',
|
|
179
|
'set show-all-if-ambiguous on',
|
|
180
|
'set show-all-if-ambiguous on',
|
|
180
|
'"\C-o": tab-insert',
|
|
181
|
'"\C-o": tab-insert',
|
|
181
|
'"\M-i": " "',
|
|
182
|
'"\M-i": " "',
|
|
182
|
'"\M-o": "\d\d\d\d"',
|
|
183
|
'"\M-o": "\d\d\d\d"',
|
|
183
|
'"\M-I": "\d\d\d\d"',
|
|
184
|
'"\M-I": "\d\d\d\d"',
|
|
184
|
'"\C-r": reverse-search-history',
|
|
185
|
'"\C-r": reverse-search-history',
|
|
185
|
'"\C-s": forward-search-history',
|
|
186
|
'"\C-s": forward-search-history',
|
|
186
|
'"\C-p": history-search-backward',
|
|
187
|
'"\C-p": history-search-backward',
|
|
187
|
'"\C-n": history-search-forward',
|
|
188
|
'"\C-n": history-search-forward',
|
|
188
|
'"\e[A": history-search-backward',
|
|
189
|
'"\e[A": history-search-backward',
|
|
189
|
'"\e[B": history-search-forward',
|
|
190
|
'"\e[B": history-search-forward',
|
|
190
|
'"\C-k": kill-line',
|
|
191
|
'"\C-k": kill-line',
|
|
191
|
'"\C-u": unix-line-discard',
|
|
192
|
'"\C-u": unix-line-discard',
|
|
192
|
], allow_none=False, config=True)
|
|
193
|
], allow_none=False, config=True)
|
|
193
|
|
|
194
|
|
|
194
|
# TODO: this part of prompt management should be moved to the frontends.
|
|
195
|
# TODO: this part of prompt management should be moved to the frontends.
|
|
195
|
# Use custom TraitTypes that convert '0'->'' and '\\n'->'\n'
|
|
196
|
# Use custom TraitTypes that convert '0'->'' and '\\n'->'\n'
|
|
196
|
separate_in = SeparateStr('\n', config=True)
|
|
197
|
separate_in = SeparateStr('\n', config=True)
|
|
197
|
separate_out = SeparateStr('\n', config=True)
|
|
198
|
separate_out = SeparateStr('\n', config=True)
|
|
198
|
separate_out2 = SeparateStr('\n', config=True)
|
|
199
|
separate_out2 = SeparateStr('\n', config=True)
|
|
199
|
system_header = Str('IPython system call: ', config=True)
|
|
200
|
system_header = Str('IPython system call: ', config=True)
|
|
200
|
system_verbose = CBool(False, config=True)
|
|
201
|
system_verbose = CBool(False, config=True)
|
|
201
|
wildcards_case_sensitive = CBool(True, config=True)
|
|
202
|
wildcards_case_sensitive = CBool(True, config=True)
|
|
202
|
xmode = CaselessStrEnum(('Context','Plain', 'Verbose'),
|
|
203
|
xmode = CaselessStrEnum(('Context','Plain', 'Verbose'),
|
|
203
|
default_value='Context', config=True)
|
|
204
|
default_value='Context', config=True)
|
|
204
|
|
|
205
|
|
|
205
|
# Subcomponents of InteractiveShell
|
|
206
|
# Subcomponents of InteractiveShell
|
|
206
|
alias_manager = Instance('IPython.core.alias.AliasManager')
|
|
207
|
alias_manager = Instance('IPython.core.alias.AliasManager')
|
|
207
|
prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager')
|
|
208
|
prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager')
|
|
208
|
builtin_trap = Instance('IPython.core.builtin_trap.BuiltinTrap')
|
|
209
|
builtin_trap = Instance('IPython.core.builtin_trap.BuiltinTrap')
|
|
209
|
display_trap = Instance('IPython.core.display_trap.DisplayTrap')
|
|
210
|
display_trap = Instance('IPython.core.display_trap.DisplayTrap')
|
|
210
|
extension_manager = Instance('IPython.core.extensions.ExtensionManager')
|
|
211
|
extension_manager = Instance('IPython.core.extensions.ExtensionManager')
|
|
211
|
plugin_manager = Instance('IPython.core.plugin.PluginManager')
|
|
212
|
plugin_manager = Instance('IPython.core.plugin.PluginManager')
|
|
212
|
payload_manager = Instance('IPython.core.paylaod.PayloadManager')
|
|
213
|
payload_manager = Instance('IPython.core.payload.PayloadManager')
|
|
213
|
|
|
214
|
|
|
214
|
def __init__(self, config=None, ipython_dir=None,
|
|
215
|
def __init__(self, config=None, ipython_dir=None,
|
|
215
|
user_ns=None, user_global_ns=None,
|
|
216
|
user_ns=None, user_global_ns=None,
|
|
216
|
custom_exceptions=((),None)):
|
|
217
|
custom_exceptions=((),None)):
|
|
217
|
|
|
218
|
|
|
218
|
# This is where traits with a config_key argument are updated
|
|
219
|
# This is where traits with a config_key argument are updated
|
|
219
|
# from the values on config.
|
|
220
|
# from the values on config.
|
|
220
|
super(InteractiveShell, self).__init__(config=config)
|
|
221
|
super(InteractiveShell, self).__init__(config=config)
|
|
221
|
|
|
222
|
|
|
222
|
# These are relatively independent and stateless
|
|
223
|
# These are relatively independent and stateless
|
|
223
|
self.init_ipython_dir(ipython_dir)
|
|
224
|
self.init_ipython_dir(ipython_dir)
|
|
224
|
self.init_instance_attrs()
|
|
225
|
self.init_instance_attrs()
|
|
225
|
|
|
226
|
|
|
226
|
# Create namespaces (user_ns, user_global_ns, etc.)
|
|
227
|
# Create namespaces (user_ns, user_global_ns, etc.)
|
|
227
|
self.init_create_namespaces(user_ns, user_global_ns)
|
|
228
|
self.init_create_namespaces(user_ns, user_global_ns)
|
|
228
|
# This has to be done after init_create_namespaces because it uses
|
|
229
|
# This has to be done after init_create_namespaces because it uses
|
|
229
|
# something in self.user_ns, but before init_sys_modules, which
|
|
230
|
# something in self.user_ns, but before init_sys_modules, which
|
|
230
|
# is the first thing to modify sys.
|
|
231
|
# is the first thing to modify sys.
|
|
231
|
# TODO: When we override sys.stdout and sys.stderr before this class
|
|
232
|
# TODO: When we override sys.stdout and sys.stderr before this class
|
|
232
|
# is created, we are saving the overridden ones here. Not sure if this
|
|
233
|
# is created, we are saving the overridden ones here. Not sure if this
|
|
233
|
# is what we want to do.
|
|
234
|
# is what we want to do.
|
|
234
|
self.save_sys_module_state()
|
|
235
|
self.save_sys_module_state()
|
|
235
|
self.init_sys_modules()
|
|
236
|
self.init_sys_modules()
|
|
236
|
|
|
237
|
|
|
237
|
self.init_history()
|
|
238
|
self.init_history()
|
|
238
|
self.init_encoding()
|
|
239
|
self.init_encoding()
|
|
239
|
self.init_prefilter()
|
|
240
|
self.init_prefilter()
|
|
240
|
|
|
241
|
|
|
241
|
Magic.__init__(self, self)
|
|
242
|
Magic.__init__(self, self)
|
|
242
|
|
|
243
|
|
|
243
|
self.init_syntax_highlighting()
|
|
244
|
self.init_syntax_highlighting()
|
|
244
|
self.init_hooks()
|
|
245
|
self.init_hooks()
|
|
245
|
self.init_pushd_popd_magic()
|
|
246
|
self.init_pushd_popd_magic()
|
|
246
|
# self.init_traceback_handlers use to be here, but we moved it below
|
|
247
|
# self.init_traceback_handlers use to be here, but we moved it below
|
|
247
|
# because it and init_io have to come after init_readline.
|
|
248
|
# because it and init_io have to come after init_readline.
|
|
248
|
self.init_user_ns()
|
|
249
|
self.init_user_ns()
|
|
249
|
self.init_logger()
|
|
250
|
self.init_logger()
|
|
250
|
self.init_alias()
|
|
251
|
self.init_alias()
|
|
251
|
self.init_builtins()
|
|
252
|
self.init_builtins()
|
|
252
|
|
|
253
|
|
|
253
|
# pre_config_initialization
|
|
254
|
# pre_config_initialization
|
|
254
|
self.init_shadow_hist()
|
|
255
|
self.init_shadow_hist()
|
|
255
|
|
|
256
|
|
|
256
|
# The next section should contain averything that was in ipmaker.
|
|
257
|
# The next section should contain averything that was in ipmaker.
|
|
257
|
self.init_logstart()
|
|
258
|
self.init_logstart()
|
|
258
|
|
|
259
|
|
|
259
|
# The following was in post_config_initialization
|
|
260
|
# The following was in post_config_initialization
|
|
260
|
self.init_inspector()
|
|
261
|
self.init_inspector()
|
|
261
|
# init_readline() must come before init_io(), because init_io uses
|
|
262
|
# init_readline() must come before init_io(), because init_io uses
|
|
262
|
# readline related things.
|
|
263
|
# readline related things.
|
|
263
|
self.init_readline()
|
|
264
|
self.init_readline()
|
|
264
|
# TODO: init_io() needs to happen before init_traceback handlers
|
|
265
|
# TODO: init_io() needs to happen before init_traceback handlers
|
|
265
|
# because the traceback handlers hardcode the stdout/stderr streams.
|
|
266
|
# because the traceback handlers hardcode the stdout/stderr streams.
|
|
266
|
# This logic in in debugger.Pdb and should eventually be changed.
|
|
267
|
# This logic in in debugger.Pdb and should eventually be changed.
|
|
267
|
self.init_io()
|
|
268
|
self.init_io()
|
|
268
|
self.init_traceback_handlers(custom_exceptions)
|
|
269
|
self.init_traceback_handlers(custom_exceptions)
|
|
269
|
self.init_prompts()
|
|
270
|
self.init_prompts()
|
|
270
|
self.init_displayhook()
|
|
271
|
self.init_displayhook()
|
|
271
|
self.init_reload_doctest()
|
|
272
|
self.init_reload_doctest()
|
|
272
|
self.init_magics()
|
|
273
|
self.init_magics()
|
|
273
|
self.init_pdb()
|
|
274
|
self.init_pdb()
|
|
274
|
self.init_extension_manager()
|
|
275
|
self.init_extension_manager()
|
|
275
|
self.init_plugin_manager()
|
|
276
|
self.init_plugin_manager()
|
|
276
|
self.init_payload()
|
|
277
|
self.init_payload()
|
|
277
|
self.hooks.late_startup_hook()
|
|
278
|
self.hooks.late_startup_hook()
|
|
278
|
|
|
279
|
|
|
279
|
@classmethod
|
|
280
|
@classmethod
|
|
280
|
def instance(cls, *args, **kwargs):
|
|
281
|
def instance(cls, *args, **kwargs):
|
|
281
|
"""Returns a global InteractiveShell instance."""
|
|
282
|
"""Returns a global InteractiveShell instance."""
|
|
282
|
if cls._instance is None:
|
|
283
|
if cls._instance is None:
|
|
283
|
inst = cls(*args, **kwargs)
|
|
284
|
inst = cls(*args, **kwargs)
|
|
284
|
# Now make sure that the instance will also be returned by
|
|
285
|
# Now make sure that the instance will also be returned by
|
|
285
|
# the subclasses instance attribute.
|
|
286
|
# the subclasses instance attribute.
|
|
286
|
for subclass in cls.mro():
|
|
287
|
for subclass in cls.mro():
|
|
287
|
if issubclass(cls, subclass) and issubclass(subclass, InteractiveShell):
|
|
288
|
if issubclass(cls, subclass) and issubclass(subclass, InteractiveShell):
|
|
288
|
subclass._instance = inst
|
|
289
|
subclass._instance = inst
|
|
289
|
else:
|
|
290
|
else:
|
|
290
|
break
|
|
291
|
break
|
|
291
|
if isinstance(cls._instance, cls):
|
|
292
|
if isinstance(cls._instance, cls):
|
|
292
|
return cls._instance
|
|
293
|
return cls._instance
|
|
293
|
else:
|
|
294
|
else:
|
|
294
|
raise MultipleInstanceError(
|
|
295
|
raise MultipleInstanceError(
|
|
295
|
'Multiple incompatible subclass instances of '
|
|
296
|
'Multiple incompatible subclass instances of '
|
|
296
|
'InteractiveShell are being created.'
|
|
297
|
'InteractiveShell are being created.'
|
|
297
|
)
|
|
298
|
)
|
|
298
|
|
|
299
|
|
|
299
|
@classmethod
|
|
300
|
@classmethod
|
|
300
|
def initialized(cls):
|
|
301
|
def initialized(cls):
|
|
301
|
return hasattr(cls, "_instance")
|
|
302
|
return hasattr(cls, "_instance")
|
|
302
|
|
|
303
|
|
|
303
|
def get_ipython(self):
|
|
304
|
def get_ipython(self):
|
|
304
|
"""Return the currently running IPython instance."""
|
|
305
|
"""Return the currently running IPython instance."""
|
|
305
|
return self
|
|
306
|
return self
|
|
306
|
|
|
307
|
|
|
307
|
#-------------------------------------------------------------------------
|
|
308
|
#-------------------------------------------------------------------------
|
|
308
|
# Trait changed handlers
|
|
309
|
# Trait changed handlers
|
|
309
|
#-------------------------------------------------------------------------
|
|
310
|
#-------------------------------------------------------------------------
|
|
310
|
|
|
311
|
|
|
311
|
def _ipython_dir_changed(self, name, new):
|
|
312
|
def _ipython_dir_changed(self, name, new):
|
|
312
|
if not os.path.isdir(new):
|
|
313
|
if not os.path.isdir(new):
|
|
313
|
os.makedirs(new, mode = 0777)
|
|
314
|
os.makedirs(new, mode = 0777)
|
|
314
|
|
|
315
|
|
|
315
|
def set_autoindent(self,value=None):
|
|
316
|
def set_autoindent(self,value=None):
|
|
316
|
"""Set the autoindent flag, checking for readline support.
|
|
317
|
"""Set the autoindent flag, checking for readline support.
|
|
317
|
|
|
318
|
|
|
318
|
If called with no arguments, it acts as a toggle."""
|
|
319
|
If called with no arguments, it acts as a toggle."""
|
|
319
|
|
|
320
|
|
|
320
|
if not self.has_readline:
|
|
321
|
if not self.has_readline:
|
|
321
|
if os.name == 'posix':
|
|
322
|
if os.name == 'posix':
|
|
322
|
warn("The auto-indent feature requires the readline library")
|
|
323
|
warn("The auto-indent feature requires the readline library")
|
|
323
|
self.autoindent = 0
|
|
324
|
self.autoindent = 0
|
|
324
|
return
|
|
325
|
return
|
|
325
|
if value is None:
|
|
326
|
if value is None:
|
|
326
|
self.autoindent = not self.autoindent
|
|
327
|
self.autoindent = not self.autoindent
|
|
327
|
else:
|
|
328
|
else:
|
|
328
|
self.autoindent = value
|
|
329
|
self.autoindent = value
|
|
329
|
|
|
330
|
|
|
330
|
#-------------------------------------------------------------------------
|
|
331
|
#-------------------------------------------------------------------------
|
|
331
|
# init_* methods called by __init__
|
|
332
|
# init_* methods called by __init__
|
|
332
|
#-------------------------------------------------------------------------
|
|
333
|
#-------------------------------------------------------------------------
|
|
333
|
|
|
334
|
|
|
334
|
def init_ipython_dir(self, ipython_dir):
|
|
335
|
def init_ipython_dir(self, ipython_dir):
|
|
335
|
if ipython_dir is not None:
|
|
336
|
if ipython_dir is not None:
|
|
336
|
self.ipython_dir = ipython_dir
|
|
337
|
self.ipython_dir = ipython_dir
|
|
337
|
self.config.Global.ipython_dir = self.ipython_dir
|
|
338
|
self.config.Global.ipython_dir = self.ipython_dir
|
|
338
|
return
|
|
339
|
return
|
|
339
|
|
|
340
|
|
|
340
|
if hasattr(self.config.Global, 'ipython_dir'):
|
|
341
|
if hasattr(self.config.Global, 'ipython_dir'):
|
|
341
|
self.ipython_dir = self.config.Global.ipython_dir
|
|
342
|
self.ipython_dir = self.config.Global.ipython_dir
|
|
342
|
else:
|
|
343
|
else:
|
|
343
|
self.ipython_dir = get_ipython_dir()
|
|
344
|
self.ipython_dir = get_ipython_dir()
|
|
344
|
|
|
345
|
|
|
345
|
# All children can just read this
|
|
346
|
# All children can just read this
|
|
346
|
self.config.Global.ipython_dir = self.ipython_dir
|
|
347
|
self.config.Global.ipython_dir = self.ipython_dir
|
|
347
|
|
|
348
|
|
|
348
|
def init_instance_attrs(self):
|
|
349
|
def init_instance_attrs(self):
|
|
349
|
self.more = False
|
|
350
|
self.more = False
|
|
350
|
|
|
351
|
|
|
351
|
# command compiler
|
|
352
|
# command compiler
|
|
352
|
self.compile = codeop.CommandCompiler()
|
|
353
|
self.compile = codeop.CommandCompiler()
|
|
353
|
|
|
354
|
|
|
354
|
# User input buffer
|
|
355
|
# User input buffer
|
|
355
|
self.buffer = []
|
|
356
|
self.buffer = []
|
|
356
|
|
|
357
|
|
|
357
|
# Make an empty namespace, which extension writers can rely on both
|
|
358
|
# Make an empty namespace, which extension writers can rely on both
|
|
358
|
# existing and NEVER being used by ipython itself. This gives them a
|
|
359
|
# existing and NEVER being used by ipython itself. This gives them a
|
|
359
|
# convenient location for storing additional information and state
|
|
360
|
# convenient location for storing additional information and state
|
|
360
|
# their extensions may require, without fear of collisions with other
|
|
361
|
# their extensions may require, without fear of collisions with other
|
|
361
|
# ipython names that may develop later.
|
|
362
|
# ipython names that may develop later.
|
|
362
|
self.meta = Struct()
|
|
363
|
self.meta = Struct()
|
|
363
|
|
|
364
|
|
|
364
|
# Object variable to store code object waiting execution. This is
|
|
365
|
# Object variable to store code object waiting execution. This is
|
|
365
|
# used mainly by the multithreaded shells, but it can come in handy in
|
|
366
|
# used mainly by the multithreaded shells, but it can come in handy in
|
|
366
|
# other situations. No need to use a Queue here, since it's a single
|
|
367
|
# other situations. No need to use a Queue here, since it's a single
|
|
367
|
# item which gets cleared once run.
|
|
368
|
# item which gets cleared once run.
|
|
368
|
self.code_to_run = None
|
|
369
|
self.code_to_run = None
|
|
369
|
|
|
370
|
|
|
370
|
# Temporary files used for various purposes. Deleted at exit.
|
|
371
|
# Temporary files used for various purposes. Deleted at exit.
|
|
371
|
self.tempfiles = []
|
|
372
|
self.tempfiles = []
|
|
372
|
|
|
373
|
|
|
373
|
# Keep track of readline usage (later set by init_readline)
|
|
374
|
# Keep track of readline usage (later set by init_readline)
|
|
374
|
self.has_readline = False
|
|
375
|
self.has_readline = False
|
|
375
|
|
|
376
|
|
|
376
|
# keep track of where we started running (mainly for crash post-mortem)
|
|
377
|
# keep track of where we started running (mainly for crash post-mortem)
|
|
377
|
# This is not being used anywhere currently.
|
|
378
|
# This is not being used anywhere currently.
|
|
378
|
self.starting_dir = os.getcwd()
|
|
379
|
self.starting_dir = os.getcwd()
|
|
379
|
|
|
380
|
|
|
380
|
# Indentation management
|
|
381
|
# Indentation management
|
|
381
|
self.indent_current_nsp = 0
|
|
382
|
self.indent_current_nsp = 0
|
|
382
|
|
|
383
|
|
|
383
|
def init_encoding(self):
|
|
384
|
def init_encoding(self):
|
|
384
|
# Get system encoding at startup time. Certain terminals (like Emacs
|
|
385
|
# Get system encoding at startup time. Certain terminals (like Emacs
|
|
385
|
# under Win32 have it set to None, and we need to have a known valid
|
|
386
|
# under Win32 have it set to None, and we need to have a known valid
|
|
386
|
# encoding to use in the raw_input() method
|
|
387
|
# encoding to use in the raw_input() method
|
|
387
|
try:
|
|
388
|
try:
|
|
388
|
self.stdin_encoding = sys.stdin.encoding or 'ascii'
|
|
389
|
self.stdin_encoding = sys.stdin.encoding or 'ascii'
|
|
389
|
except AttributeError:
|
|
390
|
except AttributeError:
|
|
390
|
self.stdin_encoding = 'ascii'
|
|
391
|
self.stdin_encoding = 'ascii'
|
|
391
|
|
|
392
|
|
|
392
|
def init_syntax_highlighting(self):
|
|
393
|
def init_syntax_highlighting(self):
|
|
393
|
# Python source parser/formatter for syntax highlighting
|
|
394
|
# Python source parser/formatter for syntax highlighting
|
|
394
|
pyformat = PyColorize.Parser().format
|
|
395
|
pyformat = PyColorize.Parser().format
|
|
395
|
self.pycolorize = lambda src: pyformat(src,'str',self.colors)
|
|
396
|
self.pycolorize = lambda src: pyformat(src,'str',self.colors)
|
|
396
|
|
|
397
|
|
|
397
|
def init_pushd_popd_magic(self):
|
|
398
|
def init_pushd_popd_magic(self):
|
|
398
|
# for pushd/popd management
|
|
399
|
# for pushd/popd management
|
|
399
|
try:
|
|
400
|
try:
|
|
400
|
self.home_dir = get_home_dir()
|
|
401
|
self.home_dir = get_home_dir()
|
|
401
|
except HomeDirError, msg:
|
|
402
|
except HomeDirError, msg:
|
|
402
|
fatal(msg)
|
|
403
|
fatal(msg)
|
|
403
|
|
|
404
|
|
|
404
|
self.dir_stack = []
|
|
405
|
self.dir_stack = []
|
|
405
|
|
|
406
|
|
|
406
|
def init_logger(self):
|
|
407
|
def init_logger(self):
|
|
407
|
self.logger = Logger(self, logfname='ipython_log.py', logmode='rotate')
|
|
408
|
self.logger = Logger(self, logfname='ipython_log.py', logmode='rotate')
|
|
408
|
# local shortcut, this is used a LOT
|
|
409
|
# local shortcut, this is used a LOT
|
|
409
|
self.log = self.logger.log
|
|
410
|
self.log = self.logger.log
|
|
410
|
|
|
411
|
|
|
411
|
def init_logstart(self):
|
|
412
|
def init_logstart(self):
|
|
412
|
if self.logappend:
|
|
413
|
if self.logappend:
|
|
413
|
self.magic_logstart(self.logappend + ' append')
|
|
414
|
self.magic_logstart(self.logappend + ' append')
|
|
414
|
elif self.logfile:
|
|
415
|
elif self.logfile:
|
|
415
|
self.magic_logstart(self.logfile)
|
|
416
|
self.magic_logstart(self.logfile)
|
|
416
|
elif self.logstart:
|
|
417
|
elif self.logstart:
|
|
417
|
self.magic_logstart()
|
|
418
|
self.magic_logstart()
|
|
418
|
|
|
419
|
|
|
419
|
def init_builtins(self):
|
|
420
|
def init_builtins(self):
|
|
420
|
self.builtin_trap = BuiltinTrap(shell=self)
|
|
421
|
self.builtin_trap = BuiltinTrap(shell=self)
|
|
421
|
|
|
422
|
|
|
422
|
def init_inspector(self):
|
|
423
|
def init_inspector(self):
|
|
423
|
# Object inspector
|
|
424
|
# Object inspector
|
|
424
|
self.inspector = oinspect.Inspector(oinspect.InspectColors,
|
|
425
|
self.inspector = oinspect.Inspector(oinspect.InspectColors,
|
|
425
|
PyColorize.ANSICodeColors,
|
|
426
|
PyColorize.ANSICodeColors,
|
|
426
|
'NoColor',
|
|
427
|
'NoColor',
|
|
427
|
self.object_info_string_level)
|
|
428
|
self.object_info_string_level)
|
|
428
|
|
|
429
|
|
|
429
|
def init_io(self):
|
|
430
|
def init_io(self):
|
|
430
|
import IPython.utils.io
|
|
431
|
import IPython.utils.io
|
|
431
|
if sys.platform == 'win32' and self.has_readline:
|
|
432
|
if sys.platform == 'win32' and self.has_readline:
|
|
432
|
Term = IPython.utils.io.IOTerm(
|
|
433
|
Term = IPython.utils.io.IOTerm(
|
|
433
|
cout=self.readline._outputfile,cerr=self.readline._outputfile
|
|
434
|
cout=self.readline._outputfile,cerr=self.readline._outputfile
|
|
434
|
)
|
|
435
|
)
|
|
435
|
else:
|
|
436
|
else:
|
|
436
|
Term = IPython.utils.io.IOTerm()
|
|
437
|
Term = IPython.utils.io.IOTerm()
|
|
437
|
IPython.utils.io.Term = Term
|
|
438
|
IPython.utils.io.Term = Term
|
|
438
|
|
|
439
|
|
|
439
|
def init_prompts(self):
|
|
440
|
def init_prompts(self):
|
|
440
|
# TODO: This is a pass for now because the prompts are managed inside
|
|
441
|
# TODO: This is a pass for now because the prompts are managed inside
|
|
441
|
# the DisplayHook. Once there is a separate prompt manager, this
|
|
442
|
# the DisplayHook. Once there is a separate prompt manager, this
|
|
442
|
# will initialize that object and all prompt related information.
|
|
443
|
# will initialize that object and all prompt related information.
|
|
443
|
pass
|
|
444
|
pass
|
|
444
|
|
|
445
|
|
|
445
|
def init_displayhook(self):
|
|
446
|
def init_displayhook(self):
|
|
446
|
# Initialize displayhook, set in/out prompts and printing system
|
|
447
|
# Initialize displayhook, set in/out prompts and printing system
|
|
447
|
self.displayhook = self.displayhook_class(
|
|
448
|
self.displayhook = self.displayhook_class(
|
|
448
|
shell=self,
|
|
449
|
shell=self,
|
|
449
|
cache_size=self.cache_size,
|
|
450
|
cache_size=self.cache_size,
|
|
450
|
input_sep = self.separate_in,
|
|
451
|
input_sep = self.separate_in,
|
|
451
|
output_sep = self.separate_out,
|
|
452
|
output_sep = self.separate_out,
|
|
452
|
output_sep2 = self.separate_out2,
|
|
453
|
output_sep2 = self.separate_out2,
|
|
453
|
ps1 = self.prompt_in1,
|
|
454
|
ps1 = self.prompt_in1,
|
|
454
|
ps2 = self.prompt_in2,
|
|
455
|
ps2 = self.prompt_in2,
|
|
455
|
ps_out = self.prompt_out,
|
|
456
|
ps_out = self.prompt_out,
|
|
456
|
pad_left = self.prompts_pad_left
|
|
457
|
pad_left = self.prompts_pad_left
|
|
457
|
)
|
|
458
|
)
|
|
458
|
# This is a context manager that installs/revmoes the displayhook at
|
|
459
|
# This is a context manager that installs/revmoes the displayhook at
|
|
459
|
# the appropriate time.
|
|
460
|
# the appropriate time.
|
|
460
|
self.display_trap = DisplayTrap(hook=self.displayhook)
|
|
461
|
self.display_trap = DisplayTrap(hook=self.displayhook)
|
|
461
|
|
|
462
|
|
|
462
|
def init_reload_doctest(self):
|
|
463
|
def init_reload_doctest(self):
|
|
463
|
# Do a proper resetting of doctest, including the necessary displayhook
|
|
464
|
# Do a proper resetting of doctest, including the necessary displayhook
|
|
464
|
# monkeypatching
|
|
465
|
# monkeypatching
|
|
465
|
try:
|
|
466
|
try:
|
|
466
|
doctest_reload()
|
|
467
|
doctest_reload()
|
|
467
|
except ImportError:
|
|
468
|
except ImportError:
|
|
468
|
warn("doctest module does not exist.")
|
|
469
|
warn("doctest module does not exist.")
|
|
469
|
|
|
470
|
|
|
470
|
#-------------------------------------------------------------------------
|
|
471
|
#-------------------------------------------------------------------------
|
|
471
|
# Things related to injections into the sys module
|
|
472
|
# Things related to injections into the sys module
|
|
472
|
#-------------------------------------------------------------------------
|
|
473
|
#-------------------------------------------------------------------------
|
|
473
|
|
|
474
|
|
|
474
|
def save_sys_module_state(self):
|
|
475
|
def save_sys_module_state(self):
|
|
475
|
"""Save the state of hooks in the sys module.
|
|
476
|
"""Save the state of hooks in the sys module.
|
|
476
|
|
|
477
|
|
|
477
|
This has to be called after self.user_ns is created.
|
|
478
|
This has to be called after self.user_ns is created.
|
|
478
|
"""
|
|
479
|
"""
|
|
479
|
self._orig_sys_module_state = {}
|
|
480
|
self._orig_sys_module_state = {}
|
|
480
|
self._orig_sys_module_state['stdin'] = sys.stdin
|
|
481
|
self._orig_sys_module_state['stdin'] = sys.stdin
|
|
481
|
self._orig_sys_module_state['stdout'] = sys.stdout
|
|
482
|
self._orig_sys_module_state['stdout'] = sys.stdout
|
|
482
|
self._orig_sys_module_state['stderr'] = sys.stderr
|
|
483
|
self._orig_sys_module_state['stderr'] = sys.stderr
|
|
483
|
self._orig_sys_module_state['excepthook'] = sys.excepthook
|
|
484
|
self._orig_sys_module_state['excepthook'] = sys.excepthook
|
|
484
|
try:
|
|
485
|
try:
|
|
485
|
self._orig_sys_modules_main_name = self.user_ns['__name__']
|
|
486
|
self._orig_sys_modules_main_name = self.user_ns['__name__']
|
|
486
|
except KeyError:
|
|
487
|
except KeyError:
|
|
487
|
pass
|
|
488
|
pass
|
|
488
|
|
|
489
|
|
|
489
|
def restore_sys_module_state(self):
|
|
490
|
def restore_sys_module_state(self):
|
|
490
|
"""Restore the state of the sys module."""
|
|
491
|
"""Restore the state of the sys module."""
|
|
491
|
try:
|
|
492
|
try:
|
|
492
|
for k, v in self._orig_sys_module_state.items():
|
|
493
|
for k, v in self._orig_sys_module_state.items():
|
|
493
|
setattr(sys, k, v)
|
|
494
|
setattr(sys, k, v)
|
|
494
|
except AttributeError:
|
|
495
|
except AttributeError:
|
|
495
|
pass
|
|
496
|
pass
|
|
496
|
try:
|
|
497
|
try:
|
|
497
|
delattr(sys, 'ipcompleter')
|
|
498
|
delattr(sys, 'ipcompleter')
|
|
498
|
except AttributeError:
|
|
499
|
except AttributeError:
|
|
499
|
pass
|
|
500
|
pass
|
|
500
|
# Reset what what done in self.init_sys_modules
|
|
501
|
# Reset what what done in self.init_sys_modules
|
|
501
|
try:
|
|
502
|
try:
|
|
502
|
sys.modules[self.user_ns['__name__']] = self._orig_sys_modules_main_name
|
|
503
|
sys.modules[self.user_ns['__name__']] = self._orig_sys_modules_main_name
|
|
503
|
except (AttributeError, KeyError):
|
|
504
|
except (AttributeError, KeyError):
|
|
504
|
pass
|
|
505
|
pass
|
|
505
|
|
|
506
|
|
|
506
|
#-------------------------------------------------------------------------
|
|
507
|
#-------------------------------------------------------------------------
|
|
507
|
# Things related to hooks
|
|
508
|
# Things related to hooks
|
|
508
|
#-------------------------------------------------------------------------
|
|
509
|
#-------------------------------------------------------------------------
|
|
509
|
|
|
510
|
|
|
510
|
def init_hooks(self):
|
|
511
|
def init_hooks(self):
|
|
511
|
# hooks holds pointers used for user-side customizations
|
|
512
|
# hooks holds pointers used for user-side customizations
|
|
512
|
self.hooks = Struct()
|
|
513
|
self.hooks = Struct()
|
|
513
|
|
|
514
|
|
|
514
|
self.strdispatchers = {}
|
|
515
|
self.strdispatchers = {}
|
|
515
|
|
|
516
|
|
|
516
|
# Set all default hooks, defined in the IPython.hooks module.
|
|
517
|
# Set all default hooks, defined in the IPython.hooks module.
|
|
517
|
hooks = IPython.core.hooks
|
|
518
|
hooks = IPython.core.hooks
|
|
518
|
for hook_name in hooks.__all__:
|
|
519
|
for hook_name in hooks.__all__:
|
|
519
|
# default hooks have priority 100, i.e. low; user hooks should have
|
|
520
|
# default hooks have priority 100, i.e. low; user hooks should have
|
|
520
|
# 0-100 priority
|
|
521
|
# 0-100 priority
|
|
521
|
self.set_hook(hook_name,getattr(hooks,hook_name), 100)
|
|
522
|
self.set_hook(hook_name,getattr(hooks,hook_name), 100)
|
|
522
|
|
|
523
|
|
|
523
|
def set_hook(self,name,hook, priority = 50, str_key = None, re_key = None):
|
|
524
|
def set_hook(self,name,hook, priority = 50, str_key = None, re_key = None):
|
|
524
|
"""set_hook(name,hook) -> sets an internal IPython hook.
|
|
525
|
"""set_hook(name,hook) -> sets an internal IPython hook.
|
|
525
|
|
|
526
|
|
|
526
|
IPython exposes some of its internal API as user-modifiable hooks. By
|
|
527
|
IPython exposes some of its internal API as user-modifiable hooks. By
|
|
527
|
adding your function to one of these hooks, you can modify IPython's
|
|
528
|
adding your function to one of these hooks, you can modify IPython's
|
|
528
|
behavior to call at runtime your own routines."""
|
|
529
|
behavior to call at runtime your own routines."""
|
|
529
|
|
|
530
|
|
|
530
|
# At some point in the future, this should validate the hook before it
|
|
531
|
# At some point in the future, this should validate the hook before it
|
|
531
|
# accepts it. Probably at least check that the hook takes the number
|
|
532
|
# accepts it. Probably at least check that the hook takes the number
|
|
532
|
# of args it's supposed to.
|
|
533
|
# of args it's supposed to.
|
|
533
|
|
|
534
|
|
|
534
|
f = new.instancemethod(hook,self,self.__class__)
|
|
535
|
f = new.instancemethod(hook,self,self.__class__)
|
|
535
|
|
|
536
|
|
|
536
|
# check if the hook is for strdispatcher first
|
|
537
|
# check if the hook is for strdispatcher first
|
|
537
|
if str_key is not None:
|
|
538
|
if str_key is not None:
|
|
538
|
sdp = self.strdispatchers.get(name, StrDispatch())
|
|
539
|
sdp = self.strdispatchers.get(name, StrDispatch())
|
|
539
|
sdp.add_s(str_key, f, priority )
|
|
540
|
sdp.add_s(str_key, f, priority )
|
|
540
|
self.strdispatchers[name] = sdp
|
|
541
|
self.strdispatchers[name] = sdp
|
|
541
|
return
|
|
542
|
return
|
|
542
|
if re_key is not None:
|
|
543
|
if re_key is not None:
|
|
543
|
sdp = self.strdispatchers.get(name, StrDispatch())
|
|
544
|
sdp = self.strdispatchers.get(name, StrDispatch())
|
|
544
|
sdp.add_re(re.compile(re_key), f, priority )
|
|
545
|
sdp.add_re(re.compile(re_key), f, priority )
|
|
545
|
self.strdispatchers[name] = sdp
|
|
546
|
self.strdispatchers[name] = sdp
|
|
546
|
return
|
|
547
|
return
|
|
547
|
|
|
548
|
|
|
548
|
dp = getattr(self.hooks, name, None)
|
|
549
|
dp = getattr(self.hooks, name, None)
|
|
549
|
if name not in IPython.core.hooks.__all__:
|
|
550
|
if name not in IPython.core.hooks.__all__:
|
|
550
|
print "Warning! Hook '%s' is not one of %s" % (name, IPython.core.hooks.__all__ )
|
|
551
|
print "Warning! Hook '%s' is not one of %s" % (name, IPython.core.hooks.__all__ )
|
|
551
|
if not dp:
|
|
552
|
if not dp:
|
|
552
|
dp = IPython.core.hooks.CommandChainDispatcher()
|
|
553
|
dp = IPython.core.hooks.CommandChainDispatcher()
|
|
553
|
|
|
554
|
|
|
554
|
try:
|
|
555
|
try:
|
|
555
|
dp.add(f,priority)
|
|
556
|
dp.add(f,priority)
|
|
556
|
except AttributeError:
|
|
557
|
except AttributeError:
|
|
557
|
# it was not commandchain, plain old func - replace
|
|
558
|
# it was not commandchain, plain old func - replace
|
|
558
|
dp = f
|
|
559
|
dp = f
|
|
559
|
|
|
560
|
|
|
560
|
setattr(self.hooks,name, dp)
|
|
561
|
setattr(self.hooks,name, dp)
|
|
561
|
|
|
562
|
|
|
562
|
#-------------------------------------------------------------------------
|
|
563
|
#-------------------------------------------------------------------------
|
|
563
|
# Things related to the "main" module
|
|
564
|
# Things related to the "main" module
|
|
564
|
#-------------------------------------------------------------------------
|
|
565
|
#-------------------------------------------------------------------------
|
|
565
|
|
|
566
|
|
|
566
|
def new_main_mod(self,ns=None):
|
|
567
|
def new_main_mod(self,ns=None):
|
|
567
|
"""Return a new 'main' module object for user code execution.
|
|
568
|
"""Return a new 'main' module object for user code execution.
|
|
568
|
"""
|
|
569
|
"""
|
|
569
|
main_mod = self._user_main_module
|
|
570
|
main_mod = self._user_main_module
|
|
570
|
init_fakemod_dict(main_mod,ns)
|
|
571
|
init_fakemod_dict(main_mod,ns)
|
|
571
|
return main_mod
|
|
572
|
return main_mod
|
|
572
|
|
|
573
|
|
|
573
|
def cache_main_mod(self,ns,fname):
|
|
574
|
def cache_main_mod(self,ns,fname):
|
|
574
|
"""Cache a main module's namespace.
|
|
575
|
"""Cache a main module's namespace.
|
|
575
|
|
|
576
|
|
|
576
|
When scripts are executed via %run, we must keep a reference to the
|
|
577
|
When scripts are executed via %run, we must keep a reference to the
|
|
577
|
namespace of their __main__ module (a FakeModule instance) around so
|
|
578
|
namespace of their __main__ module (a FakeModule instance) around so
|
|
578
|
that Python doesn't clear it, rendering objects defined therein
|
|
579
|
that Python doesn't clear it, rendering objects defined therein
|
|
579
|
useless.
|
|
580
|
useless.
|
|
580
|
|
|
581
|
|
|
581
|
This method keeps said reference in a private dict, keyed by the
|
|
582
|
This method keeps said reference in a private dict, keyed by the
|
|
582
|
absolute path of the module object (which corresponds to the script
|
|
583
|
absolute path of the module object (which corresponds to the script
|
|
583
|
path). This way, for multiple executions of the same script we only
|
|
584
|
path). This way, for multiple executions of the same script we only
|
|
584
|
keep one copy of the namespace (the last one), thus preventing memory
|
|
585
|
keep one copy of the namespace (the last one), thus preventing memory
|
|
585
|
leaks from old references while allowing the objects from the last
|
|
586
|
leaks from old references while allowing the objects from the last
|
|
586
|
execution to be accessible.
|
|
587
|
execution to be accessible.
|
|
587
|
|
|
588
|
|
|
588
|
Note: we can not allow the actual FakeModule instances to be deleted,
|
|
589
|
Note: we can not allow the actual FakeModule instances to be deleted,
|
|
589
|
because of how Python tears down modules (it hard-sets all their
|
|
590
|
because of how Python tears down modules (it hard-sets all their
|
|
590
|
references to None without regard for reference counts). This method
|
|
591
|
references to None without regard for reference counts). This method
|
|
591
|
must therefore make a *copy* of the given namespace, to allow the
|
|
592
|
must therefore make a *copy* of the given namespace, to allow the
|
|
592
|
original module's __dict__ to be cleared and reused.
|
|
593
|
original module's __dict__ to be cleared and reused.
|
|
593
|
|
|
594
|
|
|
594
|
|
|
595
|
|
|
595
|
Parameters
|
|
596
|
Parameters
|
|
596
|
----------
|
|
597
|
----------
|
|
597
|
ns : a namespace (a dict, typically)
|
|
598
|
ns : a namespace (a dict, typically)
|
|
598
|
|
|
599
|
|
|
599
|
fname : str
|
|
600
|
fname : str
|
|
600
|
Filename associated with the namespace.
|
|
601
|
Filename associated with the namespace.
|
|
601
|
|
|
602
|
|
|
602
|
Examples
|
|
603
|
Examples
|
|
603
|
--------
|
|
604
|
--------
|
|
604
|
|
|
605
|
|
|
605
|
In [10]: import IPython
|
|
606
|
In [10]: import IPython
|
|
606
|
|
|
607
|
|
|
607
|
In [11]: _ip.cache_main_mod(IPython.__dict__,IPython.__file__)
|
|
608
|
|