##// END OF EJS Templates
Merge pull request #950 from minrk/startup...
Fernando Perez -
r5251:b1311503 merge
parent child Browse files
Show More
@@ -0,0 +1,11 b''
1 This is the IPython startup directory
2
3 .py and .ipy files in this directory will be run *prior* to any code or files specified
4 via the exec_lines or exec_files configurables whenever you load this profile.
5
6 Files will be run in lexicographical order, so you can control the execution order of files
7 with a prefix, e.g.::
8
9 00-first.py
10 50-middle.py
11 99-last.ipy
@@ -0,0 +1,103 b''
1 """Tests for profile-related functions.
2
3 Currently only the startup-dir functionality is tested, but more tests should
4 be added for:
5
6 * ipython profile create
7 * ipython profile list
8 * ipython profile create --parallel
9 * security dir permissions
10
11 Authors
12 -------
13
14 * MinRK
15
16 """
17 from __future__ import absolute_import
18
19 #-----------------------------------------------------------------------------
20 # Imports
21 #-----------------------------------------------------------------------------
22
23 import os
24 import shutil
25 import sys
26 import tempfile
27
28 import nose.tools as nt
29 from nose import SkipTest
30
31 from IPython.core.profiledir import ProfileDir
32
33 from IPython.testing import decorators as dec
34 from IPython.testing import tools as tt
35 from IPython.utils import py3compat
36
37
38 #-----------------------------------------------------------------------------
39 # Globals
40 #-----------------------------------------------------------------------------
41 TMP_TEST_DIR = tempfile.mkdtemp()
42 HOME_TEST_DIR = os.path.join(TMP_TEST_DIR, "home_test_dir")
43 IP_TEST_DIR = os.path.join(HOME_TEST_DIR,'.ipython')
44
45 #
46 # Setup/teardown functions/decorators
47 #
48
49 def setup():
50 """Setup test environment for the module:
51
52 - Adds dummy home dir tree
53 """
54 # Do not mask exceptions here. In particular, catching WindowsError is a
55 # problem because that exception is only defined on Windows...
56 os.makedirs(IP_TEST_DIR)
57
58
59 def teardown():
60 """Teardown test environment for the module:
61
62 - Remove dummy home dir tree
63 """
64 # Note: we remove the parent test dir, which is the root of all test
65 # subdirs we may have created. Use shutil instead of os.removedirs, so
66 # that non-empty directories are all recursively removed.
67 shutil.rmtree(TMP_TEST_DIR)
68
69
70 #-----------------------------------------------------------------------------
71 # Test functions
72 #-----------------------------------------------------------------------------
73
74 def test_startup_py():
75 # create profile dir
76 pd = ProfileDir.create_profile_dir_by_name(IP_TEST_DIR, 'test')
77 # write startup python file
78 with open(os.path.join(pd.startup_dir, '00-start.py'), 'w') as f:
79 f.write('zzz=123\n')
80 # write simple test file, to check that the startup file was run
81 fname = os.path.join(TMP_TEST_DIR, 'test.py')
82 with open(fname, 'w') as f:
83 f.write('print zzz\n')
84 # validate output
85 tt.ipexec_validate(fname, '123', '',
86 options=['--ipython-dir', IP_TEST_DIR, '--profile', 'test'])
87
88 def test_startup_ipy():
89 # create profile dir
90 pd = ProfileDir.create_profile_dir_by_name(IP_TEST_DIR, 'test')
91 # write startup ipython file
92 with open(os.path.join(pd.startup_dir, '00-start.ipy'), 'w') as f:
93 f.write('%profile\n')
94 # write empty script, because we don't need anything to happen
95 # after the startup file is run
96 fname = os.path.join(TMP_TEST_DIR, 'test.py')
97 with open(fname, 'w') as f:
98 f.write('')
99 # validate output
100 tt.ipexec_validate(fname, 'test', '',
101 options=['--ipython-dir', IP_TEST_DIR, '--profile', 'test'])
102
103 No newline at end of file
@@ -59,9 +59,11 b' class ProfileDir(LoggingConfigurable):'
59
59
60 security_dir_name = Unicode('security')
60 security_dir_name = Unicode('security')
61 log_dir_name = Unicode('log')
61 log_dir_name = Unicode('log')
62 startup_dir_name = Unicode('startup')
62 pid_dir_name = Unicode('pid')
63 pid_dir_name = Unicode('pid')
63 security_dir = Unicode(u'')
64 security_dir = Unicode(u'')
64 log_dir = Unicode(u'')
65 log_dir = Unicode(u'')
66 startup_dir = Unicode(u'')
65 pid_dir = Unicode(u'')
67 pid_dir = Unicode(u'')
66
68
67 location = Unicode(u'', config=True,
69 location = Unicode(u'', config=True,
@@ -81,6 +83,7 b' class ProfileDir(LoggingConfigurable):'
81 # ensure config files exist:
83 # ensure config files exist:
82 self.security_dir = os.path.join(new, self.security_dir_name)
84 self.security_dir = os.path.join(new, self.security_dir_name)
83 self.log_dir = os.path.join(new, self.log_dir_name)
85 self.log_dir = os.path.join(new, self.log_dir_name)
86 self.startup_dir = os.path.join(new, self.startup_dir_name)
84 self.pid_dir = os.path.join(new, self.pid_dir_name)
87 self.pid_dir = os.path.join(new, self.pid_dir_name)
85 self.check_dirs()
88 self.check_dirs()
86
89
@@ -91,6 +94,17 b' class ProfileDir(LoggingConfigurable):'
91 if not os.path.isdir(self.log_dir):
94 if not os.path.isdir(self.log_dir):
92 os.mkdir(self.log_dir)
95 os.mkdir(self.log_dir)
93
96
97 def _startup_dir_changed(self, name, old, new):
98 self.check_startup_dir()
99
100 def check_startup_dir(self):
101 if not os.path.isdir(self.startup_dir):
102 os.mkdir(self.startup_dir)
103 readme = os.path.join(self.startup_dir, 'README')
104 src = os.path.join(get_ipython_package_dir(), u'config', u'profile', u'README_STARTUP')
105 if not os.path.exists(readme):
106 shutil.copy(src, readme)
107
94 def _security_dir_changed(self, name, old, new):
108 def _security_dir_changed(self, name, old, new):
95 self.check_security_dir()
109 self.check_security_dir()
96
110
@@ -119,6 +133,7 b' class ProfileDir(LoggingConfigurable):'
119 self.check_security_dir()
133 self.check_security_dir()
120 self.check_log_dir()
134 self.check_log_dir()
121 self.check_pid_dir()
135 self.check_pid_dir()
136 self.check_startup_dir()
122
137
123 def copy_config_file(self, config_file, path=None, overwrite=False):
138 def copy_config_file(self, config_file, path=None, overwrite=False):
124 """Copy a default config file into the active profile directory.
139 """Copy a default config file into the active profile directory.
@@ -22,6 +22,7 b' Authors'
22
22
23 from __future__ import absolute_import
23 from __future__ import absolute_import
24
24
25 import glob
25 import os
26 import os
26 import sys
27 import sys
27
28
@@ -175,6 +176,7 b' class InteractiveShellApp(Configurable):'
175
176
176 def init_code(self):
177 def init_code(self):
177 """run the pre-flight code, specified via exec_lines"""
178 """run the pre-flight code, specified via exec_lines"""
179 self._run_startup_files()
178 self._run_exec_lines()
180 self._run_exec_lines()
179 self._run_exec_files()
181 self._run_exec_files()
180 self._run_cmd_line_code()
182 self._run_cmd_line_code()
@@ -230,6 +232,22 b' class InteractiveShellApp(Configurable):'
230 finally:
232 finally:
231 sys.argv = save_argv
233 sys.argv = save_argv
232
234
235 def _run_startup_files(self):
236 """Run files from profile startup directory"""
237 startup_dir = self.profile_dir.startup_dir
238 startup_files = glob.glob(os.path.join(startup_dir, '*.py'))
239 startup_files += glob.glob(os.path.join(startup_dir, '*.ipy'))
240 if not startup_files:
241 return
242
243 self.log.debug("Running startup files from %s...", startup_dir)
244 try:
245 for fname in sorted(startup_files):
246 self._exec_file(fname)
247 except:
248 self.log.warn("Unknown error in handling startup files:")
249 self.shell.showtraceback()
250
233 def _run_exec_files(self):
251 def _run_exec_files(self):
234 """Run files from IPythonApp.exec_files"""
252 """Run files from IPythonApp.exec_files"""
235 if not self.exec_files:
253 if not self.exec_files:
@@ -259,7 +259,7 b" def ipexec_validate(fname, expected_out, expected_err='',"
259
259
260 import nose.tools as nt
260 import nose.tools as nt
261
261
262 out, err = ipexec(fname)
262 out, err = ipexec(fname, options)
263 #print 'OUT', out # dbg
263 #print 'OUT', out # dbg
264 #print 'ERR', err # dbg
264 #print 'ERR', err # dbg
265 # If there are any errors, we must check those befor stdout, as they may be
265 # If there are any errors, we must check those befor stdout, as they may be
@@ -358,6 +358,35 b' you create profiles with the name of one of our shipped profiles, these config'
358 files will be copied over instead of starting with the automatically generated
358 files will be copied over instead of starting with the automatically generated
359 config files.
359 config files.
360
360
361 Security Files
362 --------------
363
364 If you are using the notebook, qtconsole, or parallel code, IPython stores
365 connection information in small JSON files in the active profile's security
366 directory. This directory is made private, so only you can see the files inside. If
367 you need to move connection files around to other computers, this is where they will
368 be. If you want your code to be able to open security files by name, we have a
369 convenience function :func:`IPython.utils.path.get_security_file`, which will return
370 the absolute path to a security file from its filename and [optionally] profile
371 name.
372
373 Startup Files
374 -------------
375
376 If you want some code to be run at the beginning of every IPython session with a
377 particular profile, the easiest way is to add Python (.py) or IPython (.ipy) scripts
378 to your :file:`<profile>/startup` directory. Files in this directory will always be
379 executed as soon as the IPython shell is constructed, and before any other code or
380 scripts you have specified. If you have multiple files in the startup directory,
381 they will be run in lexicographical order, so you can control the ordering by adding
382 a '00-' prefix.
383
384 .. note::
385
386 Automatic startup files are new in IPython 0.12. Use the
387 InteractiveShellApp.exec_files configurable for similar behavior in 0.11.
388
389
361 .. _commandline:
390 .. _commandline:
362
391
363 Command-line arguments
392 Command-line arguments
@@ -142,4 +142,19 b' Profiles allow you to use IPython for different tasks, keeping separate config'
142 files and history for each one. More details in :ref:`the profiles section
142 files and history for each one. More details in :ref:`the profiles section
143 <profiles>`.
143 <profiles>`.
144
144
145 Startup Files
146 -------------
147
148 If you want some code to be run at the beginning of every IPython session, the
149 easiest way is to add Python (.py) or IPython (.ipy) scripts to your
150 :file:`<profile>/startup` directory. Files in this directory will always be executed
151 as soon as the IPython shell is constructed, and before any other code or scripts
152 you have specified. If you have multiple files in the startup directory, they will
153 be run in lexicographical order, so you can control the ordering by adding a '00-'
154 prefix.
155
156 .. note::
157
158 Automatic startup files are new in IPython 0.12. Use the
159 InteractiveShellApp.exec_files configurable for similar behavior in 0.11.
145
160
@@ -132,7 +132,7 b' def find_package_data():'
132 static_data.append(os.path.join(parent, f))
132 static_data.append(os.path.join(parent, f))
133
133
134 package_data = {
134 package_data = {
135 'IPython.config.profile' : ['README', '*/*.py'],
135 'IPython.config.profile' : ['README*', '*/*.py'],
136 'IPython.testing' : ['*.txt'],
136 'IPython.testing' : ['*.txt'],
137 'IPython.frontend.html.notebook' : ['templates/*'] + static_data,
137 'IPython.frontend.html.notebook' : ['templates/*'] + static_data,
138 'IPython.frontend.qt.console' : ['resources/icon/*.svg'],
138 'IPython.frontend.qt.console' : ['resources/icon/*.svg'],
General Comments 0
You need to be logged in to leave comments. Login now