##// END OF EJS Templates
add startup_dir to profiles...
MinRK -
Show More
@@ -1,213 +1,223 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 An object for managing IPython profile directories.
3 An object for managing IPython profile directories.
4
4
5 Authors:
5 Authors:
6
6
7 * Brian Granger
7 * Brian Granger
8 * Fernando Perez
8 * Fernando Perez
9 * Min RK
9 * Min RK
10
10
11 """
11 """
12
12
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 # Copyright (C) 2008-2011 The IPython Development Team
14 # Copyright (C) 2008-2011 The IPython Development Team
15 #
15 #
16 # Distributed under the terms of the BSD License. The full license is in
16 # Distributed under the terms of the BSD License. The full license is in
17 # the file COPYING, distributed as part of this software.
17 # the file COPYING, distributed as part of this software.
18 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
19
19
20 #-----------------------------------------------------------------------------
20 #-----------------------------------------------------------------------------
21 # Imports
21 # Imports
22 #-----------------------------------------------------------------------------
22 #-----------------------------------------------------------------------------
23
23
24 import os
24 import os
25 import shutil
25 import shutil
26 import sys
26 import sys
27
27
28 from IPython.config.configurable import LoggingConfigurable
28 from IPython.config.configurable import LoggingConfigurable
29 from IPython.config.loader import Config
29 from IPython.config.loader import Config
30 from IPython.utils.path import get_ipython_package_dir, expand_path
30 from IPython.utils.path import get_ipython_package_dir, expand_path
31 from IPython.utils.traitlets import List, Unicode, Bool
31 from IPython.utils.traitlets import List, Unicode, Bool
32
32
33 #-----------------------------------------------------------------------------
33 #-----------------------------------------------------------------------------
34 # Classes and functions
34 # Classes and functions
35 #-----------------------------------------------------------------------------
35 #-----------------------------------------------------------------------------
36
36
37
37
38 #-----------------------------------------------------------------------------
38 #-----------------------------------------------------------------------------
39 # Module errors
39 # Module errors
40 #-----------------------------------------------------------------------------
40 #-----------------------------------------------------------------------------
41
41
42 class ProfileDirError(Exception):
42 class ProfileDirError(Exception):
43 pass
43 pass
44
44
45
45
46 #-----------------------------------------------------------------------------
46 #-----------------------------------------------------------------------------
47 # Class for managing profile directories
47 # Class for managing profile directories
48 #-----------------------------------------------------------------------------
48 #-----------------------------------------------------------------------------
49
49
50 class ProfileDir(LoggingConfigurable):
50 class ProfileDir(LoggingConfigurable):
51 """An object to manage the profile directory and its resources.
51 """An object to manage the profile directory and its resources.
52
52
53 The profile directory is used by all IPython applications, to manage
53 The profile directory is used by all IPython applications, to manage
54 configuration, logging and security.
54 configuration, logging and security.
55
55
56 This object knows how to find, create and manage these directories. This
56 This object knows how to find, create and manage these directories. This
57 should be used by any code that wants to handle profiles.
57 should be used by any code that wants to handle profiles.
58 """
58 """
59
59
60 security_dir_name = Unicode('security')
60 security_dir_name = Unicode('security')
61 log_dir_name = Unicode('log')
61 log_dir_name = Unicode('log')
62 startup_dir_name = Unicode('startup')
62 pid_dir_name = Unicode('pid')
63 pid_dir_name = Unicode('pid')
63 security_dir = Unicode(u'')
64 security_dir = Unicode(u'')
64 log_dir = Unicode(u'')
65 log_dir = Unicode(u'')
66 startup_dir = Unicode(u'')
65 pid_dir = Unicode(u'')
67 pid_dir = Unicode(u'')
66
68
67 location = Unicode(u'', config=True,
69 location = Unicode(u'', config=True,
68 help="""Set the profile location directly. This overrides the logic used by the
70 help="""Set the profile location directly. This overrides the logic used by the
69 `profile` option.""",
71 `profile` option.""",
70 )
72 )
71
73
72 _location_isset = Bool(False) # flag for detecting multiply set location
74 _location_isset = Bool(False) # flag for detecting multiply set location
73
75
74 def _location_changed(self, name, old, new):
76 def _location_changed(self, name, old, new):
75 if self._location_isset:
77 if self._location_isset:
76 raise RuntimeError("Cannot set profile location more than once.")
78 raise RuntimeError("Cannot set profile location more than once.")
77 self._location_isset = True
79 self._location_isset = True
78 if not os.path.isdir(new):
80 if not os.path.isdir(new):
79 os.makedirs(new)
81 os.makedirs(new)
80
82
81 # ensure config files exist:
83 # ensure config files exist:
82 self.security_dir = os.path.join(new, self.security_dir_name)
84 self.security_dir = os.path.join(new, self.security_dir_name)
83 self.log_dir = os.path.join(new, self.log_dir_name)
85 self.log_dir = os.path.join(new, self.log_dir_name)
86 self.startup_dir = os.path.join(new, self.startup_dir_name)
84 self.pid_dir = os.path.join(new, self.pid_dir_name)
87 self.pid_dir = os.path.join(new, self.pid_dir_name)
85 self.check_dirs()
88 self.check_dirs()
86
89
87 def _log_dir_changed(self, name, old, new):
90 def _log_dir_changed(self, name, old, new):
88 self.check_log_dir()
91 self.check_log_dir()
89
92
90 def check_log_dir(self):
93 def check_log_dir(self):
91 if not os.path.isdir(self.log_dir):
94 if not os.path.isdir(self.log_dir):
92 os.mkdir(self.log_dir)
95 os.mkdir(self.log_dir)
93
96
97 def _startup_dir_changed(self, name, old, new):
98 self.check_startup_dir()
99
100 def check_startup_dir(self):
101 if not os.path.isdir(self.startup_dir):
102 os.mkdir(self.startup_dir)
103
94 def _security_dir_changed(self, name, old, new):
104 def _security_dir_changed(self, name, old, new):
95 self.check_security_dir()
105 self.check_security_dir()
96
106
97 def check_security_dir(self):
107 def check_security_dir(self):
98 if not os.path.isdir(self.security_dir):
108 if not os.path.isdir(self.security_dir):
99 os.mkdir(self.security_dir, 0700)
109 os.mkdir(self.security_dir, 0700)
100 else:
110 else:
101 try:
111 try:
102 os.chmod(self.security_dir, 0700)
112 os.chmod(self.security_dir, 0700)
103 except OSError:
113 except OSError:
104 self.log.warn("Could not set security dir permissions to private.")
114 self.log.warn("Could not set security dir permissions to private.")
105
115
106 def _pid_dir_changed(self, name, old, new):
116 def _pid_dir_changed(self, name, old, new):
107 self.check_pid_dir()
117 self.check_pid_dir()
108
118
109 def check_pid_dir(self):
119 def check_pid_dir(self):
110 if not os.path.isdir(self.pid_dir):
120 if not os.path.isdir(self.pid_dir):
111 os.mkdir(self.pid_dir, 0700)
121 os.mkdir(self.pid_dir, 0700)
112 else:
122 else:
113 try:
123 try:
114 os.chmod(self.pid_dir, 0700)
124 os.chmod(self.pid_dir, 0700)
115 except OSError:
125 except OSError:
116 self.log.warn("Could not set pid dir permissions to private.")
126 self.log.warn("Could not set pid dir permissions to private.")
117
127
118 def check_dirs(self):
128 def check_dirs(self):
119 self.check_security_dir()
129 self.check_security_dir()
120 self.check_log_dir()
130 self.check_log_dir()
121 self.check_pid_dir()
131 self.check_pid_dir()
122
132
123 def copy_config_file(self, config_file, path=None, overwrite=False):
133 def copy_config_file(self, config_file, path=None, overwrite=False):
124 """Copy a default config file into the active profile directory.
134 """Copy a default config file into the active profile directory.
125
135
126 Default configuration files are kept in :mod:`IPython.config.default`.
136 Default configuration files are kept in :mod:`IPython.config.default`.
127 This function moves these from that location to the working profile
137 This function moves these from that location to the working profile
128 directory.
138 directory.
129 """
139 """
130 dst = os.path.join(self.location, config_file)
140 dst = os.path.join(self.location, config_file)
131 if os.path.isfile(dst) and not overwrite:
141 if os.path.isfile(dst) and not overwrite:
132 return False
142 return False
133 if path is None:
143 if path is None:
134 path = os.path.join(get_ipython_package_dir(), u'config', u'profile', u'default')
144 path = os.path.join(get_ipython_package_dir(), u'config', u'profile', u'default')
135 src = os.path.join(path, config_file)
145 src = os.path.join(path, config_file)
136 shutil.copy(src, dst)
146 shutil.copy(src, dst)
137 return True
147 return True
138
148
139 @classmethod
149 @classmethod
140 def create_profile_dir(cls, profile_dir, config=None):
150 def create_profile_dir(cls, profile_dir, config=None):
141 """Create a new profile directory given a full path.
151 """Create a new profile directory given a full path.
142
152
143 Parameters
153 Parameters
144 ----------
154 ----------
145 profile_dir : str
155 profile_dir : str
146 The full path to the profile directory. If it does exist, it will
156 The full path to the profile directory. If it does exist, it will
147 be used. If not, it will be created.
157 be used. If not, it will be created.
148 """
158 """
149 return cls(location=profile_dir, config=config)
159 return cls(location=profile_dir, config=config)
150
160
151 @classmethod
161 @classmethod
152 def create_profile_dir_by_name(cls, path, name=u'default', config=None):
162 def create_profile_dir_by_name(cls, path, name=u'default', config=None):
153 """Create a profile dir by profile name and path.
163 """Create a profile dir by profile name and path.
154
164
155 Parameters
165 Parameters
156 ----------
166 ----------
157 path : unicode
167 path : unicode
158 The path (directory) to put the profile directory in.
168 The path (directory) to put the profile directory in.
159 name : unicode
169 name : unicode
160 The name of the profile. The name of the profile directory will
170 The name of the profile. The name of the profile directory will
161 be "profile_<profile>".
171 be "profile_<profile>".
162 """
172 """
163 if not os.path.isdir(path):
173 if not os.path.isdir(path):
164 raise ProfileDirError('Directory not found: %s' % path)
174 raise ProfileDirError('Directory not found: %s' % path)
165 profile_dir = os.path.join(path, u'profile_' + name)
175 profile_dir = os.path.join(path, u'profile_' + name)
166 return cls(location=profile_dir, config=config)
176 return cls(location=profile_dir, config=config)
167
177
168 @classmethod
178 @classmethod
169 def find_profile_dir_by_name(cls, ipython_dir, name=u'default', config=None):
179 def find_profile_dir_by_name(cls, ipython_dir, name=u'default', config=None):
170 """Find an existing profile dir by profile name, return its ProfileDir.
180 """Find an existing profile dir by profile name, return its ProfileDir.
171
181
172 This searches through a sequence of paths for a profile dir. If it
182 This searches through a sequence of paths for a profile dir. If it
173 is not found, a :class:`ProfileDirError` exception will be raised.
183 is not found, a :class:`ProfileDirError` exception will be raised.
174
184
175 The search path algorithm is:
185 The search path algorithm is:
176 1. ``os.getcwdu()``
186 1. ``os.getcwdu()``
177 2. ``ipython_dir``
187 2. ``ipython_dir``
178
188
179 Parameters
189 Parameters
180 ----------
190 ----------
181 ipython_dir : unicode or str
191 ipython_dir : unicode or str
182 The IPython directory to use.
192 The IPython directory to use.
183 name : unicode or str
193 name : unicode or str
184 The name of the profile. The name of the profile directory
194 The name of the profile. The name of the profile directory
185 will be "profile_<profile>".
195 will be "profile_<profile>".
186 """
196 """
187 dirname = u'profile_' + name
197 dirname = u'profile_' + name
188 paths = [os.getcwdu(), ipython_dir]
198 paths = [os.getcwdu(), ipython_dir]
189 for p in paths:
199 for p in paths:
190 profile_dir = os.path.join(p, dirname)
200 profile_dir = os.path.join(p, dirname)
191 if os.path.isdir(profile_dir):
201 if os.path.isdir(profile_dir):
192 return cls(location=profile_dir, config=config)
202 return cls(location=profile_dir, config=config)
193 else:
203 else:
194 raise ProfileDirError('Profile directory not found in paths: %s' % dirname)
204 raise ProfileDirError('Profile directory not found in paths: %s' % dirname)
195
205
196 @classmethod
206 @classmethod
197 def find_profile_dir(cls, profile_dir, config=None):
207 def find_profile_dir(cls, profile_dir, config=None):
198 """Find/create a profile dir and return its ProfileDir.
208 """Find/create a profile dir and return its ProfileDir.
199
209
200 This will create the profile directory if it doesn't exist.
210 This will create the profile directory if it doesn't exist.
201
211
202 Parameters
212 Parameters
203 ----------
213 ----------
204 profile_dir : unicode or str
214 profile_dir : unicode or str
205 The path of the profile directory. This is expanded using
215 The path of the profile directory. This is expanded using
206 :func:`IPython.utils.genutils.expand_path`.
216 :func:`IPython.utils.genutils.expand_path`.
207 """
217 """
208 profile_dir = expand_path(profile_dir)
218 profile_dir = expand_path(profile_dir)
209 if not os.path.isdir(profile_dir):
219 if not os.path.isdir(profile_dir):
210 raise ProfileDirError('Profile directory not found: %s' % profile_dir)
220 raise ProfileDirError('Profile directory not found: %s' % profile_dir)
211 return cls(location=profile_dir, config=config)
221 return cls(location=profile_dir, config=config)
212
222
213
223
@@ -1,268 +1,286 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 A mixin for :class:`~IPython.core.application.Application` classes that
3 A mixin for :class:`~IPython.core.application.Application` classes that
4 launch InteractiveShell instances, load extensions, etc.
4 launch InteractiveShell instances, load extensions, etc.
5
5
6 Authors
6 Authors
7 -------
7 -------
8
8
9 * Min Ragan-Kelley
9 * Min Ragan-Kelley
10 """
10 """
11
11
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13 # Copyright (C) 2008-2011 The IPython Development Team
13 # Copyright (C) 2008-2011 The IPython Development Team
14 #
14 #
15 # 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
16 # the file COPYING, distributed as part of this software.
16 # the file COPYING, distributed as part of this software.
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18
18
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20 # Imports
20 # Imports
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22
22
23 from __future__ import absolute_import
23 from __future__ import absolute_import
24
24
25 import glob
25 import os
26 import os
26 import sys
27 import sys
27
28
28 from IPython.config.application import boolean_flag
29 from IPython.config.application import boolean_flag
29 from IPython.config.configurable import Configurable
30 from IPython.config.configurable import Configurable
30 from IPython.config.loader import Config
31 from IPython.config.loader import Config
31 from IPython.utils import py3compat
32 from IPython.utils import py3compat
32 from IPython.utils.path import filefind
33 from IPython.utils.path import filefind
33 from IPython.utils.traitlets import Unicode, Instance, List, Bool
34 from IPython.utils.traitlets import Unicode, Instance, List, Bool
34
35
35 #-----------------------------------------------------------------------------
36 #-----------------------------------------------------------------------------
36 # Aliases and Flags
37 # Aliases and Flags
37 #-----------------------------------------------------------------------------
38 #-----------------------------------------------------------------------------
38
39
39 shell_flags = {}
40 shell_flags = {}
40
41
41 addflag = lambda *args: shell_flags.update(boolean_flag(*args))
42 addflag = lambda *args: shell_flags.update(boolean_flag(*args))
42 addflag('autoindent', 'InteractiveShell.autoindent',
43 addflag('autoindent', 'InteractiveShell.autoindent',
43 'Turn on autoindenting.', 'Turn off autoindenting.'
44 'Turn on autoindenting.', 'Turn off autoindenting.'
44 )
45 )
45 addflag('automagic', 'InteractiveShell.automagic',
46 addflag('automagic', 'InteractiveShell.automagic',
46 """Turn on the auto calling of magic commands. Type %%magic at the
47 """Turn on the auto calling of magic commands. Type %%magic at the
47 IPython prompt for more information.""",
48 IPython prompt for more information.""",
48 'Turn off the auto calling of magic commands.'
49 'Turn off the auto calling of magic commands.'
49 )
50 )
50 addflag('pdb', 'InteractiveShell.pdb',
51 addflag('pdb', 'InteractiveShell.pdb',
51 "Enable auto calling the pdb debugger after every exception.",
52 "Enable auto calling the pdb debugger after every exception.",
52 "Disable auto calling the pdb debugger after every exception."
53 "Disable auto calling the pdb debugger after every exception."
53 )
54 )
54 # pydb flag doesn't do any config, as core.debugger switches on import,
55 # pydb flag doesn't do any config, as core.debugger switches on import,
55 # which is before parsing. This just allows the flag to be passed.
56 # which is before parsing. This just allows the flag to be passed.
56 shell_flags.update(dict(
57 shell_flags.update(dict(
57 pydb = ({},
58 pydb = ({},
58 """"Use the third party 'pydb' package as debugger, instead of pdb.
59 """"Use the third party 'pydb' package as debugger, instead of pdb.
59 Requires that pydb is installed."""
60 Requires that pydb is installed."""
60 )
61 )
61 ))
62 ))
62 addflag('pprint', 'PlainTextFormatter.pprint',
63 addflag('pprint', 'PlainTextFormatter.pprint',
63 "Enable auto pretty printing of results.",
64 "Enable auto pretty printing of results.",
64 "Disable auto auto pretty printing of results."
65 "Disable auto auto pretty printing of results."
65 )
66 )
66 addflag('color-info', 'InteractiveShell.color_info',
67 addflag('color-info', 'InteractiveShell.color_info',
67 """IPython can display information about objects via a set of func-
68 """IPython can display information about objects via a set of func-
68 tions, and optionally can use colors for this, syntax highlighting
69 tions, and optionally can use colors for this, syntax highlighting
69 source code and various other elements. However, because this
70 source code and various other elements. However, because this
70 information is passed through a pager (like 'less') and many pagers get
71 information is passed through a pager (like 'less') and many pagers get
71 confused with color codes, this option is off by default. You can test
72 confused with color codes, this option is off by default. You can test
72 it and turn it on permanently in your ipython_config.py file if it
73 it and turn it on permanently in your ipython_config.py file if it
73 works for you. Test it and turn it on permanently if it works with
74 works for you. Test it and turn it on permanently if it works with
74 your system. The magic function %%color_info allows you to toggle this
75 your system. The magic function %%color_info allows you to toggle this
75 interactively for testing.""",
76 interactively for testing.""",
76 "Disable using colors for info related things."
77 "Disable using colors for info related things."
77 )
78 )
78 addflag('deep-reload', 'InteractiveShell.deep_reload',
79 addflag('deep-reload', 'InteractiveShell.deep_reload',
79 """Enable deep (recursive) reloading by default. IPython can use the
80 """Enable deep (recursive) reloading by default. IPython can use the
80 deep_reload module which reloads changes in modules recursively (it
81 deep_reload module which reloads changes in modules recursively (it
81 replaces the reload() function, so you don't need to change anything to
82 replaces the reload() function, so you don't need to change anything to
82 use it). deep_reload() forces a full reload of modules whose code may
83 use it). deep_reload() forces a full reload of modules whose code may
83 have changed, which the default reload() function does not. When
84 have changed, which the default reload() function does not. When
84 deep_reload is off, IPython will use the normal reload(), but
85 deep_reload is off, IPython will use the normal reload(), but
85 deep_reload will still be available as dreload(). This feature is off
86 deep_reload will still be available as dreload(). This feature is off
86 by default [which means that you have both normal reload() and
87 by default [which means that you have both normal reload() and
87 dreload()].""",
88 dreload()].""",
88 "Disable deep (recursive) reloading by default."
89 "Disable deep (recursive) reloading by default."
89 )
90 )
90 nosep_config = Config()
91 nosep_config = Config()
91 nosep_config.InteractiveShell.separate_in = ''
92 nosep_config.InteractiveShell.separate_in = ''
92 nosep_config.InteractiveShell.separate_out = ''
93 nosep_config.InteractiveShell.separate_out = ''
93 nosep_config.InteractiveShell.separate_out2 = ''
94 nosep_config.InteractiveShell.separate_out2 = ''
94
95
95 shell_flags['nosep']=(nosep_config, "Eliminate all spacing between prompts.")
96 shell_flags['nosep']=(nosep_config, "Eliminate all spacing between prompts.")
96
97
97
98
98 # it's possible we don't want short aliases for *all* of these:
99 # it's possible we don't want short aliases for *all* of these:
99 shell_aliases = dict(
100 shell_aliases = dict(
100 autocall='InteractiveShell.autocall',
101 autocall='InteractiveShell.autocall',
101 colors='InteractiveShell.colors',
102 colors='InteractiveShell.colors',
102 logfile='InteractiveShell.logfile',
103 logfile='InteractiveShell.logfile',
103 logappend='InteractiveShell.logappend',
104 logappend='InteractiveShell.logappend',
104 c='InteractiveShellApp.code_to_run',
105 c='InteractiveShellApp.code_to_run',
105 ext='InteractiveShellApp.extra_extension',
106 ext='InteractiveShellApp.extra_extension',
106 )
107 )
107 shell_aliases['cache-size'] = 'InteractiveShell.cache_size'
108 shell_aliases['cache-size'] = 'InteractiveShell.cache_size'
108
109
109 #-----------------------------------------------------------------------------
110 #-----------------------------------------------------------------------------
110 # Main classes and functions
111 # Main classes and functions
111 #-----------------------------------------------------------------------------
112 #-----------------------------------------------------------------------------
112
113
113 class InteractiveShellApp(Configurable):
114 class InteractiveShellApp(Configurable):
114 """A Mixin for applications that start InteractiveShell instances.
115 """A Mixin for applications that start InteractiveShell instances.
115
116
116 Provides configurables for loading extensions and executing files
117 Provides configurables for loading extensions and executing files
117 as part of configuring a Shell environment.
118 as part of configuring a Shell environment.
118
119
119 Provides init_extensions() and init_code() methods, to be called
120 Provides init_extensions() and init_code() methods, to be called
120 after init_shell(), which must be implemented by subclasses.
121 after init_shell(), which must be implemented by subclasses.
121 """
122 """
122 extensions = List(Unicode, config=True,
123 extensions = List(Unicode, config=True,
123 help="A list of dotted module names of IPython extensions to load."
124 help="A list of dotted module names of IPython extensions to load."
124 )
125 )
125 extra_extension = Unicode('', config=True,
126 extra_extension = Unicode('', config=True,
126 help="dotted module name of an IPython extension to load."
127 help="dotted module name of an IPython extension to load."
127 )
128 )
128 def _extra_extension_changed(self, name, old, new):
129 def _extra_extension_changed(self, name, old, new):
129 if new:
130 if new:
130 # add to self.extensions
131 # add to self.extensions
131 self.extensions.append(new)
132 self.extensions.append(new)
132
133
133 exec_files = List(Unicode, config=True,
134 exec_files = List(Unicode, config=True,
134 help="""List of files to run at IPython startup."""
135 help="""List of files to run at IPython startup."""
135 )
136 )
136 file_to_run = Unicode('', config=True,
137 file_to_run = Unicode('', config=True,
137 help="""A file to be run""")
138 help="""A file to be run""")
138
139
139 exec_lines = List(Unicode, config=True,
140 exec_lines = List(Unicode, config=True,
140 help="""lines of code to run at IPython startup."""
141 help="""lines of code to run at IPython startup."""
141 )
142 )
142 code_to_run = Unicode('', config=True,
143 code_to_run = Unicode('', config=True,
143 help="Execute the given command string."
144 help="Execute the given command string."
144 )
145 )
145 pylab_import_all = Bool(True, config=True,
146 pylab_import_all = Bool(True, config=True,
146 help="""If true, an 'import *' is done from numpy and pylab,
147 help="""If true, an 'import *' is done from numpy and pylab,
147 when using pylab"""
148 when using pylab"""
148 )
149 )
149 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
150 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
150
151
151 def init_shell(self):
152 def init_shell(self):
152 raise NotImplementedError("Override in subclasses")
153 raise NotImplementedError("Override in subclasses")
153
154
154 def init_extensions(self):
155 def init_extensions(self):
155 """Load all IPython extensions in IPythonApp.extensions.
156 """Load all IPython extensions in IPythonApp.extensions.
156
157
157 This uses the :meth:`ExtensionManager.load_extensions` to load all
158 This uses the :meth:`ExtensionManager.load_extensions` to load all
158 the extensions listed in ``self.extensions``.
159 the extensions listed in ``self.extensions``.
159 """
160 """
160 if not self.extensions:
161 if not self.extensions:
161 return
162 return
162 try:
163 try:
163 self.log.debug("Loading IPython extensions...")
164 self.log.debug("Loading IPython extensions...")
164 extensions = self.extensions
165 extensions = self.extensions
165 for ext in extensions:
166 for ext in extensions:
166 try:
167 try:
167 self.log.info("Loading IPython extension: %s" % ext)
168 self.log.info("Loading IPython extension: %s" % ext)
168 self.shell.extension_manager.load_extension(ext)
169 self.shell.extension_manager.load_extension(ext)
169 except:
170 except:
170 self.log.warn("Error in loading extension: %s" % ext)
171 self.log.warn("Error in loading extension: %s" % ext)
171 self.shell.showtraceback()
172 self.shell.showtraceback()
172 except:
173 except:
173 self.log.warn("Unknown error in loading extensions:")
174 self.log.warn("Unknown error in loading extensions:")
174 self.shell.showtraceback()
175 self.shell.showtraceback()
175
176
176 def init_code(self):
177 def init_code(self):
177 """run the pre-flight code, specified via exec_lines"""
178 """run the pre-flight code, specified via exec_lines"""
179 self._run_startup_files()
178 self._run_exec_lines()
180 self._run_exec_lines()
179 self._run_exec_files()
181 self._run_exec_files()
180 self._run_cmd_line_code()
182 self._run_cmd_line_code()
181
183
182 def _run_exec_lines(self):
184 def _run_exec_lines(self):
183 """Run lines of code in IPythonApp.exec_lines in the user's namespace."""
185 """Run lines of code in IPythonApp.exec_lines in the user's namespace."""
184 if not self.exec_lines:
186 if not self.exec_lines:
185 return
187 return
186 try:
188 try:
187 self.log.debug("Running code from IPythonApp.exec_lines...")
189 self.log.debug("Running code from IPythonApp.exec_lines...")
188 for line in self.exec_lines:
190 for line in self.exec_lines:
189 try:
191 try:
190 self.log.info("Running code in user namespace: %s" %
192 self.log.info("Running code in user namespace: %s" %
191 line)
193 line)
192 self.shell.run_cell(line, store_history=False)
194 self.shell.run_cell(line, store_history=False)
193 except:
195 except:
194 self.log.warn("Error in executing line in user "
196 self.log.warn("Error in executing line in user "
195 "namespace: %s" % line)
197 "namespace: %s" % line)
196 self.shell.showtraceback()
198 self.shell.showtraceback()
197 except:
199 except:
198 self.log.warn("Unknown error in handling IPythonApp.exec_lines:")
200 self.log.warn("Unknown error in handling IPythonApp.exec_lines:")
199 self.shell.showtraceback()
201 self.shell.showtraceback()
200
202
201 def _exec_file(self, fname):
203 def _exec_file(self, fname):
202 try:
204 try:
203 full_filename = filefind(fname, [u'.', self.ipython_dir])
205 full_filename = filefind(fname, [u'.', self.ipython_dir])
204 except IOError as e:
206 except IOError as e:
205 self.log.warn("File not found: %r"%fname)
207 self.log.warn("File not found: %r"%fname)
206 return
208 return
207 # Make sure that the running script gets a proper sys.argv as if it
209 # Make sure that the running script gets a proper sys.argv as if it
208 # were run from a system shell.
210 # were run from a system shell.
209 save_argv = sys.argv
211 save_argv = sys.argv
210 sys.argv = [full_filename] + self.extra_args[1:]
212 sys.argv = [full_filename] + self.extra_args[1:]
211 # protect sys.argv from potential unicode strings on Python 2:
213 # protect sys.argv from potential unicode strings on Python 2:
212 if not py3compat.PY3:
214 if not py3compat.PY3:
213 sys.argv = [ py3compat.cast_bytes(a) for a in sys.argv ]
215 sys.argv = [ py3compat.cast_bytes(a) for a in sys.argv ]
214 try:
216 try:
215 if os.path.isfile(full_filename):
217 if os.path.isfile(full_filename):
216 if full_filename.endswith('.ipy'):
218 if full_filename.endswith('.ipy'):
217 self.log.info("Running file in user namespace: %s" %
219 self.log.info("Running file in user namespace: %s" %
218 full_filename)
220 full_filename)
219 self.shell.safe_execfile_ipy(full_filename)
221 self.shell.safe_execfile_ipy(full_filename)
220 else:
222 else:
221 # default to python, even without extension
223 # default to python, even without extension
222 self.log.info("Running file in user namespace: %s" %
224 self.log.info("Running file in user namespace: %s" %
223 full_filename)
225 full_filename)
224 # Ensure that __file__ is always defined to match Python behavior
226 # Ensure that __file__ is always defined to match Python behavior
225 self.shell.user_ns['__file__'] = fname
227 self.shell.user_ns['__file__'] = fname
226 try:
228 try:
227 self.shell.safe_execfile(full_filename, self.shell.user_ns)
229 self.shell.safe_execfile(full_filename, self.shell.user_ns)
228 finally:
230 finally:
229 del self.shell.user_ns['__file__']
231 del self.shell.user_ns['__file__']
230 finally:
232 finally:
231 sys.argv = save_argv
233 sys.argv = save_argv
232
234
235 def _run_startup_files(self):
236 """Run files from profile startup directory"""
237 startup_dir = self.profile_dir.startup_dir
238 startup_files = glob.glob(os.path.join(startup_dir, '*.py'))
239 startup_files += glob.glob(os.path.join(startup_dir, '*.ipy'))
240 if not startup_files:
241 return
242
243 self.log.debug("Running startup files from %s...", startup_dir)
244 try:
245 for fname in sorted(startup_files):
246 self._exec_file(fname)
247 except:
248 self.log.warn("Unknown error in handling startup files:")
249 self.shell.showtraceback()
250
233 def _run_exec_files(self):
251 def _run_exec_files(self):
234 """Run files from IPythonApp.exec_files"""
252 """Run files from IPythonApp.exec_files"""
235 if not self.exec_files:
253 if not self.exec_files:
236 return
254 return
237
255
238 self.log.debug("Running files in IPythonApp.exec_files...")
256 self.log.debug("Running files in IPythonApp.exec_files...")
239 try:
257 try:
240 for fname in self.exec_files:
258 for fname in self.exec_files:
241 self._exec_file(fname)
259 self._exec_file(fname)
242 except:
260 except:
243 self.log.warn("Unknown error in handling IPythonApp.exec_files:")
261 self.log.warn("Unknown error in handling IPythonApp.exec_files:")
244 self.shell.showtraceback()
262 self.shell.showtraceback()
245
263
246 def _run_cmd_line_code(self):
264 def _run_cmd_line_code(self):
247 """Run code or file specified at the command-line"""
265 """Run code or file specified at the command-line"""
248 if self.code_to_run:
266 if self.code_to_run:
249 line = self.code_to_run
267 line = self.code_to_run
250 try:
268 try:
251 self.log.info("Running code given at command line (c=): %s" %
269 self.log.info("Running code given at command line (c=): %s" %
252 line)
270 line)
253 self.shell.run_cell(line, store_history=False)
271 self.shell.run_cell(line, store_history=False)
254 except:
272 except:
255 self.log.warn("Error in executing line in user namespace: %s" %
273 self.log.warn("Error in executing line in user namespace: %s" %
256 line)
274 line)
257 self.shell.showtraceback()
275 self.shell.showtraceback()
258
276
259 # Like Python itself, ignore the second if the first of these is present
277 # Like Python itself, ignore the second if the first of these is present
260 elif self.file_to_run:
278 elif self.file_to_run:
261 fname = self.file_to_run
279 fname = self.file_to_run
262 try:
280 try:
263 self._exec_file(fname)
281 self._exec_file(fname)
264 except:
282 except:
265 self.log.warn("Error in executing file in user namespace: %s" %
283 self.log.warn("Error in executing file in user namespace: %s" %
266 fname)
284 fname)
267 self.shell.showtraceback()
285 self.shell.showtraceback()
268
286
General Comments 0
You need to be logged in to leave comments. Login now