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