##// END OF EJS Templates
Same in profileapp.py , profiledir.py, shellapp.py
Pierre Gerold -
Show More
@@ -1,311 +1,311 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 An application for managing IPython profiles.
3 An application for managing IPython profiles.
4
4
5 To be invoked as the `ipython profile` subcommand.
5 To be invoked as the `ipython profile` subcommand.
6
6
7 Authors:
7 Authors:
8
8
9 * Min RK
9 * Min RK
10
10
11 """
11 """
12 from __future__ import print_function
12 from __future__ import print_function
13
13
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15 # Copyright (C) 2008 The IPython Development Team
15 # Copyright (C) 2008 The IPython Development Team
16 #
16 #
17 # Distributed under the terms of the BSD License. The full license is in
17 # Distributed under the terms of the BSD License. The full license is in
18 # the file COPYING, distributed as part of this software.
18 # the file COPYING, distributed as part of this software.
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20
20
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22 # Imports
22 # Imports
23 #-----------------------------------------------------------------------------
23 #-----------------------------------------------------------------------------
24
24
25 import os
25 import os
26
26
27 from traitlets.config.application import Application
27 from traitlets.config.application import Application
28 from IPython.core.application import (
28 from IPython.core.application import (
29 BaseIPythonApplication, base_flags
29 BaseIPythonApplication, base_flags
30 )
30 )
31 from IPython.core.profiledir import ProfileDir
31 from IPython.core.profiledir import ProfileDir
32 from IPython.utils.importstring import import_item
32 from IPython.utils.importstring import import_item
33 from IPython.paths import get_ipython_dir, get_ipython_package_dir
33 from IPython.paths import get_ipython_dir, get_ipython_package_dir
34 from IPython.utils import py3compat
34 from IPython.utils import py3compat
35 from traitlets import Unicode, Bool, Dict
35 from traitlets import Unicode, Bool, Dict
36
36
37 #-----------------------------------------------------------------------------
37 #-----------------------------------------------------------------------------
38 # Constants
38 # Constants
39 #-----------------------------------------------------------------------------
39 #-----------------------------------------------------------------------------
40
40
41 create_help = """Create an IPython profile by name
41 create_help = """Create an IPython profile by name
42
42
43 Create an ipython profile directory by its name or
43 Create an ipython profile directory by its name or
44 profile directory path. Profile directories contain
44 profile directory path. Profile directories contain
45 configuration, log and security related files and are named
45 configuration, log and security related files and are named
46 using the convention 'profile_<name>'. By default they are
46 using the convention 'profile_<name>'. By default they are
47 located in your ipython directory. Once created, you will
47 located in your ipython directory. Once created, you will
48 can edit the configuration files in the profile
48 can edit the configuration files in the profile
49 directory to configure IPython. Most users will create a
49 directory to configure IPython. Most users will create a
50 profile directory by name,
50 profile directory by name,
51 `ipython profile create myprofile`, which will put the directory
51 `ipython profile create myprofile`, which will put the directory
52 in `<ipython_dir>/profile_myprofile`.
52 in `<ipython_dir>/profile_myprofile`.
53 """
53 """
54 list_help = """List available IPython profiles
54 list_help = """List available IPython profiles
55
55
56 List all available profiles, by profile location, that can
56 List all available profiles, by profile location, that can
57 be found in the current working directly or in the ipython
57 be found in the current working directly or in the ipython
58 directory. Profile directories are named using the convention
58 directory. Profile directories are named using the convention
59 'profile_<profile>'.
59 'profile_<profile>'.
60 """
60 """
61 profile_help = """Manage IPython profiles
61 profile_help = """Manage IPython profiles
62
62
63 Profile directories contain
63 Profile directories contain
64 configuration, log and security related files and are named
64 configuration, log and security related files and are named
65 using the convention 'profile_<name>'. By default they are
65 using the convention 'profile_<name>'. By default they are
66 located in your ipython directory. You can create profiles
66 located in your ipython directory. You can create profiles
67 with `ipython profile create <name>`, or see the profiles you
67 with `ipython profile create <name>`, or see the profiles you
68 already have with `ipython profile list`
68 already have with `ipython profile list`
69
69
70 To get started configuring IPython, simply do:
70 To get started configuring IPython, simply do:
71
71
72 $> ipython profile create
72 $> ipython profile create
73
73
74 and IPython will create the default profile in <ipython_dir>/profile_default,
74 and IPython will create the default profile in <ipython_dir>/profile_default,
75 where you can edit ipython_config.py to start configuring IPython.
75 where you can edit ipython_config.py to start configuring IPython.
76
76
77 """
77 """
78
78
79 _list_examples = "ipython profile list # list all profiles"
79 _list_examples = "ipython profile list # list all profiles"
80
80
81 _create_examples = """
81 _create_examples = """
82 ipython profile create foo # create profile foo w/ default config files
82 ipython profile create foo # create profile foo w/ default config files
83 ipython profile create foo --reset # restage default config files over current
83 ipython profile create foo --reset # restage default config files over current
84 ipython profile create foo --parallel # also stage parallel config files
84 ipython profile create foo --parallel # also stage parallel config files
85 """
85 """
86
86
87 _main_examples = """
87 _main_examples = """
88 ipython profile create -h # show the help string for the create subcommand
88 ipython profile create -h # show the help string for the create subcommand
89 ipython profile list -h # show the help string for the list subcommand
89 ipython profile list -h # show the help string for the list subcommand
90
90
91 ipython locate profile foo # print the path to the directory for profile 'foo'
91 ipython locate profile foo # print the path to the directory for profile 'foo'
92 """
92 """
93
93
94 #-----------------------------------------------------------------------------
94 #-----------------------------------------------------------------------------
95 # Profile Application Class (for `ipython profile` subcommand)
95 # Profile Application Class (for `ipython profile` subcommand)
96 #-----------------------------------------------------------------------------
96 #-----------------------------------------------------------------------------
97
97
98
98
99 def list_profiles_in(path):
99 def list_profiles_in(path):
100 """list profiles in a given root directory"""
100 """list profiles in a given root directory"""
101 files = os.listdir(path)
101 files = os.listdir(path)
102 profiles = []
102 profiles = []
103 for f in files:
103 for f in files:
104 try:
104 try:
105 full_path = os.path.join(path, f)
105 full_path = os.path.join(path, f)
106 except UnicodeError:
106 except UnicodeError:
107 continue
107 continue
108 if os.path.isdir(full_path) and f.startswith('profile_'):
108 if os.path.isdir(full_path) and f.startswith('profile_'):
109 profiles.append(f.split('_',1)[-1])
109 profiles.append(f.split('_',1)[-1])
110 return profiles
110 return profiles
111
111
112
112
113 def list_bundled_profiles():
113 def list_bundled_profiles():
114 """list profiles that are bundled with IPython."""
114 """list profiles that are bundled with IPython."""
115 path = os.path.join(get_ipython_package_dir(), u'core', u'profile')
115 path = os.path.join(get_ipython_package_dir(), u'core', u'profile')
116 files = os.listdir(path)
116 files = os.listdir(path)
117 profiles = []
117 profiles = []
118 for profile in files:
118 for profile in files:
119 full_path = os.path.join(path, profile)
119 full_path = os.path.join(path, profile)
120 if os.path.isdir(full_path) and profile != "__pycache__":
120 if os.path.isdir(full_path) and profile != "__pycache__":
121 profiles.append(profile)
121 profiles.append(profile)
122 return profiles
122 return profiles
123
123
124
124
125 class ProfileLocate(BaseIPythonApplication):
125 class ProfileLocate(BaseIPythonApplication):
126 description = """print the path to an IPython profile dir"""
126 description = """print the path to an IPython profile dir"""
127
127
128 def parse_command_line(self, argv=None):
128 def parse_command_line(self, argv=None):
129 super(ProfileLocate, self).parse_command_line(argv)
129 super(ProfileLocate, self).parse_command_line(argv)
130 if self.extra_args:
130 if self.extra_args:
131 self.profile = self.extra_args[0]
131 self.profile = self.extra_args[0]
132
132
133 def start(self):
133 def start(self):
134 print(self.profile_dir.location)
134 print(self.profile_dir.location)
135
135
136
136
137 class ProfileList(Application):
137 class ProfileList(Application):
138 name = u'ipython-profile'
138 name = u'ipython-profile'
139 description = list_help
139 description = list_help
140 examples = _list_examples
140 examples = _list_examples
141
141
142 aliases = Dict({
142 aliases = Dict({
143 'ipython-dir' : 'ProfileList.ipython_dir',
143 'ipython-dir' : 'ProfileList.ipython_dir',
144 'log-level' : 'Application.log_level',
144 'log-level' : 'Application.log_level',
145 })
145 })
146 flags = Dict(dict(
146 flags = Dict(dict(
147 debug = ({'Application' : {'log_level' : 0}},
147 debug = ({'Application' : {'log_level' : 0}},
148 "Set Application.log_level to 0, maximizing log output."
148 "Set Application.log_level to 0, maximizing log output."
149 )
149 )
150 ))
150 ))
151
151
152 ipython_dir = Unicode(get_ipython_dir(), config=True,
152 ipython_dir = Unicode(get_ipython_dir(), config=True,
153 help="""
153 help="""
154 The name of the IPython directory. This directory is used for logging
154 The name of the IPython directory. This directory is used for logging
155 configuration (through profiles), history storage, etc. The default
155 configuration (through profiles), history storage, etc. The default
156 is usually $HOME/.ipython. This options can also be specified through
156 is usually $HOME/.ipython. This options can also be specified through
157 the environment variable IPYTHONDIR.
157 the environment variable IPYTHONDIR.
158 """
158 """
159 )
159 )
160
160
161
161
162 def _print_profiles(self, profiles):
162 def _print_profiles(self, profiles):
163 """print list of profiles, indented."""
163 """print list of profiles, indented."""
164 for profile in profiles:
164 for profile in profiles:
165 print(' %s' % profile)
165 print(' %s' % profile)
166
166
167 def list_profile_dirs(self):
167 def list_profile_dirs(self):
168 profiles = list_bundled_profiles()
168 profiles = list_bundled_profiles()
169 if profiles:
169 if profiles:
170 print()
170 print()
171 print("Available profiles in IPython:")
171 print("Available profiles in IPython:")
172 self._print_profiles(profiles)
172 self._print_profiles(profiles)
173 print()
173 print()
174 print(" The first request for a bundled profile will copy it")
174 print(" The first request for a bundled profile will copy it")
175 print(" into your IPython directory (%s)," % self.ipython_dir)
175 print(" into your IPython directory (%s)," % self.ipython_dir)
176 print(" where you can customize it.")
176 print(" where you can customize it.")
177
177
178 profiles = list_profiles_in(self.ipython_dir)
178 profiles = list_profiles_in(self.ipython_dir)
179 if profiles:
179 if profiles:
180 print()
180 print()
181 print("Available profiles in %s:" % self.ipython_dir)
181 print("Available profiles in %s:" % self.ipython_dir)
182 self._print_profiles(profiles)
182 self._print_profiles(profiles)
183
183
184 profiles = list_profiles_in(py3compat.getcwd())
184 profiles = list_profiles_in(py3compat.getcwd())
185 if profiles:
185 if profiles:
186 print()
186 print()
187 print("Available profiles in current directory (%s):" % py3compat.getcwd())
187 print("Available profiles in current directory (%s):" % py3compat.getcwd())
188 self._print_profiles(profiles)
188 self._print_profiles(profiles)
189
189
190 print()
190 print()
191 print("To use any of the above profiles, start IPython with:")
191 print("To use any of the above profiles, start IPython with:")
192 print(" ipython --profile=<name>")
192 print(" ipython --profile=<name>")
193 print()
193 print()
194
194
195 def start(self):
195 def start(self):
196 self.list_profile_dirs()
196 self.list_profile_dirs()
197
197
198
198
199 create_flags = {}
199 create_flags = {}
200 create_flags.update(base_flags)
200 create_flags.update(base_flags)
201 # don't include '--init' flag, which implies running profile create in other apps
201 # don't include '--init' flag, which implies running profile create in other apps
202 create_flags.pop('init')
202 create_flags.pop('init')
203 create_flags['reset'] = ({'ProfileCreate': {'overwrite' : True}},
203 create_flags['reset'] = ({'ProfileCreate': {'overwrite' : True}},
204 "reset config files in this profile to the defaults.")
204 "reset config files in this profile to the defaults.")
205 create_flags['parallel'] = ({'ProfileCreate': {'parallel' : True}},
205 create_flags['parallel'] = ({'ProfileCreate': {'parallel' : True}},
206 "Include the config files for parallel "
206 "Include the config files for parallel "
207 "computing apps (ipengine, ipcontroller, etc.)")
207 "computing apps (ipengine, ipcontroller, etc.)")
208
208
209
209
210 class ProfileCreate(BaseIPythonApplication):
210 class ProfileCreate(BaseIPythonApplication):
211 name = u'ipython-profile'
211 name = u'ipython-profile'
212 description = create_help
212 description = create_help
213 examples = _create_examples
213 examples = _create_examples
214 auto_create = Bool(True, config=False)
214 auto_create = Bool(True, config=False)
215 def _log_format_default(self):
215 def _log_format_default(self):
216 return "[%(name)s] %(message)s"
216 return "[%(name)s] %(message)s"
217
217
218 def _copy_config_files_default(self):
218 def _copy_config_files_default(self):
219 return True
219 return True
220
220
221 parallel = Bool(False, config=True,
221 parallel = Bool(False, config=True,
222 help="whether to include parallel computing config files")
222 help="whether to include parallel computing config files")
223 def _parallel_changed(self, name, old, new):
223 def _parallel_changed(self, name, old, new):
224 parallel_files = [ 'ipcontroller_config.py',
224 parallel_files = [ 'ipcontroller_config.py',
225 'ipengine_config.py',
225 'ipengine_config.py',
226 'ipcluster_config.py'
226 'ipcluster_config.py'
227 ]
227 ]
228 if new:
228 if new:
229 for cf in parallel_files:
229 for cf in parallel_files:
230 self.config_files.append(cf)
230 self.config_files.append(cf)
231 else:
231 else:
232 for cf in parallel_files:
232 for cf in parallel_files:
233 if cf in self.config_files:
233 if cf in self.config_files:
234 self.config_files.remove(cf)
234 self.config_files.remove(cf)
235
235
236 def parse_command_line(self, argv):
236 def parse_command_line(self, argv):
237 super(ProfileCreate, self).parse_command_line(argv)
237 super(ProfileCreate, self).parse_command_line(argv)
238 # accept positional arg as profile name
238 # accept positional arg as profile name
239 if self.extra_args:
239 if self.extra_args:
240 self.profile = self.extra_args[0]
240 self.profile = self.extra_args[0]
241
241
242 flags = Dict(create_flags)
242 flags = Dict(create_flags)
243
243
244 classes = [ProfileDir]
244 classes = [ProfileDir]
245
245
246 def _import_app(self, app_path):
246 def _import_app(self, app_path):
247 """import an app class"""
247 """import an app class"""
248 app = None
248 app = None
249 name = app_path.rsplit('.', 1)[-1]
249 name = app_path.rsplit('.', 1)[-1]
250 try:
250 try:
251 app = import_item(app_path)
251 app = import_item(app_path)
252 except ImportError:
252 except ImportError:
253 self.log.info("Couldn't import %s, config file will be excluded", name)
253 self.log.info("Couldn't import %s, config file will be excluded", name)
254 except Exception:
254 except Exception:
255 self.log.warn('Unexpected error importing %s', name, exc_info=True)
255 self.log.warning('Unexpected error importing %s', name, exc_info=True)
256 return app
256 return app
257
257
258 def init_config_files(self):
258 def init_config_files(self):
259 super(ProfileCreate, self).init_config_files()
259 super(ProfileCreate, self).init_config_files()
260 # use local imports, since these classes may import from here
260 # use local imports, since these classes may import from here
261 from IPython.terminal.ipapp import TerminalIPythonApp
261 from IPython.terminal.ipapp import TerminalIPythonApp
262 apps = [TerminalIPythonApp]
262 apps = [TerminalIPythonApp]
263 for app_path in (
263 for app_path in (
264 'ipykernel.kernelapp.IPKernelApp',
264 'ipykernel.kernelapp.IPKernelApp',
265 ):
265 ):
266 app = self._import_app(app_path)
266 app = self._import_app(app_path)
267 if app is not None:
267 if app is not None:
268 apps.append(app)
268 apps.append(app)
269 if self.parallel:
269 if self.parallel:
270 from ipyparallel.apps.ipcontrollerapp import IPControllerApp
270 from ipyparallel.apps.ipcontrollerapp import IPControllerApp
271 from ipyparallel.apps.ipengineapp import IPEngineApp
271 from ipyparallel.apps.ipengineapp import IPEngineApp
272 from ipyparallel.apps.ipclusterapp import IPClusterStart
272 from ipyparallel.apps.ipclusterapp import IPClusterStart
273 apps.extend([
273 apps.extend([
274 IPControllerApp,
274 IPControllerApp,
275 IPEngineApp,
275 IPEngineApp,
276 IPClusterStart,
276 IPClusterStart,
277 ])
277 ])
278 for App in apps:
278 for App in apps:
279 app = App()
279 app = App()
280 app.config.update(self.config)
280 app.config.update(self.config)
281 app.log = self.log
281 app.log = self.log
282 app.overwrite = self.overwrite
282 app.overwrite = self.overwrite
283 app.copy_config_files=True
283 app.copy_config_files=True
284 app.ipython_dir=self.ipython_dir
284 app.ipython_dir=self.ipython_dir
285 app.profile_dir=self.profile_dir
285 app.profile_dir=self.profile_dir
286 app.init_config_files()
286 app.init_config_files()
287
287
288 def stage_default_config_file(self):
288 def stage_default_config_file(self):
289 pass
289 pass
290
290
291
291
292 class ProfileApp(Application):
292 class ProfileApp(Application):
293 name = u'ipython profile'
293 name = u'ipython profile'
294 description = profile_help
294 description = profile_help
295 examples = _main_examples
295 examples = _main_examples
296
296
297 subcommands = Dict(dict(
297 subcommands = Dict(dict(
298 create = (ProfileCreate, ProfileCreate.description.splitlines()[0]),
298 create = (ProfileCreate, ProfileCreate.description.splitlines()[0]),
299 list = (ProfileList, ProfileList.description.splitlines()[0]),
299 list = (ProfileList, ProfileList.description.splitlines()[0]),
300 locate = (ProfileLocate, ProfileLocate.description.splitlines()[0]),
300 locate = (ProfileLocate, ProfileLocate.description.splitlines()[0]),
301 ))
301 ))
302
302
303 def start(self):
303 def start(self):
304 if self.subapp is None:
304 if self.subapp is None:
305 print("No subcommand specified. Must specify one of: %s"%(self.subcommands.keys()))
305 print("No subcommand specified. Must specify one of: %s"%(self.subcommands.keys()))
306 print()
306 print()
307 self.print_description()
307 self.print_description()
308 self.print_subcommands()
308 self.print_subcommands()
309 self.exit(1)
309 self.exit(1)
310 else:
310 else:
311 return self.subapp.start()
311 return self.subapp.start()
@@ -1,234 +1,234 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """An object for managing IPython profile directories."""
2 """An object for managing IPython profile directories."""
3
3
4 # Copyright (c) IPython Development Team.
4 # Copyright (c) IPython Development Team.
5 # Distributed under the terms of the Modified BSD License.
5 # Distributed under the terms of the Modified BSD License.
6
6
7 import os
7 import os
8 import shutil
8 import shutil
9 import errno
9 import errno
10
10
11 from traitlets.config.configurable import LoggingConfigurable
11 from traitlets.config.configurable import LoggingConfigurable
12 from IPython.paths import get_ipython_package_dir
12 from IPython.paths import get_ipython_package_dir
13 from IPython.utils.path import expand_path, ensure_dir_exists
13 from IPython.utils.path import expand_path, ensure_dir_exists
14 from IPython.utils import py3compat
14 from IPython.utils import py3compat
15 from traitlets import Unicode, Bool
15 from traitlets import Unicode, Bool
16
16
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18 # Module errors
18 # Module errors
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20
20
21 class ProfileDirError(Exception):
21 class ProfileDirError(Exception):
22 pass
22 pass
23
23
24
24
25 #-----------------------------------------------------------------------------
25 #-----------------------------------------------------------------------------
26 # Class for managing profile directories
26 # Class for managing profile directories
27 #-----------------------------------------------------------------------------
27 #-----------------------------------------------------------------------------
28
28
29 class ProfileDir(LoggingConfigurable):
29 class ProfileDir(LoggingConfigurable):
30 """An object to manage the profile directory and its resources.
30 """An object to manage the profile directory and its resources.
31
31
32 The profile directory is used by all IPython applications, to manage
32 The profile directory is used by all IPython applications, to manage
33 configuration, logging and security.
33 configuration, logging and security.
34
34
35 This object knows how to find, create and manage these directories. This
35 This object knows how to find, create and manage these directories. This
36 should be used by any code that wants to handle profiles.
36 should be used by any code that wants to handle profiles.
37 """
37 """
38
38
39 security_dir_name = Unicode('security')
39 security_dir_name = Unicode('security')
40 log_dir_name = Unicode('log')
40 log_dir_name = Unicode('log')
41 startup_dir_name = Unicode('startup')
41 startup_dir_name = Unicode('startup')
42 pid_dir_name = Unicode('pid')
42 pid_dir_name = Unicode('pid')
43 static_dir_name = Unicode('static')
43 static_dir_name = Unicode('static')
44 security_dir = Unicode(u'')
44 security_dir = Unicode(u'')
45 log_dir = Unicode(u'')
45 log_dir = Unicode(u'')
46 startup_dir = Unicode(u'')
46 startup_dir = Unicode(u'')
47 pid_dir = Unicode(u'')
47 pid_dir = Unicode(u'')
48 static_dir = Unicode(u'')
48 static_dir = Unicode(u'')
49
49
50 location = Unicode(u'', config=True,
50 location = Unicode(u'', config=True,
51 help="""Set the profile location directly. This overrides the logic used by the
51 help="""Set the profile location directly. This overrides the logic used by the
52 `profile` option.""",
52 `profile` option.""",
53 )
53 )
54
54
55 _location_isset = Bool(False) # flag for detecting multiply set location
55 _location_isset = Bool(False) # flag for detecting multiply set location
56
56
57 def _location_changed(self, name, old, new):
57 def _location_changed(self, name, old, new):
58 if self._location_isset:
58 if self._location_isset:
59 raise RuntimeError("Cannot set profile location more than once.")
59 raise RuntimeError("Cannot set profile location more than once.")
60 self._location_isset = True
60 self._location_isset = True
61 ensure_dir_exists(new)
61 ensure_dir_exists(new)
62
62
63 # ensure config files exist:
63 # ensure config files exist:
64 self.security_dir = os.path.join(new, self.security_dir_name)
64 self.security_dir = os.path.join(new, self.security_dir_name)
65 self.log_dir = os.path.join(new, self.log_dir_name)
65 self.log_dir = os.path.join(new, self.log_dir_name)
66 self.startup_dir = os.path.join(new, self.startup_dir_name)
66 self.startup_dir = os.path.join(new, self.startup_dir_name)
67 self.pid_dir = os.path.join(new, self.pid_dir_name)
67 self.pid_dir = os.path.join(new, self.pid_dir_name)
68 self.static_dir = os.path.join(new, self.static_dir_name)
68 self.static_dir = os.path.join(new, self.static_dir_name)
69 self.check_dirs()
69 self.check_dirs()
70
70
71 def _log_dir_changed(self, name, old, new):
71 def _log_dir_changed(self, name, old, new):
72 self.check_log_dir()
72 self.check_log_dir()
73
73
74 def _mkdir(self, path, mode=None):
74 def _mkdir(self, path, mode=None):
75 """ensure a directory exists at a given path
75 """ensure a directory exists at a given path
76
76
77 This is a version of os.mkdir, with the following differences:
77 This is a version of os.mkdir, with the following differences:
78
78
79 - returns True if it created the directory, False otherwise
79 - returns True if it created the directory, False otherwise
80 - ignores EEXIST, protecting against race conditions where
80 - ignores EEXIST, protecting against race conditions where
81 the dir may have been created in between the check and
81 the dir may have been created in between the check and
82 the creation
82 the creation
83 - sets permissions if requested and the dir already exists
83 - sets permissions if requested and the dir already exists
84 """
84 """
85 if os.path.exists(path):
85 if os.path.exists(path):
86 if mode and os.stat(path).st_mode != mode:
86 if mode and os.stat(path).st_mode != mode:
87 try:
87 try:
88 os.chmod(path, mode)
88 os.chmod(path, mode)
89 except OSError:
89 except OSError:
90 self.log.warn(
90 self.log.warning(
91 "Could not set permissions on %s",
91 "Could not set permissions on %s",
92 path
92 path
93 )
93 )
94 return False
94 return False
95 try:
95 try:
96 if mode:
96 if mode:
97 os.mkdir(path, mode)
97 os.mkdir(path, mode)
98 else:
98 else:
99 os.mkdir(path)
99 os.mkdir(path)
100 except OSError as e:
100 except OSError as e:
101 if e.errno == errno.EEXIST:
101 if e.errno == errno.EEXIST:
102 return False
102 return False
103 else:
103 else:
104 raise
104 raise
105
105
106 return True
106 return True
107
107
108 def check_log_dir(self):
108 def check_log_dir(self):
109 self._mkdir(self.log_dir)
109 self._mkdir(self.log_dir)
110
110
111 def _startup_dir_changed(self, name, old, new):
111 def _startup_dir_changed(self, name, old, new):
112 self.check_startup_dir()
112 self.check_startup_dir()
113
113
114 def check_startup_dir(self):
114 def check_startup_dir(self):
115 self._mkdir(self.startup_dir)
115 self._mkdir(self.startup_dir)
116
116
117 readme = os.path.join(self.startup_dir, 'README')
117 readme = os.path.join(self.startup_dir, 'README')
118 src = os.path.join(get_ipython_package_dir(), u'core', u'profile', u'README_STARTUP')
118 src = os.path.join(get_ipython_package_dir(), u'core', u'profile', u'README_STARTUP')
119
119
120 if not os.path.exists(src):
120 if not os.path.exists(src):
121 self.log.warn("Could not copy README_STARTUP to startup dir. Source file %s does not exist.", src)
121 self.log.warn("Could not copy README_STARTUP to startup dir. Source file %s does not exist.", src)
122
122
123 if os.path.exists(src) and not os.path.exists(readme):
123 if os.path.exists(src) and not os.path.exists(readme):
124 shutil.copy(src, readme)
124 shutil.copy(src, readme)
125
125
126 def _security_dir_changed(self, name, old, new):
126 def _security_dir_changed(self, name, old, new):
127 self.check_security_dir()
127 self.check_security_dir()
128
128
129 def check_security_dir(self):
129 def check_security_dir(self):
130 self._mkdir(self.security_dir, 0o40700)
130 self._mkdir(self.security_dir, 0o40700)
131
131
132 def _pid_dir_changed(self, name, old, new):
132 def _pid_dir_changed(self, name, old, new):
133 self.check_pid_dir()
133 self.check_pid_dir()
134
134
135 def check_pid_dir(self):
135 def check_pid_dir(self):
136 self._mkdir(self.pid_dir, 0o40700)
136 self._mkdir(self.pid_dir, 0o40700)
137
137
138 def _static_dir_changed(self, name, old, new):
138 def _static_dir_changed(self, name, old, new):
139 self.check_startup_dir()
139 self.check_startup_dir()
140
140
141 def check_dirs(self):
141 def check_dirs(self):
142 self.check_security_dir()
142 self.check_security_dir()
143 self.check_log_dir()
143 self.check_log_dir()
144 self.check_pid_dir()
144 self.check_pid_dir()
145 self.check_startup_dir()
145 self.check_startup_dir()
146
146
147 def copy_config_file(self, config_file, path=None, overwrite=False):
147 def copy_config_file(self, config_file, path=None, overwrite=False):
148 """Copy a default config file into the active profile directory.
148 """Copy a default config file into the active profile directory.
149
149
150 Default configuration files are kept in :mod:`IPython.core.profile`.
150 Default configuration files are kept in :mod:`IPython.core.profile`.
151 This function moves these from that location to the working profile
151 This function moves these from that location to the working profile
152 directory.
152 directory.
153 """
153 """
154 dst = os.path.join(self.location, config_file)
154 dst = os.path.join(self.location, config_file)
155 if os.path.isfile(dst) and not overwrite:
155 if os.path.isfile(dst) and not overwrite:
156 return False
156 return False
157 if path is None:
157 if path is None:
158 path = os.path.join(get_ipython_package_dir(), u'core', u'profile', u'default')
158 path = os.path.join(get_ipython_package_dir(), u'core', u'profile', u'default')
159 src = os.path.join(path, config_file)
159 src = os.path.join(path, config_file)
160 shutil.copy(src, dst)
160 shutil.copy(src, dst)
161 return True
161 return True
162
162
163 @classmethod
163 @classmethod
164 def create_profile_dir(cls, profile_dir, config=None):
164 def create_profile_dir(cls, profile_dir, config=None):
165 """Create a new profile directory given a full path.
165 """Create a new profile directory given a full path.
166
166
167 Parameters
167 Parameters
168 ----------
168 ----------
169 profile_dir : str
169 profile_dir : str
170 The full path to the profile directory. If it does exist, it will
170 The full path to the profile directory. If it does exist, it will
171 be used. If not, it will be created.
171 be used. If not, it will be created.
172 """
172 """
173 return cls(location=profile_dir, config=config)
173 return cls(location=profile_dir, config=config)
174
174
175 @classmethod
175 @classmethod
176 def create_profile_dir_by_name(cls, path, name=u'default', config=None):
176 def create_profile_dir_by_name(cls, path, name=u'default', config=None):
177 """Create a profile dir by profile name and path.
177 """Create a profile dir by profile name and path.
178
178
179 Parameters
179 Parameters
180 ----------
180 ----------
181 path : unicode
181 path : unicode
182 The path (directory) to put the profile directory in.
182 The path (directory) to put the profile directory in.
183 name : unicode
183 name : unicode
184 The name of the profile. The name of the profile directory will
184 The name of the profile. The name of the profile directory will
185 be "profile_<profile>".
185 be "profile_<profile>".
186 """
186 """
187 if not os.path.isdir(path):
187 if not os.path.isdir(path):
188 raise ProfileDirError('Directory not found: %s' % path)
188 raise ProfileDirError('Directory not found: %s' % path)
189 profile_dir = os.path.join(path, u'profile_' + name)
189 profile_dir = os.path.join(path, u'profile_' + name)
190 return cls(location=profile_dir, config=config)
190 return cls(location=profile_dir, config=config)
191
191
192 @classmethod
192 @classmethod
193 def find_profile_dir_by_name(cls, ipython_dir, name=u'default', config=None):
193 def find_profile_dir_by_name(cls, ipython_dir, name=u'default', config=None):
194 """Find an existing profile dir by profile name, return its ProfileDir.
194 """Find an existing profile dir by profile name, return its ProfileDir.
195
195
196 This searches through a sequence of paths for a profile dir. If it
196 This searches through a sequence of paths for a profile dir. If it
197 is not found, a :class:`ProfileDirError` exception will be raised.
197 is not found, a :class:`ProfileDirError` exception will be raised.
198
198
199 The search path algorithm is:
199 The search path algorithm is:
200 1. ``py3compat.getcwd()``
200 1. ``py3compat.getcwd()``
201 2. ``ipython_dir``
201 2. ``ipython_dir``
202
202
203 Parameters
203 Parameters
204 ----------
204 ----------
205 ipython_dir : unicode or str
205 ipython_dir : unicode or str
206 The IPython directory to use.
206 The IPython directory to use.
207 name : unicode or str
207 name : unicode or str
208 The name of the profile. The name of the profile directory
208 The name of the profile. The name of the profile directory
209 will be "profile_<profile>".
209 will be "profile_<profile>".
210 """
210 """
211 dirname = u'profile_' + name
211 dirname = u'profile_' + name
212 paths = [py3compat.getcwd(), ipython_dir]
212 paths = [py3compat.getcwd(), ipython_dir]
213 for p in paths:
213 for p in paths:
214 profile_dir = os.path.join(p, dirname)
214 profile_dir = os.path.join(p, dirname)
215 if os.path.isdir(profile_dir):
215 if os.path.isdir(profile_dir):
216 return cls(location=profile_dir, config=config)
216 return cls(location=profile_dir, config=config)
217 else:
217 else:
218 raise ProfileDirError('Profile directory not found in paths: %s' % dirname)
218 raise ProfileDirError('Profile directory not found in paths: %s' % dirname)
219
219
220 @classmethod
220 @classmethod
221 def find_profile_dir(cls, profile_dir, config=None):
221 def find_profile_dir(cls, profile_dir, config=None):
222 """Find/create a profile dir and return its ProfileDir.
222 """Find/create a profile dir and return its ProfileDir.
223
223
224 This will create the profile directory if it doesn't exist.
224 This will create the profile directory if it doesn't exist.
225
225
226 Parameters
226 Parameters
227 ----------
227 ----------
228 profile_dir : unicode or str
228 profile_dir : unicode or str
229 The path of the profile directory.
229 The path of the profile directory.
230 """
230 """
231 profile_dir = expand_path(profile_dir)
231 profile_dir = expand_path(profile_dir)
232 if not os.path.isdir(profile_dir):
232 if not os.path.isdir(profile_dir):
233 raise ProfileDirError('Profile directory not found: %s' % profile_dir)
233 raise ProfileDirError('Profile directory not found: %s' % profile_dir)
234 return cls(location=profile_dir, config=config)
234 return cls(location=profile_dir, config=config)
@@ -1,433 +1,433 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
6
7 # Copyright (c) IPython Development Team.
7 # Copyright (c) IPython Development Team.
8 # Distributed under the terms of the Modified BSD License.
8 # Distributed under the terms of the Modified BSD License.
9
9
10 from __future__ import absolute_import
10 from __future__ import absolute_import
11 from __future__ import print_function
11 from __future__ import print_function
12
12
13 import glob
13 import glob
14 import os
14 import os
15 import sys
15 import sys
16
16
17 from traitlets.config.application import boolean_flag
17 from traitlets.config.application import boolean_flag
18 from traitlets.config.configurable import Configurable
18 from traitlets.config.configurable import Configurable
19 from traitlets.config.loader import Config
19 from traitlets.config.loader import Config
20 from IPython.core import pylabtools
20 from IPython.core import pylabtools
21 from IPython.utils import py3compat
21 from IPython.utils import py3compat
22 from IPython.utils.contexts import preserve_keys
22 from IPython.utils.contexts import preserve_keys
23 from IPython.utils.path import filefind
23 from IPython.utils.path import filefind
24 from traitlets import (
24 from traitlets import (
25 Unicode, Instance, List, Bool, CaselessStrEnum
25 Unicode, Instance, List, Bool, CaselessStrEnum
26 )
26 )
27 from IPython.lib.inputhook import guis
27 from IPython.lib.inputhook import guis
28
28
29 #-----------------------------------------------------------------------------
29 #-----------------------------------------------------------------------------
30 # Aliases and Flags
30 # Aliases and Flags
31 #-----------------------------------------------------------------------------
31 #-----------------------------------------------------------------------------
32
32
33 gui_keys = tuple(sorted([ key for key in guis if key is not None ]))
33 gui_keys = tuple(sorted([ key for key in guis if key is not None ]))
34
34
35 backend_keys = sorted(pylabtools.backends.keys())
35 backend_keys = sorted(pylabtools.backends.keys())
36 backend_keys.insert(0, 'auto')
36 backend_keys.insert(0, 'auto')
37
37
38 shell_flags = {}
38 shell_flags = {}
39
39
40 addflag = lambda *args: shell_flags.update(boolean_flag(*args))
40 addflag = lambda *args: shell_flags.update(boolean_flag(*args))
41 addflag('autoindent', 'InteractiveShell.autoindent',
41 addflag('autoindent', 'InteractiveShell.autoindent',
42 'Turn on autoindenting.', 'Turn off autoindenting.'
42 'Turn on autoindenting.', 'Turn off autoindenting.'
43 )
43 )
44 addflag('automagic', 'InteractiveShell.automagic',
44 addflag('automagic', 'InteractiveShell.automagic',
45 """Turn on the auto calling of magic commands. Type %%magic at the
45 """Turn on the auto calling of magic commands. Type %%magic at the
46 IPython prompt for more information.""",
46 IPython prompt for more information.""",
47 'Turn off the auto calling of magic commands.'
47 'Turn off the auto calling of magic commands.'
48 )
48 )
49 addflag('pdb', 'InteractiveShell.pdb',
49 addflag('pdb', 'InteractiveShell.pdb',
50 "Enable auto calling the pdb debugger after every exception.",
50 "Enable auto calling the pdb debugger after every exception.",
51 "Disable auto calling the pdb debugger after every exception."
51 "Disable auto calling the pdb debugger after every exception."
52 )
52 )
53 # pydb flag doesn't do any config, as core.debugger switches on import,
53 # pydb flag doesn't do any config, as core.debugger switches on import,
54 # which is before parsing. This just allows the flag to be passed.
54 # which is before parsing. This just allows the flag to be passed.
55 shell_flags.update(dict(
55 shell_flags.update(dict(
56 pydb = ({},
56 pydb = ({},
57 """Use the third party 'pydb' package as debugger, instead of pdb.
57 """Use the third party 'pydb' package as debugger, instead of pdb.
58 Requires that pydb is installed."""
58 Requires that pydb is installed."""
59 )
59 )
60 ))
60 ))
61 addflag('pprint', 'PlainTextFormatter.pprint',
61 addflag('pprint', 'PlainTextFormatter.pprint',
62 "Enable auto pretty printing of results.",
62 "Enable auto pretty printing of results.",
63 "Disable auto pretty printing of results."
63 "Disable auto pretty printing of results."
64 )
64 )
65 addflag('color-info', 'InteractiveShell.color_info',
65 addflag('color-info', 'InteractiveShell.color_info',
66 """IPython can display information about objects via a set of functions,
66 """IPython can display information about objects via a set of functions,
67 and optionally can use colors for this, syntax highlighting
67 and optionally can use colors for this, syntax highlighting
68 source code and various other elements. This is on by default, but can cause
68 source code and various other elements. This is on by default, but can cause
69 problems with some pagers. If you see such problems, you can disable the
69 problems with some pagers. If you see such problems, you can disable the
70 colours.""",
70 colours.""",
71 "Disable using colors for info related things."
71 "Disable using colors for info related things."
72 )
72 )
73 addflag('deep-reload', 'InteractiveShell.deep_reload',
73 addflag('deep-reload', 'InteractiveShell.deep_reload',
74 """ **Deprecated** Enable deep (recursive) reloading by default. IPython can use the
74 """ **Deprecated** Enable deep (recursive) reloading by default. IPython can use the
75 deep_reload module which reloads changes in modules recursively (it
75 deep_reload module which reloads changes in modules recursively (it
76 replaces the reload() function, so you don't need to change anything to
76 replaces the reload() function, so you don't need to change anything to
77 use it). deep_reload() forces a full reload of modules whose code may
77 use it). deep_reload() forces a full reload of modules whose code may
78 have changed, which the default reload() function does not. When
78 have changed, which the default reload() function does not. When
79 deep_reload is off, IPython will use the normal reload(), but
79 deep_reload is off, IPython will use the normal reload(), but
80 deep_reload will still be available as dreload(). This feature is off
80 deep_reload will still be available as dreload(). This feature is off
81 by default [which means that you have both normal reload() and
81 by default [which means that you have both normal reload() and
82 dreload()].""",
82 dreload()].""",
83 "Disable deep (recursive) reloading by default."
83 "Disable deep (recursive) reloading by default."
84 )
84 )
85 nosep_config = Config()
85 nosep_config = Config()
86 nosep_config.InteractiveShell.separate_in = ''
86 nosep_config.InteractiveShell.separate_in = ''
87 nosep_config.InteractiveShell.separate_out = ''
87 nosep_config.InteractiveShell.separate_out = ''
88 nosep_config.InteractiveShell.separate_out2 = ''
88 nosep_config.InteractiveShell.separate_out2 = ''
89
89
90 shell_flags['nosep']=(nosep_config, "Eliminate all spacing between prompts.")
90 shell_flags['nosep']=(nosep_config, "Eliminate all spacing between prompts.")
91 shell_flags['pylab'] = (
91 shell_flags['pylab'] = (
92 {'InteractiveShellApp' : {'pylab' : 'auto'}},
92 {'InteractiveShellApp' : {'pylab' : 'auto'}},
93 """Pre-load matplotlib and numpy for interactive use with
93 """Pre-load matplotlib and numpy for interactive use with
94 the default matplotlib backend."""
94 the default matplotlib backend."""
95 )
95 )
96 shell_flags['matplotlib'] = (
96 shell_flags['matplotlib'] = (
97 {'InteractiveShellApp' : {'matplotlib' : 'auto'}},
97 {'InteractiveShellApp' : {'matplotlib' : 'auto'}},
98 """Configure matplotlib for interactive use with
98 """Configure matplotlib for interactive use with
99 the default matplotlib backend."""
99 the default matplotlib backend."""
100 )
100 )
101
101
102 # it's possible we don't want short aliases for *all* of these:
102 # it's possible we don't want short aliases for *all* of these:
103 shell_aliases = dict(
103 shell_aliases = dict(
104 autocall='InteractiveShell.autocall',
104 autocall='InteractiveShell.autocall',
105 colors='InteractiveShell.colors',
105 colors='InteractiveShell.colors',
106 logfile='InteractiveShell.logfile',
106 logfile='InteractiveShell.logfile',
107 logappend='InteractiveShell.logappend',
107 logappend='InteractiveShell.logappend',
108 c='InteractiveShellApp.code_to_run',
108 c='InteractiveShellApp.code_to_run',
109 m='InteractiveShellApp.module_to_run',
109 m='InteractiveShellApp.module_to_run',
110 ext='InteractiveShellApp.extra_extension',
110 ext='InteractiveShellApp.extra_extension',
111 gui='InteractiveShellApp.gui',
111 gui='InteractiveShellApp.gui',
112 pylab='InteractiveShellApp.pylab',
112 pylab='InteractiveShellApp.pylab',
113 matplotlib='InteractiveShellApp.matplotlib',
113 matplotlib='InteractiveShellApp.matplotlib',
114 )
114 )
115 shell_aliases['cache-size'] = 'InteractiveShell.cache_size'
115 shell_aliases['cache-size'] = 'InteractiveShell.cache_size'
116
116
117 #-----------------------------------------------------------------------------
117 #-----------------------------------------------------------------------------
118 # Main classes and functions
118 # Main classes and functions
119 #-----------------------------------------------------------------------------
119 #-----------------------------------------------------------------------------
120
120
121 class InteractiveShellApp(Configurable):
121 class InteractiveShellApp(Configurable):
122 """A Mixin for applications that start InteractiveShell instances.
122 """A Mixin for applications that start InteractiveShell instances.
123
123
124 Provides configurables for loading extensions and executing files
124 Provides configurables for loading extensions and executing files
125 as part of configuring a Shell environment.
125 as part of configuring a Shell environment.
126
126
127 The following methods should be called by the :meth:`initialize` method
127 The following methods should be called by the :meth:`initialize` method
128 of the subclass:
128 of the subclass:
129
129
130 - :meth:`init_path`
130 - :meth:`init_path`
131 - :meth:`init_shell` (to be implemented by the subclass)
131 - :meth:`init_shell` (to be implemented by the subclass)
132 - :meth:`init_gui_pylab`
132 - :meth:`init_gui_pylab`
133 - :meth:`init_extensions`
133 - :meth:`init_extensions`
134 - :meth:`init_code`
134 - :meth:`init_code`
135 """
135 """
136 extensions = List(Unicode(), config=True,
136 extensions = List(Unicode(), config=True,
137 help="A list of dotted module names of IPython extensions to load."
137 help="A list of dotted module names of IPython extensions to load."
138 )
138 )
139 extra_extension = Unicode('', config=True,
139 extra_extension = Unicode('', config=True,
140 help="dotted module name of an IPython extension to load."
140 help="dotted module name of an IPython extension to load."
141 )
141 )
142
142
143 reraise_ipython_extension_failures = Bool(
143 reraise_ipython_extension_failures = Bool(
144 False,
144 False,
145 config=True,
145 config=True,
146 help="Reraise exceptions encountered loading IPython extensions?",
146 help="Reraise exceptions encountered loading IPython extensions?",
147 )
147 )
148
148
149 # Extensions that are always loaded (not configurable)
149 # Extensions that are always loaded (not configurable)
150 default_extensions = List(Unicode(), [u'storemagic'], config=False)
150 default_extensions = List(Unicode(), [u'storemagic'], config=False)
151
151
152 hide_initial_ns = Bool(True, config=True,
152 hide_initial_ns = Bool(True, config=True,
153 help="""Should variables loaded at startup (by startup files, exec_lines, etc.)
153 help="""Should variables loaded at startup (by startup files, exec_lines, etc.)
154 be hidden from tools like %who?"""
154 be hidden from tools like %who?"""
155 )
155 )
156
156
157 exec_files = List(Unicode(), config=True,
157 exec_files = List(Unicode(), config=True,
158 help="""List of files to run at IPython startup."""
158 help="""List of files to run at IPython startup."""
159 )
159 )
160 exec_PYTHONSTARTUP = Bool(True, config=True,
160 exec_PYTHONSTARTUP = Bool(True, config=True,
161 help="""Run the file referenced by the PYTHONSTARTUP environment
161 help="""Run the file referenced by the PYTHONSTARTUP environment
162 variable at IPython startup."""
162 variable at IPython startup."""
163 )
163 )
164 file_to_run = Unicode('', config=True,
164 file_to_run = Unicode('', config=True,
165 help="""A file to be run""")
165 help="""A file to be run""")
166
166
167 exec_lines = List(Unicode(), config=True,
167 exec_lines = List(Unicode(), config=True,
168 help="""lines of code to run at IPython startup."""
168 help="""lines of code to run at IPython startup."""
169 )
169 )
170 code_to_run = Unicode('', config=True,
170 code_to_run = Unicode('', config=True,
171 help="Execute the given command string."
171 help="Execute the given command string."
172 )
172 )
173 module_to_run = Unicode('', config=True,
173 module_to_run = Unicode('', config=True,
174 help="Run the module as a script."
174 help="Run the module as a script."
175 )
175 )
176 gui = CaselessStrEnum(gui_keys, config=True, allow_none=True,
176 gui = CaselessStrEnum(gui_keys, config=True, allow_none=True,
177 help="Enable GUI event loop integration with any of {0}.".format(gui_keys)
177 help="Enable GUI event loop integration with any of {0}.".format(gui_keys)
178 )
178 )
179 matplotlib = CaselessStrEnum(backend_keys, allow_none=True,
179 matplotlib = CaselessStrEnum(backend_keys, allow_none=True,
180 config=True,
180 config=True,
181 help="""Configure matplotlib for interactive use with
181 help="""Configure matplotlib for interactive use with
182 the default matplotlib backend."""
182 the default matplotlib backend."""
183 )
183 )
184 pylab = CaselessStrEnum(backend_keys, allow_none=True,
184 pylab = CaselessStrEnum(backend_keys, allow_none=True,
185 config=True,
185 config=True,
186 help="""Pre-load matplotlib and numpy for interactive use,
186 help="""Pre-load matplotlib and numpy for interactive use,
187 selecting a particular matplotlib backend and loop integration.
187 selecting a particular matplotlib backend and loop integration.
188 """
188 """
189 )
189 )
190 pylab_import_all = Bool(True, config=True,
190 pylab_import_all = Bool(True, config=True,
191 help="""If true, IPython will populate the user namespace with numpy, pylab, etc.
191 help="""If true, IPython will populate the user namespace with numpy, pylab, etc.
192 and an ``import *`` is done from numpy and pylab, when using pylab mode.
192 and an ``import *`` is done from numpy and pylab, when using pylab mode.
193
193
194 When False, pylab mode should not import any names into the user namespace.
194 When False, pylab mode should not import any names into the user namespace.
195 """
195 """
196 )
196 )
197 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC',
197 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC',
198 allow_none=True)
198 allow_none=True)
199
199
200 user_ns = Instance(dict, args=None, allow_none=True)
200 user_ns = Instance(dict, args=None, allow_none=True)
201 def _user_ns_changed(self, name, old, new):
201 def _user_ns_changed(self, name, old, new):
202 if self.shell is not None:
202 if self.shell is not None:
203 self.shell.user_ns = new
203 self.shell.user_ns = new
204 self.shell.init_user_ns()
204 self.shell.init_user_ns()
205
205
206 def init_path(self):
206 def init_path(self):
207 """Add current working directory, '', to sys.path"""
207 """Add current working directory, '', to sys.path"""
208 if sys.path[0] != '':
208 if sys.path[0] != '':
209 sys.path.insert(0, '')
209 sys.path.insert(0, '')
210
210
211 def init_shell(self):
211 def init_shell(self):
212 raise NotImplementedError("Override in subclasses")
212 raise NotImplementedError("Override in subclasses")
213
213
214 def init_gui_pylab(self):
214 def init_gui_pylab(self):
215 """Enable GUI event loop integration, taking pylab into account."""
215 """Enable GUI event loop integration, taking pylab into account."""
216 enable = False
216 enable = False
217 shell = self.shell
217 shell = self.shell
218 if self.pylab:
218 if self.pylab:
219 enable = lambda key: shell.enable_pylab(key, import_all=self.pylab_import_all)
219 enable = lambda key: shell.enable_pylab(key, import_all=self.pylab_import_all)
220 key = self.pylab
220 key = self.pylab
221 elif self.matplotlib:
221 elif self.matplotlib:
222 enable = shell.enable_matplotlib
222 enable = shell.enable_matplotlib
223 key = self.matplotlib
223 key = self.matplotlib
224 elif self.gui:
224 elif self.gui:
225 enable = shell.enable_gui
225 enable = shell.enable_gui
226 key = self.gui
226 key = self.gui
227
227
228 if not enable:
228 if not enable:
229 return
229 return
230
230
231 try:
231 try:
232 r = enable(key)
232 r = enable(key)
233 except ImportError:
233 except ImportError:
234 self.log.warn("Eventloop or matplotlib integration failed. Is matplotlib installed?")
234 self.log.warning("Eventloop or matplotlib integration failed. Is matplotlib installed?")
235 self.shell.showtraceback()
235 self.shell.showtraceback()
236 return
236 return
237 except Exception:
237 except Exception:
238 self.log.warn("GUI event loop or pylab initialization failed")
238 self.log.warning("GUI event loop or pylab initialization failed")
239 self.shell.showtraceback()
239 self.shell.showtraceback()
240 return
240 return
241
241
242 if isinstance(r, tuple):
242 if isinstance(r, tuple):
243 gui, backend = r[:2]
243 gui, backend = r[:2]
244 self.log.info("Enabling GUI event loop integration, "
244 self.log.info("Enabling GUI event loop integration, "
245 "eventloop=%s, matplotlib=%s", gui, backend)
245 "eventloop=%s, matplotlib=%s", gui, backend)
246 if key == "auto":
246 if key == "auto":
247 print("Using matplotlib backend: %s" % backend)
247 print("Using matplotlib backend: %s" % backend)
248 else:
248 else:
249 gui = r
249 gui = r
250 self.log.info("Enabling GUI event loop integration, "
250 self.log.info("Enabling GUI event loop integration, "
251 "eventloop=%s", gui)
251 "eventloop=%s", gui)
252
252
253 def init_extensions(self):
253 def init_extensions(self):
254 """Load all IPython extensions in IPythonApp.extensions.
254 """Load all IPython extensions in IPythonApp.extensions.
255
255
256 This uses the :meth:`ExtensionManager.load_extensions` to load all
256 This uses the :meth:`ExtensionManager.load_extensions` to load all
257 the extensions listed in ``self.extensions``.
257 the extensions listed in ``self.extensions``.
258 """
258 """
259 try:
259 try:
260 self.log.debug("Loading IPython extensions...")
260 self.log.debug("Loading IPython extensions...")
261 extensions = self.default_extensions + self.extensions
261 extensions = self.default_extensions + self.extensions
262 if self.extra_extension:
262 if self.extra_extension:
263 extensions.append(self.extra_extension)
263 extensions.append(self.extra_extension)
264 for ext in extensions:
264 for ext in extensions:
265 try:
265 try:
266 self.log.info("Loading IPython extension: %s" % ext)
266 self.log.info("Loading IPython extension: %s" % ext)
267 self.shell.extension_manager.load_extension(ext)
267 self.shell.extension_manager.load_extension(ext)
268 except:
268 except:
269 if self.reraise_ipython_extension_failures:
269 if self.reraise_ipython_extension_failures:
270 raise
270 raise
271 msg = ("Error in loading extension: {ext}\n"
271 msg = ("Error in loading extension: {ext}\n"
272 "Check your config files in {location}".format(
272 "Check your config files in {location}".format(
273 ext=ext,
273 ext=ext,
274 location=self.profile_dir.location
274 location=self.profile_dir.location
275 ))
275 ))
276 self.log.warn(msg, exc_info=True)
276 self.log.warning(msg, exc_info=True)
277 except:
277 except:
278 if self.reraise_ipython_extension_failures:
278 if self.reraise_ipython_extension_failures:
279 raise
279 raise
280 self.log.warn("Unknown error in loading extensions:", exc_info=True)
280 self.log.warning("Unknown error in loading extensions:", exc_info=True)
281
281
282 def init_code(self):
282 def init_code(self):
283 """run the pre-flight code, specified via exec_lines"""
283 """run the pre-flight code, specified via exec_lines"""
284 self._run_startup_files()
284 self._run_startup_files()
285 self._run_exec_lines()
285 self._run_exec_lines()
286 self._run_exec_files()
286 self._run_exec_files()
287
287
288 # Hide variables defined here from %who etc.
288 # Hide variables defined here from %who etc.
289 if self.hide_initial_ns:
289 if self.hide_initial_ns:
290 self.shell.user_ns_hidden.update(self.shell.user_ns)
290 self.shell.user_ns_hidden.update(self.shell.user_ns)
291
291
292 # command-line execution (ipython -i script.py, ipython -m module)
292 # command-line execution (ipython -i script.py, ipython -m module)
293 # should *not* be excluded from %whos
293 # should *not* be excluded from %whos
294 self._run_cmd_line_code()
294 self._run_cmd_line_code()
295 self._run_module()
295 self._run_module()
296
296
297 # flush output, so itwon't be attached to the first cell
297 # flush output, so itwon't be attached to the first cell
298 sys.stdout.flush()
298 sys.stdout.flush()
299 sys.stderr.flush()
299 sys.stderr.flush()
300
300
301 def _run_exec_lines(self):
301 def _run_exec_lines(self):
302 """Run lines of code in IPythonApp.exec_lines in the user's namespace."""
302 """Run lines of code in IPythonApp.exec_lines in the user's namespace."""
303 if not self.exec_lines:
303 if not self.exec_lines:
304 return
304 return
305 try:
305 try:
306 self.log.debug("Running code from IPythonApp.exec_lines...")
306 self.log.debug("Running code from IPythonApp.exec_lines...")
307 for line in self.exec_lines:
307 for line in self.exec_lines:
308 try:
308 try:
309 self.log.info("Running code in user namespace: %s" %
309 self.log.info("Running code in user namespace: %s" %
310 line)
310 line)
311 self.shell.run_cell(line, store_history=False)
311 self.shell.run_cell(line, store_history=False)
312 except:
312 except:
313 self.log.warn("Error in executing line in user "
313 self.log.warning("Error in executing line in user "
314 "namespace: %s" % line)
314 "namespace: %s" % line)
315 self.shell.showtraceback()
315 self.shell.showtraceback()
316 except:
316 except:
317 self.log.warn("Unknown error in handling IPythonApp.exec_lines:")
317 self.log.warning("Unknown error in handling IPythonApp.exec_lines:")
318 self.shell.showtraceback()
318 self.shell.showtraceback()
319
319
320 def _exec_file(self, fname, shell_futures=False):
320 def _exec_file(self, fname, shell_futures=False):
321 try:
321 try:
322 full_filename = filefind(fname, [u'.', self.ipython_dir])
322 full_filename = filefind(fname, [u'.', self.ipython_dir])
323 except IOError as e:
323 except IOError as e:
324 self.log.warn("File not found: %r"%fname)
324 self.log.warning("File not found: %r"%fname)
325 return
325 return
326 # Make sure that the running script gets a proper sys.argv as if it
326 # Make sure that the running script gets a proper sys.argv as if it
327 # were run from a system shell.
327 # were run from a system shell.
328 save_argv = sys.argv
328 save_argv = sys.argv
329 sys.argv = [full_filename] + self.extra_args[1:]
329 sys.argv = [full_filename] + self.extra_args[1:]
330 # protect sys.argv from potential unicode strings on Python 2:
330 # protect sys.argv from potential unicode strings on Python 2:
331 if not py3compat.PY3:
331 if not py3compat.PY3:
332 sys.argv = [ py3compat.cast_bytes(a) for a in sys.argv ]
332 sys.argv = [ py3compat.cast_bytes(a) for a in sys.argv ]
333 try:
333 try:
334 if os.path.isfile(full_filename):
334 if os.path.isfile(full_filename):
335 self.log.info("Running file in user namespace: %s" %
335 self.log.info("Running file in user namespace: %s" %
336 full_filename)
336 full_filename)
337 # Ensure that __file__ is always defined to match Python
337 # Ensure that __file__ is always defined to match Python
338 # behavior.
338 # behavior.
339 with preserve_keys(self.shell.user_ns, '__file__'):
339 with preserve_keys(self.shell.user_ns, '__file__'):
340 self.shell.user_ns['__file__'] = fname
340 self.shell.user_ns['__file__'] = fname
341 if full_filename.endswith('.ipy'):
341 if full_filename.endswith('.ipy'):
342 self.shell.safe_execfile_ipy(full_filename,
342 self.shell.safe_execfile_ipy(full_filename,
343 shell_futures=shell_futures)
343 shell_futures=shell_futures)
344 else:
344 else:
345 # default to python, even without extension
345 # default to python, even without extension
346 self.shell.safe_execfile(full_filename,
346 self.shell.safe_execfile(full_filename,
347 self.shell.user_ns,
347 self.shell.user_ns,
348 shell_futures=shell_futures,
348 shell_futures=shell_futures,
349 raise_exceptions=True)
349 raise_exceptions=True)
350 finally:
350 finally:
351 sys.argv = save_argv
351 sys.argv = save_argv
352
352
353 def _run_startup_files(self):
353 def _run_startup_files(self):
354 """Run files from profile startup directory"""
354 """Run files from profile startup directory"""
355 startup_dir = self.profile_dir.startup_dir
355 startup_dir = self.profile_dir.startup_dir
356 startup_files = []
356 startup_files = []
357
357
358 if self.exec_PYTHONSTARTUP and os.environ.get('PYTHONSTARTUP', False) and \
358 if self.exec_PYTHONSTARTUP and os.environ.get('PYTHONSTARTUP', False) and \
359 not (self.file_to_run or self.code_to_run or self.module_to_run):
359 not (self.file_to_run or self.code_to_run or self.module_to_run):
360 python_startup = os.environ['PYTHONSTARTUP']
360 python_startup = os.environ['PYTHONSTARTUP']
361 self.log.debug("Running PYTHONSTARTUP file %s...", python_startup)
361 self.log.debug("Running PYTHONSTARTUP file %s...", python_startup)
362 try:
362 try:
363 self._exec_file(python_startup)
363 self._exec_file(python_startup)
364 except:
364 except:
365 self.log.warn("Unknown error in handling PYTHONSTARTUP file %s:", python_startup)
365 self.log.warning("Unknown error in handling PYTHONSTARTUP file %s:", python_startup)
366 self.shell.showtraceback()
366 self.shell.showtraceback()
367 finally:
367 finally:
368 # Many PYTHONSTARTUP files set up the readline completions,
368 # Many PYTHONSTARTUP files set up the readline completions,
369 # but this is often at odds with IPython's own completions.
369 # but this is often at odds with IPython's own completions.
370 # Do not allow PYTHONSTARTUP to set up readline.
370 # Do not allow PYTHONSTARTUP to set up readline.
371 if self.shell.has_readline:
371 if self.shell.has_readline:
372 self.shell.set_readline_completer()
372 self.shell.set_readline_completer()
373
373
374 startup_files += glob.glob(os.path.join(startup_dir, '*.py'))
374 startup_files += glob.glob(os.path.join(startup_dir, '*.py'))
375 startup_files += glob.glob(os.path.join(startup_dir, '*.ipy'))
375 startup_files += glob.glob(os.path.join(startup_dir, '*.ipy'))
376 if not startup_files:
376 if not startup_files:
377 return
377 return
378
378
379 self.log.debug("Running startup files from %s...", startup_dir)
379 self.log.debug("Running startup files from %s...", startup_dir)
380 try:
380 try:
381 for fname in sorted(startup_files):
381 for fname in sorted(startup_files):
382 self._exec_file(fname)
382 self._exec_file(fname)
383 except:
383 except:
384 self.log.warn("Unknown error in handling startup files:")
384 self.log.warning("Unknown error in handling startup files:")
385 self.shell.showtraceback()
385 self.shell.showtraceback()
386
386
387 def _run_exec_files(self):
387 def _run_exec_files(self):
388 """Run files from IPythonApp.exec_files"""
388 """Run files from IPythonApp.exec_files"""
389 if not self.exec_files:
389 if not self.exec_files:
390 return
390 return
391
391
392 self.log.debug("Running files in IPythonApp.exec_files...")
392 self.log.debug("Running files in IPythonApp.exec_files...")
393 try:
393 try:
394 for fname in self.exec_files:
394 for fname in self.exec_files:
395 self._exec_file(fname)
395 self._exec_file(fname)
396 except:
396 except:
397 self.log.warn("Unknown error in handling IPythonApp.exec_files:")
397 self.log.warning("Unknown error in handling IPythonApp.exec_files:")
398 self.shell.showtraceback()
398 self.shell.showtraceback()
399
399
400 def _run_cmd_line_code(self):
400 def _run_cmd_line_code(self):
401 """Run code or file specified at the command-line"""
401 """Run code or file specified at the command-line"""
402 if self.code_to_run:
402 if self.code_to_run:
403 line = self.code_to_run
403 line = self.code_to_run
404 try:
404 try:
405 self.log.info("Running code given at command line (c=): %s" %
405 self.log.info("Running code given at command line (c=): %s" %
406 line)
406 line)
407 self.shell.run_cell(line, store_history=False)
407 self.shell.run_cell(line, store_history=False)
408 except:
408 except:
409 self.log.warn("Error in executing line in user namespace: %s" %
409 self.log.warning("Error in executing line in user namespace: %s" %
410 line)
410 line)
411 self.shell.showtraceback()
411 self.shell.showtraceback()
412
412
413 # Like Python itself, ignore the second if the first of these is present
413 # Like Python itself, ignore the second if the first of these is present
414 elif self.file_to_run:
414 elif self.file_to_run:
415 fname = self.file_to_run
415 fname = self.file_to_run
416 try:
416 try:
417 self._exec_file(fname, shell_futures=True)
417 self._exec_file(fname, shell_futures=True)
418 except:
418 except:
419 self.shell.showtraceback(tb_offset=4)
419 self.shell.showtraceback(tb_offset=4)
420 self.exit(1)
420 self.exit(1)
421
421
422 def _run_module(self):
422 def _run_module(self):
423 """Run module specified at the command-line."""
423 """Run module specified at the command-line."""
424 if self.module_to_run:
424 if self.module_to_run:
425 # Make sure that the module gets a proper sys.argv as if it were
425 # Make sure that the module gets a proper sys.argv as if it were
426 # run using `python -m`.
426 # run using `python -m`.
427 save_argv = sys.argv
427 save_argv = sys.argv
428 sys.argv = [sys.executable] + self.extra_args
428 sys.argv = [sys.executable] + self.extra_args
429 try:
429 try:
430 self.shell.safe_run_module(self.module_to_run,
430 self.shell.safe_run_module(self.module_to_run,
431 self.shell.user_ns)
431 self.shell.user_ns)
432 finally:
432 finally:
433 sys.argv = save_argv
433 sys.argv = save_argv
General Comments 0
You need to be logged in to leave comments. Login now