##// 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
@@ -1,213 +1,228 b''
1 1 # encoding: utf-8
2 2 """
3 3 An object for managing IPython profile directories.
4 4
5 5 Authors:
6 6
7 7 * Brian Granger
8 8 * Fernando Perez
9 9 * Min RK
10 10
11 11 """
12 12
13 13 #-----------------------------------------------------------------------------
14 14 # Copyright (C) 2008-2011 The IPython Development Team
15 15 #
16 16 # Distributed under the terms of the BSD License. The full license is in
17 17 # the file COPYING, distributed as part of this software.
18 18 #-----------------------------------------------------------------------------
19 19
20 20 #-----------------------------------------------------------------------------
21 21 # Imports
22 22 #-----------------------------------------------------------------------------
23 23
24 24 import os
25 25 import shutil
26 26 import sys
27 27
28 28 from IPython.config.configurable import LoggingConfigurable
29 29 from IPython.config.loader import Config
30 30 from IPython.utils.path import get_ipython_package_dir, expand_path
31 31 from IPython.utils.traitlets import List, Unicode, Bool
32 32
33 33 #-----------------------------------------------------------------------------
34 34 # Classes and functions
35 35 #-----------------------------------------------------------------------------
36 36
37 37
38 38 #-----------------------------------------------------------------------------
39 39 # Module errors
40 40 #-----------------------------------------------------------------------------
41 41
42 42 class ProfileDirError(Exception):
43 43 pass
44 44
45 45
46 46 #-----------------------------------------------------------------------------
47 47 # Class for managing profile directories
48 48 #-----------------------------------------------------------------------------
49 49
50 50 class ProfileDir(LoggingConfigurable):
51 51 """An object to manage the profile directory and its resources.
52 52
53 53 The profile directory is used by all IPython applications, to manage
54 54 configuration, logging and security.
55 55
56 56 This object knows how to find, create and manage these directories. This
57 57 should be used by any code that wants to handle profiles.
58 58 """
59 59
60 60 security_dir_name = Unicode('security')
61 61 log_dir_name = Unicode('log')
62 startup_dir_name = Unicode('startup')
62 63 pid_dir_name = Unicode('pid')
63 64 security_dir = Unicode(u'')
64 65 log_dir = Unicode(u'')
66 startup_dir = Unicode(u'')
65 67 pid_dir = Unicode(u'')
66 68
67 69 location = Unicode(u'', config=True,
68 70 help="""Set the profile location directly. This overrides the logic used by the
69 71 `profile` option.""",
70 72 )
71 73
72 74 _location_isset = Bool(False) # flag for detecting multiply set location
73 75
74 76 def _location_changed(self, name, old, new):
75 77 if self._location_isset:
76 78 raise RuntimeError("Cannot set profile location more than once.")
77 79 self._location_isset = True
78 80 if not os.path.isdir(new):
79 81 os.makedirs(new)
80 82
81 83 # ensure config files exist:
82 84 self.security_dir = os.path.join(new, self.security_dir_name)
83 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 87 self.pid_dir = os.path.join(new, self.pid_dir_name)
85 88 self.check_dirs()
86 89
87 90 def _log_dir_changed(self, name, old, new):
88 91 self.check_log_dir()
89 92
90 93 def check_log_dir(self):
91 94 if not os.path.isdir(self.log_dir):
92 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 108 def _security_dir_changed(self, name, old, new):
95 109 self.check_security_dir()
96 110
97 111 def check_security_dir(self):
98 112 if not os.path.isdir(self.security_dir):
99 113 os.mkdir(self.security_dir, 0700)
100 114 else:
101 115 try:
102 116 os.chmod(self.security_dir, 0700)
103 117 except OSError:
104 118 self.log.warn("Could not set security dir permissions to private.")
105 119
106 120 def _pid_dir_changed(self, name, old, new):
107 121 self.check_pid_dir()
108 122
109 123 def check_pid_dir(self):
110 124 if not os.path.isdir(self.pid_dir):
111 125 os.mkdir(self.pid_dir, 0700)
112 126 else:
113 127 try:
114 128 os.chmod(self.pid_dir, 0700)
115 129 except OSError:
116 130 self.log.warn("Could not set pid dir permissions to private.")
117 131
118 132 def check_dirs(self):
119 133 self.check_security_dir()
120 134 self.check_log_dir()
121 135 self.check_pid_dir()
136 self.check_startup_dir()
122 137
123 138 def copy_config_file(self, config_file, path=None, overwrite=False):
124 139 """Copy a default config file into the active profile directory.
125 140
126 141 Default configuration files are kept in :mod:`IPython.config.default`.
127 142 This function moves these from that location to the working profile
128 143 directory.
129 144 """
130 145 dst = os.path.join(self.location, config_file)
131 146 if os.path.isfile(dst) and not overwrite:
132 147 return False
133 148 if path is None:
134 149 path = os.path.join(get_ipython_package_dir(), u'config', u'profile', u'default')
135 150 src = os.path.join(path, config_file)
136 151 shutil.copy(src, dst)
137 152 return True
138 153
139 154 @classmethod
140 155 def create_profile_dir(cls, profile_dir, config=None):
141 156 """Create a new profile directory given a full path.
142 157
143 158 Parameters
144 159 ----------
145 160 profile_dir : str
146 161 The full path to the profile directory. If it does exist, it will
147 162 be used. If not, it will be created.
148 163 """
149 164 return cls(location=profile_dir, config=config)
150 165
151 166 @classmethod
152 167 def create_profile_dir_by_name(cls, path, name=u'default', config=None):
153 168 """Create a profile dir by profile name and path.
154 169
155 170 Parameters
156 171 ----------
157 172 path : unicode
158 173 The path (directory) to put the profile directory in.
159 174 name : unicode
160 175 The name of the profile. The name of the profile directory will
161 176 be "profile_<profile>".
162 177 """
163 178 if not os.path.isdir(path):
164 179 raise ProfileDirError('Directory not found: %s' % path)
165 180 profile_dir = os.path.join(path, u'profile_' + name)
166 181 return cls(location=profile_dir, config=config)
167 182
168 183 @classmethod
169 184 def find_profile_dir_by_name(cls, ipython_dir, name=u'default', config=None):
170 185 """Find an existing profile dir by profile name, return its ProfileDir.
171 186
172 187 This searches through a sequence of paths for a profile dir. If it
173 188 is not found, a :class:`ProfileDirError` exception will be raised.
174 189
175 190 The search path algorithm is:
176 191 1. ``os.getcwdu()``
177 192 2. ``ipython_dir``
178 193
179 194 Parameters
180 195 ----------
181 196 ipython_dir : unicode or str
182 197 The IPython directory to use.
183 198 name : unicode or str
184 199 The name of the profile. The name of the profile directory
185 200 will be "profile_<profile>".
186 201 """
187 202 dirname = u'profile_' + name
188 203 paths = [os.getcwdu(), ipython_dir]
189 204 for p in paths:
190 205 profile_dir = os.path.join(p, dirname)
191 206 if os.path.isdir(profile_dir):
192 207 return cls(location=profile_dir, config=config)
193 208 else:
194 209 raise ProfileDirError('Profile directory not found in paths: %s' % dirname)
195 210
196 211 @classmethod
197 212 def find_profile_dir(cls, profile_dir, config=None):
198 213 """Find/create a profile dir and return its ProfileDir.
199 214
200 215 This will create the profile directory if it doesn't exist.
201 216
202 217 Parameters
203 218 ----------
204 219 profile_dir : unicode or str
205 220 The path of the profile directory. This is expanded using
206 221 :func:`IPython.utils.genutils.expand_path`.
207 222 """
208 223 profile_dir = expand_path(profile_dir)
209 224 if not os.path.isdir(profile_dir):
210 225 raise ProfileDirError('Profile directory not found: %s' % profile_dir)
211 226 return cls(location=profile_dir, config=config)
212 227
213 228
@@ -1,268 +1,286 b''
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 Authors
7 7 -------
8 8
9 9 * Min Ragan-Kelley
10 10 """
11 11
12 12 #-----------------------------------------------------------------------------
13 13 # Copyright (C) 2008-2011 The IPython Development Team
14 14 #
15 15 # Distributed under the terms of the BSD License. The full license is in
16 16 # the file COPYING, distributed as part of this software.
17 17 #-----------------------------------------------------------------------------
18 18
19 19 #-----------------------------------------------------------------------------
20 20 # Imports
21 21 #-----------------------------------------------------------------------------
22 22
23 23 from __future__ import absolute_import
24 24
25 import glob
25 26 import os
26 27 import sys
27 28
28 29 from IPython.config.application import boolean_flag
29 30 from IPython.config.configurable import Configurable
30 31 from IPython.config.loader import Config
31 32 from IPython.utils import py3compat
32 33 from IPython.utils.path import filefind
33 34 from IPython.utils.traitlets import Unicode, Instance, List, Bool
34 35
35 36 #-----------------------------------------------------------------------------
36 37 # Aliases and Flags
37 38 #-----------------------------------------------------------------------------
38 39
39 40 shell_flags = {}
40 41
41 42 addflag = lambda *args: shell_flags.update(boolean_flag(*args))
42 43 addflag('autoindent', 'InteractiveShell.autoindent',
43 44 'Turn on autoindenting.', 'Turn off autoindenting.'
44 45 )
45 46 addflag('automagic', 'InteractiveShell.automagic',
46 47 """Turn on the auto calling of magic commands. Type %%magic at the
47 48 IPython prompt for more information.""",
48 49 'Turn off the auto calling of magic commands.'
49 50 )
50 51 addflag('pdb', 'InteractiveShell.pdb',
51 52 "Enable auto calling the pdb debugger after every exception.",
52 53 "Disable auto calling the pdb debugger after every exception."
53 54 )
54 55 # pydb flag doesn't do any config, as core.debugger switches on import,
55 56 # which is before parsing. This just allows the flag to be passed.
56 57 shell_flags.update(dict(
57 58 pydb = ({},
58 59 """"Use the third party 'pydb' package as debugger, instead of pdb.
59 60 Requires that pydb is installed."""
60 61 )
61 62 ))
62 63 addflag('pprint', 'PlainTextFormatter.pprint',
63 64 "Enable auto pretty printing of results.",
64 65 "Disable auto auto pretty printing of results."
65 66 )
66 67 addflag('color-info', 'InteractiveShell.color_info',
67 68 """IPython can display information about objects via a set of func-
68 69 tions, and optionally can use colors for this, syntax highlighting
69 70 source code and various other elements. However, because this
70 71 information is passed through a pager (like 'less') and many pagers get
71 72 confused with color codes, this option is off by default. You can test
72 73 it and turn it on permanently in your ipython_config.py file if it
73 74 works for you. Test it and turn it on permanently if it works with
74 75 your system. The magic function %%color_info allows you to toggle this
75 76 interactively for testing.""",
76 77 "Disable using colors for info related things."
77 78 )
78 79 addflag('deep-reload', 'InteractiveShell.deep_reload',
79 80 """Enable deep (recursive) reloading by default. IPython can use the
80 81 deep_reload module which reloads changes in modules recursively (it
81 82 replaces the reload() function, so you don't need to change anything to
82 83 use it). deep_reload() forces a full reload of modules whose code may
83 84 have changed, which the default reload() function does not. When
84 85 deep_reload is off, IPython will use the normal reload(), but
85 86 deep_reload will still be available as dreload(). This feature is off
86 87 by default [which means that you have both normal reload() and
87 88 dreload()].""",
88 89 "Disable deep (recursive) reloading by default."
89 90 )
90 91 nosep_config = Config()
91 92 nosep_config.InteractiveShell.separate_in = ''
92 93 nosep_config.InteractiveShell.separate_out = ''
93 94 nosep_config.InteractiveShell.separate_out2 = ''
94 95
95 96 shell_flags['nosep']=(nosep_config, "Eliminate all spacing between prompts.")
96 97
97 98
98 99 # it's possible we don't want short aliases for *all* of these:
99 100 shell_aliases = dict(
100 101 autocall='InteractiveShell.autocall',
101 102 colors='InteractiveShell.colors',
102 103 logfile='InteractiveShell.logfile',
103 104 logappend='InteractiveShell.logappend',
104 105 c='InteractiveShellApp.code_to_run',
105 106 ext='InteractiveShellApp.extra_extension',
106 107 )
107 108 shell_aliases['cache-size'] = 'InteractiveShell.cache_size'
108 109
109 110 #-----------------------------------------------------------------------------
110 111 # Main classes and functions
111 112 #-----------------------------------------------------------------------------
112 113
113 114 class InteractiveShellApp(Configurable):
114 115 """A Mixin for applications that start InteractiveShell instances.
115 116
116 117 Provides configurables for loading extensions and executing files
117 118 as part of configuring a Shell environment.
118 119
119 120 Provides init_extensions() and init_code() methods, to be called
120 121 after init_shell(), which must be implemented by subclasses.
121 122 """
122 123 extensions = List(Unicode, config=True,
123 124 help="A list of dotted module names of IPython extensions to load."
124 125 )
125 126 extra_extension = Unicode('', config=True,
126 127 help="dotted module name of an IPython extension to load."
127 128 )
128 129 def _extra_extension_changed(self, name, old, new):
129 130 if new:
130 131 # add to self.extensions
131 132 self.extensions.append(new)
132 133
133 134 exec_files = List(Unicode, config=True,
134 135 help="""List of files to run at IPython startup."""
135 136 )
136 137 file_to_run = Unicode('', config=True,
137 138 help="""A file to be run""")
138 139
139 140 exec_lines = List(Unicode, config=True,
140 141 help="""lines of code to run at IPython startup."""
141 142 )
142 143 code_to_run = Unicode('', config=True,
143 144 help="Execute the given command string."
144 145 )
145 146 pylab_import_all = Bool(True, config=True,
146 147 help="""If true, an 'import *' is done from numpy and pylab,
147 148 when using pylab"""
148 149 )
149 150 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
150 151
151 152 def init_shell(self):
152 153 raise NotImplementedError("Override in subclasses")
153 154
154 155 def init_extensions(self):
155 156 """Load all IPython extensions in IPythonApp.extensions.
156 157
157 158 This uses the :meth:`ExtensionManager.load_extensions` to load all
158 159 the extensions listed in ``self.extensions``.
159 160 """
160 161 if not self.extensions:
161 162 return
162 163 try:
163 164 self.log.debug("Loading IPython extensions...")
164 165 extensions = self.extensions
165 166 for ext in extensions:
166 167 try:
167 168 self.log.info("Loading IPython extension: %s" % ext)
168 169 self.shell.extension_manager.load_extension(ext)
169 170 except:
170 171 self.log.warn("Error in loading extension: %s" % ext)
171 172 self.shell.showtraceback()
172 173 except:
173 174 self.log.warn("Unknown error in loading extensions:")
174 175 self.shell.showtraceback()
175 176
176 177 def init_code(self):
177 178 """run the pre-flight code, specified via exec_lines"""
179 self._run_startup_files()
178 180 self._run_exec_lines()
179 181 self._run_exec_files()
180 182 self._run_cmd_line_code()
181 183
182 184 def _run_exec_lines(self):
183 185 """Run lines of code in IPythonApp.exec_lines in the user's namespace."""
184 186 if not self.exec_lines:
185 187 return
186 188 try:
187 189 self.log.debug("Running code from IPythonApp.exec_lines...")
188 190 for line in self.exec_lines:
189 191 try:
190 192 self.log.info("Running code in user namespace: %s" %
191 193 line)
192 194 self.shell.run_cell(line, store_history=False)
193 195 except:
194 196 self.log.warn("Error in executing line in user "
195 197 "namespace: %s" % line)
196 198 self.shell.showtraceback()
197 199 except:
198 200 self.log.warn("Unknown error in handling IPythonApp.exec_lines:")
199 201 self.shell.showtraceback()
200 202
201 203 def _exec_file(self, fname):
202 204 try:
203 205 full_filename = filefind(fname, [u'.', self.ipython_dir])
204 206 except IOError as e:
205 207 self.log.warn("File not found: %r"%fname)
206 208 return
207 209 # Make sure that the running script gets a proper sys.argv as if it
208 210 # were run from a system shell.
209 211 save_argv = sys.argv
210 212 sys.argv = [full_filename] + self.extra_args[1:]
211 213 # protect sys.argv from potential unicode strings on Python 2:
212 214 if not py3compat.PY3:
213 215 sys.argv = [ py3compat.cast_bytes(a) for a in sys.argv ]
214 216 try:
215 217 if os.path.isfile(full_filename):
216 218 if full_filename.endswith('.ipy'):
217 219 self.log.info("Running file in user namespace: %s" %
218 220 full_filename)
219 221 self.shell.safe_execfile_ipy(full_filename)
220 222 else:
221 223 # default to python, even without extension
222 224 self.log.info("Running file in user namespace: %s" %
223 225 full_filename)
224 226 # Ensure that __file__ is always defined to match Python behavior
225 227 self.shell.user_ns['__file__'] = fname
226 228 try:
227 229 self.shell.safe_execfile(full_filename, self.shell.user_ns)
228 230 finally:
229 231 del self.shell.user_ns['__file__']
230 232 finally:
231 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 251 def _run_exec_files(self):
234 252 """Run files from IPythonApp.exec_files"""
235 253 if not self.exec_files:
236 254 return
237 255
238 256 self.log.debug("Running files in IPythonApp.exec_files...")
239 257 try:
240 258 for fname in self.exec_files:
241 259 self._exec_file(fname)
242 260 except:
243 261 self.log.warn("Unknown error in handling IPythonApp.exec_files:")
244 262 self.shell.showtraceback()
245 263
246 264 def _run_cmd_line_code(self):
247 265 """Run code or file specified at the command-line"""
248 266 if self.code_to_run:
249 267 line = self.code_to_run
250 268 try:
251 269 self.log.info("Running code given at command line (c=): %s" %
252 270 line)
253 271 self.shell.run_cell(line, store_history=False)
254 272 except:
255 273 self.log.warn("Error in executing line in user namespace: %s" %
256 274 line)
257 275 self.shell.showtraceback()
258 276
259 277 # Like Python itself, ignore the second if the first of these is present
260 278 elif self.file_to_run:
261 279 fname = self.file_to_run
262 280 try:
263 281 self._exec_file(fname)
264 282 except:
265 283 self.log.warn("Error in executing file in user namespace: %s" %
266 284 fname)
267 285 self.shell.showtraceback()
268 286
@@ -1,402 +1,402 b''
1 1 """Generic testing tools that do NOT depend on Twisted.
2 2
3 3 In particular, this module exposes a set of top-level assert* functions that
4 4 can be used in place of nose.tools.assert* in method generators (the ones in
5 5 nose can not, at least as of nose 0.10.4).
6 6
7 7 Note: our testing package contains testing.util, which does depend on Twisted
8 8 and provides utilities for tests that manage Deferreds. All testing support
9 9 tools that only depend on nose, IPython or the standard library should go here
10 10 instead.
11 11
12 12
13 13 Authors
14 14 -------
15 15 - Fernando Perez <Fernando.Perez@berkeley.edu>
16 16 """
17 17
18 18 from __future__ import absolute_import
19 19
20 20 #-----------------------------------------------------------------------------
21 21 # Copyright (C) 2009 The IPython Development Team
22 22 #
23 23 # Distributed under the terms of the BSD License. The full license is in
24 24 # the file COPYING, distributed as part of this software.
25 25 #-----------------------------------------------------------------------------
26 26
27 27 #-----------------------------------------------------------------------------
28 28 # Imports
29 29 #-----------------------------------------------------------------------------
30 30
31 31 import os
32 32 import re
33 33 import sys
34 34 import tempfile
35 35
36 36 from contextlib import contextmanager
37 37 from io import StringIO
38 38
39 39 try:
40 40 # These tools are used by parts of the runtime, so we make the nose
41 41 # dependency optional at this point. Nose is a hard dependency to run the
42 42 # test suite, but NOT to use ipython itself.
43 43 import nose.tools as nt
44 44 has_nose = True
45 45 except ImportError:
46 46 has_nose = False
47 47
48 48 from IPython.config.loader import Config
49 49 from IPython.utils.process import find_cmd, getoutputerror
50 50 from IPython.utils.text import list_strings, getdefaultencoding
51 51 from IPython.utils.io import temp_pyfile, Tee
52 52 from IPython.utils import py3compat
53 53
54 54 from . import decorators as dec
55 55 from . import skipdoctest
56 56
57 57 #-----------------------------------------------------------------------------
58 58 # Globals
59 59 #-----------------------------------------------------------------------------
60 60
61 61 # Make a bunch of nose.tools assert wrappers that can be used in test
62 62 # generators. This will expose an assert* function for each one in nose.tools.
63 63
64 64 _tpl = """
65 65 def %(name)s(*a,**kw):
66 66 return nt.%(name)s(*a,**kw)
67 67 """
68 68
69 69 if has_nose:
70 70 for _x in [a for a in dir(nt) if a.startswith('assert')]:
71 71 exec _tpl % dict(name=_x)
72 72
73 73 #-----------------------------------------------------------------------------
74 74 # Functions and classes
75 75 #-----------------------------------------------------------------------------
76 76
77 77 # The docstring for full_path doctests differently on win32 (different path
78 78 # separator) so just skip the doctest there. The example remains informative.
79 79 doctest_deco = skipdoctest.skip_doctest if sys.platform == 'win32' else dec.null_deco
80 80
81 81 @doctest_deco
82 82 def full_path(startPath,files):
83 83 """Make full paths for all the listed files, based on startPath.
84 84
85 85 Only the base part of startPath is kept, since this routine is typically
86 86 used with a script's __file__ variable as startPath. The base of startPath
87 87 is then prepended to all the listed files, forming the output list.
88 88
89 89 Parameters
90 90 ----------
91 91 startPath : string
92 92 Initial path to use as the base for the results. This path is split
93 93 using os.path.split() and only its first component is kept.
94 94
95 95 files : string or list
96 96 One or more files.
97 97
98 98 Examples
99 99 --------
100 100
101 101 >>> full_path('/foo/bar.py',['a.txt','b.txt'])
102 102 ['/foo/a.txt', '/foo/b.txt']
103 103
104 104 >>> full_path('/foo',['a.txt','b.txt'])
105 105 ['/a.txt', '/b.txt']
106 106
107 107 If a single file is given, the output is still a list:
108 108 >>> full_path('/foo','a.txt')
109 109 ['/a.txt']
110 110 """
111 111
112 112 files = list_strings(files)
113 113 base = os.path.split(startPath)[0]
114 114 return [ os.path.join(base,f) for f in files ]
115 115
116 116
117 117 def parse_test_output(txt):
118 118 """Parse the output of a test run and return errors, failures.
119 119
120 120 Parameters
121 121 ----------
122 122 txt : str
123 123 Text output of a test run, assumed to contain a line of one of the
124 124 following forms::
125 125 'FAILED (errors=1)'
126 126 'FAILED (failures=1)'
127 127 'FAILED (errors=1, failures=1)'
128 128
129 129 Returns
130 130 -------
131 131 nerr, nfail: number of errors and failures.
132 132 """
133 133
134 134 err_m = re.search(r'^FAILED \(errors=(\d+)\)', txt, re.MULTILINE)
135 135 if err_m:
136 136 nerr = int(err_m.group(1))
137 137 nfail = 0
138 138 return nerr, nfail
139 139
140 140 fail_m = re.search(r'^FAILED \(failures=(\d+)\)', txt, re.MULTILINE)
141 141 if fail_m:
142 142 nerr = 0
143 143 nfail = int(fail_m.group(1))
144 144 return nerr, nfail
145 145
146 146 both_m = re.search(r'^FAILED \(errors=(\d+), failures=(\d+)\)', txt,
147 147 re.MULTILINE)
148 148 if both_m:
149 149 nerr = int(both_m.group(1))
150 150 nfail = int(both_m.group(2))
151 151 return nerr, nfail
152 152
153 153 # If the input didn't match any of these forms, assume no error/failures
154 154 return 0, 0
155 155
156 156
157 157 # So nose doesn't think this is a test
158 158 parse_test_output.__test__ = False
159 159
160 160
161 161 def default_argv():
162 162 """Return a valid default argv for creating testing instances of ipython"""
163 163
164 164 return ['--quick', # so no config file is loaded
165 165 # Other defaults to minimize side effects on stdout
166 166 '--colors=NoColor', '--no-term-title','--no-banner',
167 167 '--autocall=0']
168 168
169 169
170 170 def default_config():
171 171 """Return a config object with good defaults for testing."""
172 172 config = Config()
173 173 config.TerminalInteractiveShell.colors = 'NoColor'
174 174 config.TerminalTerminalInteractiveShell.term_title = False,
175 175 config.TerminalInteractiveShell.autocall = 0
176 176 config.HistoryManager.hist_file = tempfile.mktemp(u'test_hist.sqlite')
177 177 config.HistoryManager.db_cache_size = 10000
178 178 return config
179 179
180 180
181 181 def ipexec(fname, options=None):
182 182 """Utility to call 'ipython filename'.
183 183
184 184 Starts IPython witha minimal and safe configuration to make startup as fast
185 185 as possible.
186 186
187 187 Note that this starts IPython in a subprocess!
188 188
189 189 Parameters
190 190 ----------
191 191 fname : str
192 192 Name of file to be executed (should have .py or .ipy extension).
193 193
194 194 options : optional, list
195 195 Extra command-line flags to be passed to IPython.
196 196
197 197 Returns
198 198 -------
199 199 (stdout, stderr) of ipython subprocess.
200 200 """
201 201 if options is None: options = []
202 202
203 203 # For these subprocess calls, eliminate all prompt printing so we only see
204 204 # output from script execution
205 205 prompt_opts = [ '--InteractiveShell.prompt_in1=""',
206 206 '--InteractiveShell.prompt_in2=""',
207 207 '--InteractiveShell.prompt_out=""'
208 208 ]
209 209 cmdargs = ' '.join(default_argv() + prompt_opts + options)
210 210
211 211 _ip = get_ipython()
212 212 test_dir = os.path.dirname(__file__)
213 213
214 214 ipython_cmd = find_cmd('ipython3' if py3compat.PY3 else 'ipython')
215 215 # Absolute path for filename
216 216 full_fname = os.path.join(test_dir, fname)
217 217 full_cmd = '%s %s %s' % (ipython_cmd, cmdargs, full_fname)
218 218 #print >> sys.stderr, 'FULL CMD:', full_cmd # dbg
219 219 out = getoutputerror(full_cmd)
220 220 # `import readline` causes 'ESC[?1034h' to be the first output sometimes,
221 221 # so strip that off the front of the first line if it is found
222 222 if out:
223 223 first = out[0]
224 224 m = re.match(r'\x1b\[[^h]+h', first)
225 225 if m:
226 226 # strip initial readline escape
227 227 out = list(out)
228 228 out[0] = first[len(m.group()):]
229 229 out = tuple(out)
230 230 return out
231 231
232 232
233 233 def ipexec_validate(fname, expected_out, expected_err='',
234 234 options=None):
235 235 """Utility to call 'ipython filename' and validate output/error.
236 236
237 237 This function raises an AssertionError if the validation fails.
238 238
239 239 Note that this starts IPython in a subprocess!
240 240
241 241 Parameters
242 242 ----------
243 243 fname : str
244 244 Name of the file to be executed (should have .py or .ipy extension).
245 245
246 246 expected_out : str
247 247 Expected stdout of the process.
248 248
249 249 expected_err : optional, str
250 250 Expected stderr of the process.
251 251
252 252 options : optional, list
253 253 Extra command-line flags to be passed to IPython.
254 254
255 255 Returns
256 256 -------
257 257 None
258 258 """
259 259
260 260 import nose.tools as nt
261 261
262 out, err = ipexec(fname)
262 out, err = ipexec(fname, options)
263 263 #print 'OUT', out # dbg
264 264 #print 'ERR', err # dbg
265 265 # If there are any errors, we must check those befor stdout, as they may be
266 266 # more informative than simply having an empty stdout.
267 267 if err:
268 268 if expected_err:
269 269 nt.assert_equals(err.strip(), expected_err.strip())
270 270 else:
271 271 raise ValueError('Running file %r produced error: %r' %
272 272 (fname, err))
273 273 # If no errors or output on stderr was expected, match stdout
274 274 nt.assert_equals(out.strip(), expected_out.strip())
275 275
276 276
277 277 class TempFileMixin(object):
278 278 """Utility class to create temporary Python/IPython files.
279 279
280 280 Meant as a mixin class for test cases."""
281 281
282 282 def mktmp(self, src, ext='.py'):
283 283 """Make a valid python temp file."""
284 284 fname, f = temp_pyfile(src, ext)
285 285 self.tmpfile = f
286 286 self.fname = fname
287 287
288 288 def tearDown(self):
289 289 if hasattr(self, 'tmpfile'):
290 290 # If the tmpfile wasn't made because of skipped tests, like in
291 291 # win32, there's nothing to cleanup.
292 292 self.tmpfile.close()
293 293 try:
294 294 os.unlink(self.fname)
295 295 except:
296 296 # On Windows, even though we close the file, we still can't
297 297 # delete it. I have no clue why
298 298 pass
299 299
300 300 pair_fail_msg = ("Testing {0}\n\n"
301 301 "In:\n"
302 302 " {1!r}\n"
303 303 "Expected:\n"
304 304 " {2!r}\n"
305 305 "Got:\n"
306 306 " {3!r}\n")
307 307 def check_pairs(func, pairs):
308 308 """Utility function for the common case of checking a function with a
309 309 sequence of input/output pairs.
310 310
311 311 Parameters
312 312 ----------
313 313 func : callable
314 314 The function to be tested. Should accept a single argument.
315 315 pairs : iterable
316 316 A list of (input, expected_output) tuples.
317 317
318 318 Returns
319 319 -------
320 320 None. Raises an AssertionError if any output does not match the expected
321 321 value.
322 322 """
323 323 name = getattr(func, "func_name", getattr(func, "__name__", "<unknown>"))
324 324 for inp, expected in pairs:
325 325 out = func(inp)
326 326 assert out == expected, pair_fail_msg.format(name, inp, expected, out)
327 327
328 328
329 329 if py3compat.PY3:
330 330 MyStringIO = StringIO
331 331 else:
332 332 # In Python 2, stdout/stderr can have either bytes or unicode written to them,
333 333 # so we need a class that can handle both.
334 334 class MyStringIO(StringIO):
335 335 def write(self, s):
336 336 s = py3compat.cast_unicode(s, encoding=getdefaultencoding())
337 337 super(MyStringIO, self).write(s)
338 338
339 339 notprinted_msg = """Did not find {0!r} in printed output (on {1}):
340 340 {2!r}"""
341 341
342 342 class AssertPrints(object):
343 343 """Context manager for testing that code prints certain text.
344 344
345 345 Examples
346 346 --------
347 347 >>> with AssertPrints("abc", suppress=False):
348 348 ... print "abcd"
349 349 ... print "def"
350 350 ...
351 351 abcd
352 352 def
353 353 """
354 354 def __init__(self, s, channel='stdout', suppress=True):
355 355 self.s = s
356 356 self.channel = channel
357 357 self.suppress = suppress
358 358
359 359 def __enter__(self):
360 360 self.orig_stream = getattr(sys, self.channel)
361 361 self.buffer = MyStringIO()
362 362 self.tee = Tee(self.buffer, channel=self.channel)
363 363 setattr(sys, self.channel, self.buffer if self.suppress else self.tee)
364 364
365 365 def __exit__(self, etype, value, traceback):
366 366 self.tee.flush()
367 367 setattr(sys, self.channel, self.orig_stream)
368 368 printed = self.buffer.getvalue()
369 369 assert self.s in printed, notprinted_msg.format(self.s, self.channel, printed)
370 370 return False
371 371
372 372 class AssertNotPrints(AssertPrints):
373 373 """Context manager for checking that certain output *isn't* produced.
374 374
375 375 Counterpart of AssertPrints"""
376 376 def __exit__(self, etype, value, traceback):
377 377 self.tee.flush()
378 378 setattr(sys, self.channel, self.orig_stream)
379 379 printed = self.buffer.getvalue()
380 380 assert self.s not in printed, notprinted_msg.format(self.s, self.channel, printed)
381 381 return False
382 382
383 383 @contextmanager
384 384 def mute_warn():
385 385 from IPython.utils import warn
386 386 save_warn = warn.warn
387 387 warn.warn = lambda *a, **kw: None
388 388 try:
389 389 yield
390 390 finally:
391 391 warn.warn = save_warn
392 392
393 393 @contextmanager
394 394 def make_tempfile(name):
395 395 """ Create an empty, named, temporary file for the duration of the context.
396 396 """
397 397 f = open(name, 'w')
398 398 f.close()
399 399 try:
400 400 yield
401 401 finally:
402 402 os.unlink(name)
@@ -1,499 +1,528 b''
1 1 .. _config_overview:
2 2
3 3 ============================================
4 4 Overview of the IPython configuration system
5 5 ============================================
6 6
7 7 This section describes the IPython configuration system. Starting with version
8 8 0.11, IPython has a completely new configuration system that is quite
9 9 different from the older :file:`ipythonrc` or :file:`ipy_user_conf.py`
10 10 approaches. The new configuration system was designed from scratch to address
11 11 the particular configuration needs of IPython. While there are many
12 12 other excellent configuration systems out there, we found that none of them
13 13 met our requirements.
14 14
15 15 .. warning::
16 16
17 17 If you are upgrading to version 0.11 of IPython, you will need to migrate
18 18 your old :file:`ipythonrc` or :file:`ipy_user_conf.py` configuration files
19 19 to the new system. Read on for information on how to do this.
20 20
21 21 The discussion that follows is focused on teaching users how to configure
22 22 IPython to their liking. Developers who want to know more about how they
23 23 can enable their objects to take advantage of the configuration system
24 24 should consult our :ref:`developer guide <developer_guide>`
25 25
26 26 The main concepts
27 27 =================
28 28
29 29 There are a number of abstractions that the IPython configuration system uses.
30 30 Each of these abstractions is represented by a Python class.
31 31
32 32 Configuration object: :class:`~IPython.config.loader.Config`
33 33 A configuration object is a simple dictionary-like class that holds
34 34 configuration attributes and sub-configuration objects. These classes
35 35 support dotted attribute style access (``Foo.bar``) in addition to the
36 36 regular dictionary style access (``Foo['bar']``). Configuration objects
37 37 are smart. They know how to merge themselves with other configuration
38 38 objects and they automatically create sub-configuration objects.
39 39
40 40 Application: :class:`~IPython.config.application.Application`
41 41 An application is a process that does a specific job. The most obvious
42 42 application is the :command:`ipython` command line program. Each
43 43 application reads *one or more* configuration files and a single set of
44 44 command line options
45 45 and then produces a master configuration object for the application. This
46 46 configuration object is then passed to the configurable objects that the
47 47 application creates. These configurable objects implement the actual logic
48 48 of the application and know how to configure themselves given the
49 49 configuration object.
50 50
51 51 Applications always have a `log` attribute that is a configured Logger.
52 52 This allows centralized logging configuration per-application.
53 53
54 54 Configurable: :class:`~IPython.config.configurable.Configurable`
55 55 A configurable is a regular Python class that serves as a base class for
56 56 all main classes in an application. The
57 57 :class:`~IPython.config.configurable.Configurable` base class is
58 58 lightweight and only does one things.
59 59
60 60 This :class:`~IPython.config.configurable.Configurable` is a subclass
61 61 of :class:`~IPython.utils.traitlets.HasTraits` that knows how to configure
62 62 itself. Class level traits with the metadata ``config=True`` become
63 63 values that can be configured from the command line and configuration
64 64 files.
65 65
66 66 Developers create :class:`~IPython.config.configurable.Configurable`
67 67 subclasses that implement all of the logic in the application. Each of
68 68 these subclasses has its own configuration information that controls how
69 69 instances are created.
70 70
71 71 Singletons: :class:`~IPython.config.configurable.SingletonConfigurable`
72 72 Any object for which there is a single canonical instance. These are
73 73 just like Configurables, except they have a class method
74 74 :meth:`~IPython.config.configurable.SingletonConfigurable.instance`,
75 75 that returns the current active instance (or creates one if it
76 76 does not exist). Examples of singletons include
77 77 :class:`~IPython.config.application.Application`s and
78 78 :class:`~IPython.core.interactiveshell.InteractiveShell`. This lets
79 79 objects easily connect to the current running Application without passing
80 80 objects around everywhere. For instance, to get the current running
81 81 Application instance, simply do: ``app = Application.instance()``.
82 82
83 83
84 84 .. note::
85 85
86 86 Singletons are not strictly enforced - you can have many instances
87 87 of a given singleton class, but the :meth:`instance` method will always
88 88 return the same one.
89 89
90 90 Having described these main concepts, we can now state the main idea in our
91 91 configuration system: *"configuration" allows the default values of class
92 92 attributes to be controlled on a class by class basis*. Thus all instances of
93 93 a given class are configured in the same way. Furthermore, if two instances
94 94 need to be configured differently, they need to be instances of two different
95 95 classes. While this model may seem a bit restrictive, we have found that it
96 96 expresses most things that need to be configured extremely well. However, it
97 97 is possible to create two instances of the same class that have different
98 98 trait values. This is done by overriding the configuration.
99 99
100 100 Now, we show what our configuration objects and files look like.
101 101
102 102 Configuration objects and files
103 103 ===============================
104 104
105 105 A configuration file is simply a pure Python file that sets the attributes
106 106 of a global, pre-created configuration object. This configuration object is a
107 107 :class:`~IPython.config.loader.Config` instance. While in a configuration
108 108 file, to get a reference to this object, simply call the :func:`get_config`
109 109 function. We inject this function into the global namespace that the
110 110 configuration file is executed in.
111 111
112 112 Here is an example of a super simple configuration file that does nothing::
113 113
114 114 c = get_config()
115 115
116 116 Once you get a reference to the configuration object, you simply set
117 117 attributes on it. All you have to know is:
118 118
119 119 * The name of each attribute.
120 120 * The type of each attribute.
121 121
122 122 The answers to these two questions are provided by the various
123 123 :class:`~IPython.config.configurable.Configurable` subclasses that an
124 124 application uses. Let's look at how this would work for a simple configurable
125 125 subclass::
126 126
127 127 # Sample configurable:
128 128 from IPython.config.configurable import Configurable
129 129 from IPython.utils.traitlets import Int, Float, Unicode, Bool
130 130
131 131 class MyClass(Configurable):
132 132 name = Unicode(u'defaultname', config=True)
133 133 ranking = Int(0, config=True)
134 134 value = Float(99.0)
135 135 # The rest of the class implementation would go here..
136 136
137 137 In this example, we see that :class:`MyClass` has three attributes, two
138 138 of whom (``name``, ``ranking``) can be configured. All of the attributes
139 139 are given types and default values. If a :class:`MyClass` is instantiated,
140 140 but not configured, these default values will be used. But let's see how
141 141 to configure this class in a configuration file::
142 142
143 143 # Sample config file
144 144 c = get_config()
145 145
146 146 c.MyClass.name = 'coolname'
147 147 c.MyClass.ranking = 10
148 148
149 149 After this configuration file is loaded, the values set in it will override
150 150 the class defaults anytime a :class:`MyClass` is created. Furthermore,
151 151 these attributes will be type checked and validated anytime they are set.
152 152 This type checking is handled by the :mod:`IPython.utils.traitlets` module,
153 153 which provides the :class:`Unicode`, :class:`Int` and :class:`Float` types.
154 154 In addition to these traitlets, the :mod:`IPython.utils.traitlets` provides
155 155 traitlets for a number of other types.
156 156
157 157 .. note::
158 158
159 159 Underneath the hood, the :class:`Configurable` base class is a subclass of
160 160 :class:`IPython.utils.traitlets.HasTraits`. The
161 161 :mod:`IPython.utils.traitlets` module is a lightweight version of
162 162 :mod:`enthought.traits`. Our implementation is a pure Python subset
163 163 (mostly API compatible) of :mod:`enthought.traits` that does not have any
164 164 of the automatic GUI generation capabilities. Our plan is to achieve 100%
165 165 API compatibility to enable the actual :mod:`enthought.traits` to
166 166 eventually be used instead. Currently, we cannot use
167 167 :mod:`enthought.traits` as we are committed to the core of IPython being
168 168 pure Python.
169 169
170 170 It should be very clear at this point what the naming convention is for
171 171 configuration attributes::
172 172
173 173 c.ClassName.attribute_name = attribute_value
174 174
175 175 Here, ``ClassName`` is the name of the class whose configuration attribute you
176 176 want to set, ``attribute_name`` is the name of the attribute you want to set
177 177 and ``attribute_value`` the the value you want it to have. The ``ClassName``
178 178 attribute of ``c`` is not the actual class, but instead is another
179 179 :class:`~IPython.config.loader.Config` instance.
180 180
181 181 .. note::
182 182
183 183 The careful reader may wonder how the ``ClassName`` (``MyClass`` in
184 184 the above example) attribute of the configuration object ``c`` gets
185 185 created. These attributes are created on the fly by the
186 186 :class:`~IPython.config.loader.Config` instance, using a simple naming
187 187 convention. Any attribute of a :class:`~IPython.config.loader.Config`
188 188 instance whose name begins with an uppercase character is assumed to be a
189 189 sub-configuration and a new empty :class:`~IPython.config.loader.Config`
190 190 instance is dynamically created for that attribute. This allows deeply
191 191 hierarchical information created easily (``c.Foo.Bar.value``) on the fly.
192 192
193 193 Configuration files inheritance
194 194 ===============================
195 195
196 196 Let's say you want to have different configuration files for various purposes.
197 197 Our configuration system makes it easy for one configuration file to inherit
198 198 the information in another configuration file. The :func:`load_subconfig`
199 199 command can be used in a configuration file for this purpose. Here is a simple
200 200 example that loads all of the values from the file :file:`base_config.py`::
201 201
202 202 # base_config.py
203 203 c = get_config()
204 204 c.MyClass.name = 'coolname'
205 205 c.MyClass.ranking = 100
206 206
207 207 into the configuration file :file:`main_config.py`::
208 208
209 209 # main_config.py
210 210 c = get_config()
211 211
212 212 # Load everything from base_config.py
213 213 load_subconfig('base_config.py')
214 214
215 215 # Now override one of the values
216 216 c.MyClass.name = 'bettername'
217 217
218 218 In a situation like this the :func:`load_subconfig` makes sure that the
219 219 search path for sub-configuration files is inherited from that of the parent.
220 220 Thus, you can typically put the two in the same directory and everything will
221 221 just work.
222 222
223 223 You can also load configuration files by profile, for instance:
224 224
225 225 .. sourcecode:: python
226 226
227 227 load_subconfig('ipython_config.py', profile='default')
228 228
229 229 to inherit your default configuration as a starting point.
230 230
231 231
232 232 Class based configuration inheritance
233 233 =====================================
234 234
235 235 There is another aspect of configuration where inheritance comes into play.
236 236 Sometimes, your classes will have an inheritance hierarchy that you want
237 237 to be reflected in the configuration system. Here is a simple example::
238 238
239 239 from IPython.config.configurable import Configurable
240 240 from IPython.utils.traitlets import Int, Float, Unicode, Bool
241 241
242 242 class Foo(Configurable):
243 243 name = Unicode(u'fooname', config=True)
244 244 value = Float(100.0, config=True)
245 245
246 246 class Bar(Foo):
247 247 name = Unicode(u'barname', config=True)
248 248 othervalue = Int(0, config=True)
249 249
250 250 Now, we can create a configuration file to configure instances of :class:`Foo`
251 251 and :class:`Bar`::
252 252
253 253 # config file
254 254 c = get_config()
255 255
256 256 c.Foo.name = u'bestname'
257 257 c.Bar.othervalue = 10
258 258
259 259 This class hierarchy and configuration file accomplishes the following:
260 260
261 261 * The default value for :attr:`Foo.name` and :attr:`Bar.name` will be
262 262 'bestname'. Because :class:`Bar` is a :class:`Foo` subclass it also
263 263 picks up the configuration information for :class:`Foo`.
264 264 * The default value for :attr:`Foo.value` and :attr:`Bar.value` will be
265 265 ``100.0``, which is the value specified as the class default.
266 266 * The default value for :attr:`Bar.othervalue` will be 10 as set in the
267 267 configuration file. Because :class:`Foo` is the parent of :class:`Bar`
268 268 it doesn't know anything about the :attr:`othervalue` attribute.
269 269
270 270
271 271 .. _ipython_dir:
272 272
273 273 Configuration file location
274 274 ===========================
275 275
276 276 So where should you put your configuration files? IPython uses "profiles" for
277 277 configuration, and by default, all profiles will be stored in the so called
278 278 "IPython directory". The location of this directory is determined by the
279 279 following algorithm:
280 280
281 281 * If the ``ipython_dir`` command line flag is given, its value is used.
282 282
283 283 * If not, the value returned by :func:`IPython.utils.path.get_ipython_dir`
284 284 is used. This function will first look at the :envvar:`IPYTHON_DIR`
285 285 environment variable and then default to a platform-specific default.
286 286
287 287 On posix systems (Linux, Unix, etc.), IPython respects the ``$XDG_CONFIG_HOME``
288 288 part of the `XDG Base Directory`_ specification. If ``$XDG_CONFIG_HOME`` is
289 289 defined and exists ( ``XDG_CONFIG_HOME`` has a default interpretation of
290 290 :file:`$HOME/.config`), then IPython's config directory will be located in
291 291 :file:`$XDG_CONFIG_HOME/ipython`. If users still have an IPython directory
292 292 in :file:`$HOME/.ipython`, then that will be used. in preference to the
293 293 system default.
294 294
295 295 For most users, the default value will simply be something like
296 296 :file:`$HOME/.config/ipython` on Linux, or :file:`$HOME/.ipython`
297 297 elsewhere.
298 298
299 299 Once the location of the IPython directory has been determined, you need to know
300 300 which profile you are using. For users with a single configuration, this will
301 301 simply be 'default', and will be located in
302 302 :file:`<IPYTHON_DIR>/profile_default`.
303 303
304 304 The next thing you need to know is what to call your configuration file. The
305 305 basic idea is that each application has its own default configuration filename.
306 306 The default named used by the :command:`ipython` command line program is
307 307 :file:`ipython_config.py`, and *all* IPython applications will use this file.
308 308 Other applications, such as the parallel :command:`ipcluster` scripts or the
309 309 QtConsole will load their own config files *after* :file:`ipython_config.py`. To
310 310 load a particular configuration file instead of the default, the name can be
311 311 overridden by the ``config_file`` command line flag.
312 312
313 313 To generate the default configuration files, do::
314 314
315 315 $> ipython profile create
316 316
317 317 and you will have a default :file:`ipython_config.py` in your IPython directory
318 318 under :file:`profile_default`. If you want the default config files for the
319 319 :mod:`IPython.parallel` applications, add ``--parallel`` to the end of the
320 320 command-line args.
321 321
322 322 .. _Profiles:
323 323
324 324 Profiles
325 325 ========
326 326
327 327 A profile is a directory containing configuration and runtime files, such as
328 328 logs, connection info for the parallel apps, and your IPython command history.
329 329
330 330 The idea is that users often want to maintain a set of configuration files for
331 331 different purposes: one for doing numerical computing with NumPy and SciPy and
332 332 another for doing symbolic computing with SymPy. Profiles make it easy to keep a
333 333 separate configuration files, logs, and histories for each of these purposes.
334 334
335 335 Let's start by showing how a profile is used:
336 336
337 337 .. code-block:: bash
338 338
339 339 $ ipython --profile=sympy
340 340
341 341 This tells the :command:`ipython` command line program to get its configuration
342 342 from the "sympy" profile. The file names for various profiles do not change. The
343 343 only difference is that profiles are named in a special way. In the case above,
344 344 the "sympy" profile means looking for :file:`ipython_config.py` in :file:`<IPYTHON_DIR>/profile_sympy`.
345 345
346 346 The general pattern is this: simply create a new profile with:
347 347
348 348 .. code-block:: bash
349 349
350 350 ipython profile create <name>
351 351
352 352 which adds a directory called ``profile_<name>`` to your IPython directory. Then
353 353 you can load this profile by adding ``--profile=<name>`` to your command line
354 354 options. Profiles are supported by all IPython applications.
355 355
356 356 IPython ships with some sample profiles in :file:`IPython/config/profile`. If
357 357 you create profiles with the name of one of our shipped profiles, these config
358 358 files will be copied over instead of starting with the automatically generated
359 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 390 .. _commandline:
362 391
363 392 Command-line arguments
364 393 ======================
365 394
366 395 IPython exposes *all* configurable options on the command-line. The command-line
367 396 arguments are generated from the Configurable traits of the classes associated
368 397 with a given Application. Configuring IPython from the command-line may look
369 398 very similar to an IPython config file
370 399
371 400 IPython applications use a parser called
372 401 :class:`~IPython.config.loader.KeyValueLoader` to load values into a Config
373 402 object. Values are assigned in much the same way as in a config file:
374 403
375 404 .. code-block:: bash
376 405
377 406 $> ipython --InteractiveShell.use_readline=False --BaseIPythonApplication.profile='myprofile'
378 407
379 408 Is the same as adding:
380 409
381 410 .. sourcecode:: python
382 411
383 412 c.InteractiveShell.use_readline=False
384 413 c.BaseIPythonApplication.profile='myprofile'
385 414
386 415 to your config file. Key/Value arguments *always* take a value, separated by '='
387 416 and no spaces.
388 417
389 418 Common Arguments
390 419 ****************
391 420
392 421 Since the strictness and verbosity of the KVLoader above are not ideal for everyday
393 422 use, common arguments can be specified as flags_ or aliases_.
394 423
395 424 Flags and Aliases are handled by :mod:`argparse` instead, allowing for more flexible
396 425 parsing. In general, flags and aliases are prefixed by ``--``, except for those
397 426 that are single characters, in which case they can be specified with a single ``-``, e.g.:
398 427
399 428 .. code-block:: bash
400 429
401 430 $> ipython -i -c "import numpy; x=numpy.linspace(0,1)" --profile testing --colors=lightbg
402 431
403 432 Aliases
404 433 -------
405 434
406 435 For convenience, applications have a mapping of commonly used traits, so you don't have
407 436 to specify the whole class name:
408 437
409 438 .. code-block:: bash
410 439
411 440 $> ipython --profile myprofile
412 441 # and
413 442 $> ipython --profile='myprofile'
414 443 # are equivalent to
415 444 $> ipython --BaseIPythonApplication.profile='myprofile'
416 445
417 446 Flags
418 447 -----
419 448
420 449 Applications can also be passed **flags**. Flags are options that take no
421 450 arguments. They are simply wrappers for
422 451 setting one or more configurables with predefined values, often True/False.
423 452
424 453 For instance:
425 454
426 455 .. code-block:: bash
427 456
428 457 $> ipcontroller --debug
429 458 # is equivalent to
430 459 $> ipcontroller --Application.log_level=DEBUG
431 460 # and
432 461 $> ipython --pylab
433 462 # is equivalent to
434 463 $> ipython --pylab=auto
435 464 # or
436 465 $> ipython --no-banner
437 466 # is equivalent to
438 467 $> ipython --TerminalIPythonApp.display_banner=False
439 468
440 469 Subcommands
441 470 ***********
442 471
443 472
444 473 Some IPython applications have **subcommands**. Subcommands are modeled after
445 474 :command:`git`, and are called with the form :command:`command subcommand
446 475 [...args]`. Currently, the QtConsole is a subcommand of terminal IPython:
447 476
448 477 .. code-block:: bash
449 478
450 479 $> ipython qtconsole --profile=myprofile
451 480
452 481 and :command:`ipcluster` is simply a wrapper for its various subcommands (start,
453 482 stop, engines).
454 483
455 484 .. code-block:: bash
456 485
457 486 $> ipcluster start --profile=myprofile --n=4
458 487
459 488
460 489 To see a list of the available aliases, flags, and subcommands for an IPython application, simply pass ``-h`` or ``--help``. And to see the full list of configurable options (*very* long), pass ``--help-all``.
461 490
462 491
463 492 Design requirements
464 493 ===================
465 494
466 495 Here are the main requirements we wanted our configuration system to have:
467 496
468 497 * Support for hierarchical configuration information.
469 498
470 499 * Full integration with command line option parsers. Often, you want to read
471 500 a configuration file, but then override some of the values with command line
472 501 options. Our configuration system automates this process and allows each
473 502 command line option to be linked to a particular attribute in the
474 503 configuration hierarchy that it will override.
475 504
476 505 * Configuration files that are themselves valid Python code. This accomplishes
477 506 many things. First, it becomes possible to put logic in your configuration
478 507 files that sets attributes based on your operating system, network setup,
479 508 Python version, etc. Second, Python has a super simple syntax for accessing
480 509 hierarchical data structures, namely regular attribute access
481 510 (``Foo.Bar.Bam.name``). Third, using Python makes it easy for users to
482 511 import configuration attributes from one configuration file to another.
483 512 Fourth, even though Python is dynamically typed, it does have types that can
484 513 be checked at runtime. Thus, a ``1`` in a config file is the integer '1',
485 514 while a ``'1'`` is a string.
486 515
487 516 * A fully automated method for getting the configuration information to the
488 517 classes that need it at runtime. Writing code that walks a configuration
489 518 hierarchy to extract a particular attribute is painful. When you have
490 519 complex configuration information with hundreds of attributes, this makes
491 520 you want to cry.
492 521
493 522 * Type checking and validation that doesn't require the entire configuration
494 523 hierarchy to be specified statically before runtime. Python is a very
495 524 dynamic language and you don't always know everything that needs to be
496 525 configured when a program starts.
497 526
498 527
499 528 .. _`XDG Base Directory`: http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
@@ -1,145 +1,160 b''
1 1 .. _tutorial:
2 2
3 3 ======================
4 4 Introducing IPython
5 5 ======================
6 6
7 7 You don't need to know anything beyond Python to start using IPython – just type
8 8 commands as you would at the standard Python prompt. But IPython can do much
9 9 more than the standard prompt. Some key features are described here. For more
10 10 information, check the :ref:`tips page <tips>`, or look at examples in the
11 11 `IPython cookbook <http://wiki.ipython.org/index.php?title=Cookbook>`_.
12 12
13 13 If you've never used Python before, you might want to look at `the official
14 14 tutorial <http://docs.python.org/tutorial/>`_ or an alternative, `Dive into
15 15 Python <http://diveintopython.org/toc/index.html>`_.
16 16
17 17 Tab completion
18 18 ==============
19 19
20 20 Tab completion, especially for attributes, is a convenient way to explore the
21 21 structure of any object you're dealing with. Simply type ``object_name.<TAB>``
22 22 to view the object's attributes (see :ref:`the readline section <readline>` for
23 23 more). Besides Python objects and keywords, tab completion also works on file
24 24 and directory names.
25 25
26 26 Exploring your objects
27 27 ======================
28 28
29 29 Typing ``object_name?`` will print all sorts of details about any object,
30 30 including docstrings, function definition lines (for call arguments) and
31 31 constructor details for classes. To get specific information on an object, you
32 32 can use the magic commands ``%pdoc``, ``%pdef``, ``%psource`` and ``%pfile``
33 33
34 34 Magic functions
35 35 ===============
36 36
37 37 IPython has a set of predefined 'magic functions' that you can call with a
38 38 command line style syntax. These include:
39 39
40 40 - Functions that work with code: ``%run``, ``%edit``, ``%save``, ``%macro``,
41 41 ``%recall``, etc.
42 42 - Functions which affect the shell: ``%colors``, ``%xmode``, ``%autoindent``, etc.
43 43 - Other functions such as ``%reset``, ``%timeit`` or ``%paste``.
44 44
45 45 You can always call these using the % prefix, and if you're typing one on a line
46 46 by itself, you can omit even that::
47 47
48 48 run thescript.py
49 49
50 50 For more details on any magic function, call ``%somemagic?`` to read its
51 51 docstring. To see all the available magic functions, call ``%lsmagic``.
52 52
53 53 Running and Editing
54 54 -------------------
55 55
56 56 The %run magic command allows you to run any python script and load all of its
57 57 data directly into the interactive namespace. Since the file is re-read from
58 58 disk each time, changes you make to it are reflected immediately (unlike
59 59 imported modules, which have to be specifically reloaded). IPython also includes
60 60 :ref:`dreload <dreload>`, a recursive reload function.
61 61
62 62 %run has special flags for timing the execution of your scripts (-t), or for
63 63 running them under the control of either Python's pdb debugger (-d) or
64 64 profiler (-p).
65 65
66 66 The %edit command gives a reasonable approximation of multiline editing,
67 67 by invoking your favorite editor on the spot. IPython will execute the
68 68 code you type in there as if it were typed interactively.
69 69
70 70 Debugging
71 71 ---------
72 72
73 73 After an exception occurs, you can call ``%debug`` to jump into the Python
74 74 debugger (pdb) and examine the problem. Alternatively, if you call ``%pdb``,
75 75 IPython will automatically start the debugger on any uncaught exception. You can
76 76 print variables, see code, execute statements and even walk up and down the
77 77 call stack to track down the true source of the problem. Running programs with
78 78 %run and pdb active can be an efficient way to develop and debug code, in many
79 79 cases eliminating the need for print statements or external debugging tools.
80 80
81 81 You can also step through a program from the beginning by calling
82 82 ``%run -d theprogram.py``.
83 83
84 84 History
85 85 =======
86 86
87 87 IPython stores both the commands you enter, and the results it produces. You
88 88 can easily go through previous commands with the up- and down-arrow keys, or
89 89 access your history in more sophisticated ways.
90 90
91 91 Input and output history are kept in variables called ``In`` and ``Out``, which
92 92 can both be indexed by the prompt number on which they occurred, e.g. ``In[4]``.
93 93 The last three objects in output history are also kept in variables named ``_``,
94 94 ``__`` and ``___``.
95 95
96 96 You can use the ``%history`` magic function to examine past input and output.
97 97 Input history from previous sessions is saved in a database, and IPython can be
98 98 configured to save output history.
99 99
100 100 Several other magic functions can use your input history, including ``%edit``,
101 101 ``%rerun``, ``%recall``, ``%macro``, ``%save`` and ``%pastebin``. You can use a
102 102 standard format to refer to lines::
103 103
104 104 %pastebin 3 18-20 ~1/1-5
105 105
106 106 This will take line 3 and lines 18 to 20 from the current session, and lines
107 107 1-5 from the previous session.
108 108
109 109 System shell commands
110 110 =====================
111 111
112 112 To run any command at the system shell, simply prefix it with !, e.g.::
113 113
114 114 !ping www.bbc.co.uk
115 115
116 116 You can capture the output into a Python list, e.g.: ``files = !ls``. To pass
117 117 the values of Python variables or expressions to system commands, prefix them
118 118 with $: ``!grep -rF $pattern ipython/*``. See :ref:`our shell section
119 119 <system_shell_access>` for more details.
120 120
121 121 Define your own system aliases
122 122 ------------------------------
123 123
124 124 It's convenient to have aliases to the system commands you use most often.
125 125 This allows you to work seamlessly from inside IPython with the same commands
126 126 you are used to in your system shell. IPython comes with some pre-defined
127 127 aliases and a complete system for changing directories, both via a stack (see
128 128 %pushd, %popd and %dhist) and via direct %cd. The latter keeps a history of
129 129 visited directories and allows you to go to any previously visited one.
130 130
131 131
132 132 Configuration
133 133 =============
134 134
135 135 Much of IPython can be tweaked through configuration. To get started, use the
136 136 command ``ipython profile create`` to produce the default config files. These
137 137 will be placed in :file:`~/.ipython/profile_default` or
138 138 :file:`~/.config/ipython/profile_default`, and contain comments explaining what
139 139 the various options do.
140 140
141 141 Profiles allow you to use IPython for different tasks, keeping separate config
142 142 files and history for each one. More details in :ref:`the profiles section
143 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
@@ -1,382 +1,382 b''
1 1 # encoding: utf-8
2 2 """
3 3 This module defines the things that are used in setup.py for building IPython
4 4
5 5 This includes:
6 6
7 7 * The basic arguments to setup
8 8 * Functions for finding things like packages, package data, etc.
9 9 * A function for checking dependencies.
10 10 """
11 11 from __future__ import print_function
12 12
13 13 #-------------------------------------------------------------------------------
14 14 # Copyright (C) 2008 The IPython Development Team
15 15 #
16 16 # Distributed under the terms of the BSD License. The full license is in
17 17 # the file COPYING, distributed as part of this software.
18 18 #-------------------------------------------------------------------------------
19 19
20 20 #-------------------------------------------------------------------------------
21 21 # Imports
22 22 #-------------------------------------------------------------------------------
23 23 import os
24 24 import sys
25 25
26 26 try:
27 27 from configparser import ConfigParser
28 28 except:
29 29 from ConfigParser import ConfigParser
30 30 from distutils.command.build_py import build_py
31 31 from glob import glob
32 32
33 33 from setupext import install_data_ext
34 34
35 35 #-------------------------------------------------------------------------------
36 36 # Useful globals and utility functions
37 37 #-------------------------------------------------------------------------------
38 38
39 39 # A few handy globals
40 40 isfile = os.path.isfile
41 41 pjoin = os.path.join
42 42
43 43 def oscmd(s):
44 44 print(">", s)
45 45 os.system(s)
46 46
47 47 try:
48 48 execfile
49 49 except NameError:
50 50 def execfile(fname, globs, locs=None):
51 51 locs = locs or globs
52 52 exec(compile(open(fname).read(), fname, "exec"), globs, locs)
53 53
54 54 # A little utility we'll need below, since glob() does NOT allow you to do
55 55 # exclusion on multiple endings!
56 56 def file_doesnt_endwith(test,endings):
57 57 """Return true if test is a file and its name does NOT end with any
58 58 of the strings listed in endings."""
59 59 if not isfile(test):
60 60 return False
61 61 for e in endings:
62 62 if test.endswith(e):
63 63 return False
64 64 return True
65 65
66 66 #---------------------------------------------------------------------------
67 67 # Basic project information
68 68 #---------------------------------------------------------------------------
69 69
70 70 # release.py contains version, authors, license, url, keywords, etc.
71 71 execfile(pjoin('IPython','core','release.py'), globals())
72 72
73 73 # Create a dict with the basic information
74 74 # This dict is eventually passed to setup after additional keys are added.
75 75 setup_args = dict(
76 76 name = name,
77 77 version = version,
78 78 description = description,
79 79 long_description = long_description,
80 80 author = author,
81 81 author_email = author_email,
82 82 url = url,
83 83 download_url = download_url,
84 84 license = license,
85 85 platforms = platforms,
86 86 keywords = keywords,
87 87 classifiers = classifiers,
88 88 cmdclass = {'install_data': install_data_ext},
89 89 )
90 90
91 91
92 92 #---------------------------------------------------------------------------
93 93 # Find packages
94 94 #---------------------------------------------------------------------------
95 95
96 96 def find_packages():
97 97 """
98 98 Find all of IPython's packages.
99 99 """
100 100 excludes = ['deathrow']
101 101 packages = []
102 102 for dir,subdirs,files in os.walk('IPython'):
103 103 package = dir.replace(os.path.sep, '.')
104 104 if any([ package.startswith('IPython.'+exc) for exc in excludes ]):
105 105 # package is to be excluded (e.g. deathrow)
106 106 continue
107 107 if '__init__.py' not in files:
108 108 # not a package
109 109 continue
110 110 packages.append(package)
111 111 return packages
112 112
113 113 #---------------------------------------------------------------------------
114 114 # Find package data
115 115 #---------------------------------------------------------------------------
116 116
117 117 def find_package_data():
118 118 """
119 119 Find IPython's package_data.
120 120 """
121 121 # This is not enough for these things to appear in an sdist.
122 122 # We need to muck with the MANIFEST to get this to work
123 123
124 124 # walk notebook resources:
125 125 cwd = os.getcwd()
126 126 os.chdir(os.path.join('IPython', 'frontend', 'html', 'notebook'))
127 127 static_walk = list(os.walk('static'))
128 128 os.chdir(cwd)
129 129 static_data = []
130 130 for parent, dirs, files in static_walk:
131 131 for f in files:
132 132 static_data.append(os.path.join(parent, f))
133 133
134 134 package_data = {
135 'IPython.config.profile' : ['README', '*/*.py'],
135 'IPython.config.profile' : ['README*', '*/*.py'],
136 136 'IPython.testing' : ['*.txt'],
137 137 'IPython.frontend.html.notebook' : ['templates/*'] + static_data,
138 138 'IPython.frontend.qt.console' : ['resources/icon/*.svg'],
139 139 }
140 140 return package_data
141 141
142 142
143 143 #---------------------------------------------------------------------------
144 144 # Find data files
145 145 #---------------------------------------------------------------------------
146 146
147 147 def make_dir_struct(tag,base,out_base):
148 148 """Make the directory structure of all files below a starting dir.
149 149
150 150 This is just a convenience routine to help build a nested directory
151 151 hierarchy because distutils is too stupid to do this by itself.
152 152
153 153 XXX - this needs a proper docstring!
154 154 """
155 155
156 156 # we'll use these a lot below
157 157 lbase = len(base)
158 158 pathsep = os.path.sep
159 159 lpathsep = len(pathsep)
160 160
161 161 out = []
162 162 for (dirpath,dirnames,filenames) in os.walk(base):
163 163 # we need to strip out the dirpath from the base to map it to the
164 164 # output (installation) path. This requires possibly stripping the
165 165 # path separator, because otherwise pjoin will not work correctly
166 166 # (pjoin('foo/','/bar') returns '/bar').
167 167
168 168 dp_eff = dirpath[lbase:]
169 169 if dp_eff.startswith(pathsep):
170 170 dp_eff = dp_eff[lpathsep:]
171 171 # The output path must be anchored at the out_base marker
172 172 out_path = pjoin(out_base,dp_eff)
173 173 # Now we can generate the final filenames. Since os.walk only produces
174 174 # filenames, we must join back with the dirpath to get full valid file
175 175 # paths:
176 176 pfiles = [pjoin(dirpath,f) for f in filenames]
177 177 # Finally, generate the entry we need, which is a pari of (output
178 178 # path, files) for use as a data_files parameter in install_data.
179 179 out.append((out_path, pfiles))
180 180
181 181 return out
182 182
183 183
184 184 def find_data_files():
185 185 """
186 186 Find IPython's data_files.
187 187
188 188 Most of these are docs.
189 189 """
190 190
191 191 docdirbase = pjoin('share', 'doc', 'ipython')
192 192 manpagebase = pjoin('share', 'man', 'man1')
193 193
194 194 # Simple file lists can be made by hand
195 195 manpages = filter(isfile, glob(pjoin('docs','man','*.1.gz')))
196 196 if not manpages:
197 197 # When running from a source tree, the manpages aren't gzipped
198 198 manpages = filter(isfile, glob(pjoin('docs','man','*.1')))
199 199 igridhelpfiles = filter(isfile,
200 200 glob(pjoin('IPython','extensions','igrid_help.*')))
201 201
202 202 # For nested structures, use the utility above
203 203 example_files = make_dir_struct(
204 204 'data',
205 205 pjoin('docs','examples'),
206 206 pjoin(docdirbase,'examples')
207 207 )
208 208 manual_files = make_dir_struct(
209 209 'data',
210 210 pjoin('docs','html'),
211 211 pjoin(docdirbase,'manual')
212 212 )
213 213
214 214 # And assemble the entire output list
215 215 data_files = [ (manpagebase, manpages),
216 216 (pjoin(docdirbase, 'extensions'), igridhelpfiles),
217 217 ] + manual_files + example_files
218 218
219 219 return data_files
220 220
221 221
222 222 def make_man_update_target(manpage):
223 223 """Return a target_update-compliant tuple for the given manpage.
224 224
225 225 Parameters
226 226 ----------
227 227 manpage : string
228 228 Name of the manpage, must include the section number (trailing number).
229 229
230 230 Example
231 231 -------
232 232
233 233 >>> make_man_update_target('ipython.1') #doctest: +NORMALIZE_WHITESPACE
234 234 ('docs/man/ipython.1.gz',
235 235 ['docs/man/ipython.1'],
236 236 'cd docs/man && gzip -9c ipython.1 > ipython.1.gz')
237 237 """
238 238 man_dir = pjoin('docs', 'man')
239 239 manpage_gz = manpage + '.gz'
240 240 manpath = pjoin(man_dir, manpage)
241 241 manpath_gz = pjoin(man_dir, manpage_gz)
242 242 gz_cmd = ( "cd %(man_dir)s && gzip -9c %(manpage)s > %(manpage_gz)s" %
243 243 locals() )
244 244 return (manpath_gz, [manpath], gz_cmd)
245 245
246 246 #---------------------------------------------------------------------------
247 247 # Find scripts
248 248 #---------------------------------------------------------------------------
249 249
250 250 def find_scripts(entry_points=False, suffix=''):
251 251 """Find IPython's scripts.
252 252
253 253 if entry_points is True:
254 254 return setuptools entry_point-style definitions
255 255 else:
256 256 return file paths of plain scripts [default]
257 257
258 258 suffix is appended to script names if entry_points is True, so that the
259 259 Python 3 scripts get named "ipython3" etc.
260 260 """
261 261 if entry_points:
262 262 console_scripts = [s % suffix for s in [
263 263 'ipython%s = IPython.frontend.terminal.ipapp:launch_new_instance',
264 264 'pycolor%s = IPython.utils.PyColorize:main',
265 265 'ipcontroller%s = IPython.parallel.apps.ipcontrollerapp:launch_new_instance',
266 266 'ipengine%s = IPython.parallel.apps.ipengineapp:launch_new_instance',
267 267 'iplogger%s = IPython.parallel.apps.iploggerapp:launch_new_instance',
268 268 'ipcluster%s = IPython.parallel.apps.ipclusterapp:launch_new_instance',
269 269 'iptest%s = IPython.testing.iptest:main',
270 270 'irunner%s = IPython.lib.irunner:main'
271 271 ]]
272 272 gui_scripts = [s % suffix for s in [
273 273 'ipython%s-qtconsole = IPython.frontend.qt.console.qtconsoleapp:main',
274 274 ]]
275 275 scripts = dict(console_scripts=console_scripts, gui_scripts=gui_scripts)
276 276 else:
277 277 parallel_scripts = pjoin('IPython','parallel','scripts')
278 278 main_scripts = pjoin('IPython','scripts')
279 279 scripts = [
280 280 pjoin(parallel_scripts, 'ipengine'),
281 281 pjoin(parallel_scripts, 'ipcontroller'),
282 282 pjoin(parallel_scripts, 'ipcluster'),
283 283 pjoin(parallel_scripts, 'iplogger'),
284 284 pjoin(main_scripts, 'ipython'),
285 285 pjoin(main_scripts, 'pycolor'),
286 286 pjoin(main_scripts, 'irunner'),
287 287 pjoin(main_scripts, 'iptest')
288 288 ]
289 289 return scripts
290 290
291 291 #---------------------------------------------------------------------------
292 292 # Verify all dependencies
293 293 #---------------------------------------------------------------------------
294 294
295 295 def check_for_dependencies():
296 296 """Check for IPython's dependencies.
297 297
298 298 This function should NOT be called if running under setuptools!
299 299 """
300 300 from setupext.setupext import (
301 301 print_line, print_raw, print_status,
302 302 check_for_sphinx, check_for_pygments,
303 303 check_for_nose, check_for_pexpect,
304 304 check_for_pyzmq, check_for_readline
305 305 )
306 306 print_line()
307 307 print_raw("BUILDING IPYTHON")
308 308 print_status('python', sys.version)
309 309 print_status('platform', sys.platform)
310 310 if sys.platform == 'win32':
311 311 print_status('Windows version', sys.getwindowsversion())
312 312
313 313 print_raw("")
314 314 print_raw("OPTIONAL DEPENDENCIES")
315 315
316 316 check_for_sphinx()
317 317 check_for_pygments()
318 318 check_for_nose()
319 319 check_for_pexpect()
320 320 check_for_pyzmq()
321 321 check_for_readline()
322 322
323 323 def record_commit_info(pkg_dir, build_cmd=build_py):
324 324 """ Return extended build command class for recording commit
325 325
326 326 The extended command tries to run git to find the current commit, getting
327 327 the empty string if it fails. It then writes the commit hash into a file
328 328 in the `pkg_dir` path, named ``.git_commit_info.ini``.
329 329
330 330 In due course this information can be used by the package after it is
331 331 installed, to tell you what commit it was installed from if known.
332 332
333 333 To make use of this system, you need a package with a .git_commit_info.ini
334 334 file - e.g. ``myproject/.git_commit_info.ini`` - that might well look like
335 335 this::
336 336
337 337 # This is an ini file that may contain information about the code state
338 338 [commit hash]
339 339 # The line below may contain a valid hash if it has been substituted
340 340 # during 'git archive'
341 341 archive_subst_hash=$Format:%h$
342 342 # This line may be modified by the install process
343 343 install_hash=
344 344
345 345 The .git_commit_info file above is also designed to be used with git
346 346 substitution - so you probably also want a ``.gitattributes`` file in the
347 347 root directory of your working tree that contains something like this::
348 348
349 349 myproject/.git_commit_info.ini export-subst
350 350
351 351 That will cause the ``.git_commit_info.ini`` file to get filled in by ``git
352 352 archive`` - useful in case someone makes such an archive - for example with
353 353 via the github 'download source' button.
354 354
355 355 Although all the above will work as is, you might consider having something
356 356 like a ``get_info()`` function in your package to display the commit
357 357 information at the terminal. See the ``pkg_info.py`` module in the nipy
358 358 package for an example.
359 359 """
360 360 class MyBuildPy(build_cmd):
361 361 ''' Subclass to write commit data into installation tree '''
362 362 def run(self):
363 363 build_cmd.run(self)
364 364 import subprocess
365 365 proc = subprocess.Popen('git rev-parse --short HEAD',
366 366 stdout=subprocess.PIPE,
367 367 stderr=subprocess.PIPE,
368 368 shell=True)
369 369 repo_commit, _ = proc.communicate()
370 370 # We write the installation commit even if it's empty
371 371 cfg_parser = ConfigParser()
372 372 cfg_parser.read(pjoin(pkg_dir, '.git_commit_info.ini'))
373 373 if not cfg_parser.has_section('commit hash'):
374 374 # just in case the ini file is empty or doesn't exist, somehow
375 375 # we don't want the next line to raise
376 376 cfg_parser.add_section('commit hash')
377 377 cfg_parser.set('commit hash', 'install_hash', repo_commit.decode('ascii'))
378 378 out_pth = pjoin(self.build_lib, pkg_dir, '.git_commit_info.ini')
379 379 out_file = open(out_pth, 'wt')
380 380 cfg_parser.write(out_file)
381 381 out_file.close()
382 382 return MyBuildPy
General Comments 0
You need to be logged in to leave comments. Login now