##// END OF EJS Templates
Cosmetic cleanups: put all imports in a single line, and sort them...
fperez -
Show More

The requested changes are too big and content was truncated. Show full diff

@@ -1,116 +1,116 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Configuration loader
3 3
4 $Id: ConfigLoader.py 525 2005-02-19 10:53:12Z fperez $"""
4 $Id: ConfigLoader.py 958 2005-12-27 23:17:51Z fperez $"""
5 5
6 6 #*****************************************************************************
7 7 # Copyright (C) 2001-2004 Fernando Perez. <fperez@colorado.edu>
8 8 #
9 9 # Distributed under the terms of the BSD License. The full license is in
10 10 # the file COPYING, distributed as part of this software.
11 11 #*****************************************************************************
12 12
13 13 from IPython import Release
14 14 __author__ = '%s <%s>' % Release.authors['Fernando']
15 15 __license__ = Release.license
16 16
17 import exceptions
17 18 import os
18 19 from pprint import pprint
19 import exceptions
20 20
21 21 from IPython import ultraTB
22 22 from IPython.Struct import Struct
23 23 from IPython.genutils import *
24 24
25 25 class ConfigLoaderError(exceptions.Exception):
26 26 """Exception for ConfigLoader class."""
27 27
28 28 def __init__(self,args=None):
29 29 self.args = args
30 30
31 31 class ConfigLoader:
32 32
33 33 """Configuration file loader capable of handling recursive inclusions and
34 34 with parametrized conflict resolution for multiply found keys."""
35 35
36 36 def __init__(self,conflict=None,field_sep=None,reclimit=15):
37 37
38 38 """The reclimit parameter controls the number of recursive
39 39 configuration file inclusions. This way we can stop early on (before
40 40 python's own recursion limit is hit) if there is a circular
41 41 inclusion.
42 42
43 43 - conflict: dictionary for conflict resolutions (see Struct.merge())
44 44
45 45 """
46 46 self.conflict = conflict
47 47 self.field_sep = field_sep
48 48 self.reset(reclimit)
49 49
50 50 def reset(self,reclimit=15):
51 51 self.reclimit = reclimit
52 52 self.recdepth = 0
53 53 self.included = []
54 54
55 55 def load(self,fname,convert=None,recurse_key='',incpath = '.',**kw):
56 56 """Load a configuration file, return the resulting Struct.
57 57
58 58 Call: load_config(fname,convert=None,conflict=None,recurse_key='')
59 59
60 60 - fname: file to load from.
61 61 - convert: dictionary of type conversions (see read_dict())
62 62 - recurse_key: keyword in dictionary to trigger recursive file
63 63 inclusions.
64 64 """
65 65
66 66 if self.recdepth > self.reclimit:
67 67 raise ConfigLoaderError, 'maximum recursive inclusion of rcfiles '+\
68 68 'exceeded: ' + `self.recdepth` + \
69 69 '.\nMaybe you have a circular chain of inclusions?'
70 70 self.recdepth += 1
71 71 fname = filefind(fname,incpath)
72 72 data = Struct()
73 73 # avoid including the same file more than once
74 74 if fname in self.included:
75 75 return data
76 76 Xinfo = ultraTB.AutoFormattedTB()
77 77 if convert==None and recurse_key : convert = {qwflat:recurse_key}
78 78 # for production, change warn to 0:
79 79 data.merge(read_dict(fname,convert,fs=self.field_sep,strip=1,
80 80 warn=0,no_empty=0,**kw))
81 81 # keep track of successfully loaded files
82 82 self.included.append(fname)
83 83 if recurse_key in data.keys():
84 84 for incfilename in data[recurse_key]:
85 85 found=0
86 86 try:
87 87 incfile = filefind(incfilename,incpath)
88 88 except IOError:
89 89 if os.name in ['nt','dos']:
90 90 try:
91 91 # Try again with '.ini' extension
92 92 incfilename += '.ini'
93 93 incfile = filefind(incfilename,incpath)
94 94 except IOError:
95 95 found = 0
96 96 else:
97 97 found = 1
98 98 else:
99 99 found = 0
100 100 else:
101 101 found = 1
102 102 if found:
103 103 try:
104 104 data.merge(self.load(incfile,convert,recurse_key,
105 105 incpath,**kw),
106 106 self.conflict)
107 107 except:
108 108 Xinfo()
109 109 warn('Problem loading included file: '+
110 110 `incfilename` + '. Ignoring it...')
111 111 else:
112 112 warn('File `%s` not found. Included by %s' % (incfilename,fname))
113 113
114 114 return data
115 115
116 116 # end ConfigLoader
@@ -1,110 +1,111 b''
1 1 # -*- coding: utf-8 -*-
2 2 """sys.excepthook for IPython itself, leaves a detailed report on disk.
3 3
4 $Id: CrashHandler.py 951 2005-12-25 00:57:24Z fperez $"""
4 $Id: CrashHandler.py 958 2005-12-27 23:17:51Z fperez $"""
5 5
6 6 #*****************************************************************************
7 7 # Copyright (C) 2001-2004 Fernando Perez. <fperez@colorado.edu>
8 8 #
9 9 # Distributed under the terms of the BSD License. The full license is in
10 10 # the file COPYING, distributed as part of this software.
11 11 #*****************************************************************************
12 12
13 13 from IPython import Release
14 14 __author__ = '%s <%s>' % Release.authors['Fernando']
15 15 __license__ = Release.license
16 16 __version__ = Release.version
17 17
18 18 #****************************************************************************
19 19 # Required modules
20 20
21 21 # From the standard library
22 import os,sys
22 import os
23 import sys
23 24 from pprint import pprint,pformat
24 25
25 26 # Homebrewed
26 27 from IPython.Itpl import Itpl,itpl,printpl
27 28 from IPython.ColorANSI import ColorScheme,ColorSchemeTable # too long names
28 29 from IPython import ultraTB
29 30 from IPython.genutils import *
30 31
31 32 #****************************************************************************
32 33 class CrashHandler:
33 34 """sys.excepthook for IPython itself, leaves a detailed report on disk."""
34 35
35 36 def __init__(self,IP):
36 37 self.IP = IP # IPython instance
37 38 self.bug_contact = Release.authors['Fernando'][0]
38 39 self.mailto = Release.authors['Fernando'][1]
39 40
40 41 def __call__(self,etype, evalue, etb):
41 42
42 43 # Report tracebacks shouldn't use color in general (safer for users)
43 44 color_scheme = 'NoColor'
44 45
45 46 # Use this ONLY for developer debugging (keep commented out for release)
46 47 #color_scheme = 'Linux' # dbg
47 48
48 49 try:
49 50 rptdir = self.IP.rc.ipythondir
50 51 except:
51 52 rptdir = os.getcwd()
52 53 if not os.path.isdir(rptdir):
53 54 rptdir = os.getcwd()
54 55 self.report_name = os.path.join(rptdir,'IPython_crash_report.txt')
55 56 self.TBhandler = ultraTB.VerboseTB(color_scheme=color_scheme,long_header=1)
56 57 traceback = self.TBhandler.text(etype,evalue,etb,context=31)
57 58
58 59 # print traceback to screen
59 60 print >> sys.stderr, traceback
60 61
61 62 # and generate a complete report on disk
62 63 try:
63 64 report = open(self.report_name,'w')
64 65 except:
65 66 print >> sys.stderr, 'Could not create crash report on disk.'
66 67 return
67 68
68 69 msg = itpl('\n'+'*'*70+'\n'
69 70 """
70 71 Oops, IPython crashed. We do our best to make it stable, but...
71 72
72 73 A crash report was automatically generated with the following information:
73 74 - A verbatim copy of the traceback above this text.
74 75 - A copy of your input history during this session.
75 76 - Data on your current IPython configuration.
76 77
77 78 It was left in the file named:
78 79 \t'$self.report_name'
79 80 If you can email this file to the developers, the information in it will help
80 81 them in understanding and correcting the problem.
81 82
82 83 You can mail it to $self.bug_contact at $self.mailto
83 84 with the subject 'IPython Crash Report'.
84 85
85 86 If you want to do it now, the following command will work (under Unix):
86 87 mail -s 'IPython Crash Report' $self.mailto < $self.report_name
87 88
88 89 To ensure accurate tracking of this issue, please file a report about it at:
89 90 http://www.scipy.net/roundup/ipython (IPython's online bug tracker).
90 91 """)
91 92 print >> sys.stderr, msg
92 93
93 94 sec_sep = '\n\n'+'*'*75+'\n\n'
94 95 report.write('*'*75+'\n\n'+'IPython post-mortem report\n\n')
95 96 report.write('IPython version: %s \n\n' % Release.version)
96 97 report.write('SVN revision : %s \n\n' % Release.revision)
97 98 report.write('Platform info : os.name -> %s, sys.platform -> %s' %
98 99 (os.name,sys.platform) )
99 100 report.write(sec_sep+'Current user configuration structure:\n\n')
100 101 report.write(pformat(self.IP.rc.dict()))
101 102 report.write(sec_sep+'Crash traceback:\n\n' + traceback)
102 103 try:
103 104 report.write(sec_sep+"History of session input:")
104 105 for line in self.IP.user_ns['_ih']:
105 106 report.write(line)
106 107 report.write('\n*** Last line of input (may not be in above history):\n')
107 108 report.write(self.IP._last_input_line+'\n')
108 109 except:
109 110 pass
110 111 report.close()
@@ -1,671 +1,671 b''
1 1 # -*- coding: utf-8 -*-
2 2 """DPyGetOpt -- Demiurge Python GetOptions Module
3 3
4 $Id: DPyGetOpt.py 389 2004-10-09 07:59:30Z fperez $
4 $Id: DPyGetOpt.py 958 2005-12-27 23:17:51Z fperez $
5 5
6 6 This module is modeled after perl's Getopt::Long module-- which
7 7 is, in turn, modeled after GNU's extended getopt() function.
8 8
9 9 Upon instantiation, the option specification should be a sequence
10 10 (list) of option definitions.
11 11
12 12 Options that take no arguments should simply contain the name of
13 13 the option. If a ! is post-pended, the option can be negated by
14 14 prepending 'no'; ie 'debug!' specifies that -debug and -nodebug
15 15 should be accepted.
16 16
17 17 Mandatory arguments to options are specified using a postpended
18 18 '=' + a type specifier. '=s' specifies a mandatory string
19 19 argument, '=i' specifies a mandatory integer argument, and '=f'
20 20 specifies a mandatory real number. In all cases, the '=' can be
21 21 substituted with ':' to specify that the argument is optional.
22 22
23 23 Dashes '-' in option names are allowed.
24 24
25 25 If an option has the character '@' postpended (after the
26 26 argumentation specification), it can appear multiple times within
27 27 each argument list that is processed. The results will be stored
28 28 in a list.
29 29
30 30 The option name can actually be a list of names separated by '|'
31 31 characters; ie-- 'foo|bar|baz=f@' specifies that all -foo, -bar,
32 32 and -baz options that appear on within the parsed argument list
33 33 must have a real number argument and that the accumulated list
34 34 of values will be available under the name 'foo'
35 35
36 $Id: DPyGetOpt.py 389 2004-10-09 07:59:30Z fperez $"""
36 $Id: DPyGetOpt.py 958 2005-12-27 23:17:51Z fperez $"""
37 37
38 38 #*****************************************************************************
39 39 #
40 40 # Copyright (c) 2001 Bill Bumgarner <bbum@friday.com>
41 41 #
42 42 #
43 43 # Published under the terms of the MIT license, hereby reproduced:
44 44 #
45 45 # Permission is hereby granted, free of charge, to any person obtaining a copy
46 46 # of this software and associated documentation files (the "Software"), to
47 47 # deal in the Software without restriction, including without limitation the
48 48 # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
49 49 # sell copies of the Software, and to permit persons to whom the Software is
50 50 # furnished to do so, subject to the following conditions:
51 51 #
52 52 # The above copyright notice and this permission notice shall be included in
53 53 # all copies or substantial portions of the Software.
54 54 #
55 55 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
56 56 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
57 57 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
58 58 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
59 59 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
60 60 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
61 61 # IN THE SOFTWARE.
62 62 #
63 63 #*****************************************************************************
64 64
65 65 __author__ = 'Bill Bumgarner <bbum@friday.com>'
66 66 __license__ = 'MIT'
67 67 __version__ = '1.2'
68 68
69 69 # Modified to use re instead of regex and regsub modules.
70 70 # 2001/5/7, Jonathan Hogg <jonathan@onegoodidea.com>
71 71
72 import string
73 72 import re
73 import string
74 74 import sys
75 75 import types
76 76
77 77 arg_error = 'DPyGetOpt Argument Error'
78 78 spec_error = 'DPyGetOpt Specification Error'
79 79 term_error = 'DPyGetOpt Termination Error'
80 80
81 81 specificationExpr = re.compile('(?P<required>.)(?P<type>.)(?P<multi>@?)')
82 82
83 83 ArgRequired = 'Requires an Argument'
84 84 ArgOptional = 'Argument Optional'
85 85
86 86 # The types modules is not used for these identifiers because there
87 87 # is no identifier for 'boolean' or 'generic'
88 88 StringArgType = 'String Argument Type'
89 89 IntegerArgType = 'Integer Argument Type'
90 90 RealArgType = 'Real Argument Type'
91 91 BooleanArgType = 'Boolean Argument Type'
92 92 GenericArgType = 'Generic Argument Type'
93 93
94 94 # dictionary of conversion functions-- boolean and generic options
95 95 # do not accept arguments and do not need conversion functions;
96 96 # the identity function is used purely for convenience.
97 97 ConversionFunctions = {
98 98 StringArgType : lambda x: x,
99 99 IntegerArgType : string.atoi,
100 100 RealArgType : string.atof,
101 101 BooleanArgType : lambda x: x,
102 102 GenericArgType : lambda x: x,
103 103 }
104 104
105 105 class DPyGetOpt:
106 106
107 107 def __init__(self, spec = None, terminators = ['--']):
108 108 """
109 109 Declare and intialize instance variables
110 110
111 111 Yes, declaration is not necessary... but one of the things
112 112 I sorely miss from C/Obj-C is the concept of having an
113 113 interface definition that clearly declares all instance
114 114 variables and methods without providing any implementation
115 115 details. it is a useful reference!
116 116
117 117 all instance variables are initialized to 0/Null/None of
118 118 the appropriate type-- not even the default value...
119 119 """
120 120
121 121 # sys.stderr.write(string.join(spec) + "\n")
122 122
123 123 self.allowAbbreviations = 1 # boolean, 1 if abbreviations will
124 124 # be expanded
125 125 self.freeValues = [] # list, contains free values
126 126 self.ignoreCase = 0 # boolean, YES if ignoring case
127 127 self.needsParse = 0 # boolean, YES if need to reparse parameter spec
128 128 self.optionNames = {} # dict, all option names-- value is index of tuple
129 129 self.optionStartExpr = None # regexp defining the start of an option (ie; '-', '--')
130 130 self.optionTuples = [] # list o' tuples containing defn of options AND aliases
131 131 self.optionValues = {} # dict, option names (after alias expansion) -> option value(s)
132 132 self.orderMixed = 0 # boolean, YES if options can be mixed with args
133 133 self.posixCompliance = 0 # boolean, YES indicates posix like behaviour
134 134 self.spec = [] # list, raw specs (in case it must be reparsed)
135 135 self.terminators = terminators # list, strings that terminate argument processing
136 136 self.termValues = [] # list, values after terminator
137 137 self.terminator = None # full name of terminator that ended
138 138 # option processing
139 139
140 140 # set up defaults
141 141 self.setPosixCompliance()
142 142 self.setIgnoreCase()
143 143 self.setAllowAbbreviations()
144 144
145 145 # parse spec-- if present
146 146 if spec:
147 147 self.parseConfiguration(spec)
148 148
149 149 def setPosixCompliance(self, aFlag = 0):
150 150 """
151 151 Enables and disables posix compliance.
152 152
153 153 When enabled, '+' can be used as an option prefix and free
154 154 values can be mixed with options.
155 155 """
156 156 self.posixCompliance = aFlag
157 157 self.needsParse = 1
158 158
159 159 if self.posixCompliance:
160 160 self.optionStartExpr = re.compile('(--|-)(?P<option>[A-Za-z0-9_-]+)(?P<arg>=.*)?')
161 161 self.orderMixed = 0
162 162 else:
163 163 self.optionStartExpr = re.compile('(--|-|\+)(?P<option>[A-Za-z0-9_-]+)(?P<arg>=.*)?')
164 164 self.orderMixed = 1
165 165
166 166 def isPosixCompliant(self):
167 167 """
168 168 Returns the value of the posix compliance flag.
169 169 """
170 170 return self.posixCompliance
171 171
172 172 def setIgnoreCase(self, aFlag = 1):
173 173 """
174 174 Enables and disables ignoring case during option processing.
175 175 """
176 176 self.needsParse = 1
177 177 self.ignoreCase = aFlag
178 178
179 179 def ignoreCase(self):
180 180 """
181 181 Returns 1 if the option processor will ignore case when
182 182 processing options.
183 183 """
184 184 return self.ignoreCase
185 185
186 186 def setAllowAbbreviations(self, aFlag = 1):
187 187 """
188 188 Enables and disables the expansion of abbreviations during
189 189 option processing.
190 190 """
191 191 self.allowAbbreviations = aFlag
192 192
193 193 def willAllowAbbreviations(self):
194 194 """
195 195 Returns 1 if abbreviated options will be automatically
196 196 expanded to the non-abbreviated form (instead of causing an
197 197 unrecognized option error).
198 198 """
199 199 return self.allowAbbreviations
200 200
201 201 def addTerminator(self, newTerm):
202 202 """
203 203 Adds newTerm as terminator of option processing.
204 204
205 205 Whenever the option processor encounters one of the terminators
206 206 during option processing, the processing of options terminates
207 207 immediately, all remaining options are stored in the termValues
208 208 instance variable and the full name of the terminator is stored
209 209 in the terminator instance variable.
210 210 """
211 211 self.terminators = self.terminators + [newTerm]
212 212
213 213 def _addOption(self, oTuple):
214 214 """
215 215 Adds the option described by oTuple (name, (type, mode,
216 216 default), alias) to optionTuples. Adds index keyed under name
217 217 to optionNames. Raises spec_error if name already in
218 218 optionNames
219 219 """
220 220 (name, (type, mode, default, multi), realName) = oTuple
221 221
222 222 # verify name and add to option names dictionary
223 223 if self.optionNames.has_key(name):
224 224 if realName:
225 225 raise spec_error, 'Alias \'' + name + '\' for \'' + realName + \
226 226 '\' already used for another option or alias.'
227 227 else:
228 228 raise spec_error, 'Option named \'' + name + \
229 229 '\' specified more than once. Specification: ' + option
230 230
231 231 # validated. add to optionNames
232 232 self.optionNames[name] = self.tupleIndex
233 233 self.tupleIndex = self.tupleIndex + 1
234 234
235 235 # add to optionTuples
236 236 self.optionTuples = self.optionTuples + [oTuple]
237 237
238 238 # if type is boolean, add negation
239 239 if type == BooleanArgType:
240 240 alias = 'no' + name
241 241 specTuple = (type, mode, 0, multi)
242 242 oTuple = (alias, specTuple, name)
243 243
244 244 # verify name and add to option names dictionary
245 245 if self.optionNames.has_key(alias):
246 246 if realName:
247 247 raise spec_error, 'Negated alias \'' + name + '\' for \'' + realName + \
248 248 '\' already used for another option or alias.'
249 249 else:
250 250 raise spec_error, 'Negated option named \'' + name + \
251 251 '\' specified more than once. Specification: ' + option
252 252
253 253 # validated. add to optionNames
254 254 self.optionNames[alias] = self.tupleIndex
255 255 self.tupleIndex = self.tupleIndex + 1
256 256
257 257 # add to optionTuples
258 258 self.optionTuples = self.optionTuples + [oTuple]
259 259
260 260 def addOptionConfigurationTuple(self, oTuple):
261 261 (name, argSpec, realName) = oTuple
262 262 if self.ignoreCase:
263 263 name = string.lower(name)
264 264 if realName:
265 265 realName = string.lower(realName)
266 266 else:
267 267 realName = name
268 268
269 269 oTuple = (name, argSpec, realName)
270 270
271 271 # add option
272 272 self._addOption(oTuple)
273 273
274 274 def addOptionConfigurationTuples(self, oTuple):
275 275 if type(oTuple) is ListType:
276 276 for t in oTuple:
277 277 self.addOptionConfigurationTuple(t)
278 278 else:
279 279 self.addOptionConfigurationTuple(oTuple)
280 280
281 281 def parseConfiguration(self, spec):
282 282 # destroy previous stored information + store raw spec
283 283 self.spec = spec
284 284 self.optionTuples = []
285 285 self.optionNames = {}
286 286 self.tupleIndex = 0
287 287
288 288 tupleIndex = 0
289 289
290 290 # create some regex's for parsing each spec
291 291 splitExpr = \
292 292 re.compile('(?P<names>\w+[-A-Za-z0-9|]*)?(?P<spec>!|[=:][infs]@?)?')
293 293 for option in spec:
294 294 # push to lower case (does not negatively affect
295 295 # specification)
296 296 if self.ignoreCase:
297 297 option = string.lower(option)
298 298
299 299 # break into names, specification
300 300 match = splitExpr.match(option)
301 301 if match is None:
302 302 raise spec_error, 'Invalid specification {' + option + '}'
303 303
304 304 names = match.group('names')
305 305 specification = match.group('spec')
306 306
307 307 # break name into name, aliases
308 308 nlist = string.split(names, '|')
309 309
310 310 # get name
311 311 name = nlist[0]
312 312 aliases = nlist[1:]
313 313
314 314 # specificationExpr = regex.symcomp('\(<required>.\)\(<type>.\)\(<multi>@?\)')
315 315 if not specification:
316 316 #spec tuple is ('type', 'arg mode', 'default value', 'multiple')
317 317 argType = GenericArgType
318 318 argMode = None
319 319 argDefault = 1
320 320 argMultiple = 0
321 321 elif specification == '!':
322 322 argType = BooleanArgType
323 323 argMode = None
324 324 argDefault = 1
325 325 argMultiple = 0
326 326 else:
327 327 # parse
328 328 match = specificationExpr.match(specification)
329 329 if match is None:
330 330 # failed to parse, die
331 331 raise spec_error, 'Invalid configuration for option \'' + option + '\''
332 332
333 333 # determine mode
334 334 required = match.group('required')
335 335 if required == '=':
336 336 argMode = ArgRequired
337 337 elif required == ':':
338 338 argMode = ArgOptional
339 339 else:
340 340 raise spec_error, 'Unknown requirement configuration \'' + required + '\''
341 341
342 342 # determine type
343 343 type = match.group('type')
344 344 if type == 's':
345 345 argType = StringArgType
346 346 argDefault = ''
347 347 elif type == 'i':
348 348 argType = IntegerArgType
349 349 argDefault = 1
350 350 elif type == 'f' or type == 'n':
351 351 argType = RealArgType
352 352 argDefault = 1
353 353 else:
354 354 raise spec_error, 'Unknown type specifier \'' + type + '\''
355 355
356 356 # determine quantity
357 357 if match.group('multi') == '@':
358 358 argMultiple = 1
359 359 else:
360 360 argMultiple = 0
361 361 ## end else (of not specification)
362 362
363 363 # construct specification tuple
364 364 specTuple = (argType, argMode, argDefault, argMultiple)
365 365
366 366 # add the option-- option tuple is (name, specTuple, real name)
367 367 oTuple = (name, specTuple, name)
368 368 self._addOption(oTuple)
369 369
370 370 for alias in aliases:
371 371 # drop to all lower (if configured to do so)
372 372 if self.ignoreCase:
373 373 alias = string.lower(alias)
374 374 # create configuration tuple
375 375 oTuple = (alias, specTuple, name)
376 376 # add
377 377 self._addOption(oTuple)
378 378
379 379 # successfully parsed....
380 380 self.needsParse = 0
381 381
382 382 def _getArgTuple(self, argName):
383 383 """
384 384 Returns a list containing all the specification tuples that
385 385 match argName. If none match, None is returned. If one
386 386 matches, a list with one tuple is returned. If more than one
387 387 match, a list containing all the tuples that matched is
388 388 returned.
389 389
390 390 In other words, this function does not pass judgement upon the
391 391 validity of multiple matches.
392 392 """
393 393 # is it in the optionNames dict?
394 394
395 395 try:
396 396 # sys.stderr.write(argName + string.join(self.optionNames.keys()) + "\n")
397 397
398 398 # yes, get index
399 399 tupleIndex = self.optionNames[argName]
400 400 # and return tuple as element of list
401 401 return [self.optionTuples[tupleIndex]]
402 402 except KeyError:
403 403 # are abbreviations allowed?
404 404 if not self.allowAbbreviations:
405 405 # No! terefore, this cannot be valid argument-- nothing found
406 406 return None
407 407
408 408 # argName might be an abbreviation (and, abbreviations must
409 409 # be allowed... or this would not have been reached!)
410 410
411 411 # create regex for argName
412 412 argExpr = re.compile('^' + argName)
413 413
414 414 tuples = filter(lambda x, argExpr=argExpr: argExpr.search(x[0]) is not None,
415 415 self.optionTuples)
416 416
417 417 if not len(tuples):
418 418 return None
419 419 else:
420 420 return tuples
421 421
422 422 def _isTerminator(self, optionName):
423 423 """
424 424 Returns the full name of the terminator if optionName is a valid
425 425 terminator. If it is, sets self.terminator to the full name of
426 426 the terminator.
427 427
428 428 If more than one terminator matched, raises a term_error with a
429 429 string describing the ambiguity.
430 430 """
431 431
432 432 # sys.stderr.write(optionName + "\n")
433 433 # sys.stderr.write(repr(self.terminators))
434 434
435 435 if optionName in self.terminators:
436 436 self.terminator = optionName
437 437 elif not self.allowAbbreviations:
438 438 return None
439 439
440 440 # regex thing in bogus
441 441 # termExpr = regex.compile('^' + optionName)
442 442
443 443 terms = filter(lambda x, on=optionName: string.find(x,on) == 0, self.terminators)
444 444
445 445 if not len(terms):
446 446 return None
447 447 elif len(terms) > 1:
448 448 raise term_error, 'Ambiguous terminator \'' + optionName + \
449 449 '\' matches ' + repr(terms)
450 450
451 451 self.terminator = terms[0]
452 452 return self.terminator
453 453
454 454 def processArguments(self, args = None):
455 455 """
456 456 Processes args, a list of arguments (including options).
457 457
458 458 If args is the same as sys.argv, automatically trims the first
459 459 argument (the executable name/path).
460 460
461 461 If an exception is not raised, the argument list was parsed
462 462 correctly.
463 463
464 464 Upon successful completion, the freeValues instance variable
465 465 will contain all the arguments that were not associated with an
466 466 option in the order they were encountered. optionValues is a
467 467 dictionary containing the value of each option-- the method
468 468 valueForOption() can be used to query this dictionary.
469 469 terminator will contain the argument encountered that terminated
470 470 option processing (or None, if a terminator was never
471 471 encountered) and termValues will contain all of the options that
472 472 appeared after the Terminator (or an empty list).
473 473 """
474 474
475 475 if hasattr(sys, "argv") and args == sys.argv:
476 476 args = sys.argv[1:]
477 477
478 478 max = len(args) # maximum index + 1
479 479 self.freeValues = [] # array to hold return values
480 480 self.optionValues= {}
481 481 index = 0 # initial index
482 482 self.terminator = None
483 483 self.termValues = []
484 484
485 485 while index < max:
486 486 # obtain argument
487 487 arg = args[index]
488 488 # increment index -- REMEMBER; it is NOW incremented
489 489 index = index + 1
490 490
491 491 # terminate immediately if option terminator encountered
492 492 if self._isTerminator(arg):
493 493 self.freeValues = self.freeValues + args[index:]
494 494 self.termValues = args[index:]
495 495 return
496 496
497 497 # is this possibly an option?
498 498 match = self.optionStartExpr.match(arg)
499 499 if match is None:
500 500 # not an option-- add to freeValues
501 501 self.freeValues = self.freeValues + [arg]
502 502 if not self.orderMixed:
503 503 # mixing not allowed; add rest of args as freeValues
504 504 self.freeValues = self.freeValues + args[index:]
505 505 # return to caller
506 506 return
507 507 else:
508 508 continue
509 509
510 510 # grab name
511 511 optName = match.group('option')
512 512
513 513 # obtain next argument-- index has already been incremented
514 514 nextArg = match.group('arg')
515 515 if nextArg:
516 516 nextArg = nextArg[1:]
517 517 index = index - 1 # put it back
518 518 else:
519 519 try:
520 520 nextArg = args[index]
521 521 except:
522 522 nextArg = None
523 523
524 524 # transpose to lower case, if necessary
525 525 if self.ignoreCase:
526 526 optName = string.lower(optName)
527 527
528 528 # obtain defining tuple
529 529 tuples = self._getArgTuple(optName)
530 530
531 531 if tuples == None:
532 532 raise arg_error, 'Illegal option \'' + arg + '\''
533 533 elif len(tuples) > 1:
534 534 raise arg_error, 'Ambiguous option \'' + arg + '\'; matches ' + \
535 535 repr(map(lambda x: x[0], tuples))
536 536 else:
537 537 config = tuples[0]
538 538
539 539 # config is now set to the configuration tuple for the
540 540 # argument
541 541 (fullName, spec, realName) = config
542 542 (optType, optMode, optDefault, optMultiple) = spec
543 543
544 544 # if opt mode required, but nextArg is none, raise an error
545 545 if (optMode == ArgRequired):
546 546 if (not nextArg) or self._isTerminator(nextArg):
547 547 # print nextArg
548 548 raise arg_error, 'Option \'' + arg + \
549 549 '\' requires an argument of type ' + optType
550 550
551 551 if (not optMode == None) and nextArg and (not self._isTerminator(nextArg)):
552 552 # nextArg defined, option configured to possibly consume arg
553 553 try:
554 554 # grab conversion function-- the try is more for internal diagnostics
555 555 func = ConversionFunctions[optType]
556 556 try:
557 557 optionValue = func(nextArg)
558 558 index = index + 1
559 559 except:
560 560 # only raise conversion error if REQUIRED to consume argument
561 561 if optMode == ArgRequired:
562 562 raise arg_error, 'Invalid argument to option \'' + arg + \
563 563 '\'; should be \'' + optType + '\''
564 564 else:
565 565 optionValue = optDefault
566 566 except arg_error:
567 567 raise arg_error, sys.exc_value
568 568 except:
569 569 raise arg_error, '(' + arg + \
570 570 ') Conversion function for \'' + optType + '\' not found.'
571 571 else:
572 572 optionValue = optDefault
573 573
574 574 # add value to options dictionary
575 575 if optMultiple:
576 576 # can be multiple values
577 577 try:
578 578 # try to append element
579 579 self.optionValues[realName] = self.optionValues[realName] + [optionValue]
580 580 except:
581 581 # failed-- must not exist; add it
582 582 self.optionValues[realName] = [optionValue]
583 583 else:
584 584 # only one value per
585 585 if self.isPosixCompliant and self.optionValues.has_key(realName):
586 586 raise arg_error, 'Argument \'' + arg + '\' occurs multiple times.'
587 587
588 588 self.optionValues[realName] = optionValue
589 589
590 590 def valueForOption(self, optionName, defaultValue = None):
591 591 """
592 592 Return the value associated with optionName. If optionName was
593 593 not encountered during parsing of the arguments, returns the
594 594 defaultValue (which defaults to None).
595 595 """
596 596 try:
597 597 optionValue = self.optionValues[optionName]
598 598 except:
599 599 optionValue = defaultValue
600 600
601 601 return optionValue
602 602
603 603 ##
604 604 ## test/example section
605 605 ##
606 606 test_error = 'Test Run Amok!'
607 607 def _test():
608 608 """
609 609 A relatively complete test suite.
610 610 """
611 611 try:
612 612 DPyGetOpt(['foo', 'bar=s', 'foo'])
613 613 except:
614 614 print 'EXCEPTION (should be \'foo\' already used..): ' + sys.exc_value
615 615
616 616 try:
617 617 DPyGetOpt(['foo|bar|apple=s@', 'baz|apple!'])
618 618 except:
619 619 print 'EXCEPTION (should be duplicate alias/name error): ' + sys.exc_value
620 620
621 621 x = DPyGetOpt(['apple|atlas=i@', 'application|executable=f@'])
622 622 try:
623 623 x.processArguments(['-app', '29.3'])
624 624 except:
625 625 print 'EXCEPTION (should be ambiguous argument): ' + sys.exc_value
626 626
627 627 x = DPyGetOpt(['foo'], ['antigravity', 'antithesis'])
628 628 try:
629 629 x.processArguments(['-foo', 'anti'])
630 630 except:
631 631 print 'EXCEPTION (should be ambiguous terminator): ' + sys.exc_value
632 632
633 633 profile = ['plain-option',
634 634 'boolean-option!',
635 635 'list-of-integers=i@',
636 636 'list-real-option|list-real-alias|list-real-pseudonym=f@',
637 637 'optional-string-option:s',
638 638 'abbreviated-string-list=s@']
639 639
640 640 terminators = ['terminator']
641 641
642 642 args = ['-plain-option',
643 643 '+noboolean-option',
644 644 '--list-of-integers', '1',
645 645 '+list-of-integers', '2',
646 646 '-list-of-integers', '3',
647 647 'freeargone',
648 648 '-list-real-option', '1.1',
649 649 '+list-real-alias', '1.2',
650 650 '--list-real-pseudonym', '1.3',
651 651 'freeargtwo',
652 652 '-abbreviated-string-list', 'String1',
653 653 '--abbreviated-s', 'String2',
654 654 '-abbrev', 'String3',
655 655 '-a', 'String4',
656 656 '-optional-string-option',
657 657 'term',
658 658 'next option should look like an invalid arg',
659 659 '-a']
660 660
661 661
662 662 print 'Using profile: ' + repr(profile)
663 663 print 'With terminator: ' + repr(terminators)
664 664 print 'Processing arguments: ' + repr(args)
665 665
666 666 go = DPyGetOpt(profile, terminators)
667 667 go.processArguments(args)
668 668
669 669 print 'Options (and values): ' + repr(go.optionValues)
670 670 print 'free args: ' + repr(go.freeValues)
671 671 print 'term args: ' + repr(go.termValues)
@@ -1,264 +1,270 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 Pdb debugger class.
4 4
5 5 Modified from the standard pdb.Pdb class to avoid including readline, so that
6 6 the command line completion of other programs which include this isn't
7 7 damaged.
8 8
9 9 In the future, this class will be expanded with improvements over the standard
10 10 pdb.
11 11
12 12 The code in this file is mainly lifted out of cmd.py in Python 2.2, with minor
13 13 changes. Licensing should therefore be under the standard Python terms. For
14 14 details on the PSF (Python Software Foundation) standard license, see:
15 15
16 16 http://www.python.org/2.2.3/license.html
17 17
18 $Id: Debugger.py 951 2005-12-25 00:57:24Z fperez $"""
18 $Id: Debugger.py 958 2005-12-27 23:17:51Z fperez $"""
19 19
20 20 from IPython import Release
21 21 __author__ = '%s <%s>' % Release.authors['Fernando']
22 22 __license__ = 'Python'
23 23
24 import pdb,bdb,cmd,os,sys,linecache
24 import bdb
25 import cmd
26 import linecache
27 import os
28 import pdb
29 import sys
30
25 31 from IPython import PyColorize, ColorANSI
26 32 from IPython.genutils import Term
27 33 from IPython.excolors import ExceptionColors
28 34
29 35 def _file_lines(fname):
30 36 """Return the contents of a named file as a list of lines.
31 37
32 38 This function never raises an IOError exception: if the file can't be
33 39 read, it simply returns an empty list."""
34 40
35 41 try:
36 42 outfile = open(fname)
37 43 except IOError:
38 44 return []
39 45 else:
40 46 out = outfile.readlines()
41 47 outfile.close()
42 48 return out
43 49
44 50
45 51 class Pdb(pdb.Pdb):
46 52 """Modified Pdb class, does not load readline."""
47 53 def __init__(self,color_scheme='NoColor'):
48 54 bdb.Bdb.__init__(self)
49 55 cmd.Cmd.__init__(self,completekey=None) # don't load readline
50 56 self.prompt = 'ipdb> ' # The default prompt is '(Pdb)'
51 57 self.aliases = {}
52 58
53 59 # Read $HOME/.pdbrc and ./.pdbrc
54 60 try:
55 61 self.rcLines = _file_lines(os.path.join(os.environ['HOME'],
56 62 ".pdbrc"))
57 63 except KeyError:
58 64 self.rcLines = []
59 65 self.rcLines.extend(_file_lines(".pdbrc"))
60 66
61 67 # Create color table: we copy the default one from the traceback
62 68 # module and add a few attributes needed for debugging
63 69 self.color_scheme_table = ExceptionColors.copy()
64 70
65 71 # shorthands
66 72 C = ColorANSI.TermColors
67 73 cst = self.color_scheme_table
68 74
69 75 cst['NoColor'].colors.breakpoint_enabled = C.NoColor
70 76 cst['NoColor'].colors.breakpoint_disabled = C.NoColor
71 77
72 78 cst['Linux'].colors.breakpoint_enabled = C.LightRed
73 79 cst['Linux'].colors.breakpoint_disabled = C.Red
74 80
75 81 cst['LightBG'].colors.breakpoint_enabled = C.LightRed
76 82 cst['LightBG'].colors.breakpoint_disabled = C.Red
77 83
78 84 self.set_colors(color_scheme)
79 85
80 86 def set_colors(self, scheme):
81 87 """Shorthand access to the color table scheme selector method."""
82 88 self.color_scheme_table.set_active_scheme(scheme)
83 89
84 90
85 91 def interaction(self, frame, traceback):
86 92 __IPYTHON__.set_completer_frame(frame)
87 93 pdb.Pdb.interaction(self, frame, traceback)
88 94
89 95
90 96 def do_up(self, arg):
91 97 pdb.Pdb.do_up(self, arg)
92 98 __IPYTHON__.set_completer_frame(self.curframe)
93 99 do_u = do_up
94 100
95 101
96 102 def do_down(self, arg):
97 103 pdb.Pdb.do_down(self, arg)
98 104 __IPYTHON__.set_completer_frame(self.curframe)
99 105 do_d = do_down
100 106
101 107
102 108 def postloop(self):
103 109 __IPYTHON__.set_completer_frame(None)
104 110
105 111
106 112 def print_stack_trace(self):
107 113 try:
108 114 for frame_lineno in self.stack:
109 115 self.print_stack_entry(frame_lineno, context = 5)
110 116 except KeyboardInterrupt:
111 117 pass
112 118
113 119
114 120 def print_stack_entry(self,frame_lineno,prompt_prefix='\n-> ',
115 121 context = 3):
116 122 frame, lineno = frame_lineno
117 123 print >>Term.cout, self.format_stack_entry(frame_lineno, '', context)
118 124
119 125
120 126 def format_stack_entry(self, frame_lineno, lprefix=': ', context = 3):
121 127 import linecache, repr
122 128
123 129 ret = ""
124 130
125 131 Colors = self.color_scheme_table.active_colors
126 132 ColorsNormal = Colors.Normal
127 133 tpl_link = '%s%%s%s' % (Colors.filenameEm, ColorsNormal)
128 134 tpl_call = 'in %s%%s%s%%s%s' % (Colors.vName, Colors.valEm, ColorsNormal)
129 135 tpl_line = '%%s%s%%s %s%%s' % (Colors.lineno, ColorsNormal)
130 136 tpl_line_em = '%%s%s%%s %s%%s%s' % (Colors.linenoEm, Colors.line,
131 137 ColorsNormal)
132 138
133 139 frame, lineno = frame_lineno
134 140
135 141 return_value = ''
136 142 if '__return__' in frame.f_locals:
137 143 rv = frame.f_locals['__return__']
138 144 #return_value += '->'
139 145 return_value += repr.repr(rv) + '\n'
140 146 ret += return_value
141 147
142 148 #s = filename + '(' + `lineno` + ')'
143 149 filename = self.canonic(frame.f_code.co_filename)
144 150 link = tpl_link % filename
145 151
146 152 if frame.f_code.co_name:
147 153 func = frame.f_code.co_name
148 154 else:
149 155 func = "<lambda>"
150 156
151 157 call = ''
152 158 if func != '?':
153 159 if '__args__' in frame.f_locals:
154 160 args = repr.repr(frame.f_locals['__args__'])
155 161 else:
156 162 args = '()'
157 163 call = tpl_call % (func, args)
158 164
159 165 level = '%s %s\n' % (link, call)
160 166 ret += level
161 167
162 168 start = lineno - 1 - context//2
163 169 lines = linecache.getlines(filename)
164 170 start = max(start, 0)
165 171 start = min(start, len(lines) - context)
166 172 lines = lines[start : start + context]
167 173
168 174 for i in range(len(lines)):
169 175 line = lines[i]
170 176 if start + 1 + i == lineno:
171 177 ret += self.__format_line(tpl_line_em, filename, start + 1 + i, line, arrow = True)
172 178 else:
173 179 ret += self.__format_line(tpl_line, filename, start + 1 + i, line, arrow = False)
174 180
175 181 return ret
176 182
177 183
178 184 def __format_line(self, tpl_line, filename, lineno, line, arrow = False):
179 185 bp_mark = ""
180 186 bp_mark_color = ""
181 187
182 188 bp = None
183 189 if lineno in self.get_file_breaks(filename):
184 190 bps = self.get_breaks(filename, lineno)
185 191 bp = bps[-1]
186 192
187 193 if bp:
188 194 Colors = self.color_scheme_table.active_colors
189 195 bp_mark = str(bp.number)
190 196 bp_mark_color = Colors.breakpoint_enabled
191 197 if not bp.enabled:
192 198 bp_mark_color = Colors.breakpoint_disabled
193 199
194 200 numbers_width = 7
195 201 if arrow:
196 202 # This is the line with the error
197 203 pad = numbers_width - len(str(lineno)) - len(bp_mark)
198 204 if pad >= 3:
199 205 marker = '-'*(pad-3) + '-> '
200 206 elif pad == 2:
201 207 marker = '> '
202 208 elif pad == 1:
203 209 marker = '>'
204 210 else:
205 211 marker = ''
206 212 num = '%s%s' % (marker, str(lineno))
207 213 line = tpl_line % (bp_mark_color + bp_mark, num, line)
208 214 else:
209 215 num = '%*s' % (numbers_width - len(bp_mark), str(lineno))
210 216 line = tpl_line % (bp_mark_color + bp_mark, num, line)
211 217
212 218 return line
213 219
214 220
215 221 def do_list(self, arg):
216 222 self.lastcmd = 'list'
217 223 last = None
218 224 if arg:
219 225 try:
220 226 x = eval(arg, {}, {})
221 227 if type(x) == type(()):
222 228 first, last = x
223 229 first = int(first)
224 230 last = int(last)
225 231 if last < first:
226 232 # Assume it's a count
227 233 last = first + last
228 234 else:
229 235 first = max(1, int(x) - 5)
230 236 except:
231 237 print '*** Error in argument:', `arg`
232 238 return
233 239 elif self.lineno is None:
234 240 first = max(1, self.curframe.f_lineno - 5)
235 241 else:
236 242 first = self.lineno + 1
237 243 if last is None:
238 244 last = first + 10
239 245 filename = self.curframe.f_code.co_filename
240 246 try:
241 247 Colors = self.color_scheme_table.active_colors
242 248 ColorsNormal = Colors.Normal
243 249 tpl_line = '%%s%s%%s %s%%s' % (Colors.lineno, ColorsNormal)
244 250 tpl_line_em = '%%s%s%%s %s%%s%s' % (Colors.linenoEm, Colors.line, ColorsNormal)
245 251 src = []
246 252 for lineno in range(first, last+1):
247 253 line = linecache.getline(filename, lineno)
248 254 if not line:
249 255 break
250 256
251 257 if lineno == self.curframe.f_lineno:
252 258 line = self.__format_line(tpl_line_em, filename, lineno, line, arrow = True)
253 259 else:
254 260 line = self.__format_line(tpl_line, filename, lineno, line, arrow = False)
255 261
256 262 src.append(line)
257 263 self.lineno = lineno
258 264
259 265 print >>Term.cout, ''.join(src)
260 266
261 267 except KeyboardInterrupt:
262 268 pass
263 269
264 270 do_l = do_list
@@ -1,655 +1,660 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Improved replacement for the Gnuplot.Gnuplot class.
3 3
4 4 This module imports Gnuplot and replaces some of its functionality with
5 5 improved versions. They add better handling of arrays for plotting and more
6 6 convenient PostScript generation, plus some fixes for hardcopy().
7 7
8 8 It also adds a convenient plot2 method for plotting dictionaries and
9 9 lists/tuples of arrays.
10 10
11 11 This module is meant to be used as a drop-in replacement to the original
12 12 Gnuplot, so it should be safe to do:
13 13
14 14 import IPython.Gnuplot2 as Gnuplot
15 15
16 $Id: Gnuplot2.py 392 2004-10-09 22:01:51Z fperez $"""
16 $Id: Gnuplot2.py 958 2005-12-27 23:17:51Z fperez $"""
17 17
18 import string,os,time,types
19 18 import cStringIO
19 import os
20 import string
20 21 import sys
21 22 import tempfile
22 import Numeric
23 import time
24 import types
25
23 26 import Gnuplot as Gnuplot_ori
27 import Numeric
28
24 29 from IPython.genutils import popkey,xsys
25 30
26 31 # needed by hardcopy():
27 32 gp = Gnuplot_ori.gp
28 33
29 34 # Patch for Gnuplot.py 1.6 compatibility.
30 35 # Thanks to Hayden Callow <h.callow@elec.canterbury.ac.nz>
31 36 try:
32 37 OptionException = Gnuplot_ori.PlotItems.OptionException
33 38 except AttributeError:
34 39 OptionException = Gnuplot_ori.Errors.OptionError
35 40
36 41 # exhibit a similar interface to Gnuplot so it can be somewhat drop-in
37 42 Data = Gnuplot_ori.Data
38 43 Func = Gnuplot_ori.Func
39 44 GridData = Gnuplot_ori.GridData
40 45 PlotItem = Gnuplot_ori.PlotItem
41 46 PlotItems = Gnuplot_ori.PlotItems
42 47
43 48 # Modify some of Gnuplot's functions with improved versions (or bugfixed, in
44 49 # hardcopy's case). In order to preserve the docstrings at runtime, I've
45 50 # copied them from the original code.
46 51
47 52 # After some significant changes in v 1.7 of Gnuplot.py, we need to do a bit
48 53 # of version checking.
49 54
50 55 if Gnuplot_ori.__version__ <= '1.6':
51 56 _BaseFileItem = PlotItems.File
52 57 _BaseTempFileItem = PlotItems.TempFile
53 58
54 59 # Fix the File class to add the 'index' option for Gnuplot versions < 1.7
55 60 class File(_BaseFileItem):
56 61
57 62 _option_list = _BaseFileItem._option_list.copy()
58 63 _option_list.update({
59 64 'index' : lambda self, index: self.set_option_index(index),
60 65 })
61 66
62 67 # A new initializer is needed b/c we want to add a modified
63 68 # _option_sequence list which includes 'index' in the right place.
64 69 def __init__(self,*args,**kw):
65 70 self._option_sequence = ['binary', 'index', 'using', 'smooth', 'axes',
66 71 'title', 'with']
67 72
68 73 _BaseFileItem.__init__(self,*args,**kw)
69 74
70 75 # Let's fix the constructor docstring
71 76 __newdoc = \
72 77 """Additional Keyword arguments added by IPython:
73 78
74 79 'index=<int>' -- similar to the `index` keyword in Gnuplot.
75 80 This allows only some of the datasets in a file to be
76 81 plotted. Datasets within a file are assumed to be separated
77 82 by _pairs_ of blank lines, and the first one is numbered as
78 83 0 (similar to C/Python usage)."""
79 84 __init__.__doc__ = PlotItems.File.__init__.__doc__ + __newdoc
80 85
81 86 def set_option_index(self, index):
82 87 if index is None:
83 88 self.clear_option('index')
84 89 elif type(index) in [type(''), type(1)]:
85 90 self._options['index'] = (index, 'index %s' % index)
86 91 elif type(index) is type(()):
87 92 self._options['index'] = (index,'index %s' %
88 93 string.join(map(repr, index), ':'))
89 94 else:
90 95 raise OptionException('index=%s' % (index,))
91 96
92 97 # We need a FileClass with a different name from 'File', which is a
93 98 # factory function in 1.7, so that our String class can subclass FileClass
94 99 # in any version.
95 100 _FileClass = File
96 101
97 102 else: # Gnuplot.py version 1.7 and greater
98 103 _FileClass = _BaseFileItem = PlotItems._FileItem
99 104 _BaseTempFileItem = PlotItems._TempFileItem
100 105 File = PlotItems.File
101 106
102 107 # Now, we can add our generic code which is version independent
103 108
104 109 # First some useful utilities
105 110 def eps_fix_bbox(fname):
106 111 """Fix the bounding box of an eps file by running ps2eps on it.
107 112
108 113 If its name ends in .eps, the original file is removed.
109 114
110 115 This is particularly useful for plots made by Gnuplot with square aspect
111 116 ratio: there is a bug in Gnuplot which makes it generate a bounding box
112 117 which is far wider than the actual plot.
113 118
114 119 This function assumes that ps2eps is installed in your system."""
115 120
116 121 # note: ps2ps and eps2eps do NOT work, ONLY ps2eps works correctly. The
117 122 # others make output with bitmapped fonts, which looks horrible.
118 123 print 'Fixing eps file: <%s>' % fname
119 124 xsys('ps2eps -f -q -l %s' % fname)
120 125 if fname.endswith('.eps'):
121 126 os.rename(fname+'.eps',fname)
122 127
123 128 def is_list1d(x,containers = [types.ListType,types.TupleType]):
124 129 """Returns true if x appears to be a 1d list/tuple/array.
125 130
126 131 The heuristics are: identify Numeric arrays, or lists/tuples whose first
127 132 element is not itself a list/tuple. This way zipped lists should work like
128 133 the original Gnuplot. There's no inexpensive way to know if a list doesn't
129 134 have a composite object after its first element, so that kind of input
130 135 will produce an error. But it should work well in most cases.
131 136 """
132 137 x_type = type(x)
133 138
134 139 return x_type == Numeric.ArrayType and len(x.shape)==1 or \
135 140 (x_type in containers and
136 141 type(x[0]) not in containers + [Numeric.ArrayType])
137 142
138 143 def zip_items(items,titles=None):
139 144 """zip together neighboring 1-d arrays, and zip standalone ones
140 145 with their index. Leave other plot items alone."""
141 146
142 147 class StandaloneItem(Exception): pass
143 148
144 149 def get_titles(titles):
145 150 """Return the next title and the input titles array.
146 151
147 152 The input array may be changed to None when no titles are left to
148 153 prevent extra unnecessary calls to this function."""
149 154
150 155 try:
151 156 title = titles[tit_ct[0]] # tit_ct[0] is in zip_items'scope
152 157 except IndexError:
153 158 titles = None # so we don't enter again
154 159 title = None
155 160 else:
156 161 tit_ct[0] += 1
157 162 return title,titles
158 163
159 164 new_items = []
160 165
161 166 if titles:
162 167 # Initialize counter. It was put in a list as a hack to allow the
163 168 # nested get_titles to modify it without raising a NameError.
164 169 tit_ct = [0]
165 170
166 171 n = 0 # this loop needs to be done by hand
167 172 while n < len(items):
168 173 item = items[n]
169 174 try:
170 175 if is_list1d(item):
171 176 if n==len(items)-1: # last in list
172 177 raise StandaloneItem
173 178 else: # check the next item and zip together if needed
174 179 next_item = items[n+1]
175 180 if next_item is None:
176 181 n += 1
177 182 raise StandaloneItem
178 183 elif is_list1d(next_item):
179 184 # this would be best done with an iterator
180 185 if titles:
181 186 title,titles = get_titles(titles)
182 187 else:
183 188 title = None
184 189 new_items.append(Data(zip(item,next_item),
185 190 title=title))
186 191 n += 1 # avoid double-inclusion of next item
187 192 else: # can't zip with next, zip with own index list
188 193 raise StandaloneItem
189 194 else: # not 1-d array
190 195 new_items.append(item)
191 196 except StandaloneItem:
192 197 if titles:
193 198 title,titles = get_titles(titles)
194 199 else:
195 200 title = None
196 201 new_items.append(Data(zip(range(len(item)),item),title=title))
197 202 except AttributeError:
198 203 new_items.append(item)
199 204 n+=1
200 205
201 206 return new_items
202 207
203 208 # And some classes with enhanced functionality.
204 209 class String(_FileClass):
205 210 """Make a PlotItem from data in a string with the same format as a File.
206 211
207 212 This allows writing data directly inside python scripts using the exact
208 213 same format and manipulation options which would be used for external
209 214 files."""
210 215
211 216 def __init__(self, data_str, **keyw):
212 217 """Construct a String object.
213 218
214 219 <data_str> is a string formatted exactly like a valid Gnuplot data
215 220 file would be. All options from the File constructor are valid here.
216 221
217 222 Warning: when used for interactive plotting in scripts which exit
218 223 immediately, you may get an error because the temporary file used to
219 224 hold the string data was deleted before Gnuplot had a chance to see
220 225 it. You can work around this problem by putting a raw_input() call at
221 226 the end of the script.
222 227
223 228 This problem does not appear when generating PostScript output, only
224 229 with Gnuplot windows."""
225 230
226 231 self.tmpfile = _BaseTempFileItem()
227 232 tmpfile = file(self.tmpfile.filename,'w')
228 233 tmpfile.write(data_str)
229 234 _BaseFileItem.__init__(self,self.tmpfile,**keyw)
230 235
231 236
232 237 class Gnuplot(Gnuplot_ori.Gnuplot):
233 238 """Improved Gnuplot class.
234 239
235 240 Enhancements: better plot,replot and hardcopy methods. New methods for
236 241 quick range setting.
237 242 """
238 243
239 244 def xrange(self,min='*',max='*'):
240 245 """Set xrange. If min/max is omitted, it is set to '*' (auto).
241 246
242 247 Note that this is different from the regular Gnuplot behavior, where
243 248 an unspecified limit means no change. Here any unspecified limit is
244 249 set to autoscaling, allowing these functions to be used for full
245 250 autoscaling when called with no arguments.
246 251
247 252 To preserve one limit's current value while changing the other, an
248 253 explicit '' argument must be given as the limit to be kept.
249 254
250 255 Similar functions exist for [y{2}z{2}rtuv]range."""
251 256
252 257 self('set xrange [%s:%s]' % (min,max))
253 258
254 259 def yrange(self,min='*',max='*'):
255 260 self('set yrange [%s:%s]' % (min,max))
256 261
257 262 def zrange(self,min='*',max='*'):
258 263 self('set zrange [%s:%s]' % (min,max))
259 264
260 265 def x2range(self,min='*',max='*'):
261 266 self('set xrange [%s:%s]' % (min,max))
262 267
263 268 def y2range(self,min='*',max='*'):
264 269 self('set yrange [%s:%s]' % (min,max))
265 270
266 271 def z2range(self,min='*',max='*'):
267 272 self('set zrange [%s:%s]' % (min,max))
268 273
269 274 def rrange(self,min='*',max='*'):
270 275 self('set rrange [%s:%s]' % (min,max))
271 276
272 277 def trange(self,min='*',max='*'):
273 278 self('set trange [%s:%s]' % (min,max))
274 279
275 280 def urange(self,min='*',max='*'):
276 281 self('set urange [%s:%s]' % (min,max))
277 282
278 283 def vrange(self,min='*',max='*'):
279 284 self('set vrange [%s:%s]' % (min,max))
280 285
281 286 def set_ps(self,option):
282 287 """Set an option for the PostScript terminal and reset default term."""
283 288
284 289 self('set terminal postscript %s ' % option)
285 290 self('set terminal %s' % gp.GnuplotOpts.default_term)
286 291
287 292 def __plot_ps(self, plot_method,*items, **keyw):
288 293 """Wrapper for plot/splot/replot, with processing of hardcopy options.
289 294
290 295 For internal use only."""
291 296
292 297 # Filter out PostScript options which will crash the normal plot/replot
293 298 psargs = {'filename':None,
294 299 'mode':None,
295 300 'eps':None,
296 301 'enhanced':None,
297 302 'color':None,
298 303 'solid':None,
299 304 'duplexing':None,
300 305 'fontname':None,
301 306 'fontsize':None,
302 307 'debug':0 }
303 308
304 309 for k in psargs.keys():
305 310 if keyw.has_key(k):
306 311 psargs[k] = keyw[k]
307 312 del keyw[k]
308 313
309 314 # Filter out other options the original plot doesn't know
310 315 hardcopy = popkey(keyw,'hardcopy',psargs['filename'] is not None)
311 316 titles = popkey(keyw,'titles',0)
312 317
313 318 # the filename keyword should control hardcopy generation, this is an
314 319 # override switch only which needs to be explicitly set to zero
315 320 if hardcopy:
316 321 if psargs['filename'] is None:
317 322 raise ValueError, \
318 323 'If you request hardcopy, you must give a filename.'
319 324
320 325 # set null output so nothing goes to screen. hardcopy() restores output
321 326 self('set term dumb')
322 327 # I don't know how to prevent screen output in Windows
323 328 if os.name == 'posix':
324 329 self('set output "/dev/null"')
325 330
326 331 new_items = zip_items(items,titles)
327 332 # plot_method is either plot or replot from the original Gnuplot class:
328 333 plot_method(self,*new_items,**keyw)
329 334
330 335 # Do hardcopy if requested
331 336 if hardcopy:
332 337 if psargs['filename'].endswith('.eps'):
333 338 psargs['eps'] = 1
334 339 self.hardcopy(**psargs)
335 340
336 341 def plot(self, *items, **keyw):
337 342 """Draw a new plot.
338 343
339 344 Clear the current plot and create a new 2-d plot containing
340 345 the specified items. Each arguments should be of the
341 346 following types:
342 347
343 348 'PlotItem' (e.g., 'Data', 'File', 'Func') -- This is the most
344 349 flexible way to call plot because the PlotItems can
345 350 contain suboptions. Moreover, PlotItems can be saved to
346 351 variables so that their lifetime is longer than one plot
347 352 command; thus they can be replotted with minimal overhead.
348 353
349 354 'string' (e.g., 'sin(x)') -- The string is interpreted as
350 355 'Func(string)' (a function that is computed by gnuplot).
351 356
352 357 Anything else -- The object, which should be convertible to an
353 358 array, is passed to the 'Data' constructor, and thus
354 359 plotted as data. If the conversion fails, an exception is
355 360 raised.
356 361
357 362
358 363 This is a modified version of plot(). Compared to the original in
359 364 Gnuplot.py, this version has several enhancements, listed below.
360 365
361 366
362 367 Modifications to the input arguments
363 368 ------------------------------------
364 369
365 370 (1-d array means Numeric array, list or tuple):
366 371
367 372 (i) Any 1-d array which is NOT followed by another 1-d array, is
368 373 automatically zipped with range(len(array_1d)). Typing g.plot(y) will
369 374 plot y against its indices.
370 375
371 376 (ii) If two 1-d arrays are contiguous in the argument list, they are
372 377 automatically zipped together. So g.plot(x,y) plots y vs. x, and
373 378 g.plot(x1,y1,x2,y2) plots y1 vs. x1 and y2 vs. x2.
374 379
375 380 (iii) Any 1-d array which is followed by None is automatically zipped
376 381 with range(len(array_1d)). In this form, typing g.plot(y1,None,y2)
377 382 will plot both y1 and y2 against their respective indices (and NOT
378 383 versus one another). The None prevents zipping y1 and y2 together, and
379 384 since y2 is unpaired it is automatically zipped to its indices by (i)
380 385
381 386 (iv) Any other arguments which don't match these cases are left alone and
382 387 passed to the code below.
383 388
384 389 For lists or tuples, the heuristics used to determine whether they are
385 390 in fact 1-d is fairly simplistic: their first element is checked, and
386 391 if it is not a list or tuple itself, it is assumed that the whole
387 392 object is one-dimensional.
388 393
389 394 An additional optional keyword 'titles' has been added: it must be a
390 395 list of strings to be used as labels for the individual plots which
391 396 are NOT PlotItem objects (since those objects carry their own labels
392 397 within).
393 398
394 399
395 400 PostScript generation
396 401 ---------------------
397 402
398 403 This version of plot() also handles automatically the production of
399 404 PostScript output. The main options are (given as keyword arguments):
400 405
401 406 - filename: a string, typically ending in .eps. If given, the plot is
402 407 sent to this file in PostScript format.
403 408
404 409 - hardcopy: this can be set to 0 to override 'filename'. It does not
405 410 need to be given to produce PostScript, its purpose is to allow
406 411 switching PostScript output off globally in scripts without having to
407 412 manually change 'filename' values in multiple calls.
408 413
409 414 All other keywords accepted by Gnuplot.hardcopy() are transparently
410 415 passed, and safely ignored if output is sent to the screen instead of
411 416 PostScript.
412 417
413 418 For example:
414 419
415 420 In [1]: x=frange(0,2*pi,npts=100)
416 421
417 422 Generate a plot in file 'sin.eps':
418 423
419 424 In [2]: plot(x,sin(x),filename = 'sin.eps')
420 425
421 426 Plot to screen instead, without having to change the filename:
422 427
423 428 In [3]: plot(x,sin(x),filename = 'sin.eps',hardcopy=0)
424 429
425 430 Pass the 'color=0' option to hardcopy for monochrome output:
426 431
427 432 In [4]: plot(x,sin(x),filename = 'sin.eps',color=0)
428 433
429 434 PostScript generation through plot() is useful mainly for scripting
430 435 uses where you are not interested in interactive plotting. For
431 436 interactive use, the hardcopy() function is typically more convenient:
432 437
433 438 In [5]: plot(x,sin(x))
434 439
435 440 In [6]: hardcopy('sin.eps') """
436 441
437 442 self.__plot_ps(Gnuplot_ori.Gnuplot.plot,*items,**keyw)
438 443
439 444 def plot2(self,arg,**kw):
440 445 """Plot the entries of a dictionary or a list/tuple of arrays.
441 446
442 447 This simple utility calls plot() with a list of Gnuplot.Data objects
443 448 constructed either from the values of the input dictionary, or the entries
444 449 in it if it is a tuple or list. Each item gets labeled with the key/index
445 450 in the Gnuplot legend.
446 451
447 452 Each item is plotted by zipping it with a list of its indices.
448 453
449 454 Any keywords are passed directly to plot()."""
450 455
451 456 if hasattr(arg,'keys'):
452 457 keys = arg.keys()
453 458 keys.sort()
454 459 else:
455 460 keys = range(len(arg))
456 461
457 462 pitems = [Data(zip(range(len(arg[k])),arg[k]),title=`k`) for k in keys]
458 463 self.plot(*pitems,**kw)
459 464
460 465 def splot(self, *items, **keyw):
461 466 """Draw a new three-dimensional plot.
462 467
463 468 Clear the current plot and create a new 3-d plot containing
464 469 the specified items. Arguments can be of the following types:
465 470
466 471 'PlotItem' (e.g., 'Data', 'File', 'Func', 'GridData' ) -- This
467 472 is the most flexible way to call plot because the
468 473 PlotItems can contain suboptions. Moreover, PlotItems can
469 474 be saved to variables so that their lifetime is longer
470 475 than one plot command--thus they can be replotted with
471 476 minimal overhead.
472 477
473 478 'string' (e.g., 'sin(x*y)') -- The string is interpreted as a
474 479 'Func()' (a function that is computed by gnuplot).
475 480
476 481 Anything else -- The object is converted to a Data() item, and
477 482 thus plotted as data. Note that each data point should
478 483 normally have at least three values associated with it
479 484 (i.e., x, y, and z). If the conversion fails, an
480 485 exception is raised.
481 486
482 487 This is a modified version of splot(). Compared to the original in
483 488 Gnuplot.py, this version has several enhancements, listed in the
484 489 plot() documentation.
485 490 """
486 491
487 492 self.__plot_ps(Gnuplot_ori.Gnuplot.splot,*items,**keyw)
488 493
489 494 def replot(self, *items, **keyw):
490 495 """Replot the data, possibly adding new 'PlotItem's.
491 496
492 497 Replot the existing graph, using the items in the current
493 498 itemlist. If arguments are specified, they are interpreted as
494 499 additional items to be plotted alongside the existing items on
495 500 the same graph. See 'plot' for details.
496 501
497 502 If you want to replot to a postscript file, you MUST give the
498 503 'filename' keyword argument in each call to replot. The Gnuplot python
499 504 interface has no way of knowing that your previous call to
500 505 Gnuplot.plot() was meant for PostScript output."""
501 506
502 507 self.__plot_ps(Gnuplot_ori.Gnuplot.replot,*items,**keyw)
503 508
504 509 # The original hardcopy has a bug. See fix at the end. The rest of the code
505 510 # was lifted verbatim from the original, so that people using IPython get the
506 511 # benefits without having to manually patch Gnuplot.py
507 512 def hardcopy(self, filename=None,
508 513 mode=None,
509 514 eps=None,
510 515 enhanced=None,
511 516 color=None,
512 517 solid=None,
513 518 duplexing=None,
514 519 fontname=None,
515 520 fontsize=None,
516 521 debug = 0,
517 522 ):
518 523 """Create a hardcopy of the current plot.
519 524
520 525 Create a postscript hardcopy of the current plot to the
521 526 default printer (if configured) or to the specified filename.
522 527
523 528 Note that gnuplot remembers the postscript suboptions across
524 529 terminal changes. Therefore if you set, for example, color=1
525 530 for one hardcopy then the next hardcopy will also be color
526 531 unless you explicitly choose color=0. Alternately you can
527 532 force all of the options to their defaults by setting
528 533 mode='default'. I consider this to be a bug in gnuplot.
529 534
530 535 Keyword arguments:
531 536
532 537 'filename=<string>' -- if a filename is specified, save the
533 538 output in that file; otherwise print it immediately
534 539 using the 'default_lpr' configuration option. If the
535 540 filename ends in '.eps', EPS mode is automatically
536 541 selected (like manually specifying eps=1 or mode='eps').
537 542
538 543 'mode=<string>' -- set the postscript submode ('landscape',
539 544 'portrait', 'eps', or 'default'). The default is
540 545 to leave this option unspecified.
541 546
542 547 'eps=<bool>' -- shorthand for 'mode="eps"'; asks gnuplot to
543 548 generate encapsulated postscript.
544 549
545 550 'enhanced=<bool>' -- if set (the default), then generate
546 551 enhanced postscript, which allows extra features like
547 552 font-switching, superscripts, and subscripts in axis
548 553 labels. (Some old gnuplot versions do not support
549 554 enhanced postscript; if this is the case set
550 555 gp.GnuplotOpts.prefer_enhanced_postscript=None.)
551 556
552 557 'color=<bool>' -- if set, create a plot with color. Default
553 558 is to leave this option unchanged.
554 559
555 560 'solid=<bool>' -- if set, force lines to be solid (i.e., not
556 561 dashed).
557 562
558 563 'duplexing=<string>' -- set duplexing option ('defaultplex',
559 564 'simplex', or 'duplex'). Only request double-sided
560 565 printing if your printer can handle it. Actually this
561 566 option is probably meaningless since hardcopy() can only
562 567 print a single plot at a time.
563 568
564 569 'fontname=<string>' -- set the default font to <string>,
565 570 which must be a valid postscript font. The default is
566 571 to leave this option unspecified.
567 572
568 573 'fontsize=<double>' -- set the default font size, in
569 574 postscript points.
570 575
571 576 'debug=<bool>' -- print extra debugging information (useful if
572 577 your PostScript files are misteriously not being created).
573 578 """
574 579
575 580 if filename is None:
576 581 assert gp.GnuplotOpts.default_lpr is not None, \
577 582 OptionException('default_lpr is not set, so you can only '
578 583 'print to a file.')
579 584 filename = gp.GnuplotOpts.default_lpr
580 585 lpr_output = 1
581 586 else:
582 587 if filename.endswith('.eps'):
583 588 eps = 1
584 589 lpr_output = 0
585 590
586 591 # Be careful processing the options. If the user didn't
587 592 # request an option explicitly, do not specify it on the 'set
588 593 # terminal' line (don't even specify the default value for the
589 594 # option). This is to avoid confusing older versions of
590 595 # gnuplot that do not support all of these options. The
591 596 # exception is 'enhanced', which is just too useful to have to
592 597 # specify each time!
593 598
594 599 setterm = ['set', 'terminal', 'postscript']
595 600 if eps:
596 601 assert mode is None or mode=='eps', \
597 602 OptionException('eps option and mode are incompatible')
598 603 setterm.append('eps')
599 604 else:
600 605 if mode is not None:
601 606 assert mode in ['landscape', 'portrait', 'eps', 'default'], \
602 607 OptionException('illegal mode "%s"' % mode)
603 608 setterm.append(mode)
604 609 if enhanced is None:
605 610 enhanced = gp.GnuplotOpts.prefer_enhanced_postscript
606 611 if enhanced is not None:
607 612 if enhanced: setterm.append('enhanced')
608 613 else: setterm.append('noenhanced')
609 614 if color is not None:
610 615 if color: setterm.append('color')
611 616 else: setterm.append('monochrome')
612 617 if solid is not None:
613 618 if solid: setterm.append('solid')
614 619 else: setterm.append('dashed')
615 620 if duplexing is not None:
616 621 assert duplexing in ['defaultplex', 'simplex', 'duplex'], \
617 622 OptionException('illegal duplexing mode "%s"' % duplexing)
618 623 setterm.append(duplexing)
619 624 if fontname is not None:
620 625 setterm.append('"%s"' % fontname)
621 626 if fontsize is not None:
622 627 setterm.append('%s' % fontsize)
623 628
624 629 self(string.join(setterm))
625 630 self.set_string('output', filename)
626 631 # replot the current figure (to the printer):
627 632 self.refresh()
628 633
629 634 # fperez. Ugly kludge: often for some reason the file is NOT created
630 635 # and we must reissue the creation commands. I have no idea why!
631 636 if not lpr_output:
632 637 #print 'Hardcopy <%s>' % filename # dbg
633 638 maxtries = 20
634 639 delay = 0.1 # delay (in seconds) between print attempts
635 640 for i in range(maxtries):
636 641 time.sleep(0.05) # safety, very small delay
637 642 if os.path.isfile(filename):
638 643 if debug:
639 644 print 'Hardcopy to file <%s> success at attempt #%s.' \
640 645 % (filename,i+1)
641 646 break
642 647 time.sleep(delay)
643 648 # try again, issue all commands just in case
644 649 self(string.join(setterm))
645 650 self.set_string('output', filename)
646 651 self.refresh()
647 652 if not os.path.isfile(filename):
648 653 print >> sys.stderr,'ERROR: Tried %s times and failed to '\
649 654 'create hardcopy file `%s`' % (maxtries,filename)
650 655
651 656 # reset the terminal to its `default' setting:
652 657 self('set terminal %s' % gp.GnuplotOpts.default_term)
653 658 self.set_string('output')
654 659
655 660 #********************** End of file <Gnuplot2.py> ************************
@@ -1,277 +1,278 b''
1 1 # -*- coding: utf-8 -*-
2 2 """String interpolation for Python (by Ka-Ping Yee, 14 Feb 2000).
3 3
4 4 This module lets you quickly and conveniently interpolate values into
5 5 strings (in the flavour of Perl or Tcl, but with less extraneous
6 6 punctuation). You get a bit more power than in the other languages,
7 7 because this module allows subscripting, slicing, function calls,
8 8 attribute lookup, or arbitrary expressions. Variables and expressions
9 9 are evaluated in the namespace of the caller.
10 10
11 11 The itpl() function returns the result of interpolating a string, and
12 12 printpl() prints out an interpolated string. Here are some examples:
13 13
14 14 from Itpl import printpl
15 15 printpl("Here is a $string.")
16 16 printpl("Here is a $module.member.")
17 17 printpl("Here is an $object.member.")
18 18 printpl("Here is a $functioncall(with, arguments).")
19 19 printpl("Here is an ${arbitrary + expression}.")
20 20 printpl("Here is an $array[3] member.")
21 21 printpl("Here is a $dictionary['member'].")
22 22
23 23 The filter() function filters a file object so that output through it
24 24 is interpolated. This lets you produce the illusion that Python knows
25 25 how to do interpolation:
26 26
27 27 import Itpl
28 28 sys.stdout = Itpl.filter()
29 29 f = "fancy"
30 30 print "Isn't this $f?"
31 31 print "Standard output has been replaced with a $sys.stdout object."
32 32 sys.stdout = Itpl.unfilter()
33 33 print "Okay, back $to $normal."
34 34
35 35 Under the hood, the Itpl class represents a string that knows how to
36 36 interpolate values. An instance of the class parses the string once
37 37 upon initialization; the evaluation and substitution can then be done
38 38 each time the instance is evaluated with str(instance). For example:
39 39
40 40 from Itpl import Itpl
41 41 s = Itpl("Here is $foo.")
42 42 foo = 5
43 43 print str(s)
44 44 foo = "bar"
45 45 print str(s)
46 46
47 $Id: Itpl.py 638 2005-07-18 03:01:41Z fperez $
47 $Id: Itpl.py 958 2005-12-27 23:17:51Z fperez $
48 48 """ # ' -> close an open quote for stupid emacs
49 49
50 50 #*****************************************************************************
51 51 #
52 52 # Copyright (c) 2001 Ka-Ping Yee <ping@lfw.org>
53 53 #
54 54 #
55 55 # Published under the terms of the MIT license, hereby reproduced:
56 56 #
57 57 # Permission is hereby granted, free of charge, to any person obtaining a copy
58 58 # of this software and associated documentation files (the "Software"), to
59 59 # deal in the Software without restriction, including without limitation the
60 60 # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
61 61 # sell copies of the Software, and to permit persons to whom the Software is
62 62 # furnished to do so, subject to the following conditions:
63 63 #
64 64 # The above copyright notice and this permission notice shall be included in
65 65 # all copies or substantial portions of the Software.
66 66 #
67 67 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
68 68 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
69 69 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
70 70 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
71 71 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
72 72 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
73 73 # IN THE SOFTWARE.
74 74 #
75 75 #*****************************************************************************
76 76
77 77 __author__ = 'Ka-Ping Yee <ping@lfw.org>'
78 78 __license__ = 'MIT'
79 79
80 import sys, string
81 from types import StringType
80 import string
81 import sys
82 82 from tokenize import tokenprog
83 from types import StringType
83 84
84 85 class ItplError(ValueError):
85 86 def __init__(self, text, pos):
86 87 self.text = text
87 88 self.pos = pos
88 89 def __str__(self):
89 90 return "unfinished expression in %s at char %d" % (
90 91 repr(self.text), self.pos)
91 92
92 93 def matchorfail(text, pos):
93 94 match = tokenprog.match(text, pos)
94 95 if match is None:
95 96 raise ItplError(text, pos)
96 97 return match, match.end()
97 98
98 99 class Itpl:
99 100 """Class representing a string with interpolation abilities.
100 101
101 102 Upon creation, an instance works out what parts of the format
102 103 string are literal and what parts need to be evaluated. The
103 104 evaluation and substitution happens in the namespace of the
104 105 caller when str(instance) is called."""
105 106
106 107 def __init__(self, format,codec='utf_8',encoding_errors='backslashreplace'):
107 108 """The single mandatory argument to this constructor is a format
108 109 string.
109 110
110 111 The format string is parsed according to the following rules:
111 112
112 113 1. A dollar sign and a name, possibly followed by any of:
113 114 - an open-paren, and anything up to the matching paren
114 115 - an open-bracket, and anything up to the matching bracket
115 116 - a period and a name
116 117 any number of times, is evaluated as a Python expression.
117 118
118 119 2. A dollar sign immediately followed by an open-brace, and
119 120 anything up to the matching close-brace, is evaluated as
120 121 a Python expression.
121 122
122 123 3. Outside of the expressions described in the above two rules,
123 124 two dollar signs in a row give you one literal dollar sign.
124 125
125 126 Optional arguments:
126 127
127 128 - codec('utf_8'): a string containing the name of a valid Python
128 129 codec.
129 130
130 131 - encoding_errors('backslashreplace'): a string with a valid error handling
131 132 policy. See the codecs module documentation for details.
132 133
133 134 These are used to encode the format string if a call to str() fails on
134 135 the expanded result."""
135 136
136 137 if not isinstance(format,basestring):
137 138 raise TypeError, "needs string initializer"
138 139 self.format = format
139 140 self.codec = codec
140 141 self.encoding_errors = encoding_errors
141 142
142 143 namechars = "abcdefghijklmnopqrstuvwxyz" \
143 144 "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
144 145 chunks = []
145 146 pos = 0
146 147
147 148 while 1:
148 149 dollar = string.find(format, "$", pos)
149 150 if dollar < 0: break
150 151 nextchar = format[dollar+1]
151 152
152 153 if nextchar == "{":
153 154 chunks.append((0, format[pos:dollar]))
154 155 pos, level = dollar+2, 1
155 156 while level:
156 157 match, pos = matchorfail(format, pos)
157 158 tstart, tend = match.regs[3]
158 159 token = format[tstart:tend]
159 160 if token == "{": level = level+1
160 161 elif token == "}": level = level-1
161 162 chunks.append((1, format[dollar+2:pos-1]))
162 163
163 164 elif nextchar in namechars:
164 165 chunks.append((0, format[pos:dollar]))
165 166 match, pos = matchorfail(format, dollar+1)
166 167 while pos < len(format):
167 168 if format[pos] == "." and \
168 169 pos+1 < len(format) and format[pos+1] in namechars:
169 170 match, pos = matchorfail(format, pos+1)
170 171 elif format[pos] in "([":
171 172 pos, level = pos+1, 1
172 173 while level:
173 174 match, pos = matchorfail(format, pos)
174 175 tstart, tend = match.regs[3]
175 176 token = format[tstart:tend]
176 177 if token[0] in "([": level = level+1
177 178 elif token[0] in ")]": level = level-1
178 179 else: break
179 180 chunks.append((1, format[dollar+1:pos]))
180 181
181 182 else:
182 183 chunks.append((0, format[pos:dollar+1]))
183 184 pos = dollar + 1 + (nextchar == "$")
184 185
185 186 if pos < len(format): chunks.append((0, format[pos:]))
186 187 self.chunks = chunks
187 188
188 189 def __repr__(self):
189 190 return "<Itpl %s >" % repr(self.format)
190 191
191 192 def _str(self,glob,loc):
192 193 """Evaluate to a string in the given globals/locals.
193 194
194 195 The final output is built by calling str(), but if this fails, the
195 196 result is encoded with the instance's codec and error handling policy,
196 197 via a call to out.encode(self.codec,self.encoding_errors)"""
197 198 result = []
198 199 app = result.append
199 200 for live, chunk in self.chunks:
200 201 if live: app(str(eval(chunk,glob,loc)))
201 202 else: app(chunk)
202 203 out = ''.join(result)
203 204 try:
204 205 return str(out)
205 206 except UnicodeError:
206 207 return out.encode(self.codec,self.encoding_errors)
207 208
208 209 def __str__(self):
209 210 """Evaluate and substitute the appropriate parts of the string."""
210 211
211 212 # We need to skip enough frames to get to the actual caller outside of
212 213 # Itpl.
213 214 frame = sys._getframe(1)
214 215 while frame.f_globals["__name__"] == __name__: frame = frame.f_back
215 216 loc, glob = frame.f_locals, frame.f_globals
216 217
217 218 return self._str(glob,loc)
218 219
219 220 class ItplNS(Itpl):
220 221 """Class representing a string with interpolation abilities.
221 222
222 223 This inherits from Itpl, but at creation time a namespace is provided
223 224 where the evaluation will occur. The interpolation becomes a bit more
224 225 efficient, as no traceback needs to be extracte. It also allows the
225 226 caller to supply a different namespace for the interpolation to occur than
226 227 its own."""
227 228
228 229 def __init__(self, format,globals,locals=None,
229 230 codec='utf_8',encoding_errors='backslashreplace'):
230 231 """ItplNS(format,globals[,locals]) -> interpolating string instance.
231 232
232 233 This constructor, besides a format string, takes a globals dictionary
233 234 and optionally a locals (which defaults to globals if not provided).
234 235
235 236 For further details, see the Itpl constructor."""
236 237
237 238 if locals is None:
238 239 locals = globals
239 240 self.globals = globals
240 241 self.locals = locals
241 242 Itpl.__init__(self,format,codec,encoding_errors)
242 243
243 244 def __str__(self):
244 245 """Evaluate and substitute the appropriate parts of the string."""
245 246 return self._str(self.globals,self.locals)
246 247
247 248 def __repr__(self):
248 249 return "<ItplNS %s >" % repr(self.format)
249 250
250 251 # utilities for fast printing
251 252 def itpl(text): return str(Itpl(text))
252 253 def printpl(text): print itpl(text)
253 254 # versions with namespace
254 255 def itplns(text,globals,locals=None): return str(ItplNS(text,globals,locals))
255 256 def printplns(text,globals,locals=None): print itplns(text,globals,locals)
256 257
257 258 class ItplFile:
258 259 """A file object that filters each write() through an interpolator."""
259 260 def __init__(self, file): self.file = file
260 261 def __repr__(self): return "<interpolated " + repr(self.file) + ">"
261 262 def __getattr__(self, attr): return getattr(self.file, attr)
262 263 def write(self, text): self.file.write(str(Itpl(text)))
263 264
264 265 def filter(file=sys.stdout):
265 266 """Return an ItplFile that filters writes to the given file object.
266 267
267 268 'file = filter(file)' replaces 'file' with a filtered object that
268 269 has a write() method. When called with no argument, this creates
269 270 a filter to sys.stdout."""
270 271 return ItplFile(file)
271 272
272 273 def unfilter(ifile=None):
273 274 """Return the original file that corresponds to the given ItplFile.
274 275
275 276 'file = unfilter(file)' undoes the effect of 'file = filter(file)'.
276 277 'sys.stdout = unfilter()' undoes the effect of 'sys.stdout = filter()'."""
277 278 return ifile and ifile.file or sys.stdout.file
@@ -1,185 +1,187 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 Logger class for IPython's logging facilities.
4 4
5 $Id: Logger.py 430 2004-11-30 08:52:05Z fperez $
5 $Id: Logger.py 958 2005-12-27 23:17:51Z fperez $
6 6 """
7 7
8 8 #*****************************************************************************
9 9 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de> and
10 10 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
11 11 #
12 12 # Distributed under the terms of the BSD License. The full license is in
13 13 # the file COPYING, distributed as part of this software.
14 14 #*****************************************************************************
15 15
16 16 #****************************************************************************
17 17 # Modules and globals
18 18
19 19 from IPython import Release
20 20 __author__ = '%s <%s>\n%s <%s>' % \
21 21 ( Release.authors['Janko'] + Release.authors['Fernando'] )
22 22 __license__ = Release.license
23 23
24 24 # Python standard modules
25 import os,sys,glob
25 import glob
26 import os
27 import sys
26 28
27 29 # Homebrewed
28 30 from IPython.genutils import *
29 31
30 32 #****************************************************************************
31 33 # FIXME: The logger class shouldn't be a mixin, it throws too many things into
32 34 # the InteractiveShell namespace. Rather make it a standalone tool, and create
33 35 # a Logger instance in InteractiveShell that uses it. Doing this will require
34 36 # tracking down a *lot* of nasty uses of the Logger attributes in
35 37 # InteractiveShell, but will clean up things quite a bit.
36 38
37 39 class Logger:
38 40 """A Logfile Mixin class with different policies for file creation"""
39 41
40 42 # FIXME: once this isn't a mixin, log_ns should just be 'namespace', since the
41 43 # names won't collide anymore.
42 44 def __init__(self,log_ns):
43 45 self._i00,self._i,self._ii,self._iii = '','','',''
44 46 self.do_full_cache = 0 # FIXME. There's also a do_full.. in OutputCache
45 47 self.log_ns = log_ns
46 48 # defaults
47 49 self.LOGMODE = 'backup'
48 50 self.defname = 'logfile'
49 51
50 52 def create_log(self,header='',fname='',defname='.Logger.log'):
51 53 """Generate a new log-file with a default header"""
52 54 if fname:
53 55 self.LOG = fname
54 56
55 57 if self.LOG:
56 58 self.logfname = self.LOG
57 59 else:
58 60 self.logfname = defname
59 61
60 62 if self.LOGMODE == 'over':
61 63 if os.path.isfile(self.logfname):
62 64 os.remove(self.logfname)
63 65 self.logfile = open(self.logfname,'w')
64 66 if self.LOGMODE == 'backup':
65 67 if os.path.isfile(self.logfname):
66 68 backup_logname = self.logfname+'~'
67 69 # Manually remove any old backup, since os.rename may fail
68 70 # under Windows.
69 71 if os.path.isfile(backup_logname):
70 72 os.remove(backup_logname)
71 73 os.rename(self.logfname,backup_logname)
72 74 self.logfile = open(self.logfname,'w')
73 75 elif self.LOGMODE == 'global':
74 76 self.logfname = os.path.join(self.home_dir, self.defname)
75 77 self.logfile = open(self.logfname, 'a')
76 78 self.LOG = self.logfname
77 79 elif self.LOGMODE == 'rotate':
78 80 if os.path.isfile(self.logfname):
79 81 if os.path.isfile(self.logfname+'.001~'):
80 82 old = glob.glob(self.logfname+'.*~')
81 83 old.sort()
82 84 old.reverse()
83 85 for f in old:
84 86 root, ext = os.path.splitext(f)
85 87 num = int(ext[1:-1])+1
86 88 os.rename(f, root+'.'+`num`.zfill(3)+'~')
87 89 os.rename(self.logfname, self.logfname+'.001~')
88 90 self.logfile = open(self.logfname,'w')
89 91 elif self.LOGMODE == 'append':
90 92 self.logfile = open(self.logfname,'a')
91 93
92 94 if self.LOGMODE != 'append':
93 95 self.logfile.write(header)
94 96 self.logfile.flush()
95 97
96 98 def logstart(self, header='',parameter_s = ''):
97 99 if not hasattr(self, 'LOG'):
98 100 logfname = self.LOG or parameter_s or './'+self.defname
99 101 self.create_log(header,logfname)
100 102 elif parameter_s and hasattr(self,'logfname') and \
101 103 parameter_s != self.logfname:
102 104 self.close_log()
103 105 self.create_log(header,parameter_s)
104 106
105 107 self._dolog = 1
106 108
107 109 def switch_log(self,val):
108 110 """Switch logging on/off. val should be ONLY 0 or 1."""
109 111
110 112 if not val in [0,1]:
111 113 raise ValueError, \
112 114 'Call switch_log ONLY with 0 or 1 as argument, not with:',val
113 115
114 116 label = {0:'OFF',1:'ON'}
115 117
116 118 try:
117 119 _ = self.logfile
118 120 except AttributeError:
119 121 print """
120 122 Logging hasn't been started yet (use %logstart for that).
121 123
122 124 %logon/%logoff are for temporarily starting and stopping logging for a logfile
123 125 which already exists. But you must first start the logging process with
124 126 %logstart (optionally giving a logfile name)."""
125 127
126 128 else:
127 129 if self._dolog == val:
128 130 print 'Logging is already',label[val]
129 131 else:
130 132 print 'Switching logging',label[val]
131 133 self._dolog = 1 - self._dolog
132 134
133 135 def logstate(self):
134 136 """Print a status message about the logger."""
135 137 try:
136 138 logfile = self.logfname
137 139 except:
138 140 print 'Logging has not been activated.'
139 141 else:
140 142 state = self._dolog and 'active' or 'temporarily suspended'
141 143 print """
142 144 File:\t%s
143 145 Mode:\t%s
144 146 State:\t%s """ % (logfile,self.LOGMODE,state)
145 147
146 148
147 149 def log(self, line,continuation=None):
148 150 """Write the line to a log and create input cache variables _i*."""
149 151
150 152 # update the auto _i tables
151 153 #print '***logging line',line # dbg
152 154 #print '***cache_count', self.outputcache.prompt_count # dbg
153 155 input_hist = self.log_ns['_ih']
154 156 if not continuation and line:
155 157 self._iii = self._ii
156 158 self._ii = self._i
157 159 self._i = self._i00
158 160 # put back the final \n of every input line
159 161 self._i00 = line+'\n'
160 162 #print 'Logging input:<%s>' % line # dbg
161 163 input_hist.append(self._i00)
162 164
163 165 # hackish access to top-level namespace to create _i1,_i2... dynamically
164 166 to_main = {'_i':self._i,'_ii':self._ii,'_iii':self._iii}
165 167 if self.do_full_cache:
166 168 in_num = self.outputcache.prompt_count
167 169 # add blank lines if the input cache fell out of sync. This can happen
168 170 # for embedded instances which get killed via C-D and then get resumed.
169 171 while in_num >= len(input_hist):
170 172 input_hist.append('\n')
171 173 new_i = '_i%s' % in_num
172 174 if continuation:
173 175 self._i00 = '%s%s\n' % (self.log_ns[new_i],line)
174 176 input_hist[in_num] = self._i00
175 177 to_main[new_i] = self._i00
176 178 self.log_ns.update(to_main)
177 179
178 180 if self._dolog and line:
179 181 self.logfile.write(line+'\n')
180 182 self.logfile.flush()
181 183
182 184 def close_log(self):
183 185 if hasattr(self, 'logfile'):
184 186 self.logfile.close()
185 187 self.logfname = ''
@@ -1,2573 +1,2579 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Magic functions for InteractiveShell.
3 3
4 $Id: Magic.py 951 2005-12-25 00:57:24Z fperez $"""
4 $Id: Magic.py 958 2005-12-27 23:17:51Z fperez $"""
5 5
6 6 #*****************************************************************************
7 7 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de> and
8 8 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
9 9 #
10 10 # Distributed under the terms of the BSD License. The full license is in
11 11 # the file COPYING, distributed as part of this software.
12 12 #*****************************************************************************
13 13
14 14 #****************************************************************************
15 15 # Modules and globals
16 16
17 17 from IPython import Release
18 18 __author__ = '%s <%s>\n%s <%s>' % \
19 19 ( Release.authors['Janko'] + Release.authors['Fernando'] )
20 20 __license__ = Release.license
21 21
22 22 # Python standard modules
23 23 import __builtin__
24 import os,sys,inspect,pydoc,re,tempfile,pdb,bdb,time
25 import Debugger
24 import bdb
25 import inspect
26 import os
27 import pdb
28 import pydoc
29 import sys
30 import re
31 import tempfile
32 import time
33 from cStringIO import StringIO
26 34 from getopt import getopt
27 35 from pprint import pprint, pformat
28 from cStringIO import StringIO
29 36
30 37 # profile isn't bundled by default in Debian for license reasons
31 38 try:
32 39 import profile,pstats
33 40 except ImportError:
34 41 profile = pstats = None
35 42
36 43 # Homebrewed
37 from IPython.Struct import Struct
38 from IPython.Itpl import Itpl, itpl, printpl,itplns
44 from IPython import Debugger, OInspect, wildcard
39 45 from IPython.FakeModule import FakeModule
46 from IPython.Itpl import Itpl, itpl, printpl,itplns
40 47 from IPython.PyColorize import Parser
41 from IPython import OInspect
42 from IPython import wildcard
48 from IPython.Struct import Struct
43 49 from IPython.genutils import *
44 50
45 51 # Globals to be set later by Magic constructor
46 52 MAGIC_PREFIX = ''
47 53 MAGIC_ESCAPE = ''
48 54
49 55 #***************************************************************************
50 56 # Utility functions
51 57 def magic2python(cmd):
52 58 """Convert a command string of magic syntax to valid Python code."""
53 59
54 60 if cmd.startswith('#'+MAGIC_ESCAPE) or \
55 61 cmd.startswith(MAGIC_ESCAPE):
56 62 if cmd[0]=='#':
57 63 cmd = cmd[1:]
58 64 # we need to return the proper line end later
59 65 if cmd[-1] == '\n':
60 66 endl = '\n'
61 67 else:
62 68 endl = ''
63 69 try:
64 70 func,args = cmd[1:].split(' ',1)
65 71 except:
66 72 func,args = cmd[1:].rstrip(),''
67 73 args = args.replace('"','\\"').replace("'","\\'").rstrip()
68 74 return '%s%s ("%s")%s' % (MAGIC_PREFIX,func,args,endl)
69 75 else:
70 76 return cmd
71 77
72 78 def on_off(tag):
73 79 """Return an ON/OFF string for a 1/0 input. Simple utility function."""
74 80 return ['OFF','ON'][tag]
75 81
76 82
77 83 #****************************************************************************
78 84 # Utility classes
79 85 class Macro:
80 86 """Simple class to store the value of macros as strings.
81 87
82 88 This allows us to later exec them by checking when something is an
83 89 instance of this class."""
84 90
85 91 def __init__(self,cmds):
86 92 """Build a macro from a list of commands."""
87 93
88 94 # Since the list may include multi-line entries, first make sure that
89 95 # they've been all broken up before passing it to magic2python
90 96 cmdlist = map(magic2python,''.join(cmds).split('\n'))
91 97 self.value = '\n'.join(cmdlist)
92 98
93 99 def __str__(self):
94 100 return self.value
95 101
96 102 #***************************************************************************
97 103 # Main class implementing Magic functionality
98 104 class Magic:
99 105 """Magic functions for InteractiveShell.
100 106
101 107 Shell functions which can be reached as %function_name. All magic
102 108 functions should accept a string, which they can parse for their own
103 109 needs. This can make some functions easier to type, eg `%cd ../`
104 110 vs. `%cd("../")`
105 111
106 112 ALL definitions MUST begin with the prefix magic_. The user won't need it
107 113 at the command line, but it is is needed in the definition. """
108 114
109 115 # class globals
110 116 auto_status = ['Automagic is OFF, % prefix IS needed for magic functions.',
111 117 'Automagic is ON, % prefix NOT needed for magic functions.']
112 118
113 119 #......................................................................
114 120 # some utility functions
115 121
116 122 def __init__(self,shell):
117 123 # XXX This is hackish, clean up later to avoid these messy globals
118 124 global MAGIC_PREFIX, MAGIC_ESCAPE
119 125
120 126 self.options_table = {}
121 127 MAGIC_PREFIX = shell.name+'.magic_'
122 128 MAGIC_ESCAPE = shell.ESC_MAGIC
123 129 if profile is None:
124 130 self.magic_prun = self.profile_missing_notice
125 131
126 132 def profile_missing_notice(self, *args, **kwargs):
127 133 error("""\
128 134 The profile module could not be found. If you are a Debian user,
129 135 it has been removed from the standard Debian package because of its non-free
130 136 license. To use profiling, please install"python2.3-profiler" from non-free.""")
131 137
132 138 def default_option(self,fn,optstr):
133 139 """Make an entry in the options_table for fn, with value optstr"""
134 140
135 141 if fn not in self.lsmagic():
136 142 error("%s is not a magic function" % fn)
137 143 self.options_table[fn] = optstr
138 144
139 145 def lsmagic(self):
140 146 """Return a list of currently available magic functions.
141 147
142 148 Gives a list of the bare names after mangling (['ls','cd', ...], not
143 149 ['magic_ls','magic_cd',...]"""
144 150
145 151 # FIXME. This needs a cleanup, in the way the magics list is built.
146 152
147 153 # magics in class definition
148 154 class_magic = lambda fn: fn.startswith('magic_') and \
149 155 callable(Magic.__dict__[fn])
150 156 # in instance namespace (run-time user additions)
151 157 inst_magic = lambda fn: fn.startswith('magic_') and \
152 158 callable(self.__dict__[fn])
153 159 # and bound magics by user (so they can access self):
154 160 inst_bound_magic = lambda fn: fn.startswith('magic_') and \
155 161 callable(self.__class__.__dict__[fn])
156 162 magics = filter(class_magic,Magic.__dict__.keys()) + \
157 163 filter(inst_magic,self.__dict__.keys()) + \
158 164 filter(inst_bound_magic,self.__class__.__dict__.keys())
159 165 out = []
160 166 for fn in magics:
161 167 out.append(fn.replace('magic_','',1))
162 168 out.sort()
163 169 return out
164 170
165 171 def set_shell(self,shell):
166 172 self.shell = shell
167 173 self.alias_table = shell.alias_table
168 174
169 175 def extract_input_slices(self,slices):
170 176 """Return as a string a set of input history slices.
171 177
172 178 The set of slices is given as a list of strings (like ['1','4:8','9'],
173 179 since this function is for use by magic functions which get their
174 180 arguments as strings."""
175 181
176 182 cmds = []
177 183 for chunk in slices:
178 184 if ':' in chunk:
179 185 ini,fin = map(int,chunk.split(':'))
180 186 else:
181 187 ini = int(chunk)
182 188 fin = ini+1
183 189 cmds.append(self.shell.input_hist[ini:fin])
184 190 return cmds
185 191
186 192 def _ofind(self,oname):
187 193 """Find an object in the available namespaces.
188 194
189 195 self._ofind(oname) -> dict with keys: found,obj,ospace,ismagic
190 196
191 197 Has special code to detect magic functions.
192 198 """
193 199
194 200 oname = oname.strip()
195 201
196 202 # Namespaces to search in:
197 203 user_ns = self.shell.user_ns
198 204 internal_ns = self.shell.internal_ns
199 205 builtin_ns = __builtin__.__dict__
200 206 alias_ns = self.shell.alias_table
201 207
202 208 # Put them in a list. The order is important so that we find things in
203 209 # the same order that Python finds them.
204 210 namespaces = [ ('Interactive',user_ns),
205 211 ('IPython internal',internal_ns),
206 212 ('Python builtin',builtin_ns),
207 213 ('Alias',alias_ns),
208 214 ]
209 215
210 216 # initialize results to 'null'
211 217 found = 0; obj = None; ospace = None; ds = None;
212 218 ismagic = 0; isalias = 0
213 219
214 220 # Look for the given name by splitting it in parts. If the head is
215 221 # found, then we look for all the remaining parts as members, and only
216 222 # declare success if we can find them all.
217 223 oname_parts = oname.split('.')
218 224 oname_head, oname_rest = oname_parts[0],oname_parts[1:]
219 225 for nsname,ns in namespaces:
220 226 try:
221 227 obj = ns[oname_head]
222 228 except KeyError:
223 229 continue
224 230 else:
225 231 for part in oname_rest:
226 232 try:
227 233 obj = getattr(obj,part)
228 234 except:
229 235 # Blanket except b/c some badly implemented objects
230 236 # allow __getattr__ to raise exceptions other than
231 237 # AttributeError, which then crashes IPython.
232 238 break
233 239 else:
234 240 # If we finish the for loop (no break), we got all members
235 241 found = 1
236 242 ospace = nsname
237 243 if ns == alias_ns:
238 244 isalias = 1
239 245 break # namespace loop
240 246
241 247 # Try to see if it's magic
242 248 if not found:
243 249 if oname.startswith(self.shell.ESC_MAGIC):
244 250 oname = oname[1:]
245 251 obj = getattr(self,'magic_'+oname,None)
246 252 if obj is not None:
247 253 found = 1
248 254 ospace = 'IPython internal'
249 255 ismagic = 1
250 256
251 257 # Last try: special-case some literals like '', [], {}, etc:
252 258 if not found and oname_head in ["''",'""','[]','{}','()']:
253 259 obj = eval(oname_head)
254 260 found = 1
255 261 ospace = 'Interactive'
256 262
257 263 return {'found':found, 'obj':obj, 'namespace':ospace,
258 264 'ismagic':ismagic, 'isalias':isalias}
259 265
260 266 def arg_err(self,func):
261 267 """Print docstring if incorrect arguments were passed"""
262 268 print 'Error in arguments:'
263 269 print OInspect.getdoc(func)
264 270
265 271
266 272 def format_latex(self,str):
267 273 """Format a string for latex inclusion."""
268 274
269 275 # Characters that need to be escaped for latex:
270 276 escape_re = re.compile(r'(%|_|\$)',re.MULTILINE)
271 277 # Magic command names as headers:
272 278 cmd_name_re = re.compile(r'^(%s.*?):' % self.shell.ESC_MAGIC,
273 279 re.MULTILINE)
274 280 # Magic commands
275 281 cmd_re = re.compile(r'(?P<cmd>%s.+?\b)(?!\}\}:)' % self.shell.ESC_MAGIC,
276 282 re.MULTILINE)
277 283 # Paragraph continue
278 284 par_re = re.compile(r'\\$',re.MULTILINE)
279 285
280 286 str = cmd_name_re.sub(r'\n\\texttt{\\textsl{\\large \1}}:',str)
281 287 str = cmd_re.sub(r'\\texttt{\g<cmd>}',str)
282 288 str = par_re.sub(r'\\\\',str)
283 289 str = escape_re.sub(r'\\\1',str)
284 290 return str
285 291
286 292 def format_screen(self,str):
287 293 """Format a string for screen printing.
288 294
289 295 This removes some latex-type format codes."""
290 296 # Paragraph continue
291 297 par_re = re.compile(r'\\$',re.MULTILINE)
292 298 str = par_re.sub('',str)
293 299 return str
294 300
295 301 def parse_options(self,arg_str,opt_str,*long_opts,**kw):
296 302 """Parse options passed to an argument string.
297 303
298 304 The interface is similar to that of getopt(), but it returns back a
299 305 Struct with the options as keys and the stripped argument string still
300 306 as a string.
301 307
302 308 arg_str is quoted as a true sys.argv vector by using shlex.split.
303 309 This allows us to easily expand variables, glob files, quote
304 310 arguments, etc.
305 311
306 312 Options:
307 313 -mode: default 'string'. If given as 'list', the argument string is
308 314 returned as a list (split on whitespace) instead of a string.
309 315
310 316 -list_all: put all option values in lists. Normally only options
311 317 appearing more than once are put in a list."""
312 318
313 319 # inject default options at the beginning of the input line
314 320 caller = sys._getframe(1).f_code.co_name.replace('magic_','')
315 321 arg_str = '%s %s' % (self.options_table.get(caller,''),arg_str)
316 322
317 323 mode = kw.get('mode','string')
318 324 if mode not in ['string','list']:
319 325 raise ValueError,'incorrect mode given: %s' % mode
320 326 # Get options
321 327 list_all = kw.get('list_all',0)
322 328
323 329 # Check if we have more than one argument to warrant extra processing:
324 330 odict = {} # Dictionary with options
325 331 args = arg_str.split()
326 332 if len(args) >= 1:
327 333 # If the list of inputs only has 0 or 1 thing in it, there's no
328 334 # need to look for options
329 335 argv = shlex_split(arg_str)
330 336 # Do regular option processing
331 337 opts,args = getopt(argv,opt_str,*long_opts)
332 338 for o,a in opts:
333 339 if o.startswith('--'):
334 340 o = o[2:]
335 341 else:
336 342 o = o[1:]
337 343 try:
338 344 odict[o].append(a)
339 345 except AttributeError:
340 346 odict[o] = [odict[o],a]
341 347 except KeyError:
342 348 if list_all:
343 349 odict[o] = [a]
344 350 else:
345 351 odict[o] = a
346 352
347 353 # Prepare opts,args for return
348 354 opts = Struct(odict)
349 355 if mode == 'string':
350 356 args = ' '.join(args)
351 357
352 358 return opts,args
353 359
354 360 #......................................................................
355 361 # And now the actual magic functions
356 362
357 363 # Functions for IPython shell work (vars,funcs, config, etc)
358 364 def magic_lsmagic(self, parameter_s = ''):
359 365 """List currently available magic functions."""
360 366 mesc = self.shell.ESC_MAGIC
361 367 print 'Available magic functions:\n'+mesc+\
362 368 (' '+mesc).join(self.lsmagic())
363 369 print '\n' + Magic.auto_status[self.shell.rc.automagic]
364 370 return None
365 371
366 372 def magic_magic(self, parameter_s = ''):
367 373 """Print information about the magic function system."""
368 374
369 375 mode = ''
370 376 try:
371 377 if parameter_s.split()[0] == '-latex':
372 378 mode = 'latex'
373 379 except:
374 380 pass
375 381
376 382 magic_docs = []
377 383 for fname in self.lsmagic():
378 384 mname = 'magic_' + fname
379 385 for space in (Magic,self,self.__class__):
380 386 try:
381 387 fn = space.__dict__[mname]
382 388 except KeyError:
383 389 pass
384 390 else:
385 391 break
386 392 magic_docs.append('%s%s:\n\t%s\n' %(self.shell.ESC_MAGIC,
387 393 fname,fn.__doc__))
388 394 magic_docs = ''.join(magic_docs)
389 395
390 396 if mode == 'latex':
391 397 print self.format_latex(magic_docs)
392 398 return
393 399 else:
394 400 magic_docs = self.format_screen(magic_docs)
395 401
396 402 outmsg = """
397 403 IPython's 'magic' functions
398 404 ===========================
399 405
400 406 The magic function system provides a series of functions which allow you to
401 407 control the behavior of IPython itself, plus a lot of system-type
402 408 features. All these functions are prefixed with a % character, but parameters
403 409 are given without parentheses or quotes.
404 410
405 411 NOTE: If you have 'automagic' enabled (via the command line option or with the
406 412 %automagic function), you don't need to type in the % explicitly. By default,
407 413 IPython ships with automagic on, so you should only rarely need the % escape.
408 414
409 415 Example: typing '%cd mydir' (without the quotes) changes you working directory
410 416 to 'mydir', if it exists.
411 417
412 418 You can define your own magic functions to extend the system. See the supplied
413 419 ipythonrc and example-magic.py files for details (in your ipython
414 420 configuration directory, typically $HOME/.ipython/).
415 421
416 422 You can also define your own aliased names for magic functions. In your
417 423 ipythonrc file, placing a line like:
418 424
419 425 execute __IPYTHON__.magic_pf = __IPYTHON__.magic_profile
420 426
421 427 will define %pf as a new name for %profile.
422 428
423 429 You can also call magics in code using the ipmagic() function, which IPython
424 430 automatically adds to the builtin namespace. Type 'ipmagic?' for details.
425 431
426 432 For a list of the available magic functions, use %lsmagic. For a description
427 433 of any of them, type %magic_name?, e.g. '%cd?'.
428 434
429 435 Currently the magic system has the following functions:\n"""
430 436
431 437 mesc = self.shell.ESC_MAGIC
432 438 outmsg = ("%s\n%s\n\nSummary of magic functions (from %slsmagic):"
433 439 "\n\n%s%s\n\n%s" % (outmsg,
434 440 magic_docs,mesc,mesc,
435 441 (' '+mesc).join(self.lsmagic()),
436 442 Magic.auto_status[self.shell.rc.automagic] ) )
437 443
438 444 page(outmsg,screen_lines=self.shell.rc.screen_length)
439 445
440 446 def magic_automagic(self, parameter_s = ''):
441 447 """Make magic functions callable without having to type the initial %.
442 448
443 449 Toggles on/off (when off, you must call it as %automagic, of
444 450 course). Note that magic functions have lowest priority, so if there's
445 451 a variable whose name collides with that of a magic fn, automagic
446 452 won't work for that function (you get the variable instead). However,
447 453 if you delete the variable (del var), the previously shadowed magic
448 454 function becomes visible to automagic again."""
449 455
450 456 rc = self.shell.rc
451 457 rc.automagic = not rc.automagic
452 458 print '\n' + Magic.auto_status[rc.automagic]
453 459
454 460 def magic_autocall(self, parameter_s = ''):
455 461 """Make functions callable without having to type parentheses.
456 462
457 463 This toggles the autocall command line option on and off."""
458 464
459 465 rc = self.shell.rc
460 466 rc.autocall = not rc.autocall
461 467 print "Automatic calling is:",['OFF','ON'][rc.autocall]
462 468
463 469 def magic_autoindent(self, parameter_s = ''):
464 470 """Toggle autoindent on/off (if available)."""
465 471
466 472 self.shell.set_autoindent()
467 473 print "Automatic indentation is:",['OFF','ON'][self.shell.autoindent]
468 474
469 475 def magic_system_verbose(self, parameter_s = ''):
470 476 """Toggle verbose printing of system calls on/off."""
471 477
472 478 self.shell.rc_set_toggle('system_verbose')
473 479 print "System verbose printing is:",\
474 480 ['OFF','ON'][self.shell.rc.system_verbose]
475 481
476 482 def magic_history(self, parameter_s = ''):
477 483 """Print input history (_i<n> variables), with most recent last.
478 484
479 485 %history [-n] -> print at most 40 inputs (some may be multi-line)\\
480 486 %history [-n] n -> print at most n inputs\\
481 487 %history [-n] n1 n2 -> print inputs between n1 and n2 (n2 not included)\\
482 488
483 489 Each input's number <n> is shown, and is accessible as the
484 490 automatically generated variable _i<n>. Multi-line statements are
485 491 printed starting at a new line for easy copy/paste.
486 492
487 493 If option -n is used, input numbers are not printed. This is useful if
488 494 you want to get a printout of many lines which can be directly pasted
489 495 into a text editor.
490 496
491 497 This feature is only available if numbered prompts are in use."""
492 498
493 499 if not self.do_full_cache:
494 500 print 'This feature is only available if numbered prompts are in use.'
495 501 return
496 502 opts,args = self.parse_options(parameter_s,'n',mode='list')
497 503
498 504 default_length = 40
499 505 if len(args) == 0:
500 506 final = self.outputcache.prompt_count
501 507 init = max(1,final-default_length)
502 508 elif len(args) == 1:
503 509 final = self.outputcache.prompt_count
504 510 init = max(1,final-int(args[0]))
505 511 elif len(args) == 2:
506 512 init,final = map(int,args)
507 513 else:
508 514 warn('%hist takes 0, 1 or 2 arguments separated by spaces.')
509 515 print self.magic_hist.__doc__
510 516 return
511 517 width = len(str(final))
512 518 line_sep = ['','\n']
513 519 input_hist = self.shell.input_hist
514 520 print_nums = not opts.has_key('n')
515 521 for in_num in range(init,final):
516 522 inline = input_hist[in_num]
517 523 multiline = inline.count('\n') > 1
518 524 if print_nums:
519 525 print str(in_num).ljust(width)+':'+ line_sep[multiline],
520 526 if inline.startswith('#'+self.shell.ESC_MAGIC) or \
521 527 inline.startswith('#!'):
522 528 print inline[1:],
523 529 else:
524 530 print inline,
525 531
526 532 def magic_hist(self, parameter_s=''):
527 533 """Alternate name for %history."""
528 534 return self.magic_history(parameter_s)
529 535
530 536 def magic_p(self, parameter_s=''):
531 537 """Just a short alias for Python's 'print'."""
532 538 exec 'print ' + parameter_s in self.shell.user_ns
533 539
534 540 def magic_r(self, parameter_s=''):
535 541 """Repeat previous input.
536 542
537 543 If given an argument, repeats the previous command which starts with
538 544 the same string, otherwise it just repeats the previous input.
539 545
540 546 Shell escaped commands (with ! as first character) are not recognized
541 547 by this system, only pure python code and magic commands.
542 548 """
543 549
544 550 start = parameter_s.strip()
545 551 esc_magic = self.shell.ESC_MAGIC
546 552 # Identify magic commands even if automagic is on (which means
547 553 # the in-memory version is different from that typed by the user).
548 554 if self.shell.rc.automagic:
549 555 start_magic = esc_magic+start
550 556 else:
551 557 start_magic = start
552 558 # Look through the input history in reverse
553 559 for n in range(len(self.shell.input_hist)-2,0,-1):
554 560 input = self.shell.input_hist[n]
555 561 # skip plain 'r' lines so we don't recurse to infinity
556 562 if input != 'ipmagic("r")\n' and \
557 563 (input.startswith(start) or input.startswith(start_magic)):
558 564 #print 'match',`input` # dbg
559 565 if input.startswith(esc_magic):
560 566 input = magic2python(input)
561 567 #print 'modified',`input` # dbg
562 568 print 'Executing:',input,
563 569 exec input in self.shell.user_ns
564 570 return
565 571 print 'No previous input matching `%s` found.' % start
566 572
567 573 def magic_page(self, parameter_s=''):
568 574 """Pretty print the object and display it through a pager.
569 575
570 576 If no parameter is given, use _ (last output)."""
571 577 # After a function contributed by Olivier Aubert, slightly modified.
572 578
573 579 oname = parameter_s and parameter_s or '_'
574 580 info = self._ofind(oname)
575 581 if info['found']:
576 582 page(pformat(info['obj']))
577 583 else:
578 584 print 'Object `%s` not found' % oname
579 585
580 586 def magic_profile(self, parameter_s=''):
581 587 """Print your currently active IPyhton profile."""
582 588 if self.shell.rc.profile:
583 589 printpl('Current IPython profile: $self.shell.rc.profile.')
584 590 else:
585 591 print 'No profile active.'
586 592
587 593 def _inspect(self,meth,oname,**kw):
588 594 """Generic interface to the inspector system.
589 595
590 596 This function is meant to be called by pdef, pdoc & friends."""
591 597
592 598 oname = oname.strip()
593 599 info = Struct(self._ofind(oname))
594 600 if info.found:
595 601 pmethod = getattr(self.shell.inspector,meth)
596 602 formatter = info.ismagic and self.format_screen or None
597 603 if meth == 'pdoc':
598 604 pmethod(info.obj,oname,formatter)
599 605 elif meth == 'pinfo':
600 606 pmethod(info.obj,oname,formatter,info,**kw)
601 607 else:
602 608 pmethod(info.obj,oname)
603 609 else:
604 610 print 'Object `%s` not found.' % oname
605 611 return 'not found' # so callers can take other action
606 612
607 613 def magic_pdef(self, parameter_s=''):
608 614 """Print the definition header for any callable object.
609 615
610 616 If the object is a class, print the constructor information."""
611 617 self._inspect('pdef',parameter_s)
612 618
613 619 def magic_pdoc(self, parameter_s=''):
614 620 """Print the docstring for an object.
615 621
616 622 If the given object is a class, it will print both the class and the
617 623 constructor docstrings."""
618 624 self._inspect('pdoc',parameter_s)
619 625
620 626 def magic_psource(self, parameter_s=''):
621 627 """Print (or run through pager) the source code for an object."""
622 628 self._inspect('psource',parameter_s)
623 629
624 630 def magic_pfile(self, parameter_s=''):
625 631 """Print (or run through pager) the file where an object is defined.
626 632
627 633 The file opens at the line where the object definition begins. IPython
628 634 will honor the environment variable PAGER if set, and otherwise will
629 635 do its best to print the file in a convenient form.
630 636
631 637 If the given argument is not an object currently defined, IPython will
632 638 try to interpret it as a filename (automatically adding a .py extension
633 639 if needed). You can thus use %pfile as a syntax highlighting code
634 640 viewer."""
635 641
636 642 # first interpret argument as an object name
637 643 out = self._inspect('pfile',parameter_s)
638 644 # if not, try the input as a filename
639 645 if out == 'not found':
640 646 try:
641 647 filename = get_py_filename(parameter_s)
642 648 except IOError,msg:
643 649 print msg
644 650 return
645 651 page(self.shell.inspector.format(file(filename).read()))
646 652
647 653 def magic_pinfo(self, parameter_s=''):
648 654 """Provide detailed information about an object.
649 655
650 656 '%pinfo object' is just a synonym for object? or ?object."""
651 657
652 658 #print 'pinfo par: <%s>' % parameter_s # dbg
653 659
654 660 # detail_level: 0 -> obj? , 1 -> obj??
655 661 detail_level = 0
656 662 # We need to detect if we got called as 'pinfo pinfo foo', which can
657 663 # happen if the user types 'pinfo foo?' at the cmd line.
658 664 pinfo,qmark1,oname,qmark2 = \
659 665 re.match('(pinfo )?(\?*)(.*?)(\??$)',parameter_s).groups()
660 666 if pinfo or qmark1 or qmark2:
661 667 detail_level = 1
662 668 if "*" in oname:
663 669 self.magic_psearch(oname)
664 670 else:
665 671 self._inspect('pinfo',oname,detail_level=detail_level)
666 672
667 673 def magic_psearch(self, parameter_s=''):
668 674 """Search for object in namespaces by wildcard.
669 675
670 676 %psearch [options] PATTERN [OBJECT TYPE]
671 677
672 678 Note: ? can be used as a synonym for %psearch, at the beginning or at
673 679 the end: both a*? and ?a* are equivalent to '%psearch a*'. Still, the
674 680 rest of the command line must be unchanged (options come first), so
675 681 for example the following forms are equivalent
676 682
677 683 %psearch -i a* function
678 684 -i a* function?
679 685 ?-i a* function
680 686
681 687 Arguments:
682 688
683 689 PATTERN
684 690
685 691 where PATTERN is a string containing * as a wildcard similar to its
686 692 use in a shell. The pattern is matched in all namespaces on the
687 693 search path. By default objects starting with a single _ are not
688 694 matched, many IPython generated objects have a single
689 695 underscore. The default is case insensitive matching. Matching is
690 696 also done on the attributes of objects and not only on the objects
691 697 in a module.
692 698
693 699 [OBJECT TYPE]
694 700
695 701 Is the name of a python type from the types module. The name is
696 702 given in lowercase without the ending type, ex. StringType is
697 703 written string. By adding a type here only objects matching the
698 704 given type are matched. Using all here makes the pattern match all
699 705 types (this is the default).
700 706
701 707 Options:
702 708
703 709 -a: makes the pattern match even objects whose names start with a
704 710 single underscore. These names are normally ommitted from the
705 711 search.
706 712
707 713 -i/-c: make the pattern case insensitive/sensitive. If neither of
708 714 these options is given, the default is read from your ipythonrc
709 715 file. The option name which sets this value is
710 716 'wildcards_case_sensitive'. If this option is not specified in your
711 717 ipythonrc file, IPython's internal default is to do a case sensitive
712 718 search.
713 719
714 720 -e/-s NAMESPACE: exclude/search a given namespace. The pattern you
715 721 specifiy can be searched in any of the following namespaces:
716 722 'builtin', 'user', 'user_global','internal', 'alias', where
717 723 'builtin' and 'user' are the search defaults. Note that you should
718 724 not use quotes when specifying namespaces.
719 725
720 726 'Builtin' contains the python module builtin, 'user' contains all
721 727 user data, 'alias' only contain the shell aliases and no python
722 728 objects, 'internal' contains objects used by IPython. The
723 729 'user_global' namespace is only used by embedded IPython instances,
724 730 and it contains module-level globals. You can add namespaces to the
725 731 search with -s or exclude them with -e (these options can be given
726 732 more than once).
727 733
728 734 Examples:
729 735
730 736 %psearch a* -> objects beginning with an a
731 737 %psearch -e builtin a* -> objects NOT in the builtin space starting in a
732 738 %psearch a* function -> all functions beginning with an a
733 739 %psearch re.e* -> objects beginning with an e in module re
734 740 %psearch r*.e* -> objects that start with e in modules starting in r
735 741 %psearch r*.* string -> all strings in modules beginning with r
736 742
737 743 Case sensitve search:
738 744
739 745 %psearch -c a* list all object beginning with lower case a
740 746
741 747 Show objects beginning with a single _:
742 748
743 749 %psearch -a _* list objects beginning with a single underscore"""
744 750
745 751 # default namespaces to be searched
746 752 def_search = ['user','builtin']
747 753
748 754 # Process options/args
749 755 opts,args = self.parse_options(parameter_s,'cias:e:',list_all=True)
750 756 opt = opts.get
751 757 shell = self.shell
752 758 psearch = shell.inspector.psearch
753 759
754 760 # select case options
755 761 if opts.has_key('i'):
756 762 ignore_case = True
757 763 elif opts.has_key('c'):
758 764 ignore_case = False
759 765 else:
760 766 ignore_case = not shell.rc.wildcards_case_sensitive
761 767
762 768 # Build list of namespaces to search from user options
763 769 def_search.extend(opt('s',[]))
764 770 ns_exclude = ns_exclude=opt('e',[])
765 771 ns_search = [nm for nm in def_search if nm not in ns_exclude]
766 772
767 773 # Call the actual search
768 774 try:
769 775 psearch(args,shell.ns_table,ns_search,
770 776 show_all=opt('a'),ignore_case=ignore_case)
771 777 except:
772 778 shell.showtraceback()
773 779
774 780 def magic_who_ls(self, parameter_s=''):
775 781 """Return a sorted list of all interactive variables.
776 782
777 783 If arguments are given, only variables of types matching these
778 784 arguments are returned."""
779 785
780 786 user_ns = self.shell.user_ns
781 787 out = []
782 788 typelist = parameter_s.split()
783 789 for i in self.shell.user_ns.keys():
784 790 if not (i.startswith('_') or i.startswith('_i')) \
785 791 and not (self.internal_ns.has_key(i) or
786 792 self.user_config_ns.has_key(i)):
787 793 if typelist:
788 794 if type(user_ns[i]).__name__ in typelist:
789 795 out.append(i)
790 796 else:
791 797 out.append(i)
792 798 out.sort()
793 799 return out
794 800
795 801 def magic_who(self, parameter_s=''):
796 802 """Print all interactive variables, with some minimal formatting.
797 803
798 804 If any arguments are given, only variables whose type matches one of
799 805 these are printed. For example:
800 806
801 807 %who function str
802 808
803 809 will only list functions and strings, excluding all other types of
804 810 variables. To find the proper type names, simply use type(var) at a
805 811 command line to see how python prints type names. For example:
806 812
807 813 In [1]: type('hello')\\
808 814 Out[1]: <type 'str'>
809 815
810 816 indicates that the type name for strings is 'str'.
811 817
812 818 %who always excludes executed names loaded through your configuration
813 819 file and things which are internal to IPython.
814 820
815 821 This is deliberate, as typically you may load many modules and the
816 822 purpose of %who is to show you only what you've manually defined."""
817 823
818 824 varlist = self.magic_who_ls(parameter_s)
819 825 if not varlist:
820 826 print 'Interactive namespace is empty.'
821 827 return
822 828
823 829 # if we have variables, move on...
824 830
825 831 # stupid flushing problem: when prompts have no separators, stdout is
826 832 # getting lost. I'm starting to think this is a python bug. I'm having
827 833 # to force a flush with a print because even a sys.stdout.flush
828 834 # doesn't seem to do anything!
829 835
830 836 count = 0
831 837 for i in varlist:
832 838 print i+'\t',
833 839 count += 1
834 840 if count > 8:
835 841 count = 0
836 842 print
837 843 sys.stdout.flush() # FIXME. Why the hell isn't this flushing???
838 844
839 845 print # well, this does force a flush at the expense of an extra \n
840 846
841 847 def magic_whos(self, parameter_s=''):
842 848 """Like %who, but gives some extra information about each variable.
843 849
844 850 The same type filtering of %who can be applied here.
845 851
846 852 For all variables, the type is printed. Additionally it prints:
847 853
848 854 - For {},[],(): their length.
849 855
850 856 - For Numeric arrays, a summary with shape, number of elements,
851 857 typecode and size in memory.
852 858
853 859 - Everything else: a string representation, snipping their middle if
854 860 too long."""
855 861
856 862 varnames = self.magic_who_ls(parameter_s)
857 863 if not varnames:
858 864 print 'Interactive namespace is empty.'
859 865 return
860 866
861 867 # if we have variables, move on...
862 868
863 869 # for these types, show len() instead of data:
864 870 seq_types = [types.DictType,types.ListType,types.TupleType]
865 871
866 872 # for Numeric arrays, display summary info
867 873 try:
868 874 import Numeric
869 875 except ImportError:
870 876 array_type = None
871 877 else:
872 878 array_type = Numeric.ArrayType.__name__
873 879
874 880 # Find all variable names and types so we can figure out column sizes
875 881 get_vars = lambda i: self.shell.user_ns[i]
876 882 type_name = lambda v: type(v).__name__
877 883 varlist = map(get_vars,varnames)
878 884 typelist = map(type_name,varlist)
879 885 # column labels and # of spaces as separator
880 886 varlabel = 'Variable'
881 887 typelabel = 'Type'
882 888 datalabel = 'Data/Info'
883 889 colsep = 3
884 890 # variable format strings
885 891 vformat = "$vname.ljust(varwidth)$vtype.ljust(typewidth)"
886 892 vfmt_short = '$vstr[:25]<...>$vstr[-25:]'
887 893 aformat = "%s: %s elems, type `%s`, %s bytes"
888 894 # find the size of the columns to format the output nicely
889 895 varwidth = max(max(map(len,varnames)), len(varlabel)) + colsep
890 896 typewidth = max(max(map(len,typelist)), len(typelabel)) + colsep
891 897 # table header
892 898 print varlabel.ljust(varwidth) + typelabel.ljust(typewidth) + \
893 899 ' '+datalabel+'\n' + '-'*(varwidth+typewidth+len(datalabel)+1)
894 900 # and the table itself
895 901 kb = 1024
896 902 Mb = 1048576 # kb**2
897 903 for vname,var,vtype in zip(varnames,varlist,typelist):
898 904 print itpl(vformat),
899 905 if vtype in seq_types:
900 906 print len(var)
901 907 elif vtype==array_type:
902 908 vshape = str(var.shape).replace(',','').replace(' ','x')[1:-1]
903 909 vsize = Numeric.size(var)
904 910 vbytes = vsize*var.itemsize()
905 911 if vbytes < 100000:
906 912 print aformat % (vshape,vsize,var.typecode(),vbytes)
907 913 else:
908 914 print aformat % (vshape,vsize,var.typecode(),vbytes),
909 915 if vbytes < Mb:
910 916 print '(%s kb)' % (vbytes/kb,)
911 917 else:
912 918 print '(%s Mb)' % (vbytes/Mb,)
913 919 else:
914 920 vstr = str(var)
915 921 if len(vstr) < 50:
916 922 print vstr
917 923 else:
918 924 printpl(vfmt_short)
919 925
920 926 def magic_reset(self, parameter_s=''):
921 927 """Resets the namespace by removing all names defined by the user.
922 928
923 929 Input/Output history are left around in case you need them."""
924 930
925 931 ans = raw_input(
926 932 "Once deleted, variables cannot be recovered. Proceed (y/n)? ")
927 933 if not ans.lower() == 'y':
928 934 print 'Nothing done.'
929 935 return
930 936 user_ns = self.shell.user_ns
931 937 for i in self.magic_who_ls():
932 938 del(user_ns[i])
933 939
934 940 def magic_config(self,parameter_s=''):
935 941 """Show IPython's internal configuration."""
936 942
937 943 page('Current configuration structure:\n'+
938 944 pformat(self.shell.rc.dict()))
939 945
940 946 def magic_logstart(self,parameter_s=''):
941 947 """Start logging anywhere in a session.
942 948
943 949 %logstart [log_name [log_mode]]
944 950
945 951 If no name is given, it defaults to a file named 'ipython.log' in your
946 952 current directory, in 'rotate' mode (see below).
947 953
948 954 '%logstart name' saves to file 'name' in 'backup' mode. It saves your
949 955 history up to that point and then continues logging.
950 956
951 957 %logstart takes a second optional parameter: logging mode. This can be one
952 958 of (note that the modes are given unquoted):\\
953 959 over: overwrite existing log.\\
954 960 backup: rename (if exists) to name~ and start name.\\
955 961 append: well, that says it.\\
956 962 rotate: create rotating logs name.1~, name.2~, etc.
957 963 """
958 964
959 965 #FIXME. This function should all be moved to the Logger class.
960 966
961 967 valid_modes = qw('over backup append rotate')
962 968 if self.LOG:
963 969 print 'Logging is already in place. Logfile:',self.LOG
964 970 return
965 971
966 972 par = parameter_s.strip()
967 973 if not par:
968 974 logname = self.LOGDEF
969 975 logmode = 'rotate' # use rotate for the auto-generated logs
970 976 else:
971 977 try:
972 978 logname,logmode = par.split()
973 979 except:
974 980 try:
975 981 logname = par
976 982 logmode = 'backup'
977 983 except:
978 984 warn('Usage: %log [log_name [log_mode]]')
979 985 return
980 986 if not logmode in valid_modes:
981 987 warn('Logging NOT activated.\n'
982 988 'Usage: %log [log_name [log_mode]]\n'
983 989 'Valid modes: '+str(valid_modes))
984 990 return
985 991
986 992 # If we made it this far, I think we're ok:
987 993 print 'Activating auto-logging.'
988 994 print 'Current session state plus future input saved to:',logname
989 995 print 'Logging mode: ',logmode
990 996 # put logname into rc struct as if it had been called on the command line,
991 997 # so it ends up saved in the log header
992 998 # Save it in case we need to restore it...
993 999 old_logfile = self.shell.rc.opts.get('logfile','')
994 1000 logname = os.path.expanduser(logname)
995 1001 self.shell.rc.opts.logfile = logname
996 1002 self.LOGMODE = logmode # FIXME: this should be set through a function.
997 1003 try:
998 1004 header = str(self.LOGHEAD)
999 1005 self.create_log(header,logname)
1000 1006 self.logstart(header,logname)
1001 1007 except:
1002 1008 self.LOG = '' # we are NOT logging, something went wrong
1003 1009 self.shell.rc.opts.logfile = old_logfile
1004 1010 warn("Couldn't start log: "+str(sys.exc_info()[1]))
1005 1011 else: # log input history up to this point
1006 1012 self.logfile.write(self.shell.user_ns['_ih'][1:])
1007 1013 self.logfile.flush()
1008 1014
1009 1015 def magic_logoff(self,parameter_s=''):
1010 1016 """Temporarily stop logging.
1011 1017
1012 1018 You must have previously started logging."""
1013 1019 self.switch_log(0)
1014 1020
1015 1021 def magic_logon(self,parameter_s=''):
1016 1022 """Restart logging.
1017 1023
1018 1024 This function is for restarting logging which you've temporarily
1019 1025 stopped with %logoff. For starting logging for the first time, you
1020 1026 must use the %logstart function, which allows you to specify an
1021 1027 optional log filename."""
1022 1028
1023 1029 self.switch_log(1)
1024 1030
1025 1031 def magic_logstate(self,parameter_s=''):
1026 1032 """Print the status of the logging system."""
1027 1033
1028 1034 self.logstate()
1029 1035
1030 1036 def magic_pdb(self, parameter_s=''):
1031 1037 """Control the calling of the pdb interactive debugger.
1032 1038
1033 1039 Call as '%pdb on', '%pdb 1', '%pdb off' or '%pdb 0'. If called without
1034 1040 argument it works as a toggle.
1035 1041
1036 1042 When an exception is triggered, IPython can optionally call the
1037 1043 interactive pdb debugger after the traceback printout. %pdb toggles
1038 1044 this feature on and off."""
1039 1045
1040 1046 par = parameter_s.strip().lower()
1041 1047
1042 1048 if par:
1043 1049 try:
1044 1050 pdb = {'off':0,'0':0,'on':1,'1':1}[par]
1045 1051 except KeyError:
1046 1052 print 'Incorrect argument. Use on/1, off/0 or nothing for a toggle.'
1047 1053 return
1048 1054 else:
1049 1055 self.shell.InteractiveTB.call_pdb = pdb
1050 1056 else:
1051 1057 self.shell.InteractiveTB.call_pdb = 1 - self.shell.InteractiveTB.call_pdb
1052 1058 print 'Automatic pdb calling has been turned',\
1053 1059 on_off(self.shell.InteractiveTB.call_pdb)
1054 1060
1055 1061
1056 1062 def magic_prun(self, parameter_s ='',user_mode=1,
1057 1063 opts=None,arg_lst=None,prog_ns=None):
1058 1064
1059 1065 """Run a statement through the python code profiler.
1060 1066
1061 1067 Usage:\\
1062 1068 %prun [options] statement
1063 1069
1064 1070 The given statement (which doesn't require quote marks) is run via the
1065 1071 python profiler in a manner similar to the profile.run() function.
1066 1072 Namespaces are internally managed to work correctly; profile.run
1067 1073 cannot be used in IPython because it makes certain assumptions about
1068 1074 namespaces which do not hold under IPython.
1069 1075
1070 1076 Options:
1071 1077
1072 1078 -l <limit>: you can place restrictions on what or how much of the
1073 1079 profile gets printed. The limit value can be:
1074 1080
1075 1081 * A string: only information for function names containing this string
1076 1082 is printed.
1077 1083
1078 1084 * An integer: only these many lines are printed.
1079 1085
1080 1086 * A float (between 0 and 1): this fraction of the report is printed
1081 1087 (for example, use a limit of 0.4 to see the topmost 40% only).
1082 1088
1083 1089 You can combine several limits with repeated use of the option. For
1084 1090 example, '-l __init__ -l 5' will print only the topmost 5 lines of
1085 1091 information about class constructors.
1086 1092
1087 1093 -r: return the pstats.Stats object generated by the profiling. This
1088 1094 object has all the information about the profile in it, and you can
1089 1095 later use it for further analysis or in other functions.
1090 1096
1091 1097 Since magic functions have a particular form of calling which prevents
1092 1098 you from writing something like:\\
1093 1099 In [1]: p = %prun -r print 4 # invalid!\\
1094 1100 you must instead use IPython's automatic variables to assign this:\\
1095 1101 In [1]: %prun -r print 4 \\
1096 1102 Out[1]: <pstats.Stats instance at 0x8222cec>\\
1097 1103 In [2]: stats = _
1098 1104
1099 1105 If you really need to assign this value via an explicit function call,
1100 1106 you can always tap directly into the true name of the magic function
1101 1107 by using the ipmagic function (which IPython automatically adds to the
1102 1108 builtins):\\
1103 1109 In [3]: stats = ipmagic('prun','-r print 4')
1104 1110
1105 1111 You can type ipmagic? for more details on ipmagic.
1106 1112
1107 1113 -s <key>: sort profile by given key. You can provide more than one key
1108 1114 by using the option several times: '-s key1 -s key2 -s key3...'. The
1109 1115 default sorting key is 'time'.
1110 1116
1111 1117 The following is copied verbatim from the profile documentation
1112 1118 referenced below:
1113 1119
1114 1120 When more than one key is provided, additional keys are used as
1115 1121 secondary criteria when the there is equality in all keys selected
1116 1122 before them.
1117 1123
1118 1124 Abbreviations can be used for any key names, as long as the
1119 1125 abbreviation is unambiguous. The following are the keys currently
1120 1126 defined:
1121 1127
1122 1128 Valid Arg Meaning\\
1123 1129 "calls" call count\\
1124 1130 "cumulative" cumulative time\\
1125 1131 "file" file name\\
1126 1132 "module" file name\\
1127 1133 "pcalls" primitive call count\\
1128 1134 "line" line number\\
1129 1135 "name" function name\\
1130 1136 "nfl" name/file/line\\
1131 1137 "stdname" standard name\\
1132 1138 "time" internal time
1133 1139
1134 1140 Note that all sorts on statistics are in descending order (placing
1135 1141 most time consuming items first), where as name, file, and line number
1136 1142 searches are in ascending order (i.e., alphabetical). The subtle
1137 1143 distinction between "nfl" and "stdname" is that the standard name is a
1138 1144 sort of the name as printed, which means that the embedded line
1139 1145 numbers get compared in an odd way. For example, lines 3, 20, and 40
1140 1146 would (if the file names were the same) appear in the string order
1141 1147 "20" "3" and "40". In contrast, "nfl" does a numeric compare of the
1142 1148 line numbers. In fact, sort_stats("nfl") is the same as
1143 1149 sort_stats("name", "file", "line").
1144 1150
1145 1151 -T <filename>: save profile results as shown on screen to a text
1146 1152 file. The profile is still shown on screen.
1147 1153
1148 1154 -D <filename>: save (via dump_stats) profile statistics to given
1149 1155 filename. This data is in a format understod by the pstats module, and
1150 1156 is generated by a call to the dump_stats() method of profile
1151 1157 objects. The profile is still shown on screen.
1152 1158
1153 1159 If you want to run complete programs under the profiler's control, use
1154 1160 '%run -p [prof_opts] filename.py [args to program]' where prof_opts
1155 1161 contains profiler specific options as described here.
1156 1162
1157 1163 You can read the complete documentation for the profile module with:\\
1158 1164 In [1]: import profile; profile.help() """
1159 1165
1160 1166 opts_def = Struct(D=[''],l=[],s=['time'],T=[''])
1161 1167 # protect user quote marks
1162 1168 parameter_s = parameter_s.replace('"',r'\"').replace("'",r"\'")
1163 1169
1164 1170 if user_mode: # regular user call
1165 1171 opts,arg_str = self.parse_options(parameter_s,'D:l:rs:T:',
1166 1172 list_all=1)
1167 1173 namespace = self.shell.user_ns
1168 1174 else: # called to run a program by %run -p
1169 1175 try:
1170 1176 filename = get_py_filename(arg_lst[0])
1171 1177 except IOError,msg:
1172 1178 error(msg)
1173 1179 return
1174 1180
1175 1181 arg_str = 'execfile(filename,prog_ns)'
1176 1182 namespace = locals()
1177 1183
1178 1184 opts.merge(opts_def)
1179 1185
1180 1186 prof = profile.Profile()
1181 1187 try:
1182 1188 prof = prof.runctx(arg_str,namespace,namespace)
1183 1189 sys_exit = ''
1184 1190 except SystemExit:
1185 1191 sys_exit = """*** SystemExit exception caught in code being profiled."""
1186 1192
1187 1193 stats = pstats.Stats(prof).strip_dirs().sort_stats(*opts.s)
1188 1194
1189 1195 lims = opts.l
1190 1196 if lims:
1191 1197 lims = [] # rebuild lims with ints/floats/strings
1192 1198 for lim in opts.l:
1193 1199 try:
1194 1200 lims.append(int(lim))
1195 1201 except ValueError:
1196 1202 try:
1197 1203 lims.append(float(lim))
1198 1204 except ValueError:
1199 1205 lims.append(lim)
1200 1206
1201 1207 # trap output
1202 1208 sys_stdout = sys.stdout
1203 1209 stdout_trap = StringIO()
1204 1210 try:
1205 1211 sys.stdout = stdout_trap
1206 1212 stats.print_stats(*lims)
1207 1213 finally:
1208 1214 sys.stdout = sys_stdout
1209 1215 output = stdout_trap.getvalue()
1210 1216 output = output.rstrip()
1211 1217
1212 1218 page(output,screen_lines=self.shell.rc.screen_length)
1213 1219 print sys_exit,
1214 1220
1215 1221 dump_file = opts.D[0]
1216 1222 text_file = opts.T[0]
1217 1223 if dump_file:
1218 1224 prof.dump_stats(dump_file)
1219 1225 print '\n*** Profile stats marshalled to file',\
1220 1226 `dump_file`+'.',sys_exit
1221 1227 if text_file:
1222 1228 file(text_file,'w').write(output)
1223 1229 print '\n*** Profile printout saved to text file',\
1224 1230 `text_file`+'.',sys_exit
1225 1231
1226 1232 if opts.has_key('r'):
1227 1233 return stats
1228 1234 else:
1229 1235 return None
1230 1236
1231 1237 def magic_run(self, parameter_s ='',runner=None):
1232 1238 """Run the named file inside IPython as a program.
1233 1239
1234 1240 Usage:\\
1235 1241 %run [-n -i -t [-N<N>] -d [-b<N>] -p [profile options]] file [args]
1236 1242
1237 1243 Parameters after the filename are passed as command-line arguments to
1238 1244 the program (put in sys.argv). Then, control returns to IPython's
1239 1245 prompt.
1240 1246
1241 1247 This is similar to running at a system prompt:\\
1242 1248 $ python file args\\
1243 1249 but with the advantage of giving you IPython's tracebacks, and of
1244 1250 loading all variables into your interactive namespace for further use
1245 1251 (unless -p is used, see below).
1246 1252
1247 1253 The file is executed in a namespace initially consisting only of
1248 1254 __name__=='__main__' and sys.argv constructed as indicated. It thus
1249 1255 sees its environment as if it were being run as a stand-alone
1250 1256 program. But after execution, the IPython interactive namespace gets
1251 1257 updated with all variables defined in the program (except for __name__
1252 1258 and sys.argv). This allows for very convenient loading of code for
1253 1259 interactive work, while giving each program a 'clean sheet' to run in.
1254 1260
1255 1261 Options:
1256 1262
1257 1263 -n: __name__ is NOT set to '__main__', but to the running file's name
1258 1264 without extension (as python does under import). This allows running
1259 1265 scripts and reloading the definitions in them without calling code
1260 1266 protected by an ' if __name__ == "__main__" ' clause.
1261 1267
1262 1268 -i: run the file in IPython's namespace instead of an empty one. This
1263 1269 is useful if you are experimenting with code written in a text editor
1264 1270 which depends on variables defined interactively.
1265 1271
1266 1272 -e: ignore sys.exit() calls or SystemExit exceptions in the script
1267 1273 being run. This is particularly useful if IPython is being used to
1268 1274 run unittests, which always exit with a sys.exit() call. In such
1269 1275 cases you are interested in the output of the test results, not in
1270 1276 seeing a traceback of the unittest module.
1271 1277
1272 1278 -t: print timing information at the end of the run. IPython will give
1273 1279 you an estimated CPU time consumption for your script, which under
1274 1280 Unix uses the resource module to avoid the wraparound problems of
1275 1281 time.clock(). Under Unix, an estimate of time spent on system tasks
1276 1282 is also given (for Windows platforms this is reported as 0.0).
1277 1283
1278 1284 If -t is given, an additional -N<N> option can be given, where <N>
1279 1285 must be an integer indicating how many times you want the script to
1280 1286 run. The final timing report will include total and per run results.
1281 1287
1282 1288 For example (testing the script uniq_stable.py):
1283 1289
1284 1290 In [1]: run -t uniq_stable
1285 1291
1286 1292 IPython CPU timings (estimated):\\
1287 1293 User : 0.19597 s.\\
1288 1294 System: 0.0 s.\\
1289 1295
1290 1296 In [2]: run -t -N5 uniq_stable
1291 1297
1292 1298 IPython CPU timings (estimated):\\
1293 1299 Total runs performed: 5\\
1294 1300 Times : Total Per run\\
1295 1301 User : 0.910862 s, 0.1821724 s.\\
1296 1302 System: 0.0 s, 0.0 s.
1297 1303
1298 1304 -d: run your program under the control of pdb, the Python debugger.
1299 1305 This allows you to execute your program step by step, watch variables,
1300 1306 etc. Internally, what IPython does is similar to calling:
1301 1307
1302 1308 pdb.run('execfile("YOURFILENAME")')
1303 1309
1304 1310 with a breakpoint set on line 1 of your file. You can change the line
1305 1311 number for this automatic breakpoint to be <N> by using the -bN option
1306 1312 (where N must be an integer). For example:
1307 1313
1308 1314 %run -d -b40 myscript
1309 1315
1310 1316 will set the first breakpoint at line 40 in myscript.py. Note that
1311 1317 the first breakpoint must be set on a line which actually does
1312 1318 something (not a comment or docstring) for it to stop execution.
1313 1319
1314 1320 When the pdb debugger starts, you will see a (Pdb) prompt. You must
1315 1321 first enter 'c' (without qoutes) to start execution up to the first
1316 1322 breakpoint.
1317 1323
1318 1324 Entering 'help' gives information about the use of the debugger. You
1319 1325 can easily see pdb's full documentation with "import pdb;pdb.help()"
1320 1326 at a prompt.
1321 1327
1322 1328 -p: run program under the control of the Python profiler module (which
1323 1329 prints a detailed report of execution times, function calls, etc).
1324 1330
1325 1331 You can pass other options after -p which affect the behavior of the
1326 1332 profiler itself. See the docs for %prun for details.
1327 1333
1328 1334 In this mode, the program's variables do NOT propagate back to the
1329 1335 IPython interactive namespace (because they remain in the namespace
1330 1336 where the profiler executes them).
1331 1337
1332 1338 Internally this triggers a call to %prun, see its documentation for
1333 1339 details on the options available specifically for profiling."""
1334 1340
1335 1341 # get arguments and set sys.argv for program to be run.
1336 1342 opts,arg_lst = self.parse_options(parameter_s,'nidtN:b:pD:l:rs:T:e',
1337 1343 mode='list',list_all=1)
1338 1344
1339 1345 try:
1340 1346 filename = get_py_filename(arg_lst[0])
1341 1347 except IndexError:
1342 1348 warn('you must provide at least a filename.')
1343 1349 print '\n%run:\n',OInspect.getdoc(self.magic_run)
1344 1350 return
1345 1351 except IOError,msg:
1346 1352 error(msg)
1347 1353 return
1348 1354
1349 1355 # Control the response to exit() calls made by the script being run
1350 1356 exit_ignore = opts.has_key('e')
1351 1357
1352 1358 # Make sure that the running script gets a proper sys.argv as if it
1353 1359 # were run from a system shell.
1354 1360 save_argv = sys.argv # save it for later restoring
1355 1361 sys.argv = [filename]+ arg_lst[1:] # put in the proper filename
1356 1362
1357 1363 if opts.has_key('i'):
1358 1364 prog_ns = self.shell.user_ns
1359 1365 __name__save = self.shell.user_ns['__name__']
1360 1366 prog_ns['__name__'] = '__main__'
1361 1367 else:
1362 1368 if opts.has_key('n'):
1363 1369 name = os.path.splitext(os.path.basename(filename))[0]
1364 1370 else:
1365 1371 name = '__main__'
1366 1372 prog_ns = {'__name__':name}
1367 1373
1368 1374 # pickle fix. See iplib for an explanation
1369 1375 sys.modules[prog_ns['__name__']] = FakeModule(prog_ns)
1370 1376
1371 1377 stats = None
1372 1378 try:
1373 1379 if opts.has_key('p'):
1374 1380 stats = self.magic_prun('',0,opts,arg_lst,prog_ns)
1375 1381 else:
1376 1382 if opts.has_key('d'):
1377 1383 deb = Debugger.Pdb(self.shell.rc.colors)
1378 1384 # reset Breakpoint state, which is moronically kept
1379 1385 # in a class
1380 1386 bdb.Breakpoint.next = 1
1381 1387 bdb.Breakpoint.bplist = {}
1382 1388 bdb.Breakpoint.bpbynumber = [None]
1383 1389 # Set an initial breakpoint to stop execution
1384 1390 maxtries = 10
1385 1391 bp = int(opts.get('b',[1])[0])
1386 1392 checkline = deb.checkline(filename,bp)
1387 1393 if not checkline:
1388 1394 for bp in range(bp+1,bp+maxtries+1):
1389 1395 if deb.checkline(filename,bp):
1390 1396 break
1391 1397 else:
1392 1398 msg = ("\nI failed to find a valid line to set "
1393 1399 "a breakpoint\n"
1394 1400 "after trying up to line: %s.\n"
1395 1401 "Please set a valid breakpoint manually "
1396 1402 "with the -b option." % bp)
1397 1403 error(msg)
1398 1404 return
1399 1405 # if we find a good linenumber, set the breakpoint
1400 1406 deb.do_break('%s:%s' % (filename,bp))
1401 1407 # Start file run
1402 1408 print "NOTE: Enter 'c' at the",
1403 1409 print "ipdb> prompt to start your script."
1404 1410 try:
1405 1411 deb.run('execfile("%s")' % filename,prog_ns)
1406 1412 except:
1407 1413 etype, value, tb = sys.exc_info()
1408 1414 # Skip three frames in the traceback: the %run one,
1409 1415 # one inside bdb.py, and the command-line typed by the
1410 1416 # user (run by exec in pdb itself).
1411 1417 self.shell.InteractiveTB(etype,value,tb,tb_offset=3)
1412 1418 else:
1413 1419 if runner is None:
1414 1420 runner = self.shell.safe_execfile
1415 1421 if opts.has_key('t'):
1416 1422 try:
1417 1423 nruns = int(opts['N'][0])
1418 1424 if nruns < 1:
1419 1425 error('Number of runs must be >=1')
1420 1426 return
1421 1427 except (KeyError):
1422 1428 nruns = 1
1423 1429 if nruns == 1:
1424 1430 t0 = clock2()
1425 1431 runner(filename,prog_ns,prog_ns,exit_ignore=exit_ignore)
1426 1432 t1 = clock2()
1427 1433 t_usr = t1[0]-t0[0]
1428 1434 t_sys = t1[1]-t1[1]
1429 1435 print "\nIPython CPU timings (estimated):"
1430 1436 print " User : %10s s." % t_usr
1431 1437 print " System: %10s s." % t_sys
1432 1438 else:
1433 1439 runs = range(nruns)
1434 1440 t0 = clock2()
1435 1441 for nr in runs:
1436 1442 runner(filename,prog_ns,prog_ns,exit_ignore=exit_ignore)
1437 1443 t1 = clock2()
1438 1444 t_usr = t1[0]-t0[0]
1439 1445 t_sys = t1[1]-t1[1]
1440 1446 print "\nIPython CPU timings (estimated):"
1441 1447 print "Total runs performed:",nruns
1442 1448 print " Times : %10s %10s" % ('Total','Per run')
1443 1449 print " User : %10s s, %10s s." % (t_usr,t_usr/nruns)
1444 1450 print " System: %10s s, %10s s." % (t_sys,t_sys/nruns)
1445 1451
1446 1452 else:
1447 1453 runner(filename,prog_ns,prog_ns,exit_ignore=exit_ignore)
1448 1454 if opts.has_key('i'):
1449 1455 self.shell.user_ns['__name__'] = __name__save
1450 1456 else:
1451 1457 # update IPython interactive namespace
1452 1458 del prog_ns['__name__']
1453 1459 self.shell.user_ns.update(prog_ns)
1454 1460 finally:
1455 1461 sys.argv = save_argv
1456 1462 return stats
1457 1463
1458 1464 def magic_runlog(self, parameter_s =''):
1459 1465 """Run files as logs.
1460 1466
1461 1467 Usage:\\
1462 1468 %runlog file1 file2 ...
1463 1469
1464 1470 Run the named files (treating them as log files) in sequence inside
1465 1471 the interpreter, and return to the prompt. This is much slower than
1466 1472 %run because each line is executed in a try/except block, but it
1467 1473 allows running files with syntax errors in them.
1468 1474
1469 1475 Normally IPython will guess when a file is one of its own logfiles, so
1470 1476 you can typically use %run even for logs. This shorthand allows you to
1471 1477 force any file to be treated as a log file."""
1472 1478
1473 1479 for f in parameter_s.split():
1474 1480 self.shell.safe_execfile(f,self.shell.user_ns,
1475 1481 self.shell.user_ns,islog=1)
1476 1482
1477 1483 def magic_time(self,parameter_s = ''):
1478 1484 """Time execution of a Python statement or expression.
1479 1485
1480 1486 The CPU and wall clock times are printed, and the value of the
1481 1487 expression (if any) is returned. Note that under Win32, system time
1482 1488 is always reported as 0, since it can not be measured.
1483 1489
1484 1490 This function provides very basic timing functionality. In Python
1485 1491 2.3, the timeit module offers more control and sophistication, but for
1486 1492 now IPython supports Python 2.2, so we can not rely on timeit being
1487 1493 present.
1488 1494
1489 1495 Some examples:
1490 1496
1491 1497 In [1]: time 2**128
1492 1498 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1493 1499 Wall time: 0.00
1494 1500 Out[1]: 340282366920938463463374607431768211456L
1495 1501
1496 1502 In [2]: n = 1000000
1497 1503
1498 1504 In [3]: time sum(range(n))
1499 1505 CPU times: user 1.20 s, sys: 0.05 s, total: 1.25 s
1500 1506 Wall time: 1.37
1501 1507 Out[3]: 499999500000L
1502 1508
1503 1509 In [4]: time print 'hello world'
1504 1510 hello world
1505 1511 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1506 1512 Wall time: 0.00
1507 1513 """
1508 1514
1509 1515 # fail immediately if the given expression can't be compiled
1510 1516 try:
1511 1517 mode = 'eval'
1512 1518 code = compile(parameter_s,'<timed eval>',mode)
1513 1519 except SyntaxError:
1514 1520 mode = 'exec'
1515 1521 code = compile(parameter_s,'<timed exec>',mode)
1516 1522 # skew measurement as little as possible
1517 1523 glob = self.shell.user_ns
1518 1524 clk = clock2
1519 1525 wtime = time.time
1520 1526 # time execution
1521 1527 wall_st = wtime()
1522 1528 if mode=='eval':
1523 1529 st = clk()
1524 1530 out = eval(code,glob)
1525 1531 end = clk()
1526 1532 else:
1527 1533 st = clk()
1528 1534 exec code in glob
1529 1535 end = clk()
1530 1536 out = None
1531 1537 wall_end = wtime()
1532 1538 # Compute actual times and report
1533 1539 wall_time = wall_end-wall_st
1534 1540 cpu_user = end[0]-st[0]
1535 1541 cpu_sys = end[1]-st[1]
1536 1542 cpu_tot = cpu_user+cpu_sys
1537 1543 print "CPU times: user %.2f s, sys: %.2f s, total: %.2f s" % \
1538 1544 (cpu_user,cpu_sys,cpu_tot)
1539 1545 print "Wall time: %.2f" % wall_time
1540 1546 return out
1541 1547
1542 1548 def magic_macro(self,parameter_s = ''):
1543 1549 """Define a set of input lines as a macro for future re-execution.
1544 1550
1545 1551 Usage:\\
1546 1552 %macro name n1:n2 n3:n4 ... n5 .. n6 ...
1547 1553
1548 1554 This will define a global variable called `name` which is a string
1549 1555 made of joining the slices and lines you specify (n1,n2,... numbers
1550 1556 above) from your input history into a single string. This variable
1551 1557 acts like an automatic function which re-executes those lines as if
1552 1558 you had typed them. You just type 'name' at the prompt and the code
1553 1559 executes.
1554 1560
1555 1561 Note that the slices use the standard Python slicing notation (5:8
1556 1562 means include lines numbered 5,6,7).
1557 1563
1558 1564 For example, if your history contains (%hist prints it):
1559 1565
1560 1566 44: x=1\\
1561 1567 45: y=3\\
1562 1568 46: z=x+y\\
1563 1569 47: print x\\
1564 1570 48: a=5\\
1565 1571 49: print 'x',x,'y',y\\
1566 1572
1567 1573 you can create a macro with lines 44 through 47 (included) and line 49
1568 1574 called my_macro with:
1569 1575
1570 1576 In [51]: %macro my_macro 44:48 49
1571 1577
1572 1578 Now, typing `my_macro` (without quotes) will re-execute all this code
1573 1579 in one pass.
1574 1580
1575 1581 You don't need to give the line-numbers in order, and any given line
1576 1582 number can appear multiple times. You can assemble macros with any
1577 1583 lines from your input history in any order.
1578 1584
1579 1585 The macro is a simple object which holds its value in an attribute,
1580 1586 but IPython's display system checks for macros and executes them as
1581 1587 code instead of printing them when you type their name.
1582 1588
1583 1589 You can view a macro's contents by explicitly printing it with:
1584 1590
1585 1591 'print macro_name'.
1586 1592
1587 1593 For one-off cases which DON'T contain magic function calls in them you
1588 1594 can obtain similar results by explicitly executing slices from your
1589 1595 input history with:
1590 1596
1591 1597 In [60]: exec In[44:48]+In[49]"""
1592 1598
1593 1599 args = parameter_s.split()
1594 1600 name,ranges = args[0], args[1:]
1595 1601 #print 'rng',ranges # dbg
1596 1602 cmds = self.extract_input_slices(ranges)
1597 1603 macro = Macro(cmds)
1598 1604 self.shell.user_ns.update({name:macro})
1599 1605 print 'Macro `%s` created. To execute, type its name (without quotes).' % name
1600 1606 print 'Macro contents:'
1601 1607 print str(macro).rstrip(),
1602 1608
1603 1609 def magic_save(self,parameter_s = ''):
1604 1610 """Save a set of lines to a given filename.
1605 1611
1606 1612 Usage:\\
1607 1613 %save filename n1:n2 n3:n4 ... n5 .. n6 ...
1608 1614
1609 1615 This function uses the same syntax as %macro for line extraction, but
1610 1616 instead of creating a macro it saves the resulting string to the
1611 1617 filename you specify.
1612 1618
1613 1619 It adds a '.py' extension to the file if you don't do so yourself, and
1614 1620 it asks for confirmation before overwriting existing files."""
1615 1621
1616 1622 args = parameter_s.split()
1617 1623 fname,ranges = args[0], args[1:]
1618 1624 if not fname.endswith('.py'):
1619 1625 fname += '.py'
1620 1626 if os.path.isfile(fname):
1621 1627 ans = raw_input('File `%s` exists. Overwrite (y/[N])? ' % fname)
1622 1628 if ans.lower() not in ['y','yes']:
1623 1629 print 'Operation cancelled.'
1624 1630 return
1625 1631 cmds = ''.join(self.extract_input_slices(ranges))
1626 1632 f = file(fname,'w')
1627 1633 f.write(cmds)
1628 1634 f.close()
1629 1635 print 'The following commands were written to file `%s`:' % fname
1630 1636 print cmds
1631 1637
1632 1638 def magic_ed(self,parameter_s = ''):
1633 1639 """Alias to %edit."""
1634 1640 return self.magic_edit(parameter_s)
1635 1641
1636 1642 def magic_edit(self,parameter_s = '',last_call=['','']):
1637 1643 """Bring up an editor and execute the resulting code.
1638 1644
1639 1645 Usage:
1640 1646 %edit [options] [args]
1641 1647
1642 1648 %edit runs IPython's editor hook. The default version of this hook is
1643 1649 set to call the __IPYTHON__.rc.editor command. This is read from your
1644 1650 environment variable $EDITOR. If this isn't found, it will default to
1645 1651 vi under Linux/Unix and to notepad under Windows. See the end of this
1646 1652 docstring for how to change the editor hook.
1647 1653
1648 1654 You can also set the value of this editor via the command line option
1649 1655 '-editor' or in your ipythonrc file. This is useful if you wish to use
1650 1656 specifically for IPython an editor different from your typical default
1651 1657 (and for Windows users who typically don't set environment variables).
1652 1658
1653 1659 This command allows you to conveniently edit multi-line code right in
1654 1660 your IPython session.
1655 1661
1656 1662 If called without arguments, %edit opens up an empty editor with a
1657 1663 temporary file and will execute the contents of this file when you
1658 1664 close it (don't forget to save it!).
1659 1665
1660 1666 Options:
1661 1667
1662 1668 -p: this will call the editor with the same data as the previous time
1663 1669 it was used, regardless of how long ago (in your current session) it
1664 1670 was.
1665 1671
1666 1672 -x: do not execute the edited code immediately upon exit. This is
1667 1673 mainly useful if you are editing programs which need to be called with
1668 1674 command line arguments, which you can then do using %run.
1669 1675
1670 1676 Arguments:
1671 1677
1672 1678 If arguments are given, the following possibilites exist:
1673 1679
1674 1680 - The arguments are numbers or pairs of colon-separated numbers (like
1675 1681 1 4:8 9). These are interpreted as lines of previous input to be
1676 1682 loaded into the editor. The syntax is the same of the %macro command.
1677 1683
1678 1684 - If the argument doesn't start with a number, it is evaluated as a
1679 1685 variable and its contents loaded into the editor. You can thus edit
1680 1686 any string which contains python code (including the result of
1681 1687 previous edits).
1682 1688
1683 1689 - If the argument is the name of an object (other than a string),
1684 1690 IPython will try to locate the file where it was defined and open the
1685 1691 editor at the point where it is defined. You can use `%edit function`
1686 1692 to load an editor exactly at the point where 'function' is defined,
1687 1693 edit it and have the file be executed automatically.
1688 1694
1689 1695 Note: opening at an exact line is only supported under Unix, and some
1690 1696 editors (like kedit and gedit up to Gnome 2.8) do not understand the
1691 1697 '+NUMBER' parameter necessary for this feature. Good editors like
1692 1698 (X)Emacs, vi, jed, pico and joe all do.
1693 1699
1694 1700 - If the argument is not found as a variable, IPython will look for a
1695 1701 file with that name (adding .py if necessary) and load it into the
1696 1702 editor. It will execute its contents with execfile() when you exit,
1697 1703 loading any code in the file into your interactive namespace.
1698 1704
1699 1705 After executing your code, %edit will return as output the code you
1700 1706 typed in the editor (except when it was an existing file). This way
1701 1707 you can reload the code in further invocations of %edit as a variable,
1702 1708 via _<NUMBER> or Out[<NUMBER>], where <NUMBER> is the prompt number of
1703 1709 the output.
1704 1710
1705 1711 Note that %edit is also available through the alias %ed.
1706 1712
1707 1713 This is an example of creating a simple function inside the editor and
1708 1714 then modifying it. First, start up the editor:
1709 1715
1710 1716 In [1]: ed\\
1711 1717 Editing... done. Executing edited code...\\
1712 1718 Out[1]: 'def foo():\\n print "foo() was defined in an editing session"\\n'
1713 1719
1714 1720 We can then call the function foo():
1715 1721
1716 1722 In [2]: foo()\\
1717 1723 foo() was defined in an editing session
1718 1724
1719 1725 Now we edit foo. IPython automatically loads the editor with the
1720 1726 (temporary) file where foo() was previously defined:
1721 1727
1722 1728 In [3]: ed foo\\
1723 1729 Editing... done. Executing edited code...
1724 1730
1725 1731 And if we call foo() again we get the modified version:
1726 1732
1727 1733 In [4]: foo()\\
1728 1734 foo() has now been changed!
1729 1735
1730 1736 Here is an example of how to edit a code snippet successive
1731 1737 times. First we call the editor:
1732 1738
1733 1739 In [8]: ed\\
1734 1740 Editing... done. Executing edited code...\\
1735 1741 hello\\
1736 1742 Out[8]: "print 'hello'\\n"
1737 1743
1738 1744 Now we call it again with the previous output (stored in _):
1739 1745
1740 1746 In [9]: ed _\\
1741 1747 Editing... done. Executing edited code...\\
1742 1748 hello world\\
1743 1749 Out[9]: "print 'hello world'\\n"
1744 1750
1745 1751 Now we call it with the output #8 (stored in _8, also as Out[8]):
1746 1752
1747 1753 In [10]: ed _8\\
1748 1754 Editing... done. Executing edited code...\\
1749 1755 hello again\\
1750 1756 Out[10]: "print 'hello again'\\n"
1751 1757
1752 1758
1753 1759 Changing the default editor hook:
1754 1760
1755 1761 If you wish to write your own editor hook, you can put it in a
1756 1762 configuration file which you load at startup time. The default hook
1757 1763 is defined in the IPython.hooks module, and you can use that as a
1758 1764 starting example for further modifications. That file also has
1759 1765 general instructions on how to set a new hook for use once you've
1760 1766 defined it."""
1761 1767
1762 1768 # FIXME: This function has become a convoluted mess. It needs a
1763 1769 # ground-up rewrite with clean, simple logic.
1764 1770
1765 1771 def make_filename(arg):
1766 1772 "Make a filename from the given args"
1767 1773 try:
1768 1774 filename = get_py_filename(arg)
1769 1775 except IOError:
1770 1776 if args.endswith('.py'):
1771 1777 filename = arg
1772 1778 else:
1773 1779 filename = None
1774 1780 return filename
1775 1781
1776 1782 # custom exceptions
1777 1783 class DataIsObject(Exception): pass
1778 1784
1779 1785 opts,args = self.parse_options(parameter_s,'px')
1780 1786
1781 1787 # Default line number value
1782 1788 lineno = None
1783 1789 if opts.has_key('p'):
1784 1790 args = '_%s' % last_call[0]
1785 1791 if not self.shell.user_ns.has_key(args):
1786 1792 args = last_call[1]
1787 1793
1788 1794 # use last_call to remember the state of the previous call, but don't
1789 1795 # let it be clobbered by successive '-p' calls.
1790 1796 try:
1791 1797 last_call[0] = self.shell.outputcache.prompt_count
1792 1798 if not opts.has_key('p'):
1793 1799 last_call[1] = parameter_s
1794 1800 except:
1795 1801 pass
1796 1802
1797 1803 # by default this is done with temp files, except when the given
1798 1804 # arg is a filename
1799 1805 use_temp = 1
1800 1806
1801 1807 if re.match(r'\d',args):
1802 1808 # Mode where user specifies ranges of lines, like in %macro.
1803 1809 # This means that you can't edit files whose names begin with
1804 1810 # numbers this way. Tough.
1805 1811 ranges = args.split()
1806 1812 data = ''.join(self.extract_input_slices(ranges))
1807 1813 elif args.endswith('.py'):
1808 1814 filename = make_filename(args)
1809 1815 data = ''
1810 1816 use_temp = 0
1811 1817 elif args:
1812 1818 try:
1813 1819 # Load the parameter given as a variable. If not a string,
1814 1820 # process it as an object instead (below)
1815 1821
1816 1822 #print '*** args',args,'type',type(args) # dbg
1817 1823 data = eval(args,self.shell.user_ns)
1818 1824 if not type(data) in StringTypes:
1819 1825 raise DataIsObject
1820 1826 except (NameError,SyntaxError):
1821 1827 # given argument is not a variable, try as a filename
1822 1828 filename = make_filename(args)
1823 1829 if filename is None:
1824 1830 warn("Argument given (%s) can't be found as a variable "
1825 1831 "or as a filename." % args)
1826 1832 return
1827 1833 data = ''
1828 1834 use_temp = 0
1829 1835 except DataIsObject:
1830 1836 # For objects, try to edit the file where they are defined
1831 1837 try:
1832 1838 filename = inspect.getabsfile(data)
1833 1839 datafile = 1
1834 1840 except TypeError:
1835 1841 filename = make_filename(args)
1836 1842 datafile = 1
1837 1843 warn('Could not find file where `%s` is defined.\n'
1838 1844 'Opening a file named `%s`' % (args,filename))
1839 1845 # Now, make sure we can actually read the source (if it was in
1840 1846 # a temp file it's gone by now).
1841 1847 if datafile:
1842 1848 try:
1843 1849 lineno = inspect.getsourcelines(data)[1]
1844 1850 except IOError:
1845 1851 filename = make_filename(args)
1846 1852 if filename is None:
1847 1853 warn('The file `%s` where `%s` was defined cannot '
1848 1854 'be read.' % (filename,data))
1849 1855 return
1850 1856 use_temp = 0
1851 1857 else:
1852 1858 data = ''
1853 1859
1854 1860 if use_temp:
1855 1861 filename = tempfile.mktemp('.py')
1856 1862 self.shell.tempfiles.append(filename)
1857 1863
1858 1864 if data and use_temp:
1859 1865 tmp_file = open(filename,'w')
1860 1866 tmp_file.write(data)
1861 1867 tmp_file.close()
1862 1868
1863 1869 # do actual editing here
1864 1870 print 'Editing...',
1865 1871 sys.stdout.flush()
1866 1872 self.shell.hooks.editor(filename,lineno)
1867 1873 if opts.has_key('x'): # -x prevents actual execution
1868 1874 print
1869 1875 else:
1870 1876 print 'done. Executing edited code...'
1871 1877 try:
1872 1878 execfile(filename,self.shell.user_ns)
1873 1879 except IOError,msg:
1874 1880 if msg.filename == filename:
1875 1881 warn('File not found. Did you forget to save?')
1876 1882 return
1877 1883 else:
1878 1884 self.shell.showtraceback()
1879 1885 except:
1880 1886 self.shell.showtraceback()
1881 1887 if use_temp:
1882 1888 contents = open(filename).read()
1883 1889 return contents
1884 1890
1885 1891 def magic_xmode(self,parameter_s = ''):
1886 1892 """Switch modes for the exception handlers.
1887 1893
1888 1894 Valid modes: Plain, Context and Verbose.
1889 1895
1890 1896 If called without arguments, acts as a toggle."""
1891 1897
1892 1898 new_mode = parameter_s.strip().capitalize()
1893 1899 try:
1894 1900 self.InteractiveTB.set_mode(mode = new_mode)
1895 1901 print 'Exception reporting mode:',self.InteractiveTB.mode
1896 1902 except:
1897 1903 warn('Error changing exception modes.\n' + str(sys.exc_info()[1]))
1898 1904
1899 1905 def magic_colors(self,parameter_s = ''):
1900 1906 """Switch color scheme for prompts, info system and exception handlers.
1901 1907
1902 1908 Currently implemented schemes: NoColor, Linux, LightBG.
1903 1909
1904 1910 Color scheme names are not case-sensitive."""
1905 1911
1906 1912 new_scheme = parameter_s.strip()
1907 1913 if not new_scheme:
1908 1914 print 'You must specify a color scheme.'
1909 1915 return
1910 1916 # Under Windows, check for Gary Bishop's readline, which is necessary
1911 1917 # for ANSI coloring
1912 1918 if os.name in ['nt','dos']:
1913 1919 try:
1914 1920 import readline
1915 1921 except ImportError:
1916 1922 has_readline = 0
1917 1923 else:
1918 1924 try:
1919 1925 readline.GetOutputFile()
1920 1926 except AttributeError:
1921 1927 has_readline = 0
1922 1928 else:
1923 1929 has_readline = 1
1924 1930 if not has_readline:
1925 1931 msg = """\
1926 1932 Proper color support under MS Windows requires Gary Bishop's readline library.
1927 1933 You can find it at:
1928 1934 http://sourceforge.net/projects/uncpythontools
1929 1935 Gary's readline needs the ctypes module, from:
1930 1936 http://starship.python.net/crew/theller/ctypes
1931 1937
1932 1938 Defaulting color scheme to 'NoColor'"""
1933 1939 new_scheme = 'NoColor'
1934 1940 warn(msg)
1935 1941
1936 1942 # Set prompt colors
1937 1943 try:
1938 1944 self.shell.outputcache.set_colors(new_scheme)
1939 1945 except:
1940 1946 warn('Error changing prompt color schemes.\n'
1941 1947 + str(sys.exc_info()[1]))
1942 1948 else:
1943 1949 self.shell.rc.colors = \
1944 1950 self.shell.outputcache.color_table.active_scheme_name
1945 1951 # Set exception colors
1946 1952 try:
1947 1953 self.shell.InteractiveTB.set_colors(scheme = new_scheme)
1948 1954 self.shell.SyntaxTB.set_colors(scheme = new_scheme)
1949 1955 except:
1950 1956 warn('Error changing exception color schemes.\n'
1951 1957 + str(sys.exc_info()[1]))
1952 1958 # Set info (for 'object?') colors
1953 1959 if self.shell.rc.color_info:
1954 1960 try:
1955 1961 self.shell.inspector.set_active_scheme(new_scheme)
1956 1962 except:
1957 1963 warn('Error changing object inspector color schemes.\n'
1958 1964 + str(sys.exc_info()[1]))
1959 1965 else:
1960 1966 self.shell.inspector.set_active_scheme('NoColor')
1961 1967
1962 1968 def magic_color_info(self,parameter_s = ''):
1963 1969 """Toggle color_info.
1964 1970
1965 1971 The color_info configuration parameter controls whether colors are
1966 1972 used for displaying object details (by things like %psource, %pfile or
1967 1973 the '?' system). This function toggles this value with each call.
1968 1974
1969 1975 Note that unless you have a fairly recent pager (less works better
1970 1976 than more) in your system, using colored object information displays
1971 1977 will not work properly. Test it and see."""
1972 1978
1973 1979 self.shell.rc.color_info = 1 - self.shell.rc.color_info
1974 1980 self.magic_colors(self.shell.rc.colors)
1975 1981 print 'Object introspection functions have now coloring:',
1976 1982 print ['OFF','ON'][self.shell.rc.color_info]
1977 1983
1978 1984 def magic_Pprint(self, parameter_s=''):
1979 1985 """Toggle pretty printing on/off."""
1980 1986
1981 1987 self.shell.outputcache.Pprint = 1 - self.shell.outputcache.Pprint
1982 1988 print 'Pretty printing has been turned', \
1983 1989 ['OFF','ON'][self.shell.outputcache.Pprint]
1984 1990
1985 1991 def magic_Exit(self, parameter_s=''):
1986 1992 """Exit IPython without confirmation."""
1987 1993
1988 1994 self.shell.exit_now = True
1989 1995
1990 1996 def magic_Quit(self, parameter_s=''):
1991 1997 """Exit IPython without confirmation (like %Exit)."""
1992 1998
1993 1999 self.shell.exit_now = True
1994 2000
1995 2001 #......................................................................
1996 2002 # Functions to implement unix shell-type things
1997 2003
1998 2004 def magic_alias(self, parameter_s = ''):
1999 2005 """Define an alias for a system command.
2000 2006
2001 2007 '%alias alias_name cmd' defines 'alias_name' as an alias for 'cmd'
2002 2008
2003 2009 Then, typing 'alias_name params' will execute the system command 'cmd
2004 2010 params' (from your underlying operating system).
2005 2011
2006 2012 Aliases have lower precedence than magic functions and Python normal
2007 2013 variables, so if 'foo' is both a Python variable and an alias, the
2008 2014 alias can not be executed until 'del foo' removes the Python variable.
2009 2015
2010 2016 You can use the %l specifier in an alias definition to represent the
2011 2017 whole line when the alias is called. For example:
2012 2018
2013 2019 In [2]: alias all echo "Input in brackets: <%l>"\\
2014 2020 In [3]: all hello world\\
2015 2021 Input in brackets: <hello world>
2016 2022
2017 2023 You can also define aliases with parameters using %s specifiers (one
2018 2024 per parameter):
2019 2025
2020 2026 In [1]: alias parts echo first %s second %s\\
2021 2027 In [2]: %parts A B\\
2022 2028 first A second B\\
2023 2029 In [3]: %parts A\\
2024 2030 Incorrect number of arguments: 2 expected.\\
2025 2031 parts is an alias to: 'echo first %s second %s'
2026 2032
2027 2033 Note that %l and %s are mutually exclusive. You can only use one or
2028 2034 the other in your aliases.
2029 2035
2030 2036 Aliases expand Python variables just like system calls using ! or !!
2031 2037 do: all expressions prefixed with '$' get expanded. For details of
2032 2038 the semantic rules, see PEP-215:
2033 2039 http://www.python.org/peps/pep-0215.html. This is the library used by
2034 2040 IPython for variable expansion. If you want to access a true shell
2035 2041 variable, an extra $ is necessary to prevent its expansion by IPython:
2036 2042
2037 2043 In [6]: alias show echo\\
2038 2044 In [7]: PATH='A Python string'\\
2039 2045 In [8]: show $PATH\\
2040 2046 A Python string\\
2041 2047 In [9]: show $$PATH\\
2042 2048 /usr/local/lf9560/bin:/usr/local/intel/compiler70/ia32/bin:...
2043 2049
2044 2050 You can use the alias facility to acess all of $PATH. See the %rehash
2045 2051 and %rehashx functions, which automatically create aliases for the
2046 2052 contents of your $PATH.
2047 2053
2048 2054 If called with no parameters, %alias prints the current alias table."""
2049 2055
2050 2056 par = parameter_s.strip()
2051 2057 if not par:
2052 2058 if self.shell.rc.automagic:
2053 2059 prechar = ''
2054 2060 else:
2055 2061 prechar = self.shell.ESC_MAGIC
2056 2062 print 'Alias\t\tSystem Command\n'+'-'*30
2057 2063 atab = self.shell.alias_table
2058 2064 aliases = atab.keys()
2059 2065 aliases.sort()
2060 2066 for alias in aliases:
2061 2067 print prechar+alias+'\t\t'+atab[alias][1]
2062 2068 print '-'*30+'\nTotal number of aliases:',len(aliases)
2063 2069 return
2064 2070 try:
2065 2071 alias,cmd = par.split(None,1)
2066 2072 except:
2067 2073 print OInspect.getdoc(self.magic_alias)
2068 2074 else:
2069 2075 nargs = cmd.count('%s')
2070 2076 if nargs>0 and cmd.find('%l')>=0:
2071 2077 error('The %s and %l specifiers are mutually exclusive '
2072 2078 'in alias definitions.')
2073 2079 else: # all looks OK
2074 2080 self.shell.alias_table[alias] = (nargs,cmd)
2075 2081 self.shell.alias_table_validate(verbose=1)
2076 2082 # end magic_alias
2077 2083
2078 2084 def magic_unalias(self, parameter_s = ''):
2079 2085 """Remove an alias"""
2080 2086
2081 2087 aname = parameter_s.strip()
2082 2088 if aname in self.shell.alias_table:
2083 2089 del self.shell.alias_table[aname]
2084 2090
2085 2091 def magic_rehash(self, parameter_s = ''):
2086 2092 """Update the alias table with all entries in $PATH.
2087 2093
2088 2094 This version does no checks on execute permissions or whether the
2089 2095 contents of $PATH are truly files (instead of directories or something
2090 2096 else). For such a safer (but slower) version, use %rehashx."""
2091 2097
2092 2098 # This function (and rehashx) manipulate the alias_table directly
2093 2099 # rather than calling magic_alias, for speed reasons. A rehash on a
2094 2100 # typical Linux box involves several thousand entries, so efficiency
2095 2101 # here is a top concern.
2096 2102
2097 2103 path = filter(os.path.isdir,os.environ['PATH'].split(os.pathsep))
2098 2104 alias_table = self.shell.alias_table
2099 2105 for pdir in path:
2100 2106 for ff in os.listdir(pdir):
2101 2107 # each entry in the alias table must be (N,name), where
2102 2108 # N is the number of positional arguments of the alias.
2103 2109 alias_table[ff] = (0,ff)
2104 2110 # Make sure the alias table doesn't contain keywords or builtins
2105 2111 self.shell.alias_table_validate()
2106 2112 # Call again init_auto_alias() so we get 'rm -i' and other modified
2107 2113 # aliases since %rehash will probably clobber them
2108 2114 self.shell.init_auto_alias()
2109 2115
2110 2116 def magic_rehashx(self, parameter_s = ''):
2111 2117 """Update the alias table with all executable files in $PATH.
2112 2118
2113 2119 This version explicitly checks that every entry in $PATH is a file
2114 2120 with execute access (os.X_OK), so it is much slower than %rehash.
2115 2121
2116 2122 Under Windows, it checks executability as a match agains a
2117 2123 '|'-separated string of extensions, stored in the IPython config
2118 2124 variable win_exec_ext. This defaults to 'exe|com|bat'. """
2119 2125
2120 2126 path = filter(os.path.isdir,os.environ['PATH'].split(os.pathsep))
2121 2127 alias_table = self.shell.alias_table
2122 2128
2123 2129 if os.name == 'posix':
2124 2130 isexec = lambda fname:os.path.isfile(fname) and \
2125 2131 os.access(fname,os.X_OK)
2126 2132 else:
2127 2133
2128 2134 try:
2129 2135 winext = os.environ['pathext'].replace(';','|').replace('.','')
2130 2136 except KeyError:
2131 2137 winext = 'exe|com|bat'
2132 2138
2133 2139 execre = re.compile(r'(.*)\.(%s)$' % winext,re.IGNORECASE)
2134 2140 isexec = lambda fname:os.path.isfile(fname) and execre.match(fname)
2135 2141 savedir = os.getcwd()
2136 2142 try:
2137 2143 # write the whole loop for posix/Windows so we don't have an if in
2138 2144 # the innermost part
2139 2145 if os.name == 'posix':
2140 2146 for pdir in path:
2141 2147 os.chdir(pdir)
2142 2148 for ff in os.listdir(pdir):
2143 2149 if isexec(ff):
2144 2150 # each entry in the alias table must be (N,name),
2145 2151 # where N is the number of positional arguments of the
2146 2152 # alias.
2147 2153 alias_table[ff] = (0,ff)
2148 2154 else:
2149 2155 for pdir in path:
2150 2156 os.chdir(pdir)
2151 2157 for ff in os.listdir(pdir):
2152 2158 if isexec(ff):
2153 2159 alias_table[execre.sub(r'\1',ff)] = (0,ff)
2154 2160 # Make sure the alias table doesn't contain keywords or builtins
2155 2161 self.shell.alias_table_validate()
2156 2162 # Call again init_auto_alias() so we get 'rm -i' and other
2157 2163 # modified aliases since %rehashx will probably clobber them
2158 2164 self.shell.init_auto_alias()
2159 2165 finally:
2160 2166 os.chdir(savedir)
2161 2167
2162 2168 def magic_pwd(self, parameter_s = ''):
2163 2169 """Return the current working directory path."""
2164 2170 return os.getcwd()
2165 2171
2166 2172 def magic_cd(self, parameter_s=''):
2167 2173 """Change the current working directory.
2168 2174
2169 2175 This command automatically maintains an internal list of directories
2170 2176 you visit during your IPython session, in the variable _dh. The
2171 2177 command %dhist shows this history nicely formatted.
2172 2178
2173 2179 Usage:
2174 2180
2175 2181 cd 'dir': changes to directory 'dir'.
2176 2182
2177 2183 cd -: changes to the last visited directory.
2178 2184
2179 2185 cd -<n>: changes to the n-th directory in the directory history.
2180 2186
2181 2187 cd -b <bookmark_name>: jump to a bookmark set by %bookmark
2182 2188 (note: cd <bookmark_name> is enough if there is no
2183 2189 directory <bookmark_name>, but a bookmark with the name exists.)
2184 2190
2185 2191 Options:
2186 2192
2187 2193 -q: quiet. Do not print the working directory after the cd command is
2188 2194 executed. By default IPython's cd command does print this directory,
2189 2195 since the default prompts do not display path information.
2190 2196
2191 2197 Note that !cd doesn't work for this purpose because the shell where
2192 2198 !command runs is immediately discarded after executing 'command'."""
2193 2199
2194 2200 parameter_s = parameter_s.strip()
2195 2201 bkms = self.shell.persist.get("bookmarks",{})
2196 2202
2197 2203 numcd = re.match(r'(-)(\d+)$',parameter_s)
2198 2204 # jump in directory history by number
2199 2205 if numcd:
2200 2206 nn = int(numcd.group(2))
2201 2207 try:
2202 2208 ps = self.shell.user_ns['_dh'][nn]
2203 2209 except IndexError:
2204 2210 print 'The requested directory does not exist in history.'
2205 2211 return
2206 2212 else:
2207 2213 opts = {}
2208 2214 else:
2209 2215 opts,ps = self.parse_options(parameter_s,'qb',mode='string')
2210 2216 # jump to previous
2211 2217 if ps == '-':
2212 2218 try:
2213 2219 ps = self.shell.user_ns['_dh'][-2]
2214 2220 except IndexError:
2215 2221 print 'No previous directory to change to.'
2216 2222 return
2217 2223 # jump to bookmark
2218 2224 elif opts.has_key('b') or (bkms.has_key(ps) and not os.path.isdir(ps)):
2219 2225 if bkms.has_key(ps):
2220 2226 target = bkms[ps]
2221 2227 print '(bookmark:%s) -> %s' % (ps,target)
2222 2228 ps = target
2223 2229 else:
2224 2230 if bkms:
2225 2231 error("Bookmark '%s' not found. "
2226 2232 "Use '%bookmark -l' to see your bookmarks." % ps)
2227 2233 else:
2228 2234 print "Bookmarks not set - use %bookmark <bookmarkname>"
2229 2235 return
2230 2236
2231 2237 # at this point ps should point to the target dir
2232 2238 if ps:
2233 2239 try:
2234 2240 os.chdir(os.path.expanduser(ps))
2235 2241 except OSError:
2236 2242 print sys.exc_info()[1]
2237 2243 else:
2238 2244 self.shell.user_ns['_dh'].append(os.getcwd())
2239 2245 else:
2240 2246 os.chdir(self.home_dir)
2241 2247 self.shell.user_ns['_dh'].append(os.getcwd())
2242 2248 if not 'q' in opts:
2243 2249 print self.shell.user_ns['_dh'][-1]
2244 2250
2245 2251 def magic_dhist(self, parameter_s=''):
2246 2252 """Print your history of visited directories.
2247 2253
2248 2254 %dhist -> print full history\\
2249 2255 %dhist n -> print last n entries only\\
2250 2256 %dhist n1 n2 -> print entries between n1 and n2 (n1 not included)\\
2251 2257
2252 2258 This history is automatically maintained by the %cd command, and
2253 2259 always available as the global list variable _dh. You can use %cd -<n>
2254 2260 to go to directory number <n>."""
2255 2261
2256 2262 dh = self.shell.user_ns['_dh']
2257 2263 if parameter_s:
2258 2264 try:
2259 2265 args = map(int,parameter_s.split())
2260 2266 except:
2261 2267 self.arg_err(Magic.magic_dhist)
2262 2268 return
2263 2269 if len(args) == 1:
2264 2270 ini,fin = max(len(dh)-(args[0]),0),len(dh)
2265 2271 elif len(args) == 2:
2266 2272 ini,fin = args
2267 2273 else:
2268 2274 self.arg_err(Magic.magic_dhist)
2269 2275 return
2270 2276 else:
2271 2277 ini,fin = 0,len(dh)
2272 2278 nlprint(dh,
2273 2279 header = 'Directory history (kept in _dh)',
2274 2280 start=ini,stop=fin)
2275 2281
2276 2282 def magic_env(self, parameter_s=''):
2277 2283 """List environment variables."""
2278 2284
2279 2285 # environ is an instance of UserDict
2280 2286 return os.environ.data
2281 2287
2282 2288 def magic_pushd(self, parameter_s=''):
2283 2289 """Place the current dir on stack and change directory.
2284 2290
2285 2291 Usage:\\
2286 2292 %pushd ['dirname']
2287 2293
2288 2294 %pushd with no arguments does a %pushd to your home directory.
2289 2295 """
2290 2296 if parameter_s == '': parameter_s = '~'
2291 2297 if len(self.dir_stack)>0 and os.path.expanduser(parameter_s) != \
2292 2298 os.path.expanduser(self.dir_stack[0]):
2293 2299 try:
2294 2300 self.magic_cd(parameter_s)
2295 2301 self.dir_stack.insert(0,os.getcwd().replace(self.home_dir,'~'))
2296 2302 self.magic_dirs()
2297 2303 except:
2298 2304 print 'Invalid directory'
2299 2305 else:
2300 2306 print 'You are already there!'
2301 2307
2302 2308 def magic_popd(self, parameter_s=''):
2303 2309 """Change to directory popped off the top of the stack.
2304 2310 """
2305 2311 if len (self.dir_stack) > 1:
2306 2312 self.dir_stack.pop(0)
2307 2313 self.magic_cd(self.dir_stack[0])
2308 2314 print self.dir_stack[0]
2309 2315 else:
2310 2316 print "You can't remove the starting directory from the stack:",\
2311 2317 self.dir_stack
2312 2318
2313 2319 def magic_dirs(self, parameter_s=''):
2314 2320 """Return the current directory stack."""
2315 2321
2316 2322 return self.dir_stack[:]
2317 2323
2318 2324 def magic_sc(self, parameter_s=''):
2319 2325 """Shell capture - execute a shell command and capture its output.
2320 2326
2321 2327 %sc [options] varname=command
2322 2328
2323 2329 IPython will run the given command using commands.getoutput(), and
2324 2330 will then update the user's interactive namespace with a variable
2325 2331 called varname, containing the value of the call. Your command can
2326 2332 contain shell wildcards, pipes, etc.
2327 2333
2328 2334 The '=' sign in the syntax is mandatory, and the variable name you
2329 2335 supply must follow Python's standard conventions for valid names.
2330 2336
2331 2337 Options:
2332 2338
2333 2339 -l: list output. Split the output on newlines into a list before
2334 2340 assigning it to the given variable. By default the output is stored
2335 2341 as a single string.
2336 2342
2337 2343 -v: verbose. Print the contents of the variable.
2338 2344
2339 2345 In most cases you should not need to split as a list, because the
2340 2346 returned value is a special type of string which can automatically
2341 2347 provide its contents either as a list (split on newlines) or as a
2342 2348 space-separated string. These are convenient, respectively, either
2343 2349 for sequential processing or to be passed to a shell command.
2344 2350
2345 2351 For example:
2346 2352
2347 2353 # Capture into variable a
2348 2354 In [9]: sc a=ls *py
2349 2355
2350 2356 # a is a string with embedded newlines
2351 2357 In [10]: a
2352 2358 Out[10]: 'setup.py\nwin32_manual_post_install.py'
2353 2359
2354 2360 # which can be seen as a list:
2355 2361 In [11]: a.l
2356 2362 Out[11]: ['setup.py', 'win32_manual_post_install.py']
2357 2363
2358 2364 # or as a whitespace-separated string:
2359 2365 In [12]: a.s
2360 2366 Out[12]: 'setup.py win32_manual_post_install.py'
2361 2367
2362 2368 # a.s is useful to pass as a single command line:
2363 2369 In [13]: !wc -l $a.s
2364 2370 146 setup.py
2365 2371 130 win32_manual_post_install.py
2366 2372 276 total
2367 2373
2368 2374 # while the list form is useful to loop over:
2369 2375 In [14]: for f in a.l:
2370 2376 ....: !wc -l $f
2371 2377 ....:
2372 2378 146 setup.py
2373 2379 130 win32_manual_post_install.py
2374 2380
2375 2381 Similiarly, the lists returned by the -l option are also special, in
2376 2382 the sense that you can equally invoke the .s attribute on them to
2377 2383 automatically get a whitespace-separated string from their contents:
2378 2384
2379 2385 In [1]: sc -l b=ls *py
2380 2386
2381 2387 In [2]: b
2382 2388 Out[2]: ['setup.py', 'win32_manual_post_install.py']
2383 2389
2384 2390 In [3]: b.s
2385 2391 Out[3]: 'setup.py win32_manual_post_install.py'
2386 2392
2387 2393 In summary, both the lists and strings used for ouptut capture have
2388 2394 the following special attributes:
2389 2395
2390 2396 .l (or .list) : value as list.
2391 2397 .n (or .nlstr): value as newline-separated string.
2392 2398 .s (or .spstr): value as space-separated string.
2393 2399 """
2394 2400
2395 2401 opts,args = self.parse_options(parameter_s,'lv')
2396 2402 # Try to get a variable name and command to run
2397 2403 try:
2398 2404 # the variable name must be obtained from the parse_options
2399 2405 # output, which uses shlex.split to strip options out.
2400 2406 var,_ = args.split('=',1)
2401 2407 var = var.strip()
2402 2408 # But the the command has to be extracted from the original input
2403 2409 # parameter_s, not on what parse_options returns, to avoid the
2404 2410 # quote stripping which shlex.split performs on it.
2405 2411 _,cmd = parameter_s.split('=',1)
2406 2412 except ValueError:
2407 2413 var,cmd = '',''
2408 2414 if not var:
2409 2415 error('you must specify a variable to assign the command to.')
2410 2416 return
2411 2417 # If all looks ok, proceed
2412 2418 out,err = self.shell.getoutputerror(cmd)
2413 2419 if err:
2414 2420 print >> Term.cerr,err
2415 2421 if opts.has_key('l'):
2416 2422 out = SList(out.split('\n'))
2417 2423 else:
2418 2424 out = LSString(out)
2419 2425 if opts.has_key('v'):
2420 2426 print '%s ==\n%s' % (var,pformat(out))
2421 2427 self.shell.user_ns.update({var:out})
2422 2428
2423 2429 def magic_sx(self, parameter_s=''):
2424 2430 """Shell execute - run a shell command and capture its output.
2425 2431
2426 2432 %sx command
2427 2433
2428 2434 IPython will run the given command using commands.getoutput(), and
2429 2435 return the result formatted as a list (split on '\\n'). Since the
2430 2436 output is _returned_, it will be stored in ipython's regular output
2431 2437 cache Out[N] and in the '_N' automatic variables.
2432 2438
2433 2439 Notes:
2434 2440
2435 2441 1) If an input line begins with '!!', then %sx is automatically
2436 2442 invoked. That is, while:
2437 2443 !ls
2438 2444 causes ipython to simply issue system('ls'), typing
2439 2445 !!ls
2440 2446 is a shorthand equivalent to:
2441 2447 %sx ls
2442 2448
2443 2449 2) %sx differs from %sc in that %sx automatically splits into a list,
2444 2450 like '%sc -l'. The reason for this is to make it as easy as possible
2445 2451 to process line-oriented shell output via further python commands.
2446 2452 %sc is meant to provide much finer control, but requires more
2447 2453 typing.
2448 2454
2449 2455 3) Just like %sc -l, this is a list with special attributes:
2450 2456
2451 2457 .l (or .list) : value as list.
2452 2458 .n (or .nlstr): value as newline-separated string.
2453 2459 .s (or .spstr): value as whitespace-separated string.
2454 2460
2455 2461 This is very useful when trying to use such lists as arguments to
2456 2462 system commands."""
2457 2463
2458 2464 if parameter_s:
2459 2465 out,err = self.shell.getoutputerror(parameter_s)
2460 2466 if err:
2461 2467 print >> Term.cerr,err
2462 2468 return SList(out.split('\n'))
2463 2469
2464 2470 def magic_bg(self, parameter_s=''):
2465 2471 """Run a job in the background, in a separate thread.
2466 2472
2467 2473 For example,
2468 2474
2469 2475 %bg myfunc(x,y,z=1)
2470 2476
2471 2477 will execute 'myfunc(x,y,z=1)' in a background thread. As soon as the
2472 2478 execution starts, a message will be printed indicating the job
2473 2479 number. If your job number is 5, you can use
2474 2480
2475 2481 myvar = jobs.result(5) or myvar = jobs[5].result
2476 2482
2477 2483 to assign this result to variable 'myvar'.
2478 2484
2479 2485 IPython has a job manager, accessible via the 'jobs' object. You can
2480 2486 type jobs? to get more information about it, and use jobs.<TAB> to see
2481 2487 its attributes. All attributes not starting with an underscore are
2482 2488 meant for public use.
2483 2489
2484 2490 In particular, look at the jobs.new() method, which is used to create
2485 2491 new jobs. This magic %bg function is just a convenience wrapper
2486 2492 around jobs.new(), for expression-based jobs. If you want to create a
2487 2493 new job with an explicit function object and arguments, you must call
2488 2494 jobs.new() directly.
2489 2495
2490 2496 The jobs.new docstring also describes in detail several important
2491 2497 caveats associated with a thread-based model for background job
2492 2498 execution. Type jobs.new? for details.
2493 2499
2494 2500 You can check the status of all jobs with jobs.status().
2495 2501
2496 2502 The jobs variable is set by IPython into the Python builtin namespace.
2497 2503 If you ever declare a variable named 'jobs', you will shadow this
2498 2504 name. You can either delete your global jobs variable to regain
2499 2505 access to the job manager, or make a new name and assign it manually
2500 2506 to the manager (stored in IPython's namespace). For example, to
2501 2507 assign the job manager to the Jobs name, use:
2502 2508
2503 2509 Jobs = __builtins__.jobs"""
2504 2510
2505 2511 self.shell.jobs.new(parameter_s,self.shell.user_ns)
2506 2512
2507 2513 def magic_bookmark(self, parameter_s=''):
2508 2514 """Manage IPython's bookmark system.
2509 2515
2510 2516 %bookmark <name> - set bookmark to current dir
2511 2517 %bookmark <name> <dir> - set bookmark to <dir>
2512 2518 %bookmark -l - list all bookmarks
2513 2519 %bookmark -d <name> - remove bookmark
2514 2520 %bookmark -r - remove all bookmarks
2515 2521
2516 2522 You can later on access a bookmarked folder with:
2517 2523 %cd -b <name>
2518 2524 or simply '%cd <name>' if there is no directory called <name> AND
2519 2525 there is such a bookmark defined.
2520 2526
2521 2527 Your bookmarks persist through IPython sessions, but they are
2522 2528 associated with each profile."""
2523 2529
2524 2530 opts,args = self.parse_options(parameter_s,'drl',mode='list')
2525 2531 if len(args) > 2:
2526 2532 error('You can only give at most two arguments')
2527 2533 return
2528 2534
2529 2535 bkms = self.shell.persist.get('bookmarks',{})
2530 2536
2531 2537 if opts.has_key('d'):
2532 2538 try:
2533 2539 todel = args[0]
2534 2540 except IndexError:
2535 2541 error('You must provide a bookmark to delete')
2536 2542 else:
2537 2543 try:
2538 2544 del bkms[todel]
2539 2545 except:
2540 2546 error("Can't delete bookmark '%s'" % todel)
2541 2547 elif opts.has_key('r'):
2542 2548 bkms = {}
2543 2549 elif opts.has_key('l'):
2544 2550 bks = bkms.keys()
2545 2551 bks.sort()
2546 2552 if bks:
2547 2553 size = max(map(len,bks))
2548 2554 else:
2549 2555 size = 0
2550 2556 fmt = '%-'+str(size)+'s -> %s'
2551 2557 print 'Current bookmarks:'
2552 2558 for bk in bks:
2553 2559 print fmt % (bk,bkms[bk])
2554 2560 else:
2555 2561 if not args:
2556 2562 error("You must specify the bookmark name")
2557 2563 elif len(args)==1:
2558 2564 bkms[args[0]] = os.getcwd()
2559 2565 elif len(args)==2:
2560 2566 bkms[args[0]] = args[1]
2561 2567 self.persist['bookmarks'] = bkms
2562 2568
2563 2569 def magic_pycat(self, parameter_s=''):
2564 2570 """Show a syntax-highlighted file through a pager.
2565 2571
2566 2572 This magic is similar to the cat utility, but it will assume the file
2567 2573 to be Python source and will show it with syntax highlighting. """
2568 2574
2569 2575 filename = get_py_filename(parameter_s)
2570 2576 page(self.shell.colorize(file_read(filename)),
2571 2577 screen_lines=self.shell.rc.screen_length)
2572 2578
2573 2579 # end Magic
@@ -1,455 +1,459 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Tools for inspecting Python objects.
3 3
4 4 Uses syntax highlighting for presenting the various information elements.
5 5
6 6 Similar in spirit to the inspect module, but all calls take a name argument to
7 7 reference the name under which an object is being read.
8 8
9 $Id: OInspect.py 923 2005-11-15 08:51:15Z fperez $
9 $Id: OInspect.py 958 2005-12-27 23:17:51Z fperez $
10 10 """
11 11
12 12 #*****************************************************************************
13 13 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
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 from IPython import Release
20 20 __author__ = '%s <%s>' % Release.authors['Fernando']
21 21 __license__ = Release.license
22 22
23 23 __all__ = ['Inspector','InspectColors']
24 24
25 25 # stdlib modules
26 26 import __builtin__
27 import inspect,linecache,types,StringIO,string
27 import inspect
28 import linecache
29 import string
30 import StringIO
31 import types
28 32
29 33 # IPython's own
30 34 from IPython import PyColorize
35 from IPython.genutils import page,indent,Term,mkdict
31 36 from IPython.Itpl import itpl
32 37 from IPython.wildcard import list_namespace
33 from IPython.genutils import page,indent,Term,mkdict
34 38 from IPython.ColorANSI import *
35 39
36 40 #****************************************************************************
37 41 # Builtin color schemes
38 42
39 43 Colors = TermColors # just a shorthand
40 44
41 45 # Build a few color schemes
42 46 NoColor = ColorScheme(
43 47 'NoColor',{
44 48 'header' : Colors.NoColor,
45 49 'normal' : Colors.NoColor # color off (usu. Colors.Normal)
46 50 } )
47 51
48 52 LinuxColors = ColorScheme(
49 53 'Linux',{
50 54 'header' : Colors.LightRed,
51 55 'normal' : Colors.Normal # color off (usu. Colors.Normal)
52 56 } )
53 57
54 58 LightBGColors = ColorScheme(
55 59 'LightBG',{
56 60 'header' : Colors.Red,
57 61 'normal' : Colors.Normal # color off (usu. Colors.Normal)
58 62 } )
59 63
60 64 # Build table of color schemes (needed by the parser)
61 65 InspectColors = ColorSchemeTable([NoColor,LinuxColors,LightBGColors],
62 66 'Linux')
63 67
64 68 #****************************************************************************
65 69 # Auxiliary functions
66 70 def getdoc(obj):
67 71 """Stable wrapper around inspect.getdoc.
68 72
69 73 This can't crash because of attribute problems.
70 74
71 75 It also attempts to call a getdoc() method on the given object. This
72 76 allows objects which provide their docstrings via non-standard mechanisms
73 77 (like Pyro proxies) to still be inspected by ipython's ? system."""
74 78
75 79 ds = None # default return value
76 80 try:
77 81 ds = inspect.getdoc(obj)
78 82 except:
79 83 # Harden against an inspect failure, which can occur with
80 84 # SWIG-wrapped extensions.
81 85 pass
82 86 # Allow objects to offer customized documentation via a getdoc method:
83 87 try:
84 88 ds2 = obj.getdoc()
85 89 except:
86 90 pass
87 91 else:
88 92 # if we get extra info, we add it to the normal docstring.
89 93 if ds is None:
90 94 ds = ds2
91 95 else:
92 96 ds = '%s\n%s' % (ds,ds2)
93 97 return ds
94 98
95 99 #****************************************************************************
96 100 # Class definitions
97 101
98 102 class myStringIO(StringIO.StringIO):
99 103 """Adds a writeln method to normal StringIO."""
100 104 def writeln(self,*arg,**kw):
101 105 """Does a write() and then a write('\n')"""
102 106 self.write(*arg,**kw)
103 107 self.write('\n')
104 108
105 109 class Inspector:
106 110 def __init__(self,color_table,code_color_table,scheme):
107 111 self.color_table = color_table
108 112 self.parser = PyColorize.Parser(code_color_table,out='str')
109 113 self.format = self.parser.format
110 114 self.set_active_scheme(scheme)
111 115
112 116 def __getargspec(self,obj):
113 117 """Get the names and default values of a function's arguments.
114 118
115 119 A tuple of four things is returned: (args, varargs, varkw, defaults).
116 120 'args' is a list of the argument names (it may contain nested lists).
117 121 'varargs' and 'varkw' are the names of the * and ** arguments or None.
118 122 'defaults' is an n-tuple of the default values of the last n arguments.
119 123
120 124 Modified version of inspect.getargspec from the Python Standard
121 125 Library."""
122 126
123 127 if inspect.isfunction(obj):
124 128 func_obj = obj
125 129 elif inspect.ismethod(obj):
126 130 func_obj = obj.im_func
127 131 else:
128 132 raise TypeError, 'arg is not a Python function'
129 133 args, varargs, varkw = inspect.getargs(func_obj.func_code)
130 134 return args, varargs, varkw, func_obj.func_defaults
131 135
132 136 def __getdef(self,obj,oname=''):
133 137 """Return the definition header for any callable object.
134 138
135 139 If any exception is generated, None is returned instead and the
136 140 exception is suppressed."""
137 141
138 142 try:
139 143 return oname + inspect.formatargspec(*self.__getargspec(obj))
140 144 except:
141 145 return None
142 146
143 147 def __head(self,h):
144 148 """Return a header string with proper colors."""
145 149 return '%s%s%s' % (self.color_table.active_colors.header,h,
146 150 self.color_table.active_colors.normal)
147 151
148 152 def set_active_scheme(self,scheme):
149 153 self.color_table.set_active_scheme(scheme)
150 154 self.parser.color_table.set_active_scheme(scheme)
151 155
152 156 def noinfo(self,msg,oname):
153 157 """Generic message when no information is found."""
154 158 print 'No %s found' % msg,
155 159 if oname:
156 160 print 'for %s' % oname
157 161 else:
158 162 print
159 163
160 164 def pdef(self,obj,oname=''):
161 165 """Print the definition header for any callable object.
162 166
163 167 If the object is a class, print the constructor information."""
164 168
165 169 if not callable(obj):
166 170 print 'Object is not callable.'
167 171 return
168 172
169 173 header = ''
170 174 if type(obj) is types.ClassType:
171 175 header = self.__head('Class constructor information:\n')
172 176 obj = obj.__init__
173 177 elif type(obj) is types.InstanceType:
174 178 obj = obj.__call__
175 179
176 180 output = self.__getdef(obj,oname)
177 181 if output is None:
178 182 self.noinfo('definition header',oname)
179 183 else:
180 184 print >>Term.cout, header,self.format(output),
181 185
182 186 def pdoc(self,obj,oname='',formatter = None):
183 187 """Print the docstring for any object.
184 188
185 189 Optional:
186 190 -formatter: a function to run the docstring through for specially
187 191 formatted docstrings."""
188 192
189 193 head = self.__head # so that itpl can find it even if private
190 194 ds = getdoc(obj)
191 195 if formatter:
192 196 ds = formatter(ds)
193 197 if type(obj) is types.ClassType:
194 198 init_ds = getdoc(obj.__init__)
195 199 output = itpl('$head("Class Docstring:")\n'
196 200 '$indent(ds)\n'
197 201 '$head("Constructor Docstring"):\n'
198 202 '$indent(init_ds)')
199 203 elif type(obj) is types.InstanceType and hasattr(obj,'__call__'):
200 204 call_ds = getdoc(obj.__call__)
201 205 if call_ds:
202 206 output = itpl('$head("Class Docstring:")\n$indent(ds)\n'
203 207 '$head("Calling Docstring:")\n$indent(call_ds)')
204 208 else:
205 209 output = ds
206 210 else:
207 211 output = ds
208 212 if output is None:
209 213 self.noinfo('documentation',oname)
210 214 return
211 215 page(output)
212 216
213 217 def psource(self,obj,oname=''):
214 218 """Print the source code for an object."""
215 219
216 220 # Flush the source cache because inspect can return out-of-date source
217 221 linecache.checkcache()
218 222 try:
219 223 src = inspect.getsource(obj)
220 224 except:
221 225 self.noinfo('source',oname)
222 226 else:
223 227 page(self.format(src))
224 228
225 229 def pfile(self,obj,oname=''):
226 230 """Show the whole file where an object was defined."""
227 231 try:
228 232 sourcelines,lineno = inspect.getsourcelines(obj)
229 233 except:
230 234 self.noinfo('file',oname)
231 235 else:
232 236 # run contents of file through pager starting at line
233 237 # where the object is defined
234 238 page(self.format(open(inspect.getabsfile(obj)).read()),lineno)
235 239
236 240 def pinfo(self,obj,oname='',formatter=None,info=None,detail_level=0):
237 241 """Show detailed information about an object.
238 242
239 243 Optional arguments:
240 244
241 245 - oname: name of the variable pointing to the object.
242 246
243 247 - formatter: special formatter for docstrings (see pdoc)
244 248
245 249 - info: a structure with some information fields which may have been
246 250 precomputed already.
247 251
248 252 - detail_level: if set to 1, more information is given.
249 253 """
250 254
251 255 obj_type = type(obj)
252 256
253 257 header = self.__head
254 258 if info is None:
255 259 ismagic = 0
256 260 isalias = 0
257 261 ospace = ''
258 262 else:
259 263 ismagic = info.ismagic
260 264 isalias = info.isalias
261 265 ospace = info.namespace
262 266 # Get docstring, special-casing aliases:
263 267 if isalias:
264 268 ds = "Alias to the system command:\n %s" % obj[1]
265 269 else:
266 270 ds = getdoc(obj)
267 271 if formatter is not None:
268 272 ds = formatter(ds)
269 273
270 274 # store output in a list which gets joined with \n at the end.
271 275 out = myStringIO()
272 276
273 277 string_max = 200 # max size of strings to show (snipped if longer)
274 278 shalf = int((string_max -5)/2)
275 279
276 280 if ismagic:
277 281 obj_type_name = 'Magic function'
278 282 elif isalias:
279 283 obj_type_name = 'System alias'
280 284 else:
281 285 obj_type_name = obj_type.__name__
282 286 out.writeln(header('Type:\t\t')+obj_type_name)
283 287
284 288 try:
285 289 bclass = obj.__class__
286 290 out.writeln(header('Base Class:\t')+str(bclass))
287 291 except: pass
288 292
289 293 # String form, but snip if too long in ? form (full in ??)
290 294 try:
291 295 ostr = str(obj)
292 296 str_head = 'String Form:'
293 297 if not detail_level and len(ostr)>string_max:
294 298 ostr = ostr[:shalf] + ' <...> ' + ostr[-shalf:]
295 299 ostr = ("\n" + " " * len(str_head.expandtabs())).\
296 300 join(map(string.strip,ostr.split("\n")))
297 301 if ostr.find('\n') > -1:
298 302 # Print multi-line strings starting at the next line.
299 303 str_sep = '\n'
300 304 else:
301 305 str_sep = '\t'
302 306 out.writeln("%s%s%s" % (header(str_head),str_sep,ostr))
303 307 except:
304 308 pass
305 309
306 310 if ospace:
307 311 out.writeln(header('Namespace:\t')+ospace)
308 312
309 313 # Length (for strings and lists)
310 314 try:
311 315 length = str(len(obj))
312 316 out.writeln(header('Length:\t\t')+length)
313 317 except: pass
314 318
315 319 # Filename where object was defined
316 320 try:
317 321 file = inspect.getabsfile(obj)
318 322 if file.endswith('<string>'):
319 323 file = 'Dynamically generated function. No source code available.'
320 324 out.writeln(header('File:\t\t')+file)
321 325 except: pass
322 326
323 327 # reconstruct the function definition and print it:
324 328 defln = self.__getdef(obj,oname)
325 329 if defln:
326 330 out.write(header('Definition:\t')+self.format(defln))
327 331
328 332 # Docstrings only in detail 0 mode, since source contains them (we
329 333 # avoid repetitions). If source fails, we add them back, see below.
330 334 if ds and detail_level == 0:
331 335 out.writeln(header('Docstring:\n') + indent(ds))
332 336
333 337 # Original source code for any callable
334 338 if detail_level:
335 339 # Flush the source cache because inspect can return out-of-date source
336 340 linecache.checkcache()
337 341 try:
338 342 source = self.format(inspect.getsource(obj))
339 343 out.write(header('Source:\n')+source.rstrip())
340 344 except:
341 345 if ds:
342 346 out.writeln(header('Docstring:\n') + indent(ds))
343 347
344 348 # Constructor docstring for classes
345 349 if obj_type is types.ClassType:
346 350 # reconstruct the function definition and print it:
347 351 try:
348 352 obj_init = obj.__init__
349 353 except AttributeError:
350 354 init_def = init_ds = None
351 355 else:
352 356 init_def = self.__getdef(obj_init,oname)
353 357 init_ds = getdoc(obj_init)
354 358
355 359 if init_def or init_ds:
356 360 out.writeln(header('\nConstructor information:'))
357 361 if init_def:
358 362 out.write(header('Definition:\t')+ self.format(init_def))
359 363 if init_ds:
360 364 out.writeln(header('Docstring:\n') + indent(init_ds))
361 365 # and class docstring for instances:
362 366 elif obj_type is types.InstanceType:
363 367
364 368 # First, check whether the instance docstring is identical to the
365 369 # class one, and print it separately if they don't coincide. In
366 370 # most cases they will, but it's nice to print all the info for
367 371 # objects which use instance-customized docstrings.
368 372 if ds:
369 373 class_ds = getdoc(obj.__class__)
370 374 if class_ds and ds != class_ds:
371 375 out.writeln(header('Class Docstring:\n') +
372 376 indent(class_ds))
373 377
374 378 # Next, try to show constructor docstrings
375 379 try:
376 380 init_ds = getdoc(obj.__init__)
377 381 except AttributeError:
378 382 init_ds = None
379 383 if init_ds:
380 384 out.writeln(header('Constructor Docstring:\n') +
381 385 indent(init_ds))
382 386
383 387 # Call form docstring for callable instances
384 388 if hasattr(obj,'__call__'):
385 389 out.writeln(header('Callable:\t')+'Yes')
386 390 call_def = self.__getdef(obj.__call__,oname)
387 391 if call_def is None:
388 392 out.write(header('Call def:\t')+
389 393 'Calling definition not available.')
390 394 else:
391 395 out.write(header('Call def:\t')+self.format(call_def))
392 396 call_ds = getdoc(obj.__call__)
393 397 if call_ds:
394 398 out.writeln(header('Call docstring:\n') + indent(call_ds))
395 399
396 400 # Finally send to printer/pager
397 401 output = out.getvalue()
398 402 if output:
399 403 page(output)
400 404 # end pinfo
401 405
402 406 def psearch(self,pattern,ns_table,ns_search=[],
403 407 ignore_case=False,show_all=False):
404 408 """Search namespaces with wildcards for objects.
405 409
406 410 Arguments:
407 411
408 412 - pattern: string containing shell-like wildcards to use in namespace
409 413 searches and optionally a type specification to narrow the search to
410 414 objects of that type.
411 415
412 416 - ns_table: dict of name->namespaces for search.
413 417
414 418 Optional arguments:
415 419
416 420 - ns_search: list of namespace names to include in search.
417 421
418 422 - ignore_case(False): make the search case-insensitive.
419 423
420 424 - show_all(False): show all names, including those starting with
421 425 underscores.
422 426 """
423 427 # defaults
424 428 type_pattern = 'all'
425 429 filter = ''
426 430
427 431 cmds = pattern.split()
428 432 len_cmds = len(cmds)
429 433 if len_cmds == 1:
430 434 # Only filter pattern given
431 435 filter = cmds[0]
432 436 elif len_cmds == 2:
433 437 # Both filter and type specified
434 438 filter,type_pattern = cmds
435 439 else:
436 440 raise ValueError('invalid argument string for psearch: <%s>' %
437 441 pattern)
438 442
439 443 # filter search namespaces
440 444 for name in ns_search:
441 445 if name not in ns_table:
442 446 raise ValueError('invalid namespace <%s>. Valid names: %s' %
443 447 (name,ns_table.keys()))
444 448
445 449 #print 'type_pattern:',type_pattern # dbg
446 450 search_result = []
447 451 for ns_name in ns_search:
448 452 ns = ns_table[ns_name]
449 453 tmp_res = list(list_namespace(ns,type_pattern,filter,
450 454 ignore_case=ignore_case,
451 455 show_all=show_all))
452 456 search_result.extend(tmp_res)
453 457 search_result.sort()
454 458
455 459 page('\n'.join(search_result))
@@ -1,262 +1,263 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Class to trap stdout and stderr and log them separately.
3 3
4 $Id: OutputTrap.py 542 2005-03-18 09:16:04Z fperez $"""
4 $Id: OutputTrap.py 958 2005-12-27 23:17:51Z fperez $"""
5 5
6 6 #*****************************************************************************
7 7 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
8 8 #
9 9 # Distributed under the terms of the BSD License. The full license is in
10 10 # the file COPYING, distributed as part of this software.
11 11 #*****************************************************************************
12 12
13 13 from IPython import Release
14 14 __author__ = '%s <%s>' % Release.authors['Fernando']
15 15 __license__ = Release.license
16 16
17 import exceptions,sys
17 import exceptions
18 import sys
18 19 from cStringIO import StringIO
19 20
20 21 class OutputTrapError(exceptions.Exception):
21 22 """Exception for OutputTrap class."""
22 23
23 24 def __init__(self,args=None):
24 25 exceptions.Exception.__init__(self)
25 26 self.args = args
26 27
27 28 class OutputTrap:
28 29
29 30 """Class to trap standard output and standard error. They get logged in
30 31 StringIO objects which are available as <instance>.out and
31 32 <instance>.err. The class also offers summary methods which format this
32 33 data a bit.
33 34
34 35 A word of caution: because it blocks messages, using this class can make
35 36 debugging very tricky. If you are having bizarre problems silently, try
36 37 turning your output traps off for a while. You can call the constructor
37 38 with the parameter debug=1 for these cases. This turns actual trapping
38 39 off, but you can keep the rest of your code unchanged (this has already
39 40 been a life saver).
40 41
41 42 Example:
42 43
43 44 # config: trapper with a line of dots as log separator (final '\\n' needed)
44 45 config = OutputTrap('Config','Out ','Err ','.'*80+'\\n')
45 46
46 47 # start trapping output
47 48 config.trap_all()
48 49
49 50 # now all output is logged ...
50 51 # do stuff...
51 52
52 53 # output back to normal:
53 54 config.release_all()
54 55
55 56 # print all that got logged:
56 57 print config.summary()
57 58
58 59 # print individual raw data:
59 60 print config.out.getvalue()
60 61 print config.err.getvalue()
61 62 """
62 63
63 64 def __init__(self,name='Generic Output Trap',
64 65 out_head='Standard Output. ',err_head='Standard Error. ',
65 66 sum_sep='\n',debug=0,trap_out=0,trap_err=0,
66 67 quiet_out=0,quiet_err=0):
67 68 self.name = name
68 69 self.out_head = out_head
69 70 self.err_head = err_head
70 71 self.sum_sep = sum_sep
71 72 self.out = StringIO()
72 73 self.err = StringIO()
73 74 self.out_save = None
74 75 self.err_save = None
75 76 self.debug = debug
76 77 self.quiet_out = quiet_out
77 78 self.quiet_err = quiet_err
78 79 if trap_out:
79 80 self.trap_out()
80 81 if trap_err:
81 82 self.trap_err()
82 83
83 84 def trap_out(self):
84 85 """Trap and log stdout."""
85 86 if sys.stdout is self.out:
86 87 raise OutputTrapError,'You are already trapping stdout.'
87 88 if not self.debug:
88 89 self._out_save = sys.stdout
89 90 sys.stdout = self.out
90 91
91 92 def release_out(self):
92 93 """Release stdout."""
93 94 if not self.debug:
94 95 if not sys.stdout is self.out:
95 96 raise OutputTrapError,'You are not trapping stdout.'
96 97 sys.stdout = self._out_save
97 98 self.out_save = None
98 99
99 100 def summary_out(self):
100 101 """Return as a string the log from stdout."""
101 102 out = self.out.getvalue()
102 103 if out:
103 104 if self.quiet_out:
104 105 return out
105 106 else:
106 107 return self.out_head + 'Log by '+ self.name + ':\n' + out
107 108 else:
108 109 return ''
109 110
110 111 def flush_out(self):
111 112 """Flush the stdout log. All data held in the log is lost."""
112 113
113 114 self.out.close()
114 115 self.out = StringIO()
115 116
116 117 def trap_err(self):
117 118 """Trap and log stderr."""
118 119 if sys.stderr is self.err:
119 120 raise OutputTrapError,'You are already trapping stderr.'
120 121 if not self.debug:
121 122 self._err_save = sys.stderr
122 123 sys.stderr = self.err
123 124
124 125 def release_err(self):
125 126 """Release stderr."""
126 127 if not self.debug:
127 128 if not sys.stderr is self.err:
128 129 raise OutputTrapError,'You are not trapping stderr.'
129 130 sys.stderr = self._err_save
130 131 self.err_save = None
131 132
132 133 def summary_err(self):
133 134 """Return as a string the log from stderr."""
134 135 err = self.err.getvalue()
135 136 if err:
136 137 if self.quiet_err:
137 138 return err
138 139 else:
139 140 return self.err_head + 'Log by '+ self.name + ':\n' + err
140 141 else:
141 142 return ''
142 143
143 144 def flush_err(self):
144 145 """Flush the stdout log. All data held in the log is lost."""
145 146
146 147 self.err.close()
147 148 self.err = StringIO()
148 149
149 150 def trap_all(self):
150 151 """Trap and log both stdout and stderr.
151 152
152 153 Cacthes and discards OutputTrapError exceptions raised."""
153 154 try:
154 155 self.trap_out()
155 156 except OutputTrapError:
156 157 pass
157 158 try:
158 159 self.trap_err()
159 160 except OutputTrapError:
160 161 pass
161 162
162 163 def release_all(self):
163 164 """Release both stdout and stderr.
164 165
165 166 Cacthes and discards OutputTrapError exceptions raised."""
166 167 try:
167 168 self.release_out()
168 169 except OutputTrapError:
169 170 pass
170 171 try:
171 172 self.release_err()
172 173 except OutputTrapError:
173 174 pass
174 175
175 176 def summary_all(self):
176 177 """Return as a string the log from stdout and stderr, prepending a separator
177 178 to each (defined in __init__ as sum_sep)."""
178 179 sum = ''
179 180 sout = self.summary_out()
180 181 if sout:
181 182 sum += self.sum_sep + sout
182 183 serr = self.summary_err()
183 184 if serr:
184 185 sum += '\n'+self.sum_sep + serr
185 186 return sum
186 187
187 188 def flush_all(self):
188 189 """Flush stdout and stderr"""
189 190 self.flush_out()
190 191 self.flush_err()
191 192
192 193 # a few shorthands
193 194 trap = trap_all
194 195 release = release_all
195 196 summary = summary_all
196 197 flush = flush_all
197 198 # end OutputTrap
198 199
199 200
200 201 #****************************************************************************
201 202 # Module testing. Incomplete, I'm lazy...
202 203
203 204 def _test_all():
204 205
205 206 """Module testing functions, activated when the module is called as a
206 207 script (not imported)."""
207 208
208 209 # Put tests for this module in here.
209 210 # Define them as nested functions so they don't clobber the
210 211 # pydoc-generated docs
211 212
212 213 def _test_():
213 214 name = ''
214 215 print '#'*50+'\nRunning test for ' + name
215 216 # ...
216 217 print 'Finished test for '+ name +'\n'+'#'*50
217 218
218 219 def _test_OutputTrap():
219 220 trap = OutputTrap(name = 'Test Trap', sum_sep = '.'*50+'\n',
220 221 out_head = 'SOut. ', err_head = 'SErr. ')
221 222
222 223 name = 'OutputTrap class'
223 224 print '#'*50+'\nRunning test for ' + name
224 225 print 'Trapping out'
225 226 trap.trap_out()
226 227 print >>sys.stdout, '>>stdout. stdout is trapped.'
227 228 print >>sys.stderr, '>>stderr. stdout is trapped.'
228 229 trap.release_out()
229 230 print trap.summary_out()
230 231
231 232 print 'Trapping err'
232 233 trap.trap_err()
233 234 print >>sys.stdout, '>>stdout. stderr is trapped.'
234 235 print >>sys.stderr, '>>stderr. stderr is trapped.'
235 236 trap.release_err()
236 237 print trap.summary_err()
237 238
238 239 print 'Trapping all (no flushing)'
239 240 trap.trap_all()
240 241 print >>sys.stdout, '>>stdout. stdout/err is trapped.'
241 242 print >>sys.stderr, '>>stderr. stdout/err is trapped.'
242 243 trap.release_all()
243 244 print trap.summary_all()
244 245
245 246 print 'Trapping all (flushing first)'
246 247 trap.flush()
247 248 trap.trap_all()
248 249 print >>sys.stdout, '>>stdout. stdout/err is trapped.'
249 250 print >>sys.stderr, '>>stderr. stdout/err is trapped.'
250 251 trap.release_all()
251 252 print trap.summary_all()
252 253 print 'Finished test for '+ name +'\n'+'#'*50
253 254
254 255 # call the actual tests here:
255 256 _test_OutputTrap()
256 257
257 258
258 259 if __name__=="__main__":
259 260 # _test_all() # XXX BROKEN.
260 261 pass
261 262
262 263 #************************ end of file <OutputTrap.py> ************************
@@ -1,574 +1,576 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 Classes for handling input/output prompts.
4 4
5 $Id: Prompts.py 951 2005-12-25 00:57:24Z fperez $"""
5 $Id: Prompts.py 958 2005-12-27 23:17:51Z fperez $"""
6 6
7 7 #*****************************************************************************
8 8 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
9 9 #
10 10 # Distributed under the terms of the BSD License. The full license is in
11 11 # the file COPYING, distributed as part of this software.
12 12 #*****************************************************************************
13 13
14 14 from IPython import Release
15 15 __author__ = '%s <%s>' % Release.authors['Fernando']
16 16 __license__ = Release.license
17 17 __version__ = Release.version
18 18
19 19 #****************************************************************************
20 20 # Required modules
21 21 import __builtin__
22 import os,sys,socket
22 import os
23 import socket
24 import sys
23 25 import time
24 26 from pprint import pprint,pformat
25 27
26 28 # IPython's own
27 29 from IPython.genutils import *
28 30 from IPython.Struct import Struct
29 31 from IPython.Magic import Macro
30 32 from IPython.Itpl import ItplNS
31 33 from IPython import ColorANSI
32 34
33 35 #****************************************************************************
34 36 #Color schemes for Prompts.
35 37
36 38 PromptColors = ColorANSI.ColorSchemeTable()
37 39 InputColors = ColorANSI.InputTermColors # just a shorthand
38 40 Colors = ColorANSI.TermColors # just a shorthand
39 41
40 42 PromptColors.add_scheme(ColorANSI.ColorScheme(
41 43 'NoColor',
42 44 in_prompt = InputColors.NoColor, # Input prompt
43 45 in_number = InputColors.NoColor, # Input prompt number
44 46 in_prompt2 = InputColors.NoColor, # Continuation prompt
45 47 in_normal = InputColors.NoColor, # color off (usu. Colors.Normal)
46 48
47 49 out_prompt = Colors.NoColor, # Output prompt
48 50 out_number = Colors.NoColor, # Output prompt number
49 51
50 52 normal = Colors.NoColor # color off (usu. Colors.Normal)
51 53 ))
52 54
53 55 # make some schemes as instances so we can copy them for modification easily:
54 56 __PColLinux = ColorANSI.ColorScheme(
55 57 'Linux',
56 58 in_prompt = InputColors.Green,
57 59 in_number = InputColors.LightGreen,
58 60 in_prompt2 = InputColors.Green,
59 61 in_normal = InputColors.Normal, # color off (usu. Colors.Normal)
60 62
61 63 out_prompt = Colors.Red,
62 64 out_number = Colors.LightRed,
63 65
64 66 normal = Colors.Normal
65 67 )
66 68 # Don't forget to enter it into the table!
67 69 PromptColors.add_scheme(__PColLinux)
68 70
69 71 # Slightly modified Linux for light backgrounds
70 72 __PColLightBG = __PColLinux.copy('LightBG')
71 73
72 74 __PColLightBG.colors.update(
73 75 in_prompt = InputColors.Blue,
74 76 in_number = InputColors.LightBlue,
75 77 in_prompt2 = InputColors.Blue
76 78 )
77 79 PromptColors.add_scheme(__PColLightBG)
78 80
79 81 del Colors,InputColors
80 82
81 83 #-----------------------------------------------------------------------------
82 84 def multiple_replace(dict, text):
83 85 """ Replace in 'text' all occurences of any key in the given
84 86 dictionary by its corresponding value. Returns the new string."""
85 87
86 88 # Function by Xavier Defrang, originally found at:
87 89 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/81330
88 90
89 91 # Create a regular expression from the dictionary keys
90 92 regex = re.compile("(%s)" % "|".join(map(re.escape, dict.keys())))
91 93 # For each match, look-up corresponding value in dictionary
92 94 return regex.sub(lambda mo: dict[mo.string[mo.start():mo.end()]], text)
93 95
94 96 #-----------------------------------------------------------------------------
95 97 # Special characters that can be used in prompt templates, mainly bash-like
96 98
97 99 # If $HOME isn't defined (Windows), make it an absurd string so that it can
98 100 # never be expanded out into '~'. Basically anything which can never be a
99 101 # reasonable directory name will do, we just want the $HOME -> '~' operation
100 102 # to become a no-op. We pre-compute $HOME here so it's not done on every
101 103 # prompt call.
102 104
103 105 # FIXME:
104 106
105 107 # - This should be turned into a class which does proper namespace management,
106 108 # since the prompt specials need to be evaluated in a certain namespace.
107 109 # Currently it's just globals, which need to be managed manually by code
108 110 # below.
109 111
110 112 # - I also need to split up the color schemes from the prompt specials
111 113 # somehow. I don't have a clean design for that quite yet.
112 114
113 115 HOME = os.environ.get("HOME","//////:::::ZZZZZ,,,~~~")
114 116
115 117 # We precompute a few more strings here for the prompt_specials, which are
116 118 # fixed once ipython starts. This reduces the runtime overhead of computing
117 119 # prompt strings.
118 120 USER = os.environ.get("USER")
119 121 HOSTNAME = socket.gethostname()
120 122 HOSTNAME_SHORT = HOSTNAME.split(".")[0]
121 123 ROOT_SYMBOL = "$#"[os.name=='nt' or os.getuid()==0]
122 124
123 125 prompt_specials_color = {
124 126 # Prompt/history count
125 127 '%n' : '${self.col_num}' '${self.cache.prompt_count}' '${self.col_p}',
126 128 '\\#': '${self.col_num}' '${self.cache.prompt_count}' '${self.col_p}',
127 129 # Prompt/history count, with the actual digits replaced by dots. Used
128 130 # mainly in continuation prompts (prompt_in2)
129 131 '\\D': '${"."*len(str(self.cache.prompt_count))}',
130 132 # Current working directory
131 133 '\\w': '${os.getcwd()}',
132 134 # Current time
133 135 '\\t' : '${time.strftime("%H:%M:%S")}',
134 136 # Basename of current working directory.
135 137 # (use os.sep to make this portable across OSes)
136 138 '\\W' : '${os.getcwd().split("%s")[-1]}' % os.sep,
137 139 # These X<N> are an extension to the normal bash prompts. They return
138 140 # N terms of the path, after replacing $HOME with '~'
139 141 '\\X0': '${os.getcwd().replace("%s","~")}' % HOME,
140 142 '\\X1': '${self.cwd_filt(1)}',
141 143 '\\X2': '${self.cwd_filt(2)}',
142 144 '\\X3': '${self.cwd_filt(3)}',
143 145 '\\X4': '${self.cwd_filt(4)}',
144 146 '\\X5': '${self.cwd_filt(5)}',
145 147 # Y<N> are similar to X<N>, but they show '~' if it's the directory
146 148 # N+1 in the list. Somewhat like %cN in tcsh.
147 149 '\\Y0': '${self.cwd_filt2(0)}',
148 150 '\\Y1': '${self.cwd_filt2(1)}',
149 151 '\\Y2': '${self.cwd_filt2(2)}',
150 152 '\\Y3': '${self.cwd_filt2(3)}',
151 153 '\\Y4': '${self.cwd_filt2(4)}',
152 154 '\\Y5': '${self.cwd_filt2(5)}',
153 155 # Hostname up to first .
154 156 '\\h': HOSTNAME_SHORT,
155 157 # Full hostname
156 158 '\\H': HOSTNAME,
157 159 # Username of current user
158 160 '\\u': USER,
159 161 # Escaped '\'
160 162 '\\\\': '\\',
161 163 # Newline
162 164 '\\n': '\n',
163 165 # Carriage return
164 166 '\\r': '\r',
165 167 # Release version
166 168 '\\v': __version__,
167 169 # Root symbol ($ or #)
168 170 '\\$': ROOT_SYMBOL,
169 171 }
170 172
171 173 # A copy of the prompt_specials dictionary but with all color escapes removed,
172 174 # so we can correctly compute the prompt length for the auto_rewrite method.
173 175 prompt_specials_nocolor = prompt_specials_color.copy()
174 176 prompt_specials_nocolor['%n'] = '${self.cache.prompt_count}'
175 177 prompt_specials_nocolor['\\#'] = '${self.cache.prompt_count}'
176 178
177 179 # Add in all the InputTermColors color escapes as valid prompt characters.
178 180 # They all get added as \\C_COLORNAME, so that we don't have any conflicts
179 181 # with a color name which may begin with a letter used by any other of the
180 182 # allowed specials. This of course means that \\C will never be allowed for
181 183 # anything else.
182 184 input_colors = ColorANSI.InputTermColors
183 185 for _color in dir(input_colors):
184 186 if _color[0] != '_':
185 187 c_name = '\\C_'+_color
186 188 prompt_specials_color[c_name] = getattr(input_colors,_color)
187 189 prompt_specials_nocolor[c_name] = ''
188 190
189 191 # we default to no color for safety. Note that prompt_specials is a global
190 192 # variable used by all prompt objects.
191 193 prompt_specials = prompt_specials_nocolor
192 194
193 195 #-----------------------------------------------------------------------------
194 196 def str_safe(arg):
195 197 """Convert to a string, without ever raising an exception.
196 198
197 199 If str(arg) fails, <ERROR: ... > is returned, where ... is the exception
198 200 error message."""
199 201
200 202 try:
201 203 out = str(arg)
202 204 except UnicodeError:
203 205 try:
204 206 out = arg.encode('utf_8','replace')
205 207 except Exception,msg:
206 208 # let's keep this little duplication here, so that the most common
207 209 # case doesn't suffer from a double try wrapping.
208 210 out = '<ERROR: %s>' % msg
209 211 except Exception,msg:
210 212 out = '<ERROR: %s>' % msg
211 213 return out
212 214
213 215 class BasePrompt:
214 216 """Interactive prompt similar to Mathematica's."""
215 217 def __init__(self,cache,sep,prompt,pad_left=False):
216 218
217 219 # Hack: we access information about the primary prompt through the
218 220 # cache argument. We need this, because we want the secondary prompt
219 221 # to be aligned with the primary one. Color table info is also shared
220 222 # by all prompt classes through the cache. Nice OO spaghetti code!
221 223 self.cache = cache
222 224 self.sep = sep
223 225
224 226 # regexp to count the number of spaces at the end of a prompt
225 227 # expression, useful for prompt auto-rewriting
226 228 self.rspace = re.compile(r'(\s*)$')
227 229 # Flag to left-pad prompt strings to match the length of the primary
228 230 # prompt
229 231 self.pad_left = pad_left
230 232 # Set template to create each actual prompt (where numbers change)
231 233 self.p_template = prompt
232 234 self.set_p_str()
233 235
234 236 def set_p_str(self):
235 237 """ Set the interpolating prompt strings.
236 238
237 239 This must be called every time the color settings change, because the
238 240 prompt_specials global may have changed."""
239 241
240 242 import os,time # needed in locals for prompt string handling
241 243 loc = locals()
242 244 self.p_str = ItplNS('%s%s%s' %
243 245 ('${self.sep}${self.col_p}',
244 246 multiple_replace(prompt_specials, self.p_template),
245 247 '${self.col_norm}'),self.cache.user_ns,loc)
246 248
247 249 self.p_str_nocolor = ItplNS(multiple_replace(prompt_specials_nocolor,
248 250 self.p_template),
249 251 self.cache.user_ns,loc)
250 252
251 253 def write(self,msg): # dbg
252 254 sys.stdout.write(msg)
253 255 return ''
254 256
255 257 def __str__(self):
256 258 """Return a string form of the prompt.
257 259
258 260 This for is useful for continuation and output prompts, since it is
259 261 left-padded to match lengths with the primary one (if the
260 262 self.pad_left attribute is set)."""
261 263
262 264 out_str = str_safe(self.p_str)
263 265 if self.pad_left:
264 266 # We must find the amount of padding required to match lengths,
265 267 # taking the color escapes (which are invisible on-screen) into
266 268 # account.
267 269 esc_pad = len(out_str) - len(str_safe(self.p_str_nocolor))
268 270 format = '%%%ss' % (len(str(self.cache.last_prompt))+esc_pad)
269 271 return format % out_str
270 272 else:
271 273 return out_str
272 274
273 275 # these path filters are put in as methods so that we can control the
274 276 # namespace where the prompt strings get evaluated
275 277 def cwd_filt(self,depth):
276 278 """Return the last depth elements of the current working directory.
277 279
278 280 $HOME is always replaced with '~'.
279 281 If depth==0, the full path is returned."""
280 282
281 283 cwd = os.getcwd().replace(HOME,"~")
282 284 out = os.sep.join(cwd.split(os.sep)[-depth:])
283 285 if out:
284 286 return out
285 287 else:
286 288 return os.sep
287 289
288 290 def cwd_filt2(self,depth):
289 291 """Return the last depth elements of the current working directory.
290 292
291 293 $HOME is always replaced with '~'.
292 294 If depth==0, the full path is returned."""
293 295
294 296 cwd = os.getcwd().replace(HOME,"~").split(os.sep)
295 297 if '~' in cwd and len(cwd) == depth+1:
296 298 depth += 1
297 299 out = os.sep.join(cwd[-depth:])
298 300 if out:
299 301 return out
300 302 else:
301 303 return os.sep
302 304
303 305 class Prompt1(BasePrompt):
304 306 """Input interactive prompt similar to Mathematica's."""
305 307
306 308 def __init__(self,cache,sep='\n',prompt='In [\\#]: ',pad_left=True):
307 309 BasePrompt.__init__(self,cache,sep,prompt,pad_left)
308 310
309 311 def set_colors(self):
310 312 self.set_p_str()
311 313 Colors = self.cache.color_table.active_colors # shorthand
312 314 self.col_p = Colors.in_prompt
313 315 self.col_num = Colors.in_number
314 316 self.col_norm = Colors.in_normal
315 317 # We need a non-input version of these escapes for the '--->'
316 318 # auto-call prompts used in the auto_rewrite() method.
317 319 self.col_p_ni = self.col_p.replace('\001','').replace('\002','')
318 320 self.col_norm_ni = Colors.normal
319 321
320 322 def __str__(self):
321 323 self.cache.prompt_count += 1
322 324 self.cache.last_prompt = str_safe(self.p_str_nocolor).split('\n')[-1]
323 325 return str_safe(self.p_str)
324 326
325 327 def auto_rewrite(self):
326 328 """Print a string of the form '--->' which lines up with the previous
327 329 input string. Useful for systems which re-write the user input when
328 330 handling automatically special syntaxes."""
329 331
330 332 curr = str(self.cache.last_prompt)
331 333 nrspaces = len(self.rspace.search(curr).group())
332 334 return '%s%s>%s%s' % (self.col_p_ni,'-'*(len(curr)-nrspaces-1),
333 335 ' '*nrspaces,self.col_norm_ni)
334 336
335 337 class PromptOut(BasePrompt):
336 338 """Output interactive prompt similar to Mathematica's."""
337 339
338 340 def __init__(self,cache,sep='',prompt='Out[\\#]: ',pad_left=True):
339 341 BasePrompt.__init__(self,cache,sep,prompt,pad_left)
340 342 if not self.p_template:
341 343 self.__str__ = lambda: ''
342 344
343 345 def set_colors(self):
344 346 self.set_p_str()
345 347 Colors = self.cache.color_table.active_colors # shorthand
346 348 self.col_p = Colors.out_prompt
347 349 self.col_num = Colors.out_number
348 350 self.col_norm = Colors.normal
349 351
350 352 class Prompt2(BasePrompt):
351 353 """Interactive continuation prompt."""
352 354
353 355 def __init__(self,cache,prompt=' .\\D.: ',pad_left=True):
354 356 self.cache = cache
355 357 self.p_template = prompt
356 358 self.pad_left = pad_left
357 359 self.set_p_str()
358 360
359 361 def set_p_str(self):
360 362 import os,time # needed in locals for prompt string handling
361 363 loc = locals()
362 364 self.p_str = ItplNS('%s%s%s' %
363 365 ('${self.col_p2}',
364 366 multiple_replace(prompt_specials, self.p_template),
365 367 '$self.col_norm'),
366 368 self.cache.user_ns,loc)
367 369 self.p_str_nocolor = ItplNS(multiple_replace(prompt_specials_nocolor,
368 370 self.p_template),
369 371 self.cache.user_ns,loc)
370 372
371 373 def set_colors(self):
372 374 self.set_p_str()
373 375 Colors = self.cache.color_table.active_colors
374 376 self.col_p2 = Colors.in_prompt2
375 377 self.col_norm = Colors.in_normal
376 378 # FIXME (2004-06-16) HACK: prevent crashes for users who haven't
377 379 # updated their prompt_in2 definitions. Remove eventually.
378 380 self.col_p = Colors.out_prompt
379 381 self.col_num = Colors.out_number
380 382
381 383 #-----------------------------------------------------------------------------
382 384 class CachedOutput:
383 385 """Class for printing output from calculations while keeping a cache of
384 386 reults. It dynamically creates global variables prefixed with _ which
385 387 contain these results.
386 388
387 389 Meant to be used as a sys.displayhook replacement, providing numbered
388 390 prompts and cache services.
389 391
390 392 Initialize with initial and final values for cache counter (this defines
391 393 the maximum size of the cache."""
392 394
393 395 def __init__(self,cache_size,Pprint,colors='NoColor',input_sep='\n',
394 396 output_sep='\n',output_sep2='',user_ns={},
395 397 ps1 = None, ps2 = None,ps_out = None,
396 398 input_hist = None,pad_left=True):
397 399
398 400 cache_size_min = 20
399 401 if cache_size <= 0:
400 402 self.do_full_cache = 0
401 403 cache_size = 0
402 404 elif cache_size < cache_size_min:
403 405 self.do_full_cache = 0
404 406 cache_size = 0
405 407 warn('caching was disabled (min value for cache size is %s).' %
406 408 cache_size_min,level=3)
407 409 else:
408 410 self.do_full_cache = 1
409 411
410 412 self.cache_size = cache_size
411 413 self.input_sep = input_sep
412 414
413 415 # we need a reference to the user-level namespace
414 416 self.user_ns = user_ns
415 417 # and to the user's input
416 418 self.input_hist = input_hist
417 419
418 420 # Set input prompt strings and colors
419 421 if cache_size == 0:
420 422 if ps1.find('%n') > -1 or ps1.find('\\#') > -1: ps1 = '>>> '
421 423 if ps2.find('%n') > -1 or ps2.find('\\#') > -1: ps2 = '... '
422 424 self.ps1_str = self._set_prompt_str(ps1,'In [\\#]: ','>>> ')
423 425 self.ps2_str = self._set_prompt_str(ps2,' .\\D.: ','... ')
424 426 self.ps_out_str = self._set_prompt_str(ps_out,'Out[\\#]: ','')
425 427
426 428 self.color_table = PromptColors
427 429 self.prompt1 = Prompt1(self,sep=input_sep,prompt=self.ps1_str,
428 430 pad_left=pad_left)
429 431 self.prompt2 = Prompt2(self,prompt=self.ps2_str,pad_left=pad_left)
430 432 self.prompt_out = PromptOut(self,sep='',prompt=self.ps_out_str,
431 433 pad_left=pad_left)
432 434 self.set_colors(colors)
433 435
434 436 # other more normal stuff
435 437 # b/c each call to the In[] prompt raises it by 1, even the first.
436 438 self.prompt_count = 0
437 439 self.cache_count = 1
438 440 # Store the last prompt string each time, we need it for aligning
439 441 # continuation and auto-rewrite prompts
440 442 self.last_prompt = ''
441 443 self.entries = [None] # output counter starts at 1 for the user
442 444 self.Pprint = Pprint
443 445 self.output_sep = output_sep
444 446 self.output_sep2 = output_sep2
445 447 self._,self.__,self.___ = '','',''
446 448 self.pprint_types = map(type,[(),[],{}])
447 449
448 450 # these are deliberately global:
449 451 to_user_ns = {'_':self._,'__':self.__,'___':self.___}
450 452 self.user_ns.update(to_user_ns)
451 453
452 454 def _set_prompt_str(self,p_str,cache_def,no_cache_def):
453 455 if p_str is None:
454 456 if self.do_full_cache:
455 457 return cache_def
456 458 else:
457 459 return no_cache_def
458 460 else:
459 461 return p_str
460 462
461 463 def set_colors(self,colors):
462 464 """Set the active color scheme and configure colors for the three
463 465 prompt subsystems."""
464 466
465 467 # FIXME: the prompt_specials global should be gobbled inside this
466 468 # class instead. Do it when cleaning up the whole 3-prompt system.
467 469 global prompt_specials
468 470 if colors.lower()=='nocolor':
469 471 prompt_specials = prompt_specials_nocolor
470 472 else:
471 473 prompt_specials = prompt_specials_color
472 474
473 475 self.color_table.set_active_scheme(colors)
474 476 self.prompt1.set_colors()
475 477 self.prompt2.set_colors()
476 478 self.prompt_out.set_colors()
477 479
478 480 def __call__(self,arg=None):
479 481 """Printing with history cache management.
480 482
481 483 This is invoked everytime the interpreter needs to print, and is
482 484 activated by setting the variable sys.displayhook to it."""
483 485
484 486 # If something injected a '_' variable in __builtin__, delete
485 487 # ipython's automatic one so we don't clobber that. gettext() in
486 488 # particular uses _, so we need to stay away from it.
487 489 if '_' in __builtin__.__dict__:
488 490 try:
489 491 del self.user_ns['_']
490 492 except KeyError:
491 493 pass
492 494 if arg is not None:
493 495 cout_write = Term.cout.write # fast lookup
494 496 # first handle the cache and counters
495 497 self.update(arg)
496 498 # do not print output if input ends in ';'
497 499 if self.input_hist[self.prompt_count].endswith(';\n'):
498 500 return
499 501 # don't use print, puts an extra space
500 502 cout_write(self.output_sep)
501 503 if self.do_full_cache:
502 504 cout_write(str(self.prompt_out))
503 505
504 506 if isinstance(arg,Macro):
505 507 print 'Executing Macro...'
506 508 # in case the macro takes a long time to execute
507 509 Term.cout.flush()
508 510 exec arg.value in self.user_ns
509 511 return None
510 512
511 513 # and now call a possibly user-defined print mechanism
512 514 self.display(arg)
513 515 cout_write(self.output_sep2)
514 516 Term.cout.flush()
515 517
516 518 def _display(self,arg):
517 519 """Default printer method, uses pprint.
518 520
519 521 This can be over-ridden by the users to implement special formatting
520 522 of certain types of output."""
521 523
522 524 if self.Pprint:
523 525 out = pformat(arg)
524 526 if '\n' in out:
525 527 # So that multi-line strings line up with the left column of
526 528 # the screen, instead of having the output prompt mess up
527 529 # their first line.
528 530 Term.cout.write('\n')
529 531 print >>Term.cout, out
530 532 else:
531 533 print >>Term.cout, arg
532 534
533 535 # Assign the default display method:
534 536 display = _display
535 537
536 538 def update(self,arg):
537 539 #print '***cache_count', self.cache_count # dbg
538 540 if self.cache_count >= self.cache_size and self.do_full_cache:
539 541 self.flush()
540 542 # Don't overwrite '_' and friends if '_' is in __builtin__ (otherwise
541 543 # we cause buggy behavior for things like gettext).
542 544 if '_' not in __builtin__.__dict__:
543 545 self.___ = self.__
544 546 self.__ = self._
545 547 self._ = arg
546 548 self.user_ns.update({'_':self._,'__':self.__,'___':self.___})
547 549
548 550 # hackish access to top-level namespace to create _1,_2... dynamically
549 551 to_main = {}
550 552 if self.do_full_cache:
551 553 self.cache_count += 1
552 554 self.entries.append(arg)
553 555 new_result = '_'+`self.prompt_count`
554 556 to_main[new_result] = self.entries[-1]
555 557 self.user_ns.update(to_main)
556 558 self.user_ns['_oh'][self.prompt_count] = arg
557 559
558 560 def flush(self):
559 561 if not self.do_full_cache:
560 562 raise ValueError,"You shouldn't have reached the cache flush "\
561 563 "if full caching is not enabled!"
562 564 warn('Output cache limit (currently '+\
563 565 `self.cache_count`+' entries) hit.\n'
564 566 'Flushing cache and resetting history counter...\n'
565 567 'The only history variables available will be _,__,___ and _1\n'
566 568 'with the current result.')
567 569 # delete auto-generated vars from global namespace
568 570 for n in range(1,self.prompt_count + 1):
569 571 key = '_'+`n`
570 572 try:
571 573 del self.user_ns[key]
572 574 except: pass
573 575 self.prompt_count = 1
574 576 self.cache_count = 1
@@ -1,255 +1,260 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 Class and program to colorize python source code for ANSI terminals.
4 4
5 5 Based on an HTML code highlighter by Jurgen Hermann found at:
6 6 http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52298
7 7
8 8 Modifications by Fernando Perez (fperez@colorado.edu).
9 9
10 10 Information on the original HTML highlighter follows:
11 11
12 12 MoinMoin - Python Source Parser
13 13
14 14 Title:olorize Python source using the built-in tokenizer
15 15
16 16 Submitter: Jurgen Hermann
17 17 Last Updated:2001/04/06
18 18
19 19 Version no:1.2
20 20
21 21 Description:
22 22
23 23 This code is part of MoinMoin (http://moin.sourceforge.net/) and converts
24 24 Python source code to HTML markup, rendering comments, keywords,
25 25 operators, numeric and string literals in different colors.
26 26
27 27 It shows how to use the built-in keyword, token and tokenize modules to
28 28 scan Python source code and re-emit it with no changes to its original
29 29 formatting (which is the hard part).
30 30
31 $Id: PyColorize.py 485 2005-01-27 19:15:39Z fperez $"""
31 $Id: PyColorize.py 958 2005-12-27 23:17:51Z fperez $"""
32 32
33 33 __all__ = ['ANSICodeColors','Parser']
34 34
35 35 _scheme_default = 'Linux'
36 36
37 37 # Imports
38 import string, sys, os, cStringIO
39 import keyword, token, tokenize
38 import cStringIO
39 import keyword
40 import os
41 import string
42 import sys
43 import token
44 import tokenize
40 45
41 46 from IPython.ColorANSI import *
42 47
43 48 #############################################################################
44 49 ### Python Source Parser (does Hilighting)
45 50 #############################################################################
46 51
47 52 _KEYWORD = token.NT_OFFSET + 1
48 53 _TEXT = token.NT_OFFSET + 2
49 54
50 55 #****************************************************************************
51 56 # Builtin color schemes
52 57
53 58 Colors = TermColors # just a shorthand
54 59
55 60 # Build a few color schemes
56 61 NoColor = ColorScheme(
57 62 'NoColor',{
58 63 token.NUMBER : Colors.NoColor,
59 64 token.OP : Colors.NoColor,
60 65 token.STRING : Colors.NoColor,
61 66 tokenize.COMMENT : Colors.NoColor,
62 67 token.NAME : Colors.NoColor,
63 68 token.ERRORTOKEN : Colors.NoColor,
64 69
65 70 _KEYWORD : Colors.NoColor,
66 71 _TEXT : Colors.NoColor,
67 72
68 73 'normal' : Colors.NoColor # color off (usu. Colors.Normal)
69 74 } )
70 75
71 76 LinuxColors = ColorScheme(
72 77 'Linux',{
73 78 token.NUMBER : Colors.LightCyan,
74 79 token.OP : Colors.Yellow,
75 80 token.STRING : Colors.LightBlue,
76 81 tokenize.COMMENT : Colors.LightRed,
77 82 token.NAME : Colors.White,
78 83 token.ERRORTOKEN : Colors.Red,
79 84
80 85 _KEYWORD : Colors.LightGreen,
81 86 _TEXT : Colors.Yellow,
82 87
83 88 'normal' : Colors.Normal # color off (usu. Colors.Normal)
84 89 } )
85 90
86 91 LightBGColors = ColorScheme(
87 92 'LightBG',{
88 93 token.NUMBER : Colors.Cyan,
89 94 token.OP : Colors.Blue,
90 95 token.STRING : Colors.Blue,
91 96 tokenize.COMMENT : Colors.Red,
92 97 token.NAME : Colors.Black,
93 98 token.ERRORTOKEN : Colors.Red,
94 99
95 100 _KEYWORD : Colors.Green,
96 101 _TEXT : Colors.Blue,
97 102
98 103 'normal' : Colors.Normal # color off (usu. Colors.Normal)
99 104 } )
100 105
101 106 # Build table of color schemes (needed by the parser)
102 107 ANSICodeColors = ColorSchemeTable([NoColor,LinuxColors,LightBGColors],
103 108 _scheme_default)
104 109
105 110 class Parser:
106 111 """ Format colored Python source.
107 112 """
108 113
109 114 def __init__(self, color_table=None,out = sys.stdout):
110 115 """ Create a parser with a specified color table and output channel.
111 116
112 117 Call format() to process code.
113 118 """
114 119 self.color_table = color_table and color_table or ANSICodeColors
115 120 self.out = out
116 121
117 122 def format(self, raw, out = None, scheme = ''):
118 123 """ Parse and send the colored source.
119 124
120 125 If out and scheme are not specified, the defaults (given to
121 126 constructor) are used.
122 127
123 128 out should be a file-type object. Optionally, out can be given as the
124 129 string 'str' and the parser will automatically return the output in a
125 130 string."""
126 131
127 132 self.raw = string.strip(string.expandtabs(raw))
128 133 string_output = 0
129 134 if out == 'str' or self.out == 'str':
130 135 out_old = self.out
131 136 self.out = cStringIO.StringIO()
132 137 string_output = 1
133 138 elif out is not None:
134 139 self.out = out
135 140 # local shorthand
136 141 colors = self.color_table[scheme].colors
137 142 self.colors = colors # put in object so __call__ sees it
138 143 # store line offsets in self.lines
139 144 self.lines = [0, 0]
140 145 pos = 0
141 146 while 1:
142 147 pos = string.find(self.raw, '\n', pos) + 1
143 148 if not pos: break
144 149 self.lines.append(pos)
145 150 self.lines.append(len(self.raw))
146 151
147 152 # parse the source and write it
148 153 self.pos = 0
149 154 text = cStringIO.StringIO(self.raw)
150 155 #self.out.write('<pre><font face="Courier New">')
151 156 try:
152 157 tokenize.tokenize(text.readline, self)
153 158 except tokenize.TokenError, ex:
154 159 msg = ex[0]
155 160 line = ex[1][0]
156 161 self.out.write("%s\n\n*** ERROR: %s%s%s\n" %
157 162 (colors[token.ERRORTOKEN],
158 163 msg, self.raw[self.lines[line]:],
159 164 colors.normal)
160 165 )
161 166 self.out.write(colors.normal+'\n')
162 167 if string_output:
163 168 output = self.out.getvalue()
164 169 self.out = out_old
165 170 return output
166 171
167 172 def __call__(self, toktype, toktext, (srow,scol), (erow,ecol), line):
168 173 """ Token handler, with syntax highlighting."""
169 174
170 175 # local shorthand
171 176 colors = self.colors
172 177
173 178 # line separator, so this works across platforms
174 179 linesep = os.linesep
175 180
176 181 # calculate new positions
177 182 oldpos = self.pos
178 183 newpos = self.lines[srow] + scol
179 184 self.pos = newpos + len(toktext)
180 185
181 186 # handle newlines
182 187 if toktype in [token.NEWLINE, tokenize.NL]:
183 188 self.out.write(linesep)
184 189 return
185 190
186 191 # send the original whitespace, if needed
187 192 if newpos > oldpos:
188 193 self.out.write(self.raw[oldpos:newpos])
189 194
190 195 # skip indenting tokens
191 196 if toktype in [token.INDENT, token.DEDENT]:
192 197 self.pos = newpos
193 198 return
194 199
195 200 # map token type to a color group
196 201 if token.LPAR <= toktype and toktype <= token.OP:
197 202 toktype = token.OP
198 203 elif toktype == token.NAME and keyword.iskeyword(toktext):
199 204 toktype = _KEYWORD
200 205 color = colors.get(toktype, colors[_TEXT])
201 206
202 207 #print '<%s>' % toktext, # dbg
203 208
204 209 # Triple quoted strings must be handled carefully so that backtracking
205 210 # in pagers works correctly. We need color terminators on _each_ line.
206 211 if linesep in toktext:
207 212 toktext = toktext.replace(linesep, '%s%s%s' %
208 213 (colors.normal,linesep,color))
209 214
210 215 # send text
211 216 self.out.write('%s%s%s' % (color,toktext,colors.normal))
212 217
213 218 def main():
214 219 """Colorize a python file using ANSI color escapes and print to stdout.
215 220
216 221 Usage:
217 222 %s [-s scheme] filename
218 223
219 224 Options:
220 225
221 226 -s scheme: give the color scheme to use. Currently only 'Linux'
222 227 (default) and 'LightBG' and 'NoColor' are implemented (give without
223 228 quotes). """
224 229
225 230 def usage():
226 231 print >> sys.stderr, main.__doc__ % sys.argv[0]
227 232 sys.exit(1)
228 233
229 234 # FIXME: rewrite this to at least use getopt
230 235 try:
231 236 if sys.argv[1] == '-s':
232 237 scheme_name = sys.argv[2]
233 238 del sys.argv[1:3]
234 239 else:
235 240 scheme_name = _scheme_default
236 241
237 242 except:
238 243 usage()
239 244
240 245 try:
241 246 fname = sys.argv[1]
242 247 except:
243 248 usage()
244 249
245 250 # write colorized version to stdout
246 251 parser = Parser()
247 252 try:
248 253 parser.format(file(fname).read(),scheme = scheme_name)
249 254 except IOError,msg:
250 255 # if user reads through a pager and quits, don't print traceback
251 256 if msg.args != (32,'Broken pipe'):
252 257 raise
253 258
254 259 if __name__ == "__main__":
255 260 main()
@@ -1,901 +1,900 b''
1 1 # -*- coding: utf-8 -*-
2 2 """IPython Shell classes.
3 3
4 4 All the matplotlib support code was co-developed with John Hunter,
5 5 matplotlib's author.
6 6
7 $Id: Shell.py 952 2005-12-26 17:51:33Z fperez $"""
7 $Id: Shell.py 958 2005-12-27 23:17:51Z fperez $"""
8 8
9 9 #*****************************************************************************
10 10 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
11 11 #
12 12 # Distributed under the terms of the BSD License. The full license is in
13 13 # the file COPYING, distributed as part of this software.
14 14 #*****************************************************************************
15 15
16 16 from IPython import Release
17 17 __author__ = '%s <%s>' % Release.authors['Fernando']
18 18 __license__ = Release.license
19 19
20 20 # Code begins
21 21 import __main__
22 22 import __builtin__
23 import sys
24 23 import os
25 import code
26 import threading
24 import sys
27 25 import signal
26 import threading
28 27
29 28 import IPython
29 from IPython import ultraTB
30 from IPython.genutils import Term,warn,error,flag_calls
30 31 from IPython.iplib import InteractiveShell
31 32 from IPython.ipmaker import make_IPython
32 from IPython.genutils import Term,warn,error,flag_calls
33 from IPython.Struct import Struct
34 33 from IPython.Magic import Magic
35 from IPython import ultraTB
34 from IPython.Struct import Struct
36 35
37 36 # global flag to pass around information about Ctrl-C without exceptions
38 37 KBINT = False
39 38
40 39 # global flag to turn on/off Tk support.
41 40 USE_TK = False
42 41
43 42 #-----------------------------------------------------------------------------
44 43 # This class is trivial now, but I want to have it in to publish a clean
45 44 # interface. Later when the internals are reorganized, code that uses this
46 45 # shouldn't have to change.
47 46
48 47 class IPShell:
49 48 """Create an IPython instance."""
50 49
51 50 def __init__(self,argv=None,user_ns=None,debug=1,
52 51 shell_class=InteractiveShell):
53 52 self.IP = make_IPython(argv,user_ns=user_ns,debug=debug,
54 53 shell_class=shell_class)
55 54
56 55 def mainloop(self,sys_exit=0,banner=None):
57 56 self.IP.mainloop(banner)
58 57 if sys_exit:
59 58 sys.exit()
60 59
61 60 #-----------------------------------------------------------------------------
62 61 class IPShellEmbed:
63 62 """Allow embedding an IPython shell into a running program.
64 63
65 64 Instances of this class are callable, with the __call__ method being an
66 65 alias to the embed() method of an InteractiveShell instance.
67 66
68 67 Usage (see also the example-embed.py file for a running example):
69 68
70 69 ipshell = IPShellEmbed([argv,banner,exit_msg,rc_override])
71 70
72 71 - argv: list containing valid command-line options for IPython, as they
73 72 would appear in sys.argv[1:].
74 73
75 74 For example, the following command-line options:
76 75
77 76 $ ipython -prompt_in1 'Input <\\#>' -colors LightBG
78 77
79 78 would be passed in the argv list as:
80 79
81 80 ['-prompt_in1','Input <\\#>','-colors','LightBG']
82 81
83 82 - banner: string which gets printed every time the interpreter starts.
84 83
85 84 - exit_msg: string which gets printed every time the interpreter exits.
86 85
87 86 - rc_override: a dict or Struct of configuration options such as those
88 87 used by IPython. These options are read from your ~/.ipython/ipythonrc
89 88 file when the Shell object is created. Passing an explicit rc_override
90 89 dict with any options you want allows you to override those values at
91 90 creation time without having to modify the file. This way you can create
92 91 embeddable instances configured in any way you want without editing any
93 92 global files (thus keeping your interactive IPython configuration
94 93 unchanged).
95 94
96 95 Then the ipshell instance can be called anywhere inside your code:
97 96
98 97 ipshell(header='') -> Opens up an IPython shell.
99 98
100 99 - header: string printed by the IPython shell upon startup. This can let
101 100 you know where in your code you are when dropping into the shell. Note
102 101 that 'banner' gets prepended to all calls, so header is used for
103 102 location-specific information.
104 103
105 104 For more details, see the __call__ method below.
106 105
107 106 When the IPython shell is exited with Ctrl-D, normal program execution
108 107 resumes.
109 108
110 109 This functionality was inspired by a posting on comp.lang.python by cmkl
111 110 <cmkleffner@gmx.de> on Dec. 06/01 concerning similar uses of pyrepl, and
112 111 by the IDL stop/continue commands."""
113 112
114 113 def __init__(self,argv=None,banner='',exit_msg=None,rc_override=None):
115 114 """Note that argv here is a string, NOT a list."""
116 115 self.set_banner(banner)
117 116 self.set_exit_msg(exit_msg)
118 117 self.set_dummy_mode(0)
119 118
120 119 # sys.displayhook is a global, we need to save the user's original
121 120 # Don't rely on __displayhook__, as the user may have changed that.
122 121 self.sys_displayhook_ori = sys.displayhook
123 122
124 123 # save readline completer status
125 124 try:
126 125 #print 'Save completer',sys.ipcompleter # dbg
127 126 self.sys_ipcompleter_ori = sys.ipcompleter
128 127 except:
129 128 pass # not nested with IPython
130 129
131 130 # FIXME. Passing user_ns breaks namespace handling.
132 131 #self.IP = make_IPython(argv,user_ns=__main__.__dict__)
133 132 self.IP = make_IPython(argv,rc_override=rc_override,embedded=True)
134 133
135 134 # copy our own displayhook also
136 135 self.sys_displayhook_embed = sys.displayhook
137 136 # and leave the system's display hook clean
138 137 sys.displayhook = self.sys_displayhook_ori
139 138 # don't use the ipython crash handler so that user exceptions aren't
140 139 # trapped
141 140 sys.excepthook = ultraTB.FormattedTB(color_scheme = self.IP.rc.colors,
142 141 mode = self.IP.rc.xmode,
143 142 call_pdb = self.IP.rc.pdb)
144 143 self.restore_system_completer()
145 144
146 145 def restore_system_completer(self):
147 146 """Restores the readline completer which was in place.
148 147
149 148 This allows embedded IPython within IPython not to disrupt the
150 149 parent's completion.
151 150 """
152 151
153 152 try:
154 153 self.IP.readline.set_completer(self.sys_ipcompleter_ori)
155 154 sys.ipcompleter = self.sys_ipcompleter_ori
156 155 except:
157 156 pass
158 157
159 158 def __call__(self,header='',local_ns=None,global_ns=None,dummy=None):
160 159 """Activate the interactive interpreter.
161 160
162 161 __call__(self,header='',local_ns=None,global_ns,dummy=None) -> Start
163 162 the interpreter shell with the given local and global namespaces, and
164 163 optionally print a header string at startup.
165 164
166 165 The shell can be globally activated/deactivated using the
167 166 set/get_dummy_mode methods. This allows you to turn off a shell used
168 167 for debugging globally.
169 168
170 169 However, *each* time you call the shell you can override the current
171 170 state of dummy_mode with the optional keyword parameter 'dummy'. For
172 171 example, if you set dummy mode on with IPShell.set_dummy_mode(1), you
173 172 can still have a specific call work by making it as IPShell(dummy=0).
174 173
175 174 The optional keyword parameter dummy controls whether the call
176 175 actually does anything. """
177 176
178 177 # Allow the dummy parameter to override the global __dummy_mode
179 178 if dummy or (dummy != 0 and self.__dummy_mode):
180 179 return
181 180
182 181 # Set global subsystems (display,completions) to our values
183 182 sys.displayhook = self.sys_displayhook_embed
184 183 if self.IP.has_readline:
185 184 self.IP.readline.set_completer(self.IP.Completer.complete)
186 185
187 186 if self.banner and header:
188 187 format = '%s\n%s\n'
189 188 else:
190 189 format = '%s%s\n'
191 190 banner = format % (self.banner,header)
192 191
193 192 # Call the embedding code with a stack depth of 1 so it can skip over
194 193 # our call and get the original caller's namespaces.
195 194 self.IP.embed_mainloop(banner,local_ns,global_ns,stack_depth=1)
196 195
197 196 if self.exit_msg:
198 197 print self.exit_msg
199 198
200 199 # Restore global systems (display, completion)
201 200 sys.displayhook = self.sys_displayhook_ori
202 201 self.restore_system_completer()
203 202
204 203 def set_dummy_mode(self,dummy):
205 204 """Sets the embeddable shell's dummy mode parameter.
206 205
207 206 set_dummy_mode(dummy): dummy = 0 or 1.
208 207
209 208 This parameter is persistent and makes calls to the embeddable shell
210 209 silently return without performing any action. This allows you to
211 210 globally activate or deactivate a shell you're using with a single call.
212 211
213 212 If you need to manually"""
214 213
215 214 if dummy not in [0,1,False,True]:
216 215 raise ValueError,'dummy parameter must be boolean'
217 216 self.__dummy_mode = dummy
218 217
219 218 def get_dummy_mode(self):
220 219 """Return the current value of the dummy mode parameter.
221 220 """
222 221 return self.__dummy_mode
223 222
224 223 def set_banner(self,banner):
225 224 """Sets the global banner.
226 225
227 226 This banner gets prepended to every header printed when the shell
228 227 instance is called."""
229 228
230 229 self.banner = banner
231 230
232 231 def set_exit_msg(self,exit_msg):
233 232 """Sets the global exit_msg.
234 233
235 234 This exit message gets printed upon exiting every time the embedded
236 235 shell is called. It is None by default. """
237 236
238 237 self.exit_msg = exit_msg
239 238
240 239 #-----------------------------------------------------------------------------
241 240 def sigint_handler (signum,stack_frame):
242 241 """Sigint handler for threaded apps.
243 242
244 243 This is a horrible hack to pass information about SIGINT _without_ using
245 244 exceptions, since I haven't been able to properly manage cross-thread
246 245 exceptions in GTK/WX. In fact, I don't think it can be done (or at least
247 246 that's my understanding from a c.l.py thread where this was discussed)."""
248 247
249 248 global KBINT
250 249
251 250 print '\nKeyboardInterrupt - Press <Enter> to continue.',
252 251 Term.cout.flush()
253 252 # Set global flag so that runsource can know that Ctrl-C was hit
254 253 KBINT = True
255 254
256 255 class MTInteractiveShell(InteractiveShell):
257 256 """Simple multi-threaded shell."""
258 257
259 258 # Threading strategy taken from:
260 259 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/65109, by Brian
261 260 # McErlean and John Finlay. Modified with corrections by Antoon Pardon,
262 261 # from the pygtk mailing list, to avoid lockups with system calls.
263 262
264 263 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
265 264 user_ns = None, banner2='',**kw):
266 265 """Similar to the normal InteractiveShell, but with threading control"""
267 266
268 267 IPython.iplib.InteractiveShell.__init__(self,name,usage,rc,user_ns,banner2)
269 268
270 269 # Locking control variable
271 270 self.thread_ready = threading.Condition()
272 271
273 272 # Stuff to do at closing time
274 273 self._kill = False
275 274 on_kill = kw.get('on_kill')
276 275 if on_kill is None:
277 276 on_kill = []
278 277 # Check that all things to kill are callable:
279 278 for t in on_kill:
280 279 if not callable(t):
281 280 raise TypeError,'on_kill must be a list of callables'
282 281 self.on_kill = on_kill
283 282
284 283 def runsource(self, source, filename="<input>", symbol="single"):
285 284 """Compile and run some source in the interpreter.
286 285
287 286 Modified version of code.py's runsource(), to handle threading issues.
288 287 See the original for full docstring details."""
289 288
290 289 global KBINT
291 290
292 291 # If Ctrl-C was typed, we reset the flag and return right away
293 292 if KBINT:
294 293 KBINT = False
295 294 return False
296 295
297 296 try:
298 297 code = self.compile(source, filename, symbol)
299 298 except (OverflowError, SyntaxError, ValueError):
300 299 # Case 1
301 300 self.showsyntaxerror(filename)
302 301 return False
303 302
304 303 if code is None:
305 304 # Case 2
306 305 return True
307 306
308 307 # Case 3
309 308 # Store code in self, so the execution thread can handle it
310 309 self.thread_ready.acquire()
311 310 self.code_to_run = code
312 311 self.thread_ready.wait() # Wait until processed in timeout interval
313 312 self.thread_ready.release()
314 313
315 314 return False
316 315
317 316 def runcode(self):
318 317 """Execute a code object.
319 318
320 319 Multithreaded wrapper around IPython's runcode()."""
321 320
322 321 # lock thread-protected stuff
323 322 self.thread_ready.acquire()
324 323
325 324 # Install sigint handler
326 325 try:
327 326 signal.signal(signal.SIGINT, sigint_handler)
328 327 except SystemError:
329 328 # This happens under Windows, which seems to have all sorts
330 329 # of problems with signal handling. Oh well...
331 330 pass
332 331
333 332 if self._kill:
334 333 print >>Term.cout, 'Closing threads...',
335 334 Term.cout.flush()
336 335 for tokill in self.on_kill:
337 336 tokill()
338 337 print >>Term.cout, 'Done.'
339 338
340 339 # Run pending code by calling parent class
341 340 if self.code_to_run is not None:
342 341 self.thread_ready.notify()
343 342 InteractiveShell.runcode(self,self.code_to_run)
344 343
345 344 # We're done with thread-protected variables
346 345 self.thread_ready.release()
347 346 # This MUST return true for gtk threading to work
348 347 return True
349 348
350 349 def kill (self):
351 350 """Kill the thread, returning when it has been shut down."""
352 351 self.thread_ready.acquire()
353 352 self._kill = True
354 353 self.thread_ready.release()
355 354
356 355 class MatplotlibShellBase:
357 356 """Mixin class to provide the necessary modifications to regular IPython
358 357 shell classes for matplotlib support.
359 358
360 359 Given Python's MRO, this should be used as the FIRST class in the
361 360 inheritance hierarchy, so that it overrides the relevant methods."""
362 361
363 362 def _matplotlib_config(self,name):
364 363 """Return various items needed to setup the user's shell with matplotlib"""
365 364
366 365 # Initialize matplotlib to interactive mode always
367 366 import matplotlib
368 367 from matplotlib import backends
369 368 matplotlib.interactive(True)
370 369
371 370 def use(arg):
372 371 """IPython wrapper for matplotlib's backend switcher.
373 372
374 373 In interactive use, we can not allow switching to a different
375 374 interactive backend, since thread conflicts will most likely crash
376 375 the python interpreter. This routine does a safety check first,
377 376 and refuses to perform a dangerous switch. It still allows
378 377 switching to non-interactive backends."""
379 378
380 379 if arg in backends.interactive_bk and arg != self.mpl_backend:
381 380 m=('invalid matplotlib backend switch.\n'
382 381 'This script attempted to switch to the interactive '
383 382 'backend: `%s`\n'
384 383 'Your current choice of interactive backend is: `%s`\n\n'
385 384 'Switching interactive matplotlib backends at runtime\n'
386 385 'would crash the python interpreter, '
387 386 'and IPython has blocked it.\n\n'
388 387 'You need to either change your choice of matplotlib backend\n'
389 388 'by editing your .matplotlibrc file, or run this script as a \n'
390 389 'standalone file from the command line, not using IPython.\n' %
391 390 (arg,self.mpl_backend) )
392 391 raise RuntimeError, m
393 392 else:
394 393 self.mpl_use(arg)
395 394 self.mpl_use._called = True
396 395
397 396 self.matplotlib = matplotlib
398 397 self.mpl_backend = matplotlib.rcParams['backend']
399 398
400 399 # we also need to block switching of interactive backends by use()
401 400 self.mpl_use = matplotlib.use
402 401 self.mpl_use._called = False
403 402 # overwrite the original matplotlib.use with our wrapper
404 403 matplotlib.use = use
405 404
406 405
407 406 # This must be imported last in the matplotlib series, after
408 407 # backend/interactivity choices have been made
409 408 try:
410 409 import matplotlib.pylab as pylab
411 410 self.pylab = pylab
412 411 self.pylab_name = 'pylab'
413 412 except ImportError:
414 413 import matplotlib.matlab as matlab
415 414 self.pylab = matlab
416 415 self.pylab_name = 'matlab'
417 416
418 417 self.pylab.show._needmain = False
419 418 # We need to detect at runtime whether show() is called by the user.
420 419 # For this, we wrap it into a decorator which adds a 'called' flag.
421 420 self.pylab.draw_if_interactive = flag_calls(self.pylab.draw_if_interactive)
422 421
423 422 # Build a user namespace initialized with matplotlib/matlab features.
424 423 user_ns = {'__name__':'__main__',
425 424 '__builtins__' : __builtin__ }
426 425
427 426 # Be careful not to remove the final \n in the code string below, or
428 427 # things will break badly with py22 (I think it's a python bug, 2.3 is
429 428 # OK).
430 429 pname = self.pylab_name # Python can't interpolate dotted var names
431 430 exec ("import matplotlib\n"
432 431 "import matplotlib.%(pname)s as %(pname)s\n"
433 432 "from matplotlib.%(pname)s import *\n" % locals()) in user_ns
434 433
435 434 # Build matplotlib info banner
436 435 b="""
437 436 Welcome to pylab, a matplotlib-based Python environment.
438 437 For more information, type 'help(pylab)'.
439 438 """
440 439 return user_ns,b
441 440
442 441 def mplot_exec(self,fname,*where,**kw):
443 442 """Execute a matplotlib script.
444 443
445 444 This is a call to execfile(), but wrapped in safeties to properly
446 445 handle interactive rendering and backend switching."""
447 446
448 447 #print '*** Matplotlib runner ***' # dbg
449 448 # turn off rendering until end of script
450 449 isInteractive = self.matplotlib.rcParams['interactive']
451 450 self.matplotlib.interactive(False)
452 451 self.safe_execfile(fname,*where,**kw)
453 452 self.matplotlib.interactive(isInteractive)
454 453 # make rendering call now, if the user tried to do it
455 454 if self.pylab.draw_if_interactive.called:
456 455 self.pylab.draw()
457 456 self.pylab.draw_if_interactive.called = False
458 457
459 458 # if a backend switch was performed, reverse it now
460 459 if self.mpl_use._called:
461 460 self.matplotlib.rcParams['backend'] = self.mpl_backend
462 461
463 462 def magic_run(self,parameter_s=''):
464 463 Magic.magic_run(self,parameter_s,runner=self.mplot_exec)
465 464
466 465 # Fix the docstring so users see the original as well
467 466 magic_run.__doc__ = "%s\n%s" % (Magic.magic_run.__doc__,
468 467 "\n *** Modified %run for Matplotlib,"
469 468 " with proper interactive handling ***")
470 469
471 470 # Now we provide 2 versions of a matplotlib-aware IPython base shells, single
472 471 # and multithreaded. Note that these are meant for internal use, the IPShell*
473 472 # classes below are the ones meant for public consumption.
474 473
475 474 class MatplotlibShell(MatplotlibShellBase,InteractiveShell):
476 475 """Single-threaded shell with matplotlib support."""
477 476
478 477 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
479 478 user_ns = None, **kw):
480 479 user_ns,b2 = self._matplotlib_config(name)
481 480 InteractiveShell.__init__(self,name,usage,rc,user_ns,banner2=b2,**kw)
482 481
483 482 class MatplotlibMTShell(MatplotlibShellBase,MTInteractiveShell):
484 483 """Multi-threaded shell with matplotlib support."""
485 484
486 485 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
487 486 user_ns = None, **kw):
488 487 user_ns,b2 = self._matplotlib_config(name)
489 488 MTInteractiveShell.__init__(self,name,usage,rc,user_ns,banner2=b2,**kw)
490 489
491 490 #-----------------------------------------------------------------------------
492 491 # Utility functions for the different GUI enabled IPShell* classes.
493 492
494 493 def get_tk():
495 494 """Tries to import Tkinter and returns a withdrawn Tkinter root
496 495 window. If Tkinter is already imported or not available, this
497 496 returns None. This function calls `hijack_tk` underneath.
498 497 """
499 498 if not USE_TK or sys.modules.has_key('Tkinter'):
500 499 return None
501 500 else:
502 501 try:
503 502 import Tkinter
504 503 except ImportError:
505 504 return None
506 505 else:
507 506 hijack_tk()
508 507 r = Tkinter.Tk()
509 508 r.withdraw()
510 509 return r
511 510
512 511 def hijack_tk():
513 512 """Modifies Tkinter's mainloop with a dummy so when a module calls
514 513 mainloop, it does not block.
515 514
516 515 """
517 516 def misc_mainloop(self, n=0):
518 517 pass
519 518 def tkinter_mainloop(n=0):
520 519 pass
521 520
522 521 import Tkinter
523 522 Tkinter.Misc.mainloop = misc_mainloop
524 523 Tkinter.mainloop = tkinter_mainloop
525 524
526 525 def update_tk(tk):
527 526 """Updates the Tkinter event loop. This is typically called from
528 527 the respective WX or GTK mainloops.
529 528 """
530 529 if tk:
531 530 tk.update()
532 531
533 532 def hijack_wx():
534 533 """Modifies wxPython's MainLoop with a dummy so user code does not
535 534 block IPython. The hijacked mainloop function is returned.
536 535 """
537 536 def dummy_mainloop(*args, **kw):
538 537 pass
539 538 import wxPython
540 539 ver = wxPython.__version__
541 540 orig_mainloop = None
542 541 if ver[:3] >= '2.5':
543 542 import wx
544 543 if hasattr(wx, '_core_'): core = getattr(wx, '_core_')
545 544 elif hasattr(wx, '_core'): core = getattr(wx, '_core')
546 545 else: raise AttributeError('Could not find wx core module')
547 546 orig_mainloop = core.PyApp_MainLoop
548 547 core.PyApp_MainLoop = dummy_mainloop
549 548 elif ver[:3] == '2.4':
550 549 orig_mainloop = wxPython.wxc.wxPyApp_MainLoop
551 550 wxPython.wxc.wxPyApp_MainLoop = dummy_mainloop
552 551 else:
553 552 warn("Unable to find either wxPython version 2.4 or >= 2.5.")
554 553 return orig_mainloop
555 554
556 555 def hijack_gtk():
557 556 """Modifies pyGTK's mainloop with a dummy so user code does not
558 557 block IPython. This function returns the original `gtk.mainloop`
559 558 function that has been hijacked.
560 559 """
561 560 def dummy_mainloop(*args, **kw):
562 561 pass
563 562 import gtk
564 563 if gtk.pygtk_version >= (2,4,0): orig_mainloop = gtk.main
565 564 else: orig_mainloop = gtk.mainloop
566 565 gtk.mainloop = dummy_mainloop
567 566 gtk.main = dummy_mainloop
568 567 return orig_mainloop
569 568
570 569 #-----------------------------------------------------------------------------
571 570 # The IPShell* classes below are the ones meant to be run by external code as
572 571 # IPython instances. Note that unless a specific threading strategy is
573 572 # desired, the factory function start() below should be used instead (it
574 573 # selects the proper threaded class).
575 574
576 575 class IPShellGTK(threading.Thread):
577 576 """Run a gtk mainloop() in a separate thread.
578 577
579 578 Python commands can be passed to the thread where they will be executed.
580 579 This is implemented by periodically checking for passed code using a
581 580 GTK timeout callback."""
582 581
583 582 TIMEOUT = 100 # Millisecond interval between timeouts.
584 583
585 584 def __init__(self,argv=None,user_ns=None,debug=1,
586 585 shell_class=MTInteractiveShell):
587 586
588 587 import gtk
589 588
590 589 self.gtk = gtk
591 590 self.gtk_mainloop = hijack_gtk()
592 591
593 592 # Allows us to use both Tk and GTK.
594 593 self.tk = get_tk()
595 594
596 595 if gtk.pygtk_version >= (2,4,0): mainquit = self.gtk.main_quit
597 596 else: mainquit = self.gtk.mainquit
598 597
599 598 self.IP = make_IPython(argv,user_ns=user_ns,debug=debug,
600 599 shell_class=shell_class,
601 600 on_kill=[mainquit])
602 601
603 602 # HACK: slot for banner in self; it will be passed to the mainloop
604 603 # method only and .run() needs it. The actual value will be set by
605 604 # .mainloop().
606 605 self._banner = None
607 606
608 607 threading.Thread.__init__(self)
609 608
610 609 def run(self):
611 610 self.IP.mainloop(self._banner)
612 611 self.IP.kill()
613 612
614 613 def mainloop(self,sys_exit=0,banner=None):
615 614
616 615 self._banner = banner
617 616
618 617 if self.gtk.pygtk_version >= (2,4,0):
619 618 import gobject
620 619 gobject.idle_add(self.on_timer)
621 620 else:
622 621 self.gtk.idle_add(self.on_timer)
623 622
624 623 if sys.platform != 'win32':
625 624 try:
626 625 if self.gtk.gtk_version[0] >= 2:
627 626 self.gtk.threads_init()
628 627 except AttributeError:
629 628 pass
630 629 except RuntimeError:
631 630 error('Your pyGTK likely has not been compiled with '
632 631 'threading support.\n'
633 632 'The exception printout is below.\n'
634 633 'You can either rebuild pyGTK with threads, or '
635 634 'try using \n'
636 635 'matplotlib with a different backend (like Tk or WX).\n'
637 636 'Note that matplotlib will most likely not work in its '
638 637 'current state!')
639 638 self.IP.InteractiveTB()
640 639 self.start()
641 640 self.gtk.threads_enter()
642 641 self.gtk_mainloop()
643 642 self.gtk.threads_leave()
644 643 self.join()
645 644
646 645 def on_timer(self):
647 646 update_tk(self.tk)
648 647 return self.IP.runcode()
649 648
650 649
651 650 class IPShellWX(threading.Thread):
652 651 """Run a wx mainloop() in a separate thread.
653 652
654 653 Python commands can be passed to the thread where they will be executed.
655 654 This is implemented by periodically checking for passed code using a
656 655 GTK timeout callback."""
657 656
658 657 TIMEOUT = 100 # Millisecond interval between timeouts.
659 658
660 659 def __init__(self,argv=None,user_ns=None,debug=1,
661 660 shell_class=MTInteractiveShell):
662 661
663 662 import wxPython.wx as wx
664 663
665 664 threading.Thread.__init__(self)
666 665 self.wx = wx
667 666 self.wx_mainloop = hijack_wx()
668 667
669 668 # Allows us to use both Tk and GTK.
670 669 self.tk = get_tk()
671 670
672 671 self.IP = make_IPython(argv,user_ns=user_ns,debug=debug,
673 672 shell_class=shell_class,
674 673 on_kill=[self.wxexit])
675 674 # HACK: slot for banner in self; it will be passed to the mainloop
676 675 # method only and .run() needs it. The actual value will be set by
677 676 # .mainloop().
678 677 self._banner = None
679 678
680 679 self.app = None
681 680
682 681 def wxexit(self, *args):
683 682 if self.app is not None:
684 683 self.app.agent.timer.Stop()
685 684 self.app.ExitMainLoop()
686 685
687 686 def run(self):
688 687 self.IP.mainloop(self._banner)
689 688 self.IP.kill()
690 689
691 690 def mainloop(self,sys_exit=0,banner=None):
692 691
693 692 self._banner = banner
694 693
695 694 self.start()
696 695
697 696 class TimerAgent(self.wx.wxMiniFrame):
698 697 wx = self.wx
699 698 IP = self.IP
700 699 tk = self.tk
701 700 def __init__(self, parent, interval):
702 701 style = self.wx.wxDEFAULT_FRAME_STYLE | self.wx.wxTINY_CAPTION_HORIZ
703 702 self.wx.wxMiniFrame.__init__(self, parent, -1, ' ', pos=(200, 200),
704 703 size=(100, 100),style=style)
705 704 self.Show(False)
706 705 self.interval = interval
707 706 self.timerId = self.wx.wxNewId()
708 707
709 708 def StartWork(self):
710 709 self.timer = self.wx.wxTimer(self, self.timerId)
711 710 self.wx.EVT_TIMER(self, self.timerId, self.OnTimer)
712 711 self.timer.Start(self.interval)
713 712
714 713 def OnTimer(self, event):
715 714 update_tk(self.tk)
716 715 self.IP.runcode()
717 716
718 717 class App(self.wx.wxApp):
719 718 wx = self.wx
720 719 TIMEOUT = self.TIMEOUT
721 720 def OnInit(self):
722 721 'Create the main window and insert the custom frame'
723 722 self.agent = TimerAgent(None, self.TIMEOUT)
724 723 self.agent.Show(self.wx.false)
725 724 self.agent.StartWork()
726 725 return self.wx.true
727 726
728 727 self.app = App(redirect=False)
729 728 self.wx_mainloop(self.app)
730 729 self.join()
731 730
732 731
733 732 class IPShellQt(threading.Thread):
734 733 """Run a Qt event loop in a separate thread.
735 734
736 735 Python commands can be passed to the thread where they will be executed.
737 736 This is implemented by periodically checking for passed code using a
738 737 Qt timer / slot."""
739 738
740 739 TIMEOUT = 100 # Millisecond interval between timeouts.
741 740
742 741 def __init__(self,argv=None,user_ns=None,debug=0,
743 742 shell_class=MTInteractiveShell):
744 743
745 744 import qt
746 745
747 746 class newQApplication:
748 747 def __init__( self ):
749 748 self.QApplication = qt.QApplication
750 749
751 750 def __call__( *args, **kwargs ):
752 751 return qt.qApp
753 752
754 753 def exec_loop( *args, **kwargs ):
755 754 pass
756 755
757 756 def __getattr__( self, name ):
758 757 return getattr( self.QApplication, name )
759 758
760 759 qt.QApplication = newQApplication()
761 760
762 761 # Allows us to use both Tk and QT.
763 762 self.tk = get_tk()
764 763
765 764 self.IP = make_IPython(argv,user_ns=user_ns,debug=debug,
766 765 shell_class=shell_class,
767 766 on_kill=[qt.qApp.exit])
768 767
769 768 # HACK: slot for banner in self; it will be passed to the mainloop
770 769 # method only and .run() needs it. The actual value will be set by
771 770 # .mainloop().
772 771 self._banner = None
773 772
774 773 threading.Thread.__init__(self)
775 774
776 775 def run(self):
777 776 self.IP.mainloop(self._banner)
778 777 self.IP.kill()
779 778
780 779 def mainloop(self,sys_exit=0,banner=None):
781 780
782 781 import qt
783 782
784 783 self._banner = banner
785 784
786 785 if qt.QApplication.startingUp():
787 786 a = qt.QApplication.QApplication(sys.argv)
788 787 self.timer = qt.QTimer()
789 788 qt.QObject.connect( self.timer, qt.SIGNAL( 'timeout()' ), self.on_timer )
790 789
791 790 self.start()
792 791 self.timer.start( self.TIMEOUT, True )
793 792 while True:
794 793 if self.IP._kill: break
795 794 qt.qApp.exec_loop()
796 795 self.join()
797 796
798 797 def on_timer(self):
799 798 update_tk(self.tk)
800 799 result = self.IP.runcode()
801 800 self.timer.start( self.TIMEOUT, True )
802 801 return result
803 802
804 803 # A set of matplotlib public IPython shell classes, for single-threaded
805 804 # (Tk* and FLTK* backends) and multithreaded (GTK* and WX* backends) use.
806 805 class IPShellMatplotlib(IPShell):
807 806 """Subclass IPShell with MatplotlibShell as the internal shell.
808 807
809 808 Single-threaded class, meant for the Tk* and FLTK* backends.
810 809
811 810 Having this on a separate class simplifies the external driver code."""
812 811
813 812 def __init__(self,argv=None,user_ns=None,debug=1):
814 813 IPShell.__init__(self,argv,user_ns,debug,shell_class=MatplotlibShell)
815 814
816 815 class IPShellMatplotlibGTK(IPShellGTK):
817 816 """Subclass IPShellGTK with MatplotlibMTShell as the internal shell.
818 817
819 818 Multi-threaded class, meant for the GTK* backends."""
820 819
821 820 def __init__(self,argv=None,user_ns=None,debug=1):
822 821 IPShellGTK.__init__(self,argv,user_ns,debug,shell_class=MatplotlibMTShell)
823 822
824 823 class IPShellMatplotlibWX(IPShellWX):
825 824 """Subclass IPShellWX with MatplotlibMTShell as the internal shell.
826 825
827 826 Multi-threaded class, meant for the WX* backends."""
828 827
829 828 def __init__(self,argv=None,user_ns=None,debug=1):
830 829 IPShellWX.__init__(self,argv,user_ns,debug,shell_class=MatplotlibMTShell)
831 830
832 831 class IPShellMatplotlibQt(IPShellQt):
833 832 """Subclass IPShellQt with MatplotlibMTShell as the internal shell.
834 833
835 834 Multi-threaded class, meant for the Qt* backends."""
836 835
837 836 def __init__(self,argv=None,user_ns=None,debug=1):
838 837 IPShellQt.__init__(self,argv,user_ns,debug,shell_class=MatplotlibMTShell)
839 838
840 839 #-----------------------------------------------------------------------------
841 840 # Factory functions to actually start the proper thread-aware shell
842 841
843 842 def _matplotlib_shell_class():
844 843 """Factory function to handle shell class selection for matplotlib.
845 844
846 845 The proper shell class to use depends on the matplotlib backend, since
847 846 each backend requires a different threading strategy."""
848 847
849 848 try:
850 849 import matplotlib
851 850 except ImportError:
852 851 error('matplotlib could NOT be imported! Starting normal IPython.')
853 852 sh_class = IPShell
854 853 else:
855 854 backend = matplotlib.rcParams['backend']
856 855 if backend.startswith('GTK'):
857 856 sh_class = IPShellMatplotlibGTK
858 857 elif backend.startswith('WX'):
859 858 sh_class = IPShellMatplotlibWX
860 859 elif backend.startswith('Qt'):
861 860 sh_class = IPShellMatplotlibQt
862 861 else:
863 862 sh_class = IPShellMatplotlib
864 863 #print 'Using %s with the %s backend.' % (sh_class,backend) # dbg
865 864 return sh_class
866 865
867 866 # This is the one which should be called by external code.
868 867 def start():
869 868 """Return a running shell instance, dealing with threading options.
870 869
871 870 This is a factory function which will instantiate the proper IPython shell
872 871 based on the user's threading choice. Such a selector is needed because
873 872 different GUI toolkits require different thread handling details."""
874 873
875 874 global USE_TK
876 875 # Crude sys.argv hack to extract the threading options.
877 876 argv = sys.argv
878 877 if len(argv) > 1:
879 878 if len(argv) > 2:
880 879 arg2 = argv[2]
881 880 if arg2.endswith('-tk'):
882 881 USE_TK = True
883 882 arg1 = argv[1]
884 883 if arg1.endswith('-gthread'):
885 884 shell = IPShellGTK
886 885 elif arg1.endswith( '-qthread' ):
887 886 shell = IPShellQt
888 887 elif arg1.endswith('-wthread'):
889 888 shell = IPShellWX
890 889 elif arg1.endswith('-pylab'):
891 890 shell = _matplotlib_shell_class()
892 891 else:
893 892 shell = IPShell
894 893 else:
895 894 shell = IPShell
896 895 return shell()
897 896
898 897 # Some aliases for backwards compatibility
899 898 IPythonShell = IPShell
900 899 IPythonShellEmbed = IPShellEmbed
901 900 #************************ End of file <Shell.py> ***************************
@@ -1,375 +1,376 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Mimic C structs with lots of extra functionality.
3 3
4 $Id: Struct.py 638 2005-07-18 03:01:41Z fperez $"""
4 $Id: Struct.py 958 2005-12-27 23:17:51Z fperez $"""
5 5
6 6 #*****************************************************************************
7 7 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
8 8 #
9 9 # Distributed under the terms of the BSD License. The full license is in
10 10 # the file COPYING, distributed as part of this software.
11 11 #*****************************************************************************
12 12
13 13 from IPython import Release
14 14 __author__ = '%s <%s>' % Release.authors['Fernando']
15 15 __license__ = Release.license
16 16
17 17 __all__ = ['Struct']
18 18
19 19 import types
20
20 21 from IPython.genutils import list2dict2
21 22
22 23 class Struct:
23 24 """Class to mimic C structs but also provide convenient dictionary-like
24 25 functionality.
25 26
26 27 Instances can be initialized with a dictionary, a list of key=value pairs
27 28 or both. If both are present, the dictionary must come first.
28 29
29 30 Because Python classes provide direct assignment to their members, it's
30 31 easy to overwrite normal methods (S.copy = 1 would destroy access to
31 32 S.copy()). For this reason, all builtin method names are protected and
32 33 can't be assigned to. An attempt to do s.copy=1 or s['copy']=1 will raise
33 34 a KeyError exception. If you really want to, you can bypass this
34 35 protection by directly assigning to __dict__: s.__dict__['copy']=1 will
35 36 still work. Doing this will break functionality, though. As in most of
36 37 Python, namespace protection is weakly enforced, so feel free to shoot
37 38 yourself if you really want to.
38 39
39 40 Note that this class uses more memory and is *much* slower than a regular
40 41 dictionary, so be careful in situations where memory or performance are
41 42 critical. But for day to day use it should behave fine. It is particularly
42 43 convenient for storing configuration data in programs.
43 44
44 45 +,+=,- and -= are implemented. +/+= do merges (non-destructive updates),
45 46 -/-= remove keys from the original. See the method descripitions.
46 47
47 48 This class allows a quick access syntax: both s.key and s['key'] are
48 49 valid. This syntax has a limitation: each 'key' has to be explicitly
49 50 accessed by its original name. The normal s.key syntax doesn't provide
50 51 access to the keys via variables whose values evaluate to the desired
51 52 keys. An example should clarify this:
52 53
53 54 Define a dictionary and initialize both with dict and k=v pairs:
54 55 >>> d={'a':1,'b':2}
55 56 >>> s=Struct(d,hi=10,ho=20)
56 57 The return of __repr__ can be used to create a new instance:
57 58 >>> s
58 59 Struct({'ho': 20, 'b': 2, 'hi': 10, 'a': 1})
59 60 __str__ (called by print) shows it's not quite a regular dictionary:
60 61 >>> print s
61 62 Struct {a: 1, b: 2, hi: 10, ho: 20}
62 63 Access by explicitly named key with dot notation:
63 64 >>> s.a
64 65 1
65 66 Or like a dictionary:
66 67 >>> s['a']
67 68 1
68 69 If you want a variable to hold the key value, only dictionary access works:
69 70 >>> key='hi'
70 71 >>> s.key
71 72 Traceback (most recent call last):
72 73 File "<stdin>", line 1, in ?
73 74 AttributeError: Struct instance has no attribute 'key'
74 75 >>> s[key]
75 76 10
76 77
77 78 Another limitation of the s.key syntax (and Struct(key=val)
78 79 initialization): keys can't be numbers. But numeric keys can be used and
79 80 accessed using the dictionary syntax. Again, an example:
80 81
81 82 This doesn't work:
82 83 >>> s=Struct(4='hi')
83 84 SyntaxError: keyword can't be an expression
84 85 But this does:
85 86 >>> s=Struct()
86 87 >>> s[4]='hi'
87 88 >>> s
88 89 Struct({4: 'hi'})
89 90 >>> s[4]
90 91 'hi'
91 92 """
92 93
93 94 # Attributes to which __setitem__ and __setattr__ will block access.
94 95 # Note: much of this will be moot in Python 2.2 and will be done in a much
95 96 # cleaner way.
96 97 __protected = ('copy dict dictcopy get has_attr has_key items keys '
97 98 'merge popitem setdefault update values '
98 99 '__make_dict __dict_invert ').split()
99 100
100 101 def __init__(self,dict=None,**kw):
101 102 """Initialize with a dictionary, another Struct, or by giving
102 103 explicitly the list of attributes.
103 104
104 105 Both can be used, but the dictionary must come first:
105 106 Struct(dict), Struct(k1=v1,k2=v2) or Struct(dict,k1=v1,k2=v2).
106 107 """
107 108 if dict is None:
108 109 dict = {}
109 110 if isinstance(dict,Struct):
110 111 dict = dict.dict()
111 112 elif dict and type(dict) is not types.DictType:
112 113 raise TypeError,\
113 114 'Initialize with a dictionary or key=val pairs.'
114 115 dict.update(kw)
115 116 # do the updating by hand to guarantee that we go through the
116 117 # safety-checked __setitem__
117 118 for k,v in dict.items():
118 119 self[k] = v
119 120
120 121 def __setitem__(self,key,value):
121 122 """Used when struct[key] = val calls are made."""
122 123 if key in Struct.__protected:
123 124 raise KeyError,'Key '+`key`+' is a protected key of class Struct.'
124 125 self.__dict__[key] = value
125 126
126 127 def __setattr__(self, key, value):
127 128 """Used when struct.key = val calls are made."""
128 129 self.__setitem__(key,value)
129 130
130 131 def __str__(self):
131 132 """Gets called by print."""
132 133
133 134 return 'Struct('+str(self.__dict__)+')'
134 135
135 136 def __repr__(self):
136 137 """Gets called by repr.
137 138
138 139 A Struct can be recreated with S_new=eval(repr(S_old))."""
139 140 return 'Struct('+str(self.__dict__)+')'
140 141
141 142 def __getitem__(self,key):
142 143 """Allows struct[key] access."""
143 144 return self.__dict__[key]
144 145
145 146 def __contains__(self,key):
146 147 """Allows use of the 'in' operator."""
147 148 return self.__dict__.has_key(key)
148 149
149 150 def __iadd__(self,other):
150 151 """S += S2 is a shorthand for S.merge(S2)."""
151 152 self.merge(other)
152 153 return self
153 154
154 155 def __add__(self,other):
155 156 """S + S2 -> New Struct made form S and S.merge(S2)"""
156 157 Sout = self.copy()
157 158 Sout.merge(other)
158 159 return Sout
159 160
160 161 def __sub__(self,other):
161 162 """Return S1-S2, where all keys in S2 have been deleted (if present)
162 163 from S1."""
163 164 Sout = self.copy()
164 165 Sout -= other
165 166 return Sout
166 167
167 168 def __isub__(self,other):
168 169 """Do in place S = S - S2, meaning all keys in S2 have been deleted
169 170 (if present) from S1."""
170 171
171 172 for k in other.keys():
172 173 if self.has_key(k):
173 174 del self.__dict__[k]
174 175
175 176 def __make_dict(self,__loc_data__,**kw):
176 177 "Helper function for update and merge. Return a dict from data."
177 178
178 179 if __loc_data__ == None:
179 180 dict = {}
180 181 elif type(__loc_data__) is types.DictType:
181 182 dict = __loc_data__
182 183 elif isinstance(__loc_data__,Struct):
183 184 dict = __loc_data__.__dict__
184 185 else:
185 186 raise TypeError, 'Update with a dict, a Struct or key=val pairs.'
186 187 if kw:
187 188 dict.update(kw)
188 189 return dict
189 190
190 191 def __dict_invert(self,dict):
191 192 """Helper function for merge. Takes a dictionary whose values are
192 193 lists and returns a dict. with the elements of each list as keys and
193 194 the original keys as values."""
194 195
195 196 outdict = {}
196 197 for k,lst in dict.items():
197 198 if type(lst) is types.StringType:
198 199 lst = lst.split()
199 200 for entry in lst:
200 201 outdict[entry] = k
201 202 return outdict
202 203
203 204 def clear(self):
204 205 """Clear all attributes."""
205 206 self.__dict__.clear()
206 207
207 208 def copy(self):
208 209 """Return a (shallow) copy of a Struct."""
209 210 return Struct(self.__dict__.copy())
210 211
211 212 def dict(self):
212 213 """Return the Struct's dictionary."""
213 214 return self.__dict__
214 215
215 216 def dictcopy(self):
216 217 """Return a (shallow) copy of the Struct's dictionary."""
217 218 return self.__dict__.copy()
218 219
219 220 def popitem(self):
220 221 """S.popitem() -> (k, v), remove and return some (key, value) pair as
221 222 a 2-tuple; but raise KeyError if S is empty."""
222 223 return self.__dict__.popitem()
223 224
224 225 def update(self,__loc_data__=None,**kw):
225 226 """Update (merge) with data from another Struct or from a dictionary.
226 227 Optionally, one or more key=value pairs can be given at the end for
227 228 direct update."""
228 229
229 230 # The funny name __loc_data__ is to prevent a common variable name which
230 231 # could be a fieled of a Struct to collide with this parameter. The problem
231 232 # would arise if the function is called with a keyword with this same name
232 233 # that a user means to add as a Struct field.
233 234 newdict = Struct.__make_dict(self,__loc_data__,**kw)
234 235 for k,v in newdict.items():
235 236 self[k] = v
236 237
237 238 def merge(self,__loc_data__=None,__conflict_solve=None,**kw):
238 239 """S.merge(data,conflict,k=v1,k=v2,...) -> merge data and k=v into S.
239 240
240 241 This is similar to update(), but much more flexible. First, a dict is
241 242 made from data+key=value pairs. When merging this dict with the Struct
242 243 S, the optional dictionary 'conflict' is used to decide what to do.
243 244
244 245 If conflict is not given, the default behavior is to preserve any keys
245 246 with their current value (the opposite of the update method's
246 247 behavior).
247 248
248 249 conflict is a dictionary of binary functions which will be used to
249 250 solve key conflicts. It must have the following structure:
250 251
251 252 conflict == { fn1 : [Skey1,Skey2,...], fn2 : [Skey3], etc }
252 253
253 254 Values must be lists or whitespace separated strings which are
254 255 automatically converted to lists of strings by calling string.split().
255 256
256 257 Each key of conflict is a function which defines a policy for
257 258 resolving conflicts when merging with the input data. Each fn must be
258 259 a binary function which returns the desired outcome for a key
259 260 conflict. These functions will be called as fn(old,new).
260 261
261 262 An example is probably in order. Suppose you are merging the struct S
262 263 with a dict D and the following conflict policy dict:
263 264
264 265 S.merge(D,{fn1:['a','b',4], fn2:'key_c key_d'})
265 266
266 267 If the key 'a' is found in both S and D, the merge method will call:
267 268
268 269 S['a'] = fn1(S['a'],D['a'])
269 270
270 271 As a convenience, merge() provides five (the most commonly needed)
271 272 pre-defined policies: preserve, update, add, add_flip and add_s. The
272 273 easiest explanation is their implementation:
273 274
274 275 preserve = lambda old,new: old
275 276 update = lambda old,new: new
276 277 add = lambda old,new: old + new
277 278 add_flip = lambda old,new: new + old # note change of order!
278 279 add_s = lambda old,new: old + ' ' + new # only works for strings!
279 280
280 281 You can use those four words (as strings) as keys in conflict instead
281 282 of defining them as functions, and the merge method will substitute
282 283 the appropriate functions for you. That is, the call
283 284
284 285 S.merge(D,{'preserve':'a b c','add':[4,5,'d'],my_function:[6]})
285 286
286 287 will automatically substitute the functions preserve and add for the
287 288 names 'preserve' and 'add' before making any function calls.
288 289
289 290 For more complicated conflict resolution policies, you still need to
290 291 construct your own functions. """
291 292
292 293 data_dict = Struct.__make_dict(self,__loc_data__,**kw)
293 294
294 295 # policies for conflict resolution: two argument functions which return
295 296 # the value that will go in the new struct
296 297 preserve = lambda old,new: old
297 298 update = lambda old,new: new
298 299 add = lambda old,new: old + new
299 300 add_flip = lambda old,new: new + old # note change of order!
300 301 add_s = lambda old,new: old + ' ' + new
301 302
302 303 # default policy is to keep current keys when there's a conflict
303 304 conflict_solve = list2dict2(self.keys(),default = preserve)
304 305
305 306 # the conflict_solve dictionary is given by the user 'inverted': we
306 307 # need a name-function mapping, it comes as a function -> names
307 308 # dict. Make a local copy (b/c we'll make changes), replace user
308 309 # strings for the three builtin policies and invert it.
309 310 if __conflict_solve:
310 311 inv_conflict_solve_user = __conflict_solve.copy()
311 312 for name, func in [('preserve',preserve), ('update',update),
312 313 ('add',add), ('add_flip',add_flip), ('add_s',add_s)]:
313 314 if name in inv_conflict_solve_user.keys():
314 315 inv_conflict_solve_user[func] = inv_conflict_solve_user[name]
315 316 del inv_conflict_solve_user[name]
316 317 conflict_solve.update(Struct.__dict_invert(self,inv_conflict_solve_user))
317 318 #print 'merge. conflict_solve: '; pprint(conflict_solve) # dbg
318 319 #print '*'*50,'in merger. conflict_solver:'; pprint(conflict_solve)
319 320 for key in data_dict:
320 321 if key not in self:
321 322 self[key] = data_dict[key]
322 323 else:
323 324 self[key] = conflict_solve[key](self[key],data_dict[key])
324 325
325 326 def has_key(self,key):
326 327 """Like has_key() dictionary method."""
327 328 return self.__dict__.has_key(key)
328 329
329 330 def hasattr(self,key):
330 331 """hasattr function available as a method.
331 332
332 333 Implemented like has_key, to make sure that all available keys in the
333 334 internal dictionary of the Struct appear also as attributes (even
334 335 numeric keys)."""
335 336 return self.__dict__.has_key(key)
336 337
337 338 def items(self):
338 339 """Return the items in the Struct's dictionary, in the same format
339 340 as a call to {}.items()."""
340 341 return self.__dict__.items()
341 342
342 343 def keys(self):
343 344 """Return the keys in the Struct's dictionary, in the same format
344 345 as a call to {}.keys()."""
345 346 return self.__dict__.keys()
346 347
347 348 def values(self,keys=None):
348 349 """Return the values in the Struct's dictionary, in the same format
349 350 as a call to {}.values().
350 351
351 352 Can be called with an optional argument keys, which must be a list or
352 353 tuple of keys. In this case it returns only the values corresponding
353 354 to those keys (allowing a form of 'slicing' for Structs)."""
354 355 if not keys:
355 356 return self.__dict__.values()
356 357 else:
357 358 ret=[]
358 359 for k in keys:
359 360 ret.append(self[k])
360 361 return ret
361 362
362 363 def get(self,attr,val=None):
363 364 """S.get(k[,d]) -> S[k] if S.has_key(k), else d. d defaults to None."""
364 365 try:
365 366 return self[attr]
366 367 except KeyError:
367 368 return val
368 369
369 370 def setdefault(self,attr,val=None):
370 371 """S.setdefault(k[,d]) -> S.get(k,d), also set S[k]=d if not S.has_key(k)"""
371 372 if not self.has_key(attr):
372 373 self[attr] = val
373 374 return self.get(attr,val)
374 375 # end class Struct
375 376
@@ -1,495 +1,496 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Manage background (threaded) jobs conveniently from an interactive shell.
3 3
4 4 This module provides a BackgroundJobManager class. This is the main class
5 5 meant for public usage, it implements an object which can create and manage
6 6 new background jobs.
7 7
8 8 It also provides the actual job classes managed by these BackgroundJobManager
9 9 objects, see their docstrings below.
10 10
11 11
12 12 This system was inspired by discussions with B. Granger and the
13 13 BackgroundCommand class described in the book Python Scripting for
14 14 Computational Science, by H. P. Langtangen:
15 15
16 16 http://folk.uio.no/hpl/scripting
17 17
18 18 (although ultimately no code from this text was used, as IPython's system is a
19 19 separate implementation).
20 20
21 $Id: background_jobs.py 638 2005-07-18 03:01:41Z fperez $
21 $Id: background_jobs.py 958 2005-12-27 23:17:51Z fperez $
22 22 """
23 23
24 24 #*****************************************************************************
25 25 # Copyright (C) 2005 Fernando Perez <fperez@colorado.edu>
26 26 #
27 27 # Distributed under the terms of the BSD License. The full license is in
28 28 # the file COPYING, distributed as part of this software.
29 29 #*****************************************************************************
30 30
31 31 from IPython import Release
32 32 __author__ = '%s <%s>' % Release.authors['Fernando']
33 33 __license__ = Release.license
34 34
35 35 # Code begins
36 import threading,sys
36 import sys
37 import threading
37 38
38 39 from IPython.ultraTB import AutoFormattedTB
39 40 from IPython.genutils import warn,error
40 41
41 42 class BackgroundJobManager:
42 43 """Class to manage a pool of backgrounded threaded jobs.
43 44
44 45 Below, we assume that 'jobs' is a BackgroundJobManager instance.
45 46
46 47 Usage summary (see the method docstrings for details):
47 48
48 49 jobs.new(...) -> start a new job
49 50
50 51 jobs() or jobs.status() -> print status summary of all jobs
51 52
52 53 jobs[N] -> returns job number N.
53 54
54 55 foo = jobs[N].result -> assign to variable foo the result of job N
55 56
56 57 jobs[N].traceback() -> print the traceback of dead job N
57 58
58 59 jobs.remove(N) -> remove (finished) job N
59 60
60 61 jobs.flush_finished() -> remove all finished jobs
61 62
62 63 As a convenience feature, BackgroundJobManager instances provide the
63 64 utility result and traceback methods which retrieve the corresponding
64 65 information from the jobs list:
65 66
66 67 jobs.result(N) <--> jobs[N].result
67 68 jobs.traceback(N) <--> jobs[N].traceback()
68 69
69 70 While this appears minor, it allows you to use tab completion
70 71 interactively on the job manager instance.
71 72
72 73 In interactive mode, IPython provides the magic fuction %bg for quick
73 74 creation of backgrounded expression-based jobs. Type bg? for details."""
74 75
75 76 def __init__(self):
76 77 # Lists for job management
77 78 self.jobs_run = []
78 79 self.jobs_comp = []
79 80 self.jobs_dead = []
80 81 # A dict of all jobs, so users can easily access any of them
81 82 self.jobs_all = {}
82 83 # For reporting
83 84 self._comp_report = []
84 85 self._dead_report = []
85 86 # Store status codes locally for fast lookups
86 87 self._s_created = BackgroundJobBase.stat_created_c
87 88 self._s_running = BackgroundJobBase.stat_running_c
88 89 self._s_completed = BackgroundJobBase.stat_completed_c
89 90 self._s_dead = BackgroundJobBase.stat_dead_c
90 91
91 92 def new(self,func_or_exp,*args,**kwargs):
92 93 """Add a new background job and start it in a separate thread.
93 94
94 95 There are two types of jobs which can be created:
95 96
96 97 1. Jobs based on expressions which can be passed to an eval() call.
97 98 The expression must be given as a string. For example:
98 99
99 100 job_manager.new('myfunc(x,y,z=1)'[,glob[,loc]])
100 101
101 102 The given expression is passed to eval(), along with the optional
102 103 global/local dicts provided. If no dicts are given, they are
103 104 extracted automatically from the caller's frame.
104 105
105 106 A Python statement is NOT a valid eval() expression. Basically, you
106 107 can only use as an eval() argument something which can go on the right
107 108 of an '=' sign and be assigned to a variable.
108 109
109 110 For example,"print 'hello'" is not valid, but '2+3' is.
110 111
111 112 2. Jobs given a function object, optionally passing additional
112 113 positional arguments:
113 114
114 115 job_manager.new(myfunc,x,y)
115 116
116 117 The function is called with the given arguments.
117 118
118 119 If you need to pass keyword arguments to your function, you must
119 120 supply them as a dict named kw:
120 121
121 122 job_manager.new(myfunc,x,y,kw=dict(z=1))
122 123
123 124 The reason for this assymmetry is that the new() method needs to
124 125 maintain access to its own keywords, and this prevents name collisions
125 126 between arguments to new() and arguments to your own functions.
126 127
127 128 In both cases, the result is stored in the job.result field of the
128 129 background job object.
129 130
130 131
131 132 Notes and caveats:
132 133
133 134 1. All threads running share the same standard output. Thus, if your
134 135 background jobs generate output, it will come out on top of whatever
135 136 you are currently writing. For this reason, background jobs are best
136 137 used with silent functions which simply return their output.
137 138
138 139 2. Threads also all work within the same global namespace, and this
139 140 system does not lock interactive variables. So if you send job to the
140 141 background which operates on a mutable object for a long time, and
141 142 start modifying that same mutable object interactively (or in another
142 143 backgrounded job), all sorts of bizarre behaviour will occur.
143 144
144 145 3. If a background job is spending a lot of time inside a C extension
145 146 module which does not release the Python Global Interpreter Lock
146 147 (GIL), this will block the IPython prompt. This is simply because the
147 148 Python interpreter can only switch between threads at Python
148 149 bytecodes. While the execution is inside C code, the interpreter must
149 150 simply wait unless the extension module releases the GIL.
150 151
151 152 4. There is no way, due to limitations in the Python threads library,
152 153 to kill a thread once it has started."""
153 154
154 155 if callable(func_or_exp):
155 156 kw = kwargs.get('kw',{})
156 157 job = BackgroundJobFunc(func_or_exp,*args,**kw)
157 158 elif isinstance(func_or_exp,basestring):
158 159 if not args:
159 160 frame = sys._getframe(1)
160 161 glob, loc = frame.f_globals, frame.f_locals
161 162 elif len(args)==1:
162 163 glob = loc = args[0]
163 164 elif len(args)==2:
164 165 glob,loc = args
165 166 else:
166 167 raise ValueError,\
167 168 'Expression jobs take at most 2 args (globals,locals)'
168 169 job = BackgroundJobExpr(func_or_exp,glob,loc)
169 170 else:
170 171 raise
171 172 jkeys = self.jobs_all.keys()
172 173 if jkeys:
173 174 job.num = max(jkeys)+1
174 175 else:
175 176 job.num = 0
176 177 self.jobs_run.append(job)
177 178 self.jobs_all[job.num] = job
178 179 print 'Starting job # %s in a separate thread.' % job.num
179 180 job.start()
180 181 return job
181 182
182 183 def __getitem__(self,key):
183 184 return self.jobs_all[key]
184 185
185 186 def __call__(self):
186 187 """An alias to self.status(),
187 188
188 189 This allows you to simply call a job manager instance much like the
189 190 Unix jobs shell command."""
190 191
191 192 return self.status()
192 193
193 194 def _update_status(self):
194 195 """Update the status of the job lists.
195 196
196 197 This method moves finished jobs to one of two lists:
197 198 - self.jobs_comp: jobs which completed successfully
198 199 - self.jobs_dead: jobs which finished but died.
199 200
200 201 It also copies those jobs to corresponding _report lists. These lists
201 202 are used to report jobs completed/dead since the last update, and are
202 203 then cleared by the reporting function after each call."""
203 204
204 205 run,comp,dead = self._s_running,self._s_completed,self._s_dead
205 206 jobs_run = self.jobs_run
206 207 for num in range(len(jobs_run)):
207 208 job = jobs_run[num]
208 209 stat = job.stat_code
209 210 if stat == run:
210 211 continue
211 212 elif stat == comp:
212 213 self.jobs_comp.append(job)
213 214 self._comp_report.append(job)
214 215 jobs_run[num] = False
215 216 elif stat == dead:
216 217 self.jobs_dead.append(job)
217 218 self._dead_report.append(job)
218 219 jobs_run[num] = False
219 220 self.jobs_run = filter(None,self.jobs_run)
220 221
221 222 def _group_report(self,group,name):
222 223 """Report summary for a given job group.
223 224
224 225 Return True if the group had any elements."""
225 226
226 227 if group:
227 228 print '%s jobs:' % name
228 229 for job in group:
229 230 print '%s : %s' % (job.num,job)
230 231 print
231 232 return True
232 233
233 234 def _group_flush(self,group,name):
234 235 """Flush a given job group
235 236
236 237 Return True if the group had any elements."""
237 238
238 239 njobs = len(group)
239 240 if njobs:
240 241 plural = {1:''}.setdefault(njobs,'s')
241 242 print 'Flushing %s %s job%s.' % (njobs,name,plural)
242 243 group[:] = []
243 244 return True
244 245
245 246 def _status_new(self):
246 247 """Print the status of newly finished jobs.
247 248
248 249 Return True if any new jobs are reported.
249 250
250 251 This call resets its own state every time, so it only reports jobs
251 252 which have finished since the last time it was called."""
252 253
253 254 self._update_status()
254 255 new_comp = self._group_report(self._comp_report,'Completed')
255 256 new_dead = self._group_report(self._dead_report,
256 257 'Dead, call job.traceback() for details')
257 258 self._comp_report[:] = []
258 259 self._dead_report[:] = []
259 260 return new_comp or new_dead
260 261
261 262 def status(self,verbose=0):
262 263 """Print a status of all jobs currently being managed."""
263 264
264 265 self._update_status()
265 266 self._group_report(self.jobs_run,'Running')
266 267 self._group_report(self.jobs_comp,'Completed')
267 268 self._group_report(self.jobs_dead,'Dead')
268 269 # Also flush the report queues
269 270 self._comp_report[:] = []
270 271 self._dead_report[:] = []
271 272
272 273 def remove(self,num):
273 274 """Remove a finished (completed or dead) job."""
274 275
275 276 try:
276 277 job = self.jobs_all[num]
277 278 except KeyError:
278 279 error('Job #%s not found' % num)
279 280 else:
280 281 stat_code = job.stat_code
281 282 if stat_code == self._s_running:
282 283 error('Job #%s is still running, it can not be removed.' % num)
283 284 return
284 285 elif stat_code == self._s_completed:
285 286 self.jobs_comp.remove(job)
286 287 elif stat_code == self._s_dead:
287 288 self.jobs_dead.remove(job)
288 289
289 290 def flush_finished(self):
290 291 """Flush all jobs finished (completed and dead) from lists.
291 292
292 293 Running jobs are never flushed.
293 294
294 295 It first calls _status_new(), to update info. If any jobs have
295 296 completed since the last _status_new() call, the flush operation
296 297 aborts."""
297 298
298 299 if self._status_new():
299 300 error('New jobs completed since last '\
300 301 '_status_new(), aborting flush.')
301 302 return
302 303
303 304 # Remove the finished jobs from the master dict
304 305 jobs_all = self.jobs_all
305 306 for job in self.jobs_comp+self.jobs_dead:
306 307 del(jobs_all[job.num])
307 308
308 309 # Now flush these lists completely
309 310 fl_comp = self._group_flush(self.jobs_comp,'Completed')
310 311 fl_dead = self._group_flush(self.jobs_dead,'Dead')
311 312 if not (fl_comp or fl_dead):
312 313 print 'No jobs to flush.'
313 314
314 315 def result(self,num):
315 316 """result(N) -> return the result of job N."""
316 317 try:
317 318 return self.jobs_all[num].result
318 319 except KeyError:
319 320 error('Job #%s not found' % num)
320 321
321 322 def traceback(self,num):
322 323 try:
323 324 self.jobs_all[num].traceback()
324 325 except KeyError:
325 326 error('Job #%s not found' % num)
326 327
327 328
328 329 class BackgroundJobBase(threading.Thread):
329 330 """Base class to build BackgroundJob classes.
330 331
331 332 The derived classes must implement:
332 333
333 334 - Their own __init__, since the one here raises NotImplementedError. The
334 335 derived constructor must call self._init() at the end, to provide common
335 336 initialization.
336 337
337 338 - A strform attribute used in calls to __str__.
338 339
339 340 - A call() method, which will make the actual execution call and must
340 341 return a value to be held in the 'result' field of the job object."""
341 342
342 343 # Class constants for status, in string and as numerical codes (when
343 344 # updating jobs lists, we don't want to do string comparisons). This will
344 345 # be done at every user prompt, so it has to be as fast as possible
345 346 stat_created = 'Created'; stat_created_c = 0
346 347 stat_running = 'Running'; stat_running_c = 1
347 348 stat_completed = 'Completed'; stat_completed_c = 2
348 349 stat_dead = 'Dead (Exception), call job.traceback() for details'
349 350 stat_dead_c = -1
350 351
351 352 def __init__(self):
352 353 raise NotImplementedError, \
353 354 "This class can not be instantiated directly."
354 355
355 356 def _init(self):
356 357 """Common initialization for all BackgroundJob objects"""
357 358
358 359 for attr in ['call','strform']:
359 360 assert hasattr(self,attr), "Missing attribute <%s>" % attr
360 361
361 362 # The num tag can be set by an external job manager
362 363 self.num = None
363 364
364 365 self.status = BackgroundJobBase.stat_created
365 366 self.stat_code = BackgroundJobBase.stat_created_c
366 367 self.finished = False
367 368 self.result = '<BackgroundJob has not completed>'
368 369 # reuse the ipython traceback handler if we can get to it, otherwise
369 370 # make a new one
370 371 try:
371 372 self._make_tb = __IPYTHON__.InteractiveTB.text
372 373 except:
373 374 self._make_tb = AutoFormattedTB(mode = 'Context',
374 375 color_scheme='NoColor',
375 376 tb_offset = 1).text
376 377 # Hold a formatted traceback if one is generated.
377 378 self._tb = None
378 379
379 380 threading.Thread.__init__(self)
380 381
381 382 def __str__(self):
382 383 return self.strform
383 384
384 385 def __repr__(self):
385 386 return '<BackgroundJob: %s>' % self.strform
386 387
387 388 def traceback(self):
388 389 print self._tb
389 390
390 391 def run(self):
391 392 try:
392 393 self.status = BackgroundJobBase.stat_running
393 394 self.stat_code = BackgroundJobBase.stat_running_c
394 395 self.result = self.call()
395 396 except:
396 397 self.status = BackgroundJobBase.stat_dead
397 398 self.stat_code = BackgroundJobBase.stat_dead_c
398 399 self.finished = None
399 400 self.result = ('<BackgroundJob died, call job.traceback() for details>')
400 401 self._tb = self._make_tb()
401 402 else:
402 403 self.status = BackgroundJobBase.stat_completed
403 404 self.stat_code = BackgroundJobBase.stat_completed_c
404 405 self.finished = True
405 406
406 407 class BackgroundJobExpr(BackgroundJobBase):
407 408 """Evaluate an expression as a background job (uses a separate thread)."""
408 409
409 410 def __init__(self,expression,glob=None,loc=None):
410 411 """Create a new job from a string which can be fed to eval().
411 412
412 413 global/locals dicts can be provided, which will be passed to the eval
413 414 call."""
414 415
415 416 # fail immediately if the given expression can't be compiled
416 417 self.code = compile(expression,'<BackgroundJob compilation>','eval')
417 418
418 419 if glob is None:
419 420 glob = {}
420 421 if loc is None:
421 422 loc = {}
422 423
423 424 self.expression = self.strform = expression
424 425 self.glob = glob
425 426 self.loc = loc
426 427 self._init()
427 428
428 429 def call(self):
429 430 return eval(self.code,self.glob,self.loc)
430 431
431 432 class BackgroundJobFunc(BackgroundJobBase):
432 433 """Run a function call as a background job (uses a separate thread)."""
433 434
434 435 def __init__(self,func,*args,**kwargs):
435 436 """Create a new job from a callable object.
436 437
437 438 Any positional arguments and keyword args given to this constructor
438 439 after the initial callable are passed directly to it."""
439 440
440 441 assert callable(func),'first argument must be callable'
441 442
442 443 if args is None:
443 444 args = []
444 445 if kwargs is None:
445 446 kwargs = {}
446 447
447 448 self.func = func
448 449 self.args = args
449 450 self.kwargs = kwargs
450 451 # The string form will only include the function passed, because
451 452 # generating string representations of the arguments is a potentially
452 453 # _very_ expensive operation (e.g. with large arrays).
453 454 self.strform = str(func)
454 455 self._init()
455 456
456 457 def call(self):
457 458 return self.func(*self.args,**self.kwargs)
458 459
459 460
460 461 if __name__=='__main__':
461 462
462 463 import time
463 464
464 465 def sleepfunc(interval=2,*a,**kw):
465 466 args = dict(interval=interval,
466 467 args=a,
467 468 kwargs=kw)
468 469 time.sleep(interval)
469 470 return args
470 471
471 472 def diefunc(interval=2,*a,**kw):
472 473 time.sleep(interval)
473 474 die
474 475
475 476 def printfunc(interval=1,reps=5):
476 477 for n in range(reps):
477 478 time.sleep(interval)
478 479 print 'In the background...'
479 480
480 481 jobs = BackgroundJobManager()
481 482 # first job will have # 0
482 483 jobs.new(sleepfunc,4)
483 484 jobs.new(sleepfunc,kw={'reps':2})
484 485 # This makes a job which will die
485 486 jobs.new(diefunc,1)
486 487 jobs.new('printfunc(1,3)')
487 488
488 489 # after a while, you can get the traceback of a dead job. Run the line
489 490 # below again interactively until it prints a traceback (check the status
490 491 # of the job):
491 492 print jobs[1].status
492 493 jobs[1].traceback()
493 494
494 495 # Run this line again until the printed result changes
495 496 print "The result of job #0 is:",jobs[0].result
@@ -1,523 +1,523 b''
1 1 """Word completion for IPython.
2 2
3 3 This module is a fork of the rlcompleter module in the Python standard
4 4 library. The original enhancements made to rlcompleter have been sent
5 5 upstream and were accepted as of Python 2.3, but we need a lot more
6 6 functionality specific to IPython, so this module will continue to live as an
7 7 IPython-specific utility.
8 8
9 9 ---------------------------------------------------------------------------
10 10 Original rlcompleter documentation:
11 11
12 12 This requires the latest extension to the readline module (the
13 13 completes keywords, built-ins and globals in __main__; when completing
14 14 NAME.NAME..., it evaluates (!) the expression up to the last dot and
15 15 completes its attributes.
16 16
17 17 It's very cool to do "import string" type "string.", hit the
18 18 completion key (twice), and see the list of names defined by the
19 19 string module!
20 20
21 21 Tip: to use the tab key as the completion key, call
22 22
23 23 readline.parse_and_bind("tab: complete")
24 24
25 25 Notes:
26 26
27 27 - Exceptions raised by the completer function are *ignored* (and
28 28 generally cause the completion to fail). This is a feature -- since
29 29 readline sets the tty device in raw (or cbreak) mode, printing a
30 30 traceback wouldn't work well without some complicated hoopla to save,
31 31 reset and restore the tty state.
32 32
33 33 - The evaluation of the NAME.NAME... form may cause arbitrary
34 34 application defined code to be executed if an object with a
35 35 __getattr__ hook is found. Since it is the responsibility of the
36 36 application (or the user) to enable this feature, I consider this an
37 37 acceptable risk. More complicated expressions (e.g. function calls or
38 38 indexing operations) are *not* evaluated.
39 39
40 40 - GNU readline is also used by the built-in functions input() and
41 41 raw_input(), and thus these also benefit/suffer from the completer
42 42 features. Clearly an interactive application can benefit by
43 43 specifying its own completer function and using raw_input() for all
44 44 its input.
45 45
46 46 - When the original stdin is not a tty device, GNU readline is never
47 47 used, and this module (and the readline module) are silently inactive.
48 48
49 49 """
50 50
51 51 #*****************************************************************************
52 52 #
53 53 # Since this file is essentially a minimally modified copy of the rlcompleter
54 54 # module which is part of the standard Python distribution, I assume that the
55 55 # proper procedure is to maintain its copyright as belonging to the Python
56 56 # Software Foundation (in addition to my own, for all new code).
57 57 #
58 58 # Copyright (C) 2001 Python Software Foundation, www.python.org
59 59 # Copyright (C) 2001-2005 Fernando Perez. <fperez@colorado.edu>
60 60 #
61 61 # Distributed under the terms of the BSD License. The full license is in
62 62 # the file COPYING, distributed as part of this software.
63 63 #
64 64 #*****************************************************************************
65 65
66 66 import __builtin__
67 67 import __main__
68 68 import glob
69 69 import keyword
70 70 import os
71 71 import re
72 72 import readline
73 73 import sys
74 74 import types
75 75
76 76 from IPython.genutils import shlex_split
77 77
78 78 __all__ = ['Completer','IPCompleter']
79 79
80 def get_class_members(klass):
81 ret = dir(klass)
82 if hasattr(klass,'__bases__'):
83 for base in klass.__bases__:
80 def get_class_members(cls):
81 ret = dir(cls)
82 if hasattr(cls,'__bases__'):
83 for base in cls.__bases__:
84 84 ret.extend(get_class_members(base))
85 85 return ret
86 86
87 87 class Completer:
88 88 def __init__(self,namespace=None,global_namespace=None):
89 89 """Create a new completer for the command line.
90 90
91 91 Completer([namespace,global_namespace]) -> completer instance.
92 92
93 93 If unspecified, the default namespace where completions are performed
94 94 is __main__ (technically, __main__.__dict__). Namespaces should be
95 95 given as dictionaries.
96 96
97 97 An optional second namespace can be given. This allows the completer
98 98 to handle cases where both the local and global scopes need to be
99 99 distinguished.
100 100
101 101 Completer instances should be used as the completion mechanism of
102 102 readline via the set_completer() call:
103 103
104 104 readline.set_completer(Completer(my_namespace).complete)
105 105 """
106 106
107 107 if namespace and type(namespace) != types.DictType:
108 108 raise TypeError,'namespace must be a dictionary'
109 109
110 110 if global_namespace and type(global_namespace) != types.DictType:
111 111 raise TypeError,'global_namespace must be a dictionary'
112 112
113 113 # Don't bind to namespace quite yet, but flag whether the user wants a
114 114 # specific namespace or to use __main__.__dict__. This will allow us
115 115 # to bind to __main__.__dict__ at completion time, not now.
116 116 if namespace is None:
117 117 self.use_main_ns = 1
118 118 else:
119 119 self.use_main_ns = 0
120 120 self.namespace = namespace
121 121
122 122 # The global namespace, if given, can be bound directly
123 123 if global_namespace is None:
124 124 self.global_namespace = {}
125 125 else:
126 126 self.global_namespace = global_namespace
127 127
128 128 def complete(self, text, state):
129 129 """Return the next possible completion for 'text'.
130 130
131 131 This is called successively with state == 0, 1, 2, ... until it
132 132 returns None. The completion should begin with 'text'.
133 133
134 134 """
135 135 if self.use_main_ns:
136 136 self.namespace = __main__.__dict__
137 137
138 138 if state == 0:
139 139 if "." in text:
140 140 self.matches = self.attr_matches(text)
141 141 else:
142 142 self.matches = self.global_matches(text)
143 143 try:
144 144 return self.matches[state]
145 145 except IndexError:
146 146 return None
147 147
148 148 def global_matches(self, text):
149 149 """Compute matches when text is a simple name.
150 150
151 151 Return a list of all keywords, built-in functions and names currently
152 152 defined in self.namespace or self.global_namespace that match.
153 153
154 154 """
155 155 matches = []
156 156 match_append = matches.append
157 157 n = len(text)
158 158 for lst in [keyword.kwlist,
159 159 __builtin__.__dict__.keys(),
160 160 self.namespace.keys(),
161 161 self.global_namespace.keys()]:
162 162 for word in lst:
163 163 if word[:n] == text and word != "__builtins__":
164 164 match_append(word)
165 165 return matches
166 166
167 167 def attr_matches(self, text):
168 168 """Compute matches when text contains a dot.
169 169
170 170 Assuming the text is of the form NAME.NAME....[NAME], and is
171 171 evaluatable in self.namespace or self.global_namespace, it will be
172 172 evaluated and its attributes (as revealed by dir()) are used as
173 173 possible completions. (For class instances, class members are are
174 174 also considered.)
175 175
176 176 WARNING: this can still invoke arbitrary C code, if an object
177 177 with a __getattr__ hook is evaluated.
178 178
179 179 """
180 180 import re
181 181
182 182 # Another option, seems to work great. Catches things like ''.<tab>
183 183 m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text)
184 184
185 185 if not m:
186 186 return []
187 187 expr, attr = m.group(1, 3)
188 188 try:
189 189 object = eval(expr, self.namespace)
190 190 except:
191 191 object = eval(expr, self.global_namespace)
192 192 words = [w for w in dir(object) if isinstance(w, basestring)]
193 193 if hasattr(object,'__class__'):
194 194 words.append('__class__')
195 195 words.extend(get_class_members(object.__class__))
196 196 n = len(attr)
197 197 matches = []
198 198 for word in words:
199 199 if word[:n] == attr and word != "__builtins__":
200 200 matches.append("%s.%s" % (expr, word))
201 201 return matches
202 202
203 203 class IPCompleter(Completer):
204 204 """Extension of the completer class with IPython-specific features"""
205 205
206 206 def __init__(self,shell,namespace=None,global_namespace=None,
207 207 omit__names=0,alias_table=None):
208 208 """IPCompleter() -> completer
209 209
210 210 Return a completer object suitable for use by the readline library
211 211 via readline.set_completer().
212 212
213 213 Inputs:
214 214
215 215 - shell: a pointer to the ipython shell itself. This is needed
216 216 because this completer knows about magic functions, and those can
217 217 only be accessed via the ipython instance.
218 218
219 219 - namespace: an optional dict where completions are performed.
220 220
221 221 - global_namespace: secondary optional dict for completions, to
222 222 handle cases (such as IPython embedded inside functions) where
223 223 both Python scopes are visible.
224 224
225 225 - The optional omit__names parameter sets the completer to omit the
226 226 'magic' names (__magicname__) for python objects unless the text
227 227 to be completed explicitly starts with one or more underscores.
228 228
229 229 - If alias_table is supplied, it should be a dictionary of aliases
230 230 to complete. """
231 231
232 232 Completer.__init__(self,namespace,global_namespace)
233 233 self.magic_prefix = shell.name+'.magic_'
234 234 self.magic_escape = shell.ESC_MAGIC
235 235 self.readline = readline
236 236 delims = self.readline.get_completer_delims()
237 237 delims = delims.replace(self.magic_escape,'')
238 238 self.readline.set_completer_delims(delims)
239 239 self.get_line_buffer = self.readline.get_line_buffer
240 240 self.omit__names = omit__names
241 241 self.merge_completions = shell.rc.readline_merge_completions
242 242
243 243 if alias_table is None:
244 244 alias_table = {}
245 245 self.alias_table = alias_table
246 246 # Regexp to split filenames with spaces in them
247 247 self.space_name_re = re.compile(r'([^\\] )')
248 248 # Hold a local ref. to glob.glob for speed
249 249 self.glob = glob.glob
250 250 # Special handling of backslashes needed in win32 platforms
251 251 if sys.platform == "win32":
252 252 self.clean_glob = self._clean_glob_win32
253 253 else:
254 254 self.clean_glob = self._clean_glob
255 255 self.matchers = [self.python_matches,
256 256 self.file_matches,
257 257 self.alias_matches,
258 258 self.python_func_kw_matches]
259 259
260 260 # Code contributed by Alex Schmolck, for ipython/emacs integration
261 261 def all_completions(self, text):
262 262 """Return all possible completions for the benefit of emacs."""
263 263
264 264 completions = []
265 265 comp_append = completions.append
266 266 try:
267 267 for i in xrange(sys.maxint):
268 268 res = self.complete(text, i)
269 269
270 270 if not res: break
271 271
272 272 comp_append(res)
273 273 #XXX workaround for ``notDefined.<tab>``
274 274 except NameError:
275 275 pass
276 276 return completions
277 277 # /end Alex Schmolck code.
278 278
279 279 def _clean_glob(self,text):
280 280 return self.glob("%s*" % text)
281 281
282 282 def _clean_glob_win32(self,text):
283 283 return [f.replace("\\","/")
284 284 for f in self.glob("%s*" % text)]
285 285
286 286 def file_matches(self, text):
287 287 """Match filneames, expanding ~USER type strings.
288 288
289 289 Most of the seemingly convoluted logic in this completer is an
290 290 attempt to handle filenames with spaces in them. And yet it's not
291 291 quite perfect, because Python's readline doesn't expose all of the
292 292 GNU readline details needed for this to be done correctly.
293 293
294 294 For a filename with a space in it, the printed completions will be
295 295 only the parts after what's already been typed (instead of the
296 296 full completions, as is normally done). I don't think with the
297 297 current (as of Python 2.3) Python readline it's possible to do
298 298 better."""
299 299
300 300 #print 'Completer->file_matches: <%s>' % text # dbg
301 301
302 302 # chars that require escaping with backslash - i.e. chars
303 303 # that readline treats incorrectly as delimiters, but we
304 304 # don't want to treat as delimiters in filename matching
305 305 # when escaped with backslash
306 306
307 307 protectables = ' ()[]{}'
308 308
309 309 def protect_filename(s):
310 310 return "".join([(ch in protectables and '\\' + ch or ch)
311 311 for ch in s])
312 312
313 313 lbuf = self.get_line_buffer()[:self.readline.get_endidx()]
314 314 open_quotes = 0 # track strings with open quotes
315 315 try:
316 316 lsplit = shlex_split(lbuf)[-1]
317 317 except ValueError:
318 318 # typically an unmatched ", or backslash without escaped char.
319 319 if lbuf.count('"')==1:
320 320 open_quotes = 1
321 321 lsplit = lbuf.split('"')[-1]
322 322 elif lbuf.count("'")==1:
323 323 open_quotes = 1
324 324 lsplit = lbuf.split("'")[-1]
325 325 else:
326 326 return None
327 327 except IndexError:
328 328 # tab pressed on empty line
329 329 lsplit = ""
330 330
331 331 if lsplit != protect_filename(lsplit):
332 332 # if protectables are found, do matching on the whole escaped
333 333 # name
334 334 has_protectables = 1
335 335 text0,text = text,lsplit
336 336 else:
337 337 has_protectables = 0
338 338 text = os.path.expanduser(text)
339 339
340 340 if text == "":
341 341 return [protect_filename(f) for f in self.glob("*")]
342 342
343 343 m0 = self.clean_glob(text.replace('\\',''))
344 344 if has_protectables:
345 345 # If we had protectables, we need to revert our changes to the
346 346 # beginning of filename so that we don't double-write the part
347 347 # of the filename we have so far
348 348 len_lsplit = len(lsplit)
349 349 matches = [text0 + protect_filename(f[len_lsplit:]) for f in m0]
350 350 else:
351 351 if open_quotes:
352 352 # if we have a string with an open quote, we don't need to
353 353 # protect the names at all (and we _shouldn't_, as it
354 354 # would cause bugs when the filesystem call is made).
355 355 matches = m0
356 356 else:
357 357 matches = [protect_filename(f) for f in m0]
358 358 if len(matches) == 1 and os.path.isdir(matches[0]):
359 359 # Takes care of links to directories also. Use '/'
360 360 # explicitly, even under Windows, so that name completions
361 361 # don't end up escaped.
362 362 matches[0] += '/'
363 363 return matches
364 364
365 365 def alias_matches(self, text):
366 366 """Match internal system aliases"""
367 367 #print 'Completer->alias_matches:',text # dbg
368 368 text = os.path.expanduser(text)
369 369 aliases = self.alias_table.keys()
370 370 if text == "":
371 371 return aliases
372 372 else:
373 373 return [alias for alias in aliases if alias.startswith(text)]
374 374
375 375 def python_matches(self,text):
376 376 """Match attributes or global python names"""
377 377 #print 'Completer->python_matches' # dbg
378 378 if "." in text:
379 379 try:
380 380 matches = self.attr_matches(text)
381 381 if text.endswith('.') and self.omit__names:
382 382 if self.omit__names == 1:
383 383 # true if txt is _not_ a __ name, false otherwise:
384 384 no__name = (lambda txt:
385 385 re.match(r'.*\.__.*?__',txt) is None)
386 386 else:
387 387 # true if txt is _not_ a _ name, false otherwise:
388 388 no__name = (lambda txt:
389 389 re.match(r'.*\._.*?',txt) is None)
390 390 matches = filter(no__name, matches)
391 391 except NameError:
392 392 # catches <undefined attributes>.<tab>
393 393 matches = []
394 394 else:
395 395 matches = self.global_matches(text)
396 396 # this is so completion finds magics when automagic is on:
397 397 if matches == [] and not text.startswith(os.sep):
398 398 matches = self.attr_matches(self.magic_prefix+text)
399 399 return matches
400 400
401 401 def _default_arguments(self, obj):
402 402 """Return the list of default arguments of obj if it is callable,
403 403 or empty list otherwise."""
404 404
405 405 if not (inspect.isfunction(obj) or inspect.ismethod(obj)):
406 406 # for classes, check for __init__,__new__
407 407 if inspect.isclass(obj):
408 408 obj = (getattr(obj,'__init__',None) or
409 409 getattr(obj,'__new__',None))
410 410 # for all others, check if they are __call__able
411 411 elif hasattr(obj, '__call__'):
412 412 obj = obj.__call__
413 413 # XXX: is there a way to handle the builtins ?
414 414 try:
415 415 args,_,_1,defaults = inspect.getargspec(obj)
416 416 if defaults:
417 417 return args[-len(defaults):]
418 418 except TypeError: pass
419 419 return []
420 420
421 421 def python_func_kw_matches(self,text):
422 422 """Match named parameters (kwargs) of the last open function"""
423 423
424 424 if "." in text: # a parameter cannot be dotted
425 425 return []
426 426 try: regexp = self.__funcParamsRegex
427 427 except AttributeError:
428 428 regexp = self.__funcParamsRegex = re.compile(r'''
429 429 '.*?' | # single quoted strings or
430 430 ".*?" | # double quoted strings or
431 431 \w+ | # identifier
432 432 \S # other characters
433 433 ''', re.VERBOSE | re.DOTALL)
434 434 # 1. find the nearest identifier that comes before an unclosed
435 435 # parenthesis e.g. for "foo (1+bar(x), pa", the candidate is "foo"
436 436 tokens = regexp.findall(self.get_line_buffer())
437 437 tokens.reverse()
438 438 iterTokens = iter(tokens); openPar = 0
439 439 for token in iterTokens:
440 440 if token == ')':
441 441 openPar -= 1
442 442 elif token == '(':
443 443 openPar += 1
444 444 if openPar > 0:
445 445 # found the last unclosed parenthesis
446 446 break
447 447 else:
448 448 return []
449 449 # 2. Concatenate dotted names ("foo.bar" for "foo.bar(x, pa" )
450 450 ids = []
451 451 isId = re.compile(r'\w+$').match
452 452 while True:
453 453 try:
454 454 ids.append(iterTokens.next())
455 455 if not isId(ids[-1]):
456 456 ids.pop(); break
457 457 if not iterTokens.next() == '.':
458 458 break
459 459 except StopIteration:
460 460 break
461 461 # lookup the candidate callable matches either using global_matches
462 462 # or attr_matches for dotted names
463 463 if len(ids) == 1:
464 464 callableMatches = self.global_matches(ids[0])
465 465 else:
466 466 callableMatches = self.attr_matches('.'.join(ids[::-1]))
467 467 argMatches = []
468 468 for callableMatch in callableMatches:
469 469 try: namedArgs = self._default_arguments(eval(callableMatch,
470 470 self.namespace))
471 471 except: continue
472 472 for namedArg in namedArgs:
473 473 if namedArg.startswith(text):
474 474 argMatches.append("%s=" %namedArg)
475 475 return argMatches
476 476
477 477 def complete(self, text, state):
478 478 """Return the next possible completion for 'text'.
479 479
480 480 This is called successively with state == 0, 1, 2, ... until it
481 481 returns None. The completion should begin with 'text'. """
482 482
483 483 #print '\n*** COMPLETE: <%s> (%s)' % (text,state) # dbg
484 484
485 485 # if there is only a tab on a line with only whitespace, instead
486 486 # of the mostly useless 'do you want to see all million
487 487 # completions' message, just do the right thing and give the user
488 488 # his tab! Incidentally, this enables pasting of tabbed text from
489 489 # an editor (as long as autoindent is off).
490 490 if not self.get_line_buffer().strip():
491 491 self.readline.insert_text('\t')
492 492 return None
493 493
494 494 magic_escape = self.magic_escape
495 495 magic_prefix = self.magic_prefix
496 496
497 497 try:
498 498 if text.startswith(magic_escape):
499 499 text = text.replace(magic_escape,magic_prefix)
500 500 elif text.startswith('~'):
501 501 text = os.path.expanduser(text)
502 502 if state == 0:
503 503 # Extend the list of completions with the results of each
504 504 # matcher, so we return results to the user from all
505 505 # namespaces.
506 506 if self.merge_completions:
507 507 self.matches = []
508 508 for matcher in self.matchers:
509 509 self.matches.extend(matcher(text))
510 510 else:
511 511 for matcher in self.matchers:
512 512 self.matches = matcher(text)
513 513 if self.matches:
514 514 break
515 515
516 516 try:
517 517 return self.matches[state].replace(magic_prefix,magic_escape)
518 518 except IndexError:
519 519 return None
520 520 except:
521 521 #import traceback; traceback.print_exc() # dbg
522 522 # If completion fails, don't annoy the user.
523 523 return None
@@ -1,184 +1,186 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 A module to change reload() so that it acts recursively.
4 4 To enable it type:
5 5 >>> import __builtin__, deep_reload
6 6 >>> __builtin__.reload = deep_reload.reload
7 7 You can then disable it with:
8 8 >>> __builtin__.reload = deep_reload.original_reload
9 9
10 10 Alternatively, you can add a dreload builtin alongside normal reload with:
11 11 >>> __builtin__.dreload = deep_reload.reload
12 12
13 13 This code is almost entirely based on knee.py from the standard library.
14 14
15 $Id: deep_reload.py 410 2004-11-04 07:58:17Z fperez $"""
15 $Id: deep_reload.py 958 2005-12-27 23:17:51Z fperez $"""
16 16
17 17 #*****************************************************************************
18 18 # Copyright (C) 2001 Nathaniel Gray <n8gray@caltech.edu>
19 19 #
20 20 # Distributed under the terms of the BSD License. The full license is in
21 21 # the file COPYING, distributed as part of this software.
22 22 #*****************************************************************************
23 23
24 24 from IPython import Release # do it explicitly so pydoc can see it - pydoc bug
25 25 __author__ = '%s <%s>' % Release.authors['Nathan']
26 26 __license__ = Release.license
27 27 __version__ = "0.5"
28 28 __date__ = "21 August 2001"
29 29
30 import sys, imp, __builtin__
30 import __builtin__
31 import imp
32 import sys
31 33
32 34 # Replacement for __import__()
33 35 def deep_import_hook(name, globals=None, locals=None, fromlist=None):
34 36 parent = determine_parent(globals)
35 37 q, tail = find_head_package(parent, name)
36 38 m = load_tail(q, tail)
37 39 if not fromlist:
38 40 return q
39 41 if hasattr(m, "__path__"):
40 42 ensure_fromlist(m, fromlist)
41 43 return m
42 44
43 45 def determine_parent(globals):
44 46 if not globals or not globals.has_key("__name__"):
45 47 return None
46 48 pname = globals['__name__']
47 49 if globals.has_key("__path__"):
48 50 parent = sys.modules[pname]
49 51 assert globals is parent.__dict__
50 52 return parent
51 53 if '.' in pname:
52 54 i = pname.rfind('.')
53 55 pname = pname[:i]
54 56 parent = sys.modules[pname]
55 57 assert parent.__name__ == pname
56 58 return parent
57 59 return None
58 60
59 61 def find_head_package(parent, name):
60 62 # Import the first
61 63 if '.' in name:
62 64 # 'some.nested.package' -> head = 'some', tail = 'nested.package'
63 65 i = name.find('.')
64 66 head = name[:i]
65 67 tail = name[i+1:]
66 68 else:
67 69 # 'packagename' -> head = 'packagename', tail = ''
68 70 head = name
69 71 tail = ""
70 72 if parent:
71 73 # If this is a subpackage then qname = parent's name + head
72 74 qname = "%s.%s" % (parent.__name__, head)
73 75 else:
74 76 qname = head
75 77 q = import_module(head, qname, parent)
76 78 if q: return q, tail
77 79 if parent:
78 80 qname = head
79 81 parent = None
80 82 q = import_module(head, qname, parent)
81 83 if q: return q, tail
82 84 raise ImportError, "No module named " + qname
83 85
84 86 def load_tail(q, tail):
85 87 m = q
86 88 while tail:
87 89 i = tail.find('.')
88 90 if i < 0: i = len(tail)
89 91 head, tail = tail[:i], tail[i+1:]
90 92
91 93 # fperez: fix dotted.name reloading failures by changing:
92 94 #mname = "%s.%s" % (m.__name__, head)
93 95 # to:
94 96 mname = m.__name__
95 97 # This needs more testing!!! (I don't understand this module too well)
96 98
97 99 #print '** head,tail=|%s|->|%s|, mname=|%s|' % (head,tail,mname) # dbg
98 100 m = import_module(head, mname, m)
99 101 if not m:
100 102 raise ImportError, "No module named " + mname
101 103 return m
102 104
103 105 def ensure_fromlist(m, fromlist, recursive=0):
104 106 for sub in fromlist:
105 107 if sub == "*":
106 108 if not recursive:
107 109 try:
108 110 all = m.__all__
109 111 except AttributeError:
110 112 pass
111 113 else:
112 114 ensure_fromlist(m, all, 1)
113 115 continue
114 116 if sub != "*" and not hasattr(m, sub):
115 117 subname = "%s.%s" % (m.__name__, sub)
116 118 submod = import_module(sub, subname, m)
117 119 if not submod:
118 120 raise ImportError, "No module named " + subname
119 121
120 122 # Need to keep track of what we've already reloaded to prevent cyclic evil
121 123 found_now = {}
122 124
123 125 def import_module(partname, fqname, parent):
124 126 global found_now
125 127 if found_now.has_key(fqname):
126 128 try:
127 129 return sys.modules[fqname]
128 130 except KeyError:
129 131 pass
130 132
131 133 print 'Reloading', fqname #, sys.excepthook is sys.__excepthook__, \
132 134 #sys.displayhook is sys.__displayhook__
133 135
134 136 found_now[fqname] = 1
135 137 try:
136 138 fp, pathname, stuff = imp.find_module(partname,
137 139 parent and parent.__path__)
138 140 except ImportError:
139 141 return None
140 142
141 143 try:
142 144 m = imp.load_module(fqname, fp, pathname, stuff)
143 145 finally:
144 146 if fp: fp.close()
145 147
146 148 if parent:
147 149 setattr(parent, partname, m)
148 150
149 151 return m
150 152
151 153 def deep_reload_hook(module):
152 154 name = module.__name__
153 155 if '.' not in name:
154 156 return import_module(name, name, None)
155 157 i = name.rfind('.')
156 158 pname = name[:i]
157 159 parent = sys.modules[pname]
158 160 return import_module(name[i+1:], name, parent)
159 161
160 162 # Save the original hooks
161 163 original_reload = __builtin__.reload
162 164
163 165 # Replacement for reload()
164 166 def reload(module, exclude=['sys', '__builtin__', '__main__']):
165 167 """Recursively reload all modules used in the given module. Optionally
166 168 takes a list of modules to exclude from reloading. The default exclude
167 169 list contains sys, __main__, and __builtin__, to prevent, e.g., resetting
168 170 display, exception, and io hooks.
169 171 """
170 172 global found_now
171 173 for i in exclude:
172 174 found_now[i] = 1
173 175 original_import = __builtin__.__import__
174 176 __builtin__.__import__ = deep_import_hook
175 177 try:
176 178 ret = deep_reload_hook(module)
177 179 finally:
178 180 __builtin__.__import__ = original_import
179 181 found_now = {}
180 182 return ret
181 183
182 184 # Uncomment the following to automatically activate deep reloading whenever
183 185 # this module is imported
184 186 #__builtin__.reload = reload
@@ -1,309 +1,309 b''
1 1 """Module for interactive demos using IPython.
2 2
3 3 This module implements a single class, Demo, for running Python scripts
4 4 interactively in IPython for demonstrations. With very simple markup (a few
5 5 tags in comments), you can control points where the script stops executing and
6 6 returns control to IPython.
7 7
8 8 The file is run in its own empty namespace (though you can pass it a string of
9 9 arguments as if in a command line environment, and it will see those as
10 10 sys.argv). But at each stop, the global IPython namespace is updated with the
11 11 current internal demo namespace, so you can work interactively with the data
12 12 accumulated so far.
13 13
14 14 By default, each block of code is printed (with syntax highlighting) before
15 15 executing it and you have to confirm execution. This is intended to show the
16 16 code to an audience first so you can discuss it, and only proceed with
17 17 execution once you agree. There are a few tags which allow you to modify this
18 18 behavior.
19 19
20 20 The supported tags are:
21 21
22 22 # <demo> --- stop ---
23 23
24 24 Defines block boundaries, the points where IPython stops execution of the
25 25 file and returns to the interactive prompt.
26 26
27 27 # <demo> silent
28 28
29 29 Make a block execute silently (and hence automatically). Typically used in
30 30 cases where you have some boilerplate or initialization code which you need
31 31 executed but do not want to be seen in the demo.
32 32
33 33 # <demo> auto
34 34
35 35 Make a block execute automatically, but still being printed. Useful for
36 36 simple code which does not warrant discussion, since it avoids the extra
37 37 manual confirmation.
38 38
39 39 # <demo> auto_all
40 40
41 41 This tag can _only_ be in the first block, and if given it overrides the
42 42 individual auto tags to make the whole demo fully automatic (no block asks
43 43 for confirmation). It can also be given at creation time (or the attribute
44 44 set later) to override what's in the file.
45 45
46 46 While _any_ python file can be run as a Demo instance, if there are no stop
47 47 tags the whole file will run in a single block (no different that calling
48 48 first %pycat and then %run). The minimal markup to make this useful is to
49 49 place a set of stop tags; the other tags are only there to let you fine-tune
50 50 the execution.
51 51
52 52 This is probably best explained with the simple example file below. You can
53 53 copy this into a file named ex_demo.py, and try running it via:
54 54
55 55 from IPython.demo import Demo
56 56 d = Demo('ex_demo.py')
57 57 d() <--- Call the d object (omit the parens if you have autocall on).
58 58
59 59 Each time you call the demo object, it runs the next block. The demo object
60 60 has a few useful methods for navigation, like again(), jump(), seek() and
61 61 back(). It can be reset for a new run via reset() or reloaded from disk (in
62 62 case you've edited the source) via reload(). See their docstrings below.
63 63
64 64 #################### EXAMPLE DEMO <ex_demo.py> ###############################
65 65 '''A simple interactive demo to illustrate the use of IPython's Demo class.'''
66 66
67 67 print 'Hello, welcome to an interactive IPython demo.'
68 68
69 69 # The mark below defines a block boundary, which is a point where IPython will
70 70 # stop execution and return to the interactive prompt.
71 71 # Note that in actual interactive execution,
72 72 # <demo> --- stop ---
73 73
74 74 x = 1
75 75 y = 2
76 76
77 77 # <demo> --- stop ---
78 78
79 79 # the mark below makes this block as silent
80 80 # <demo> silent
81 81
82 82 print 'This is a silent block, which gets executed but not printed.'
83 83
84 84 # <demo> --- stop ---
85 85 # <demo> auto
86 86 print 'This is an automatic block.'
87 87 print 'It is executed without asking for confirmation, but printed.'
88 88 z = x+y
89 89
90 90 print 'z=',x
91 91
92 92 # <demo> --- stop ---
93 93 # This is just another normal block.
94 94 print 'z is now:', z
95 95
96 96 print 'bye!'
97 97 ################### END EXAMPLE DEMO <ex_demo.py> ############################
98 98
99 99 WARNING: this module uses Python 2.3 features, so it won't work in 2.2
100 100 environments.
101 101 """
102 102 #*****************************************************************************
103 103 # Copyright (C) 2005 Fernando Perez. <Fernando.Perez@colorado.edu>
104 104 #
105 105 # Distributed under the terms of the BSD License. The full license is in
106 106 # the file COPYING, distributed as part of this software.
107 107 #
108 108 #*****************************************************************************
109 109
110 import sys
111 110 import exceptions
112 111 import re
112 import sys
113 113
114 114 from IPython.PyColorize import Parser
115 115 from IPython.genutils import marquee, shlex_split, file_read
116 116
117 117 __all__ = ['Demo','DemoError']
118 118
119 119 class DemoError(exceptions.Exception): pass
120 120
121 121 def re_mark(mark):
122 122 return re.compile(r'^\s*#\s+<demo>\s+%s\s*$' % mark,re.MULTILINE)
123 123
124 124 class Demo:
125 125
126 126 re_stop = re_mark('---\s?stop\s?---')
127 127 re_silent = re_mark('silent')
128 128 re_auto = re_mark('auto')
129 129 re_auto_all = re_mark('auto_all')
130 130
131 131 def __init__(self,fname,arg_str='',auto_all=None):
132 132 """Make a new demo object. To run the demo, simply call the object.
133 133
134 134 See the module docstring for full details and an example (you can use
135 135 IPython.Demo? in IPython to see it).
136 136
137 137 Inputs:
138 138
139 139 - fname = filename.
140 140
141 141 Optional inputs:
142 142
143 143 - arg_str(''): a string of arguments, internally converted to a list
144 144 just like sys.argv, so the demo script can see a similar
145 145 environment.
146 146
147 147 - auto_all(None): global flag to run all blocks automatically without
148 148 confirmation. This attribute overrides the block-level tags and
149 149 applies to the whole demo. It is an attribute of the object, and
150 150 can be changed at runtime simply by reassigning it to a boolean
151 151 value.
152 152 """
153 153
154 154 self.fname = fname
155 155 self.sys_argv = [fname] + shlex_split(arg_str)
156 156 self.auto_all = auto_all
157 157
158 158 # get a few things from ipython. While it's a bit ugly design-wise,
159 159 # it ensures that things like color scheme and the like are always in
160 160 # sync with the ipython mode being used. This class is only meant to
161 161 # be used inside ipython anyways, so it's OK.
162 162 self.ip_showtb = __IPYTHON__.showtraceback
163 163 self.ip_ns = __IPYTHON__.user_ns
164 164 self.ip_colorize = __IPYTHON__.pycolorize
165 165
166 166 # load user data and initialize data structures
167 167 self.reload()
168 168
169 169 def reload(self):
170 170 """Reload source from disk and initialize state."""
171 171 # read data and parse into blocks
172 172 self.src = file_read(self.fname)
173 173 src_b = [b.strip() for b in self.re_stop.split(self.src) if b]
174 174 self._silent = [bool(self.re_silent.findall(b)) for b in src_b]
175 175 self._auto = [bool(self.re_auto.findall(b)) for b in src_b]
176 176
177 177 # if auto_all is not given (def. None), we read it from the file
178 178 if self.auto_all is None:
179 179 self.auto_all = bool(self.re_auto_all.findall(src_b[0]))
180 180 else:
181 181 self.auto_all = bool(self.auto_all)
182 182
183 183 # Clean the sources from all markup so it doesn't get displayed when
184 184 # running the demo
185 185 src_blocks = []
186 186 auto_strip = lambda s: self.re_auto.sub('',s)
187 187 for i,b in enumerate(src_b):
188 188 if self._auto[i]:
189 189 src_blocks.append(auto_strip(b))
190 190 else:
191 191 src_blocks.append(b)
192 192 # remove the auto_all marker
193 193 src_blocks[0] = self.re_auto_all.sub('',src_blocks[0])
194 194
195 195 self.nblocks = len(src_blocks)
196 196 self.src_blocks = src_blocks
197 197
198 198 # also build syntax-highlighted source
199 199 self.src_blocks_colored = map(self.ip_colorize,self.src_blocks)
200 200
201 201 # ensure clean namespace and seek offset
202 202 self.reset()
203 203
204 204 def reset(self):
205 205 """Reset the namespace and seek pointer to restart the demo"""
206 206 self.user_ns = {}
207 207 self.finished = False
208 208 self.block_index = 0
209 209
210 210 def _validate_index(self,index):
211 211 if index<0 or index>=self.nblocks:
212 212 raise ValueError('invalid block index %s' % index)
213 213
214 214 def seek(self,index):
215 215 """Move the current seek pointer to the given block"""
216 216 self._validate_index(index)
217 217 self.block_index = index
218 218 self.finished = False
219 219
220 220 def back(self,num=1):
221 221 """Move the seek pointer back num blocks (default is 1)."""
222 222 self.seek(self.block_index-num)
223 223
224 224 def jump(self,num):
225 225 """Jump a given number of blocks relative to the current one."""
226 226 self.seek(self.block_index+num)
227 227
228 228 def again(self):
229 229 """Move the seek pointer back one block and re-execute."""
230 230 self.back(1)
231 231 self()
232 232
233 233 def show(self,index=None):
234 234 """Show a single block on screen"""
235 235 if index is None:
236 236 if self.finished:
237 237 print 'Demo finished. Use reset() if you want to rerun it.'
238 238 return
239 239 index = self.block_index
240 240 else:
241 241 self._validate_index(index)
242 242 print marquee('<%s> block # %s (%s remaining)' %
243 243 (self.fname,index,self.nblocks-index-1))
244 244 print self.src_blocks_colored[index],
245 245
246 246 def show_all(self):
247 247 """Show entire demo on screen, block by block"""
248 248
249 249 fname = self.fname
250 250 nblocks = self.nblocks
251 251 silent = self._silent
252 252 for index,block in enumerate(self.src_blocks_colored):
253 253 if silent[index]:
254 254 print marquee('<%s> SILENT block # %s (%s remaining)' %
255 255 (fname,index,nblocks-index-1))
256 256 else:
257 257 print marquee('<%s> block # %s (%s remaining)' %
258 258 (fname,index,nblocks-index-1))
259 259 print block,
260 260
261 261 def __call__(self,index=None):
262 262 """run a block of the demo.
263 263
264 264 If index is given, it should be an integer >=1 and <= nblocks. This
265 265 means that the calling convention is one off from typical Python
266 266 lists. The reason for the inconsistency is that the demo always
267 267 prints 'Block n/N, and N is the total, so it would be very odd to use
268 268 zero-indexing here."""
269 269
270 270 if index is None and self.finished:
271 271 print 'Demo finished. Use reset() if you want to rerun it.'
272 272 return
273 273 if index is None:
274 274 index = self.block_index
275 275 self._validate_index(index)
276 276 try:
277 277 next_block = self.src_blocks[index]
278 278 self.block_index += 1
279 279 if self._silent[index]:
280 280 print marquee('Executing silent block # %s (%s remaining)' %
281 281 (index,self.nblocks-index-1))
282 282 else:
283 283 self.show(index)
284 284 if self.auto_all or self._auto[index]:
285 285 print marquee('output')
286 286 else:
287 287 print marquee('Press <q> to quit, <Enter> to execute...'),
288 288 ans = raw_input().strip()
289 289 if ans:
290 290 print marquee('Block NOT executed')
291 291 return
292 292 try:
293 293 save_argv = sys.argv
294 294 sys.argv = self.sys_argv
295 295 exec next_block in self.user_ns
296 296 finally:
297 297 sys.argv = save_argv
298 298
299 299 except:
300 300 self.ip_showtb(filename=self.fname)
301 301 else:
302 302 self.ip_ns.update(self.user_ns)
303 303
304 304 if self.block_index == self.nblocks:
305 305 print
306 306 print marquee(' END OF DEMO ')
307 307 print marquee('Use reset() if you want to rerun it.')
308 308 self.finished = True
309 309
@@ -1,1601 +1,1609 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 General purpose utilities.
4 4
5 5 This is a grab-bag of stuff I find useful in most programs I write. Some of
6 6 these things are also convenient when working at the command line.
7 7
8 $Id: genutils.py 908 2005-09-26 16:05:48Z fperez $"""
8 $Id: genutils.py 958 2005-12-27 23:17:51Z fperez $"""
9 9
10 10 #*****************************************************************************
11 11 # Copyright (C) 2001-2004 Fernando Perez. <fperez@colorado.edu>
12 12 #
13 13 # Distributed under the terms of the BSD License. The full license is in
14 14 # the file COPYING, distributed as part of this software.
15 15 #*****************************************************************************
16 16
17 17 from __future__ import generators # 2.2 compatibility
18 18
19 19 from IPython import Release
20 20 __author__ = '%s <%s>' % Release.authors['Fernando']
21 21 __license__ = Release.license
22 22
23 23 #****************************************************************************
24 # required modules
24 # required modules from the Python standard library
25 25 import __main__
26 import types,commands,time,sys,os,re,shutil
26 import commands
27 import os
28 import re
27 29 import shlex
30 import shutil
31 import sys
28 32 import tempfile
33 import time
34 import types
35
36 # Other IPython utilities
29 37 from IPython.Itpl import Itpl,itpl,printpl
30 38 from IPython import DPyGetOpt
31 39
32 40 # Build objects which appeared in Python 2.3 for 2.2, to make ipython
33 41 # 2.2-friendly
34 42 try:
35 43 basestring
36 44 except NameError:
37 45 import types
38 46 basestring = (types.StringType, types.UnicodeType)
39 47 True = 1==1
40 48 False = 1==0
41 49
42 50 def enumerate(obj):
43 51 i = -1
44 52 for item in obj:
45 53 i += 1
46 54 yield i, item
47 55
48 56 # add these to the builtin namespace, so that all modules find them
49 57 import __builtin__
50 58 __builtin__.basestring = basestring
51 59 __builtin__.True = True
52 60 __builtin__.False = False
53 61 __builtin__.enumerate = enumerate
54 62
55 63 # Try to use shlex.split for converting an input string into a sys.argv-type
56 64 # list. This appeared in Python 2.3, so here's a quick backport for 2.2.
57 65 try:
58 66 shlex_split = shlex.split
59 67 except AttributeError:
60 68 _quotesre = re.compile(r'[\'"](.*)[\'"]')
61 69 _wordchars = ('abcdfeghijklmnopqrstuvwxyz'
62 70 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-.~*?'
63 71 'ßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ'
64 72 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ%s'
65 73 % os.sep)
66 74
67 75 def shlex_split(s):
68 76 """Simplified backport to Python 2.2 of shlex.split().
69 77
70 78 This is a quick and dirty hack, since the shlex module under 2.2 lacks
71 79 several of the features needed to really match the functionality of
72 80 shlex.split() in 2.3."""
73 81
74 82 lex = shlex.shlex(StringIO(s))
75 83 # Try to get options, extensions and path separators as characters
76 84 lex.wordchars = _wordchars
77 85 lex.commenters = ''
78 86 # Make a list out of the lexer by hand, since in 2.2 it's not an
79 87 # iterator.
80 88 lout = []
81 89 while 1:
82 90 token = lex.get_token()
83 91 if token == '':
84 92 break
85 93 # Try to handle quoted tokens correctly
86 94 quotes = _quotesre.match(token)
87 95 if quotes:
88 96 token = quotes.group(1)
89 97 lout.append(token)
90 98 return lout
91 99
92 100 #****************************************************************************
93 101 # Exceptions
94 102 class Error(Exception):
95 103 """Base class for exceptions in this module."""
96 104 pass
97 105
98 106 #----------------------------------------------------------------------------
99 107 class IOStream:
100 108 def __init__(self,stream,fallback):
101 109 if not hasattr(stream,'write') or not hasattr(stream,'flush'):
102 110 stream = fallback
103 111 self.stream = stream
104 112 self._swrite = stream.write
105 113 self.flush = stream.flush
106 114
107 115 def write(self,data):
108 116 try:
109 117 self._swrite(data)
110 118 except:
111 119 try:
112 120 # print handles some unicode issues which may trip a plain
113 121 # write() call. Attempt to emulate write() by using a
114 122 # trailing comma
115 123 print >> self.stream, data,
116 124 except:
117 125 # if we get here, something is seriously broken.
118 126 print >> sys.stderr, \
119 127 'ERROR - failed to write data to stream:', stream
120 128
121 129 class IOTerm:
122 130 """ Term holds the file or file-like objects for handling I/O operations.
123 131
124 132 These are normally just sys.stdin, sys.stdout and sys.stderr but for
125 133 Windows they can can replaced to allow editing the strings before they are
126 134 displayed."""
127 135
128 136 # In the future, having IPython channel all its I/O operations through
129 137 # this class will make it easier to embed it into other environments which
130 138 # are not a normal terminal (such as a GUI-based shell)
131 139 def __init__(self,cin=None,cout=None,cerr=None):
132 140 self.cin = IOStream(cin,sys.stdin)
133 141 self.cout = IOStream(cout,sys.stdout)
134 142 self.cerr = IOStream(cerr,sys.stderr)
135 143
136 144 # Global variable to be used for all I/O
137 145 Term = IOTerm()
138 146
139 147 # Windows-specific code to load Gary Bishop's readline and configure it
140 148 # automatically for the users
141 149 # Note: os.name on cygwin returns posix, so this should only pick up 'native'
142 150 # windows. Cygwin returns 'cygwin' for sys.platform.
143 151 if os.name == 'nt':
144 152 try:
145 153 import readline
146 154 except ImportError:
147 155 pass
148 156 else:
149 157 try:
150 158 _out = readline.GetOutputFile()
151 159 except AttributeError:
152 160 pass
153 161 else:
154 162 # Remake Term to use the readline i/o facilities
155 163 Term = IOTerm(cout=_out,cerr=_out)
156 164 del _out
157 165
158 166 #****************************************************************************
159 167 # Generic warning/error printer, used by everything else
160 168 def warn(msg,level=2,exit_val=1):
161 169 """Standard warning printer. Gives formatting consistency.
162 170
163 171 Output is sent to Term.cerr (sys.stderr by default).
164 172
165 173 Options:
166 174
167 175 -level(2): allows finer control:
168 176 0 -> Do nothing, dummy function.
169 177 1 -> Print message.
170 178 2 -> Print 'WARNING:' + message. (Default level).
171 179 3 -> Print 'ERROR:' + message.
172 180 4 -> Print 'FATAL ERROR:' + message and trigger a sys.exit(exit_val).
173 181
174 182 -exit_val (1): exit value returned by sys.exit() for a level 4
175 183 warning. Ignored for all other levels."""
176 184
177 185 if level>0:
178 186 header = ['','','WARNING: ','ERROR: ','FATAL ERROR: ']
179 187 print >> Term.cerr, '%s%s' % (header[level],msg)
180 188 if level == 4:
181 189 print >> Term.cerr,'Exiting.\n'
182 190 sys.exit(exit_val)
183 191
184 192 def info(msg):
185 193 """Equivalent to warn(msg,level=1)."""
186 194
187 195 warn(msg,level=1)
188 196
189 197 def error(msg):
190 198 """Equivalent to warn(msg,level=3)."""
191 199
192 200 warn(msg,level=3)
193 201
194 202 def fatal(msg,exit_val=1):
195 203 """Equivalent to warn(msg,exit_val=exit_val,level=4)."""
196 204
197 205 warn(msg,exit_val=exit_val,level=4)
198 206
199 207 #----------------------------------------------------------------------------
200 208 StringTypes = types.StringTypes
201 209
202 210 # Basic timing functionality
203 211
204 212 # If possible (Unix), use the resource module instead of time.clock()
205 213 try:
206 214 import resource
207 215 def clock():
208 216 """clock() -> floating point number
209 217
210 218 Return the CPU time in seconds (user time only, system time is
211 219 ignored) since the start of the process. This is done via a call to
212 220 resource.getrusage, so it avoids the wraparound problems in
213 221 time.clock()."""
214 222
215 223 return resource.getrusage(resource.RUSAGE_SELF)[0]
216 224
217 225 def clock2():
218 226 """clock2() -> (t_user,t_system)
219 227
220 228 Similar to clock(), but return a tuple of user/system times."""
221 229 return resource.getrusage(resource.RUSAGE_SELF)[:2]
222 230
223 231 except ImportError:
224 232 clock = time.clock
225 233 def clock2():
226 234 """Under windows, system CPU time can't be measured.
227 235
228 236 This just returns clock() and zero."""
229 237 return time.clock(),0.0
230 238
231 239 def timings_out(reps,func,*args,**kw):
232 240 """timings_out(reps,func,*args,**kw) -> (t_total,t_per_call,output)
233 241
234 242 Execute a function reps times, return a tuple with the elapsed total
235 243 CPU time in seconds, the time per call and the function's output.
236 244
237 245 Under Unix, the return value is the sum of user+system time consumed by
238 246 the process, computed via the resource module. This prevents problems
239 247 related to the wraparound effect which the time.clock() function has.
240 248
241 249 Under Windows the return value is in wall clock seconds. See the
242 250 documentation for the time module for more details."""
243 251
244 252 reps = int(reps)
245 253 assert reps >=1, 'reps must be >= 1'
246 254 if reps==1:
247 255 start = clock()
248 256 out = func(*args,**kw)
249 257 tot_time = clock()-start
250 258 else:
251 259 rng = xrange(reps-1) # the last time is executed separately to store output
252 260 start = clock()
253 261 for dummy in rng: func(*args,**kw)
254 262 out = func(*args,**kw) # one last time
255 263 tot_time = clock()-start
256 264 av_time = tot_time / reps
257 265 return tot_time,av_time,out
258 266
259 267 def timings(reps,func,*args,**kw):
260 268 """timings(reps,func,*args,**kw) -> (t_total,t_per_call)
261 269
262 270 Execute a function reps times, return a tuple with the elapsed total CPU
263 271 time in seconds and the time per call. These are just the first two values
264 272 in timings_out()."""
265 273
266 274 return timings_out(reps,func,*args,**kw)[0:2]
267 275
268 276 def timing(func,*args,**kw):
269 277 """timing(func,*args,**kw) -> t_total
270 278
271 279 Execute a function once, return the elapsed total CPU time in
272 280 seconds. This is just the first value in timings_out()."""
273 281
274 282 return timings_out(1,func,*args,**kw)[0]
275 283
276 284 #****************************************************************************
277 285 # file and system
278 286
279 287 def system(cmd,verbose=0,debug=0,header=''):
280 288 """Execute a system command, return its exit status.
281 289
282 290 Options:
283 291
284 292 - verbose (0): print the command to be executed.
285 293
286 294 - debug (0): only print, do not actually execute.
287 295
288 296 - header (''): Header to print on screen prior to the executed command (it
289 297 is only prepended to the command, no newlines are added).
290 298
291 299 Note: a stateful version of this function is available through the
292 300 SystemExec class."""
293 301
294 302 stat = 0
295 303 if verbose or debug: print header+cmd
296 304 sys.stdout.flush()
297 305 if not debug: stat = os.system(cmd)
298 306 return stat
299 307
300 308 def shell(cmd,verbose=0,debug=0,header=''):
301 309 """Execute a command in the system shell, always return None.
302 310
303 311 Options:
304 312
305 313 - verbose (0): print the command to be executed.
306 314
307 315 - debug (0): only print, do not actually execute.
308 316
309 317 - header (''): Header to print on screen prior to the executed command (it
310 318 is only prepended to the command, no newlines are added).
311 319
312 320 Note: this is similar to genutils.system(), but it returns None so it can
313 321 be conveniently used in interactive loops without getting the return value
314 322 (typically 0) printed many times."""
315 323
316 324 stat = 0
317 325 if verbose or debug: print header+cmd
318 326 # flush stdout so we don't mangle python's buffering
319 327 sys.stdout.flush()
320 328 if not debug:
321 329 os.system(cmd)
322 330
323 331 def getoutput(cmd,verbose=0,debug=0,header='',split=0):
324 332 """Dummy substitute for perl's backquotes.
325 333
326 334 Executes a command and returns the output.
327 335
328 336 Accepts the same arguments as system(), plus:
329 337
330 338 - split(0): if true, the output is returned as a list split on newlines.
331 339
332 340 Note: a stateful version of this function is available through the
333 341 SystemExec class."""
334 342
335 343 if verbose or debug: print header+cmd
336 344 if not debug:
337 345 output = commands.getoutput(cmd)
338 346 if split:
339 347 return output.split('\n')
340 348 else:
341 349 return output
342 350
343 351 def getoutputerror(cmd,verbose=0,debug=0,header='',split=0):
344 352 """Return (standard output,standard error) of executing cmd in a shell.
345 353
346 354 Accepts the same arguments as system(), plus:
347 355
348 356 - split(0): if true, each of stdout/err is returned as a list split on
349 357 newlines.
350 358
351 359 Note: a stateful version of this function is available through the
352 360 SystemExec class."""
353 361
354 362 if verbose or debug: print header+cmd
355 363 if not cmd:
356 364 if split:
357 365 return [],[]
358 366 else:
359 367 return '',''
360 368 if not debug:
361 369 pin,pout,perr = os.popen3(cmd)
362 370 tout = pout.read().rstrip()
363 371 terr = perr.read().rstrip()
364 372 pin.close()
365 373 pout.close()
366 374 perr.close()
367 375 if split:
368 376 return tout.split('\n'),terr.split('\n')
369 377 else:
370 378 return tout,terr
371 379
372 380 # for compatibility with older naming conventions
373 381 xsys = system
374 382 bq = getoutput
375 383
376 384 class SystemExec:
377 385 """Access the system and getoutput functions through a stateful interface.
378 386
379 387 Note: here we refer to the system and getoutput functions from this
380 388 library, not the ones from the standard python library.
381 389
382 390 This class offers the system and getoutput functions as methods, but the
383 391 verbose, debug and header parameters can be set for the instance (at
384 392 creation time or later) so that they don't need to be specified on each
385 393 call.
386 394
387 395 For efficiency reasons, there's no way to override the parameters on a
388 396 per-call basis other than by setting instance attributes. If you need
389 397 local overrides, it's best to directly call system() or getoutput().
390 398
391 399 The following names are provided as alternate options:
392 400 - xsys: alias to system
393 401 - bq: alias to getoutput
394 402
395 403 An instance can then be created as:
396 404 >>> sysexec = SystemExec(verbose=1,debug=0,header='Calling: ')
397 405
398 406 And used as:
399 407 >>> sysexec.xsys('pwd')
400 408 >>> dirlist = sysexec.bq('ls -l')
401 409 """
402 410
403 411 def __init__(self,verbose=0,debug=0,header='',split=0):
404 412 """Specify the instance's values for verbose, debug and header."""
405 413 setattr_list(self,'verbose debug header split')
406 414
407 415 def system(self,cmd):
408 416 """Stateful interface to system(), with the same keyword parameters."""
409 417
410 418 system(cmd,self.verbose,self.debug,self.header)
411 419
412 420 def shell(self,cmd):
413 421 """Stateful interface to shell(), with the same keyword parameters."""
414 422
415 423 shell(cmd,self.verbose,self.debug,self.header)
416 424
417 425 xsys = system # alias
418 426
419 427 def getoutput(self,cmd):
420 428 """Stateful interface to getoutput()."""
421 429
422 430 return getoutput(cmd,self.verbose,self.debug,self.header,self.split)
423 431
424 432 def getoutputerror(self,cmd):
425 433 """Stateful interface to getoutputerror()."""
426 434
427 435 return getoutputerror(cmd,self.verbose,self.debug,self.header,self.split)
428 436
429 437 bq = getoutput # alias
430 438
431 439 #-----------------------------------------------------------------------------
432 440 def mutex_opts(dict,ex_op):
433 441 """Check for presence of mutually exclusive keys in a dict.
434 442
435 443 Call: mutex_opts(dict,[[op1a,op1b],[op2a,op2b]...]"""
436 444 for op1,op2 in ex_op:
437 445 if op1 in dict and op2 in dict:
438 446 raise ValueError,'\n*** ERROR in Arguments *** '\
439 447 'Options '+op1+' and '+op2+' are mutually exclusive.'
440 448
441 449 #-----------------------------------------------------------------------------
442 450 def get_py_filename(name):
443 451 """Return a valid python filename in the current directory.
444 452
445 453 If the given name is not a file, it adds '.py' and searches again.
446 454 Raises IOError with an informative message if the file isn't found."""
447 455
448 456 name = os.path.expanduser(name)
449 457 if not os.path.isfile(name) and not name.endswith('.py'):
450 458 name += '.py'
451 459 if os.path.isfile(name):
452 460 return name
453 461 else:
454 462 raise IOError,'File `%s` not found.' % name
455 463
456 464 #-----------------------------------------------------------------------------
457 465 def filefind(fname,alt_dirs = None):
458 466 """Return the given filename either in the current directory, if it
459 467 exists, or in a specified list of directories.
460 468
461 469 ~ expansion is done on all file and directory names.
462 470
463 471 Upon an unsuccessful search, raise an IOError exception."""
464 472
465 473 if alt_dirs is None:
466 474 try:
467 475 alt_dirs = get_home_dir()
468 476 except HomeDirError:
469 477 alt_dirs = os.getcwd()
470 478 search = [fname] + list_strings(alt_dirs)
471 479 search = map(os.path.expanduser,search)
472 480 #print 'search list for',fname,'list:',search # dbg
473 481 fname = search[0]
474 482 if os.path.isfile(fname):
475 483 return fname
476 484 for direc in search[1:]:
477 485 testname = os.path.join(direc,fname)
478 486 #print 'testname',testname # dbg
479 487 if os.path.isfile(testname):
480 488 return testname
481 489 raise IOError,'File' + `fname` + \
482 490 ' not found in current or supplied directories:' + `alt_dirs`
483 491
484 492 #----------------------------------------------------------------------------
485 493 def file_read(filename):
486 494 """Read a file and close it. Returns the file source."""
487 495 fobj=open(filename,'r');
488 496 source = fobj.read();
489 497 fobj.close()
490 498 return source
491 499
492 500 #----------------------------------------------------------------------------
493 501 def target_outdated(target,deps):
494 502 """Determine whether a target is out of date.
495 503
496 504 target_outdated(target,deps) -> 1/0
497 505
498 506 deps: list of filenames which MUST exist.
499 507 target: single filename which may or may not exist.
500 508
501 509 If target doesn't exist or is older than any file listed in deps, return
502 510 true, otherwise return false.
503 511 """
504 512 try:
505 513 target_time = os.path.getmtime(target)
506 514 except os.error:
507 515 return 1
508 516 for dep in deps:
509 517 dep_time = os.path.getmtime(dep)
510 518 if dep_time > target_time:
511 519 #print "For target",target,"Dep failed:",dep # dbg
512 520 #print "times (dep,tar):",dep_time,target_time # dbg
513 521 return 1
514 522 return 0
515 523
516 524 #-----------------------------------------------------------------------------
517 525 def target_update(target,deps,cmd):
518 526 """Update a target with a given command given a list of dependencies.
519 527
520 528 target_update(target,deps,cmd) -> runs cmd if target is outdated.
521 529
522 530 This is just a wrapper around target_outdated() which calls the given
523 531 command if target is outdated."""
524 532
525 533 if target_outdated(target,deps):
526 534 xsys(cmd)
527 535
528 536 #----------------------------------------------------------------------------
529 537 def unquote_ends(istr):
530 538 """Remove a single pair of quotes from the endpoints of a string."""
531 539
532 540 if not istr:
533 541 return istr
534 542 if (istr[0]=="'" and istr[-1]=="'") or \
535 543 (istr[0]=='"' and istr[-1]=='"'):
536 544 return istr[1:-1]
537 545 else:
538 546 return istr
539 547
540 548 #----------------------------------------------------------------------------
541 549 def process_cmdline(argv,names=[],defaults={},usage=''):
542 550 """ Process command-line options and arguments.
543 551
544 552 Arguments:
545 553
546 554 - argv: list of arguments, typically sys.argv.
547 555
548 556 - names: list of option names. See DPyGetOpt docs for details on options
549 557 syntax.
550 558
551 559 - defaults: dict of default values.
552 560
553 561 - usage: optional usage notice to print if a wrong argument is passed.
554 562
555 563 Return a dict of options and a list of free arguments."""
556 564
557 565 getopt = DPyGetOpt.DPyGetOpt()
558 566 getopt.setIgnoreCase(0)
559 567 getopt.parseConfiguration(names)
560 568
561 569 try:
562 570 getopt.processArguments(argv)
563 571 except:
564 572 print usage
565 573 warn(`sys.exc_value`,level=4)
566 574
567 575 defaults.update(getopt.optionValues)
568 576 args = getopt.freeValues
569 577
570 578 return defaults,args
571 579
572 580 #----------------------------------------------------------------------------
573 581 def optstr2types(ostr):
574 582 """Convert a string of option names to a dict of type mappings.
575 583
576 584 optstr2types(str) -> {None:'string_opts',int:'int_opts',float:'float_opts'}
577 585
578 586 This is used to get the types of all the options in a string formatted
579 587 with the conventions of DPyGetOpt. The 'type' None is used for options
580 588 which are strings (they need no further conversion). This function's main
581 589 use is to get a typemap for use with read_dict().
582 590 """
583 591
584 592 typeconv = {None:'',int:'',float:''}
585 593 typemap = {'s':None,'i':int,'f':float}
586 594 opt_re = re.compile(r'([\w]*)([^:=]*:?=?)([sif]?)')
587 595
588 596 for w in ostr.split():
589 597 oname,alias,otype = opt_re.match(w).groups()
590 598 if otype == '' or alias == '!': # simple switches are integers too
591 599 otype = 'i'
592 600 typeconv[typemap[otype]] += oname + ' '
593 601 return typeconv
594 602
595 603 #----------------------------------------------------------------------------
596 604 def read_dict(filename,type_conv=None,**opt):
597 605
598 606 """Read a dictionary of key=value pairs from an input file, optionally
599 607 performing conversions on the resulting values.
600 608
601 609 read_dict(filename,type_conv,**opt) -> dict
602 610
603 611 Only one value per line is accepted, the format should be
604 612 # optional comments are ignored
605 613 key value\n
606 614
607 615 Args:
608 616
609 617 - type_conv: A dictionary specifying which keys need to be converted to
610 618 which types. By default all keys are read as strings. This dictionary
611 619 should have as its keys valid conversion functions for strings
612 620 (int,long,float,complex, or your own). The value for each key
613 621 (converter) should be a whitespace separated string containing the names
614 622 of all the entries in the file to be converted using that function. For
615 623 keys to be left alone, use None as the conversion function (only needed
616 624 with purge=1, see below).
617 625
618 626 - opt: dictionary with extra options as below (default in parens)
619 627
620 628 purge(0): if set to 1, all keys *not* listed in type_conv are purged out
621 629 of the dictionary to be returned. If purge is going to be used, the
622 630 set of keys to be left as strings also has to be explicitly specified
623 631 using the (non-existent) conversion function None.
624 632
625 633 fs(None): field separator. This is the key/value separator to be used
626 634 when parsing the file. The None default means any whitespace [behavior
627 635 of string.split()].
628 636
629 637 strip(0): if 1, strip string values of leading/trailinig whitespace.
630 638
631 639 warn(1): warning level if requested keys are not found in file.
632 640 - 0: silently ignore.
633 641 - 1: inform but proceed.
634 642 - 2: raise KeyError exception.
635 643
636 644 no_empty(0): if 1, remove keys with whitespace strings as a value.
637 645
638 646 unique([]): list of keys (or space separated string) which can't be
639 647 repeated. If one such key is found in the file, each new instance
640 648 overwrites the previous one. For keys not listed here, the behavior is
641 649 to make a list of all appearances.
642 650
643 651 Example:
644 652 If the input file test.ini has:
645 653 i 3
646 654 x 4.5
647 655 y 5.5
648 656 s hi ho
649 657 Then:
650 658
651 659 >>> type_conv={int:'i',float:'x',None:'s'}
652 660 >>> read_dict('test.ini')
653 661 {'i': '3', 's': 'hi ho', 'x': '4.5', 'y': '5.5'}
654 662 >>> read_dict('test.ini',type_conv)
655 663 {'i': 3, 's': 'hi ho', 'x': 4.5, 'y': '5.5'}
656 664 >>> read_dict('test.ini',type_conv,purge=1)
657 665 {'i': 3, 's': 'hi ho', 'x': 4.5}
658 666 """
659 667
660 668 # starting config
661 669 opt.setdefault('purge',0)
662 670 opt.setdefault('fs',None) # field sep defaults to any whitespace
663 671 opt.setdefault('strip',0)
664 672 opt.setdefault('warn',1)
665 673 opt.setdefault('no_empty',0)
666 674 opt.setdefault('unique','')
667 675 if type(opt['unique']) in StringTypes:
668 676 unique_keys = qw(opt['unique'])
669 677 elif type(opt['unique']) in (types.TupleType,types.ListType):
670 678 unique_keys = opt['unique']
671 679 else:
672 680 raise ValueError, 'Unique keys must be given as a string, List or Tuple'
673 681
674 682 dict = {}
675 683 # first read in table of values as strings
676 684 file = open(filename,'r')
677 685 for line in file.readlines():
678 686 line = line.strip()
679 687 if len(line) and line[0]=='#': continue
680 688 if len(line)>0:
681 689 lsplit = line.split(opt['fs'],1)
682 690 try:
683 691 key,val = lsplit
684 692 except ValueError:
685 693 key,val = lsplit[0],''
686 694 key = key.strip()
687 695 if opt['strip']: val = val.strip()
688 696 if val == "''" or val == '""': val = ''
689 697 if opt['no_empty'] and (val=='' or val.isspace()):
690 698 continue
691 699 # if a key is found more than once in the file, build a list
692 700 # unless it's in the 'unique' list. In that case, last found in file
693 701 # takes precedence. User beware.
694 702 try:
695 703 if dict[key] and key in unique_keys:
696 704 dict[key] = val
697 705 elif type(dict[key]) is types.ListType:
698 706 dict[key].append(val)
699 707 else:
700 708 dict[key] = [dict[key],val]
701 709 except KeyError:
702 710 dict[key] = val
703 711 # purge if requested
704 712 if opt['purge']:
705 713 accepted_keys = qwflat(type_conv.values())
706 714 for key in dict.keys():
707 715 if key in accepted_keys: continue
708 716 del(dict[key])
709 717 # now convert if requested
710 718 if type_conv==None: return dict
711 719 conversions = type_conv.keys()
712 720 try: conversions.remove(None)
713 721 except: pass
714 722 for convert in conversions:
715 723 for val in qw(type_conv[convert]):
716 724 try:
717 725 dict[val] = convert(dict[val])
718 726 except KeyError,e:
719 727 if opt['warn'] == 0:
720 728 pass
721 729 elif opt['warn'] == 1:
722 730 print >>sys.stderr, 'Warning: key',val,\
723 731 'not found in file',filename
724 732 elif opt['warn'] == 2:
725 733 raise KeyError,e
726 734 else:
727 735 raise ValueError,'Warning level must be 0,1 or 2'
728 736
729 737 return dict
730 738
731 739 #----------------------------------------------------------------------------
732 740 def flag_calls(func):
733 741 """Wrap a function to detect and flag when it gets called.
734 742
735 743 This is a decorator which takes a function and wraps it in a function with
736 744 a 'called' attribute. wrapper.called is initialized to False.
737 745
738 746 The wrapper.called attribute is set to False right before each call to the
739 747 wrapped function, so if the call fails it remains False. After the call
740 748 completes, wrapper.called is set to True and the output is returned.
741 749
742 750 Testing for truth in wrapper.called allows you to determine if a call to
743 751 func() was attempted and succeeded."""
744 752
745 753 def wrapper(*args,**kw):
746 754 wrapper.called = False
747 755 out = func(*args,**kw)
748 756 wrapper.called = True
749 757 return out
750 758
751 759 wrapper.called = False
752 760 wrapper.__doc__ = func.__doc__
753 761 return wrapper
754 762
755 763 #----------------------------------------------------------------------------
756 764 class HomeDirError(Error):
757 765 pass
758 766
759 767 def get_home_dir():
760 768 """Return the closest possible equivalent to a 'home' directory.
761 769
762 770 We first try $HOME. Absent that, on NT it's $HOMEDRIVE\$HOMEPATH.
763 771
764 772 Currently only Posix and NT are implemented, a HomeDirError exception is
765 773 raised for all other OSes. """
766 774
767 775 isdir = os.path.isdir
768 776 env = os.environ
769 777 try:
770 778 homedir = env['HOME']
771 779 if not isdir(homedir):
772 780 # in case a user stuck some string which does NOT resolve to a
773 781 # valid path, it's as good as if we hadn't foud it
774 782 raise KeyError
775 783 return homedir
776 784 except KeyError:
777 785 if os.name == 'posix':
778 786 raise HomeDirError,'undefined $HOME, IPython can not proceed.'
779 787 elif os.name == 'nt':
780 788 # For some strange reason, win9x returns 'nt' for os.name.
781 789 try:
782 790 homedir = os.path.join(env['HOMEDRIVE'],env['HOMEPATH'])
783 791 if not isdir(homedir):
784 792 homedir = os.path.join(env['USERPROFILE'])
785 793 if not isdir(homedir):
786 794 raise HomeDirError
787 795 return homedir
788 796 except:
789 797 try:
790 798 # Use the registry to get the 'My Documents' folder.
791 799 import _winreg as wreg
792 800 key = wreg.OpenKey(wreg.HKEY_CURRENT_USER,
793 801 "Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders")
794 802 homedir = wreg.QueryValueEx(key,'Personal')[0]
795 803 key.Close()
796 804 if not isdir(homedir):
797 805 e = ('Invalid "Personal" folder registry key '
798 806 'typically "My Documents".\n'
799 807 'Value: %s\n'
800 808 'This is not a valid directory on your system.' %
801 809 homedir)
802 810 raise HomeDirError(e)
803 811 return homedir
804 812 except HomeDirError:
805 813 raise
806 814 except:
807 815 return 'C:\\'
808 816 elif os.name == 'dos':
809 817 # Desperate, may do absurd things in classic MacOS. May work under DOS.
810 818 return 'C:\\'
811 819 else:
812 820 raise HomeDirError,'support for your operating system not implemented.'
813 821
814 822 #****************************************************************************
815 823 # strings and text
816 824
817 825 class LSString(str):
818 826 """String derivative with a special access attributes.
819 827
820 828 These are normal strings, but with the special attributes:
821 829
822 830 .l (or .list) : value as list (split on newlines).
823 831 .n (or .nlstr): original value (the string itself).
824 832 .s (or .spstr): value as whitespace-separated string.
825 833
826 834 Any values which require transformations are computed only once and
827 835 cached.
828 836
829 837 Such strings are very useful to efficiently interact with the shell, which
830 838 typically only understands whitespace-separated options for commands."""
831 839
832 840 def get_list(self):
833 841 try:
834 842 return self.__list
835 843 except AttributeError:
836 844 self.__list = self.split('\n')
837 845 return self.__list
838 846
839 847 l = list = property(get_list)
840 848
841 849 def get_spstr(self):
842 850 try:
843 851 return self.__spstr
844 852 except AttributeError:
845 853 self.__spstr = self.replace('\n',' ')
846 854 return self.__spstr
847 855
848 856 s = spstr = property(get_spstr)
849 857
850 858 def get_nlstr(self):
851 859 return self
852 860
853 861 n = nlstr = property(get_nlstr)
854 862
855 863 class SList(list):
856 864 """List derivative with a special access attributes.
857 865
858 866 These are normal lists, but with the special attributes:
859 867
860 868 .l (or .list) : value as list (the list itself).
861 869 .n (or .nlstr): value as a string, joined on newlines.
862 870 .s (or .spstr): value as a string, joined on spaces.
863 871
864 872 Any values which require transformations are computed only once and
865 873 cached."""
866 874
867 875 def get_list(self):
868 876 return self
869 877
870 878 l = list = property(get_list)
871 879
872 880 def get_spstr(self):
873 881 try:
874 882 return self.__spstr
875 883 except AttributeError:
876 884 self.__spstr = ' '.join(self)
877 885 return self.__spstr
878 886
879 887 s = spstr = property(get_spstr)
880 888
881 889 def get_nlstr(self):
882 890 try:
883 891 return self.__nlstr
884 892 except AttributeError:
885 893 self.__nlstr = '\n'.join(self)
886 894 return self.__nlstr
887 895
888 896 n = nlstr = property(get_nlstr)
889 897
890 898 def raw_input_multi(header='', ps1='==> ', ps2='..> ',terminate_str = '.'):
891 899 """Take multiple lines of input.
892 900
893 901 A list with each line of input as a separate element is returned when a
894 902 termination string is entered (defaults to a single '.'). Input can also
895 903 terminate via EOF (^D in Unix, ^Z-RET in Windows).
896 904
897 905 Lines of input which end in \\ are joined into single entries (and a
898 906 secondary continuation prompt is issued as long as the user terminates
899 907 lines with \\). This allows entering very long strings which are still
900 908 meant to be treated as single entities.
901 909 """
902 910
903 911 try:
904 912 if header:
905 913 header += '\n'
906 914 lines = [raw_input(header + ps1)]
907 915 except EOFError:
908 916 return []
909 917 terminate = [terminate_str]
910 918 try:
911 919 while lines[-1:] != terminate:
912 920 new_line = raw_input(ps1)
913 921 while new_line.endswith('\\'):
914 922 new_line = new_line[:-1] + raw_input(ps2)
915 923 lines.append(new_line)
916 924
917 925 return lines[:-1] # don't return the termination command
918 926 except EOFError:
919 927 print
920 928 return lines
921 929
922 930 #----------------------------------------------------------------------------
923 931 def raw_input_ext(prompt='', ps2='... '):
924 932 """Similar to raw_input(), but accepts extended lines if input ends with \\."""
925 933
926 934 line = raw_input(prompt)
927 935 while line.endswith('\\'):
928 936 line = line[:-1] + raw_input(ps2)
929 937 return line
930 938
931 939 #----------------------------------------------------------------------------
932 940 def ask_yes_no(prompt,default=None):
933 941 """Asks a question and returns an integer 1/0 (y/n) answer.
934 942
935 943 If default is given (one of 'y','n'), it is used if the user input is
936 944 empty. Otherwise the question is repeated until an answer is given.
937 945 If EOF occurs 20 times consecutively, the default answer is assumed,
938 946 or if there is no default, an exception is raised to prevent infinite
939 947 loops.
940 948
941 949 Valid answers are: y/yes/n/no (match is not case sensitive)."""
942 950
943 951 answers = {'y':1,'n':0,'yes':1,'no':0}
944 952 ans = None
945 953 eofs, max_eofs = 0, 20
946 954 while ans not in answers.keys():
947 955 try:
948 956 ans = raw_input(prompt+' ').lower()
949 957 if not ans: # response was an empty string
950 958 ans = default
951 959 eofs = 0
952 960 except (EOFError,KeyboardInterrupt):
953 961 eofs = eofs + 1
954 962 if eofs >= max_eofs:
955 963 if default in answers.keys():
956 964 ans = default
957 965 else:
958 966 raise
959 967
960 968 return answers[ans]
961 969
962 970 #----------------------------------------------------------------------------
963 971 def marquee(txt='',width=78,mark='*'):
964 972 """Return the input string centered in a 'marquee'."""
965 973 if not txt:
966 974 return (mark*width)[:width]
967 975 nmark = (width-len(txt)-2)/len(mark)/2
968 976 if nmark < 0: nmark =0
969 977 marks = mark*nmark
970 978 return '%s %s %s' % (marks,txt,marks)
971 979
972 980 #----------------------------------------------------------------------------
973 981 class EvalDict:
974 982 """
975 983 Emulate a dict which evaluates its contents in the caller's frame.
976 984
977 985 Usage:
978 986 >>>number = 19
979 987 >>>text = "python"
980 988 >>>print "%(text.capitalize())s %(number/9.0).1f rules!" % EvalDict()
981 989 """
982 990
983 991 # This version is due to sismex01@hebmex.com on c.l.py, and is basically a
984 992 # modified (shorter) version of:
985 993 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66018 by
986 994 # Skip Montanaro (skip@pobox.com).
987 995
988 996 def __getitem__(self, name):
989 997 frame = sys._getframe(1)
990 998 return eval(name, frame.f_globals, frame.f_locals)
991 999
992 1000 EvalString = EvalDict # for backwards compatibility
993 1001 #----------------------------------------------------------------------------
994 1002 def qw(words,flat=0,sep=None,maxsplit=-1):
995 1003 """Similar to Perl's qw() operator, but with some more options.
996 1004
997 1005 qw(words,flat=0,sep=' ',maxsplit=-1) -> words.split(sep,maxsplit)
998 1006
999 1007 words can also be a list itself, and with flat=1, the output will be
1000 1008 recursively flattened. Examples:
1001 1009
1002 1010 >>> qw('1 2')
1003 1011 ['1', '2']
1004 1012 >>> qw(['a b','1 2',['m n','p q']])
1005 1013 [['a', 'b'], ['1', '2'], [['m', 'n'], ['p', 'q']]]
1006 1014 >>> qw(['a b','1 2',['m n','p q']],flat=1)
1007 1015 ['a', 'b', '1', '2', 'm', 'n', 'p', 'q'] """
1008 1016
1009 1017 if type(words) in StringTypes:
1010 1018 return [word.strip() for word in words.split(sep,maxsplit)
1011 1019 if word and not word.isspace() ]
1012 1020 if flat:
1013 1021 return flatten(map(qw,words,[1]*len(words)))
1014 1022 return map(qw,words)
1015 1023
1016 1024 #----------------------------------------------------------------------------
1017 1025 def qwflat(words,sep=None,maxsplit=-1):
1018 1026 """Calls qw(words) in flat mode. It's just a convenient shorthand."""
1019 1027 return qw(words,1,sep,maxsplit)
1020 1028
1021 1029 #-----------------------------------------------------------------------------
1022 1030 def list_strings(arg):
1023 1031 """Always return a list of strings, given a string or list of strings
1024 1032 as input."""
1025 1033
1026 1034 if type(arg) in StringTypes: return [arg]
1027 1035 else: return arg
1028 1036
1029 1037 #----------------------------------------------------------------------------
1030 1038 def grep(pat,list,case=1):
1031 1039 """Simple minded grep-like function.
1032 1040 grep(pat,list) returns occurrences of pat in list, None on failure.
1033 1041
1034 1042 It only does simple string matching, with no support for regexps. Use the
1035 1043 option case=0 for case-insensitive matching."""
1036 1044
1037 1045 # This is pretty crude. At least it should implement copying only references
1038 1046 # to the original data in case it's big. Now it copies the data for output.
1039 1047 out=[]
1040 1048 if case:
1041 1049 for term in list:
1042 1050 if term.find(pat)>-1: out.append(term)
1043 1051 else:
1044 1052 lpat=pat.lower()
1045 1053 for term in list:
1046 1054 if term.lower().find(lpat)>-1: out.append(term)
1047 1055
1048 1056 if len(out): return out
1049 1057 else: return None
1050 1058
1051 1059 #----------------------------------------------------------------------------
1052 1060 def dgrep(pat,*opts):
1053 1061 """Return grep() on dir()+dir(__builtins__).
1054 1062
1055 1063 A very common use of grep() when working interactively."""
1056 1064
1057 1065 return grep(pat,dir(__main__)+dir(__main__.__builtins__),*opts)
1058 1066
1059 1067 #----------------------------------------------------------------------------
1060 1068 def idgrep(pat):
1061 1069 """Case-insensitive dgrep()"""
1062 1070
1063 1071 return dgrep(pat,0)
1064 1072
1065 1073 #----------------------------------------------------------------------------
1066 1074 def igrep(pat,list):
1067 1075 """Synonym for case-insensitive grep."""
1068 1076
1069 1077 return grep(pat,list,case=0)
1070 1078
1071 1079 #----------------------------------------------------------------------------
1072 1080 def indent(str,nspaces=4,ntabs=0):
1073 1081 """Indent a string a given number of spaces or tabstops.
1074 1082
1075 1083 indent(str,nspaces=4,ntabs=0) -> indent str by ntabs+nspaces.
1076 1084 """
1077 1085 if str is None:
1078 1086 return
1079 1087 ind = '\t'*ntabs+' '*nspaces
1080 1088 outstr = '%s%s' % (ind,str.replace(os.linesep,os.linesep+ind))
1081 1089 if outstr.endswith(os.linesep+ind):
1082 1090 return outstr[:-len(ind)]
1083 1091 else:
1084 1092 return outstr
1085 1093
1086 1094 #-----------------------------------------------------------------------------
1087 1095 def native_line_ends(filename,backup=1):
1088 1096 """Convert (in-place) a file to line-ends native to the current OS.
1089 1097
1090 1098 If the optional backup argument is given as false, no backup of the
1091 1099 original file is left. """
1092 1100
1093 1101 backup_suffixes = {'posix':'~','dos':'.bak','nt':'.bak','mac':'.bak'}
1094 1102
1095 1103 bak_filename = filename + backup_suffixes[os.name]
1096 1104
1097 1105 original = open(filename).read()
1098 1106 shutil.copy2(filename,bak_filename)
1099 1107 try:
1100 1108 new = open(filename,'wb')
1101 1109 new.write(os.linesep.join(original.splitlines()))
1102 1110 new.write(os.linesep) # ALWAYS put an eol at the end of the file
1103 1111 new.close()
1104 1112 except:
1105 1113 os.rename(bak_filename,filename)
1106 1114 if not backup:
1107 1115 try:
1108 1116 os.remove(bak_filename)
1109 1117 except:
1110 1118 pass
1111 1119
1112 1120 #----------------------------------------------------------------------------
1113 1121 def get_pager_cmd(pager_cmd = None):
1114 1122 """Return a pager command.
1115 1123
1116 1124 Makes some attempts at finding an OS-correct one."""
1117 1125
1118 1126 if os.name == 'posix':
1119 1127 default_pager_cmd = 'less -r' # -r for color control sequences
1120 1128 elif os.name in ['nt','dos']:
1121 1129 default_pager_cmd = 'type'
1122 1130
1123 1131 if pager_cmd is None:
1124 1132 try:
1125 1133 pager_cmd = os.environ['PAGER']
1126 1134 except:
1127 1135 pager_cmd = default_pager_cmd
1128 1136 return pager_cmd
1129 1137
1130 1138 #-----------------------------------------------------------------------------
1131 1139 def get_pager_start(pager,start):
1132 1140 """Return the string for paging files with an offset.
1133 1141
1134 1142 This is the '+N' argument which less and more (under Unix) accept.
1135 1143 """
1136 1144
1137 1145 if pager in ['less','more']:
1138 1146 if start:
1139 1147 start_string = '+' + str(start)
1140 1148 else:
1141 1149 start_string = ''
1142 1150 else:
1143 1151 start_string = ''
1144 1152 return start_string
1145 1153
1146 1154 #----------------------------------------------------------------------------
1147 1155 def page_dumb(strng,start=0,screen_lines=25):
1148 1156 """Very dumb 'pager' in Python, for when nothing else works.
1149 1157
1150 1158 Only moves forward, same interface as page(), except for pager_cmd and
1151 1159 mode."""
1152 1160
1153 1161 out_ln = strng.splitlines()[start:]
1154 1162 screens = chop(out_ln,screen_lines-1)
1155 1163 if len(screens) == 1:
1156 1164 print >>Term.cout, os.linesep.join(screens[0])
1157 1165 else:
1158 1166 for scr in screens[0:-1]:
1159 1167 print >>Term.cout, os.linesep.join(scr)
1160 1168 ans = raw_input('---Return to continue, q to quit--- ')
1161 1169 if ans.lower().startswith('q'):
1162 1170 return
1163 1171 print >>Term.cout, os.linesep.join(screens[-1])
1164 1172
1165 1173 #----------------------------------------------------------------------------
1166 1174 def page(strng,start=0,screen_lines=0,pager_cmd = None):
1167 1175 """Print a string, piping through a pager after a certain length.
1168 1176
1169 1177 The screen_lines parameter specifies the number of *usable* lines of your
1170 1178 terminal screen (total lines minus lines you need to reserve to show other
1171 1179 information).
1172 1180
1173 1181 If you set screen_lines to a number <=0, page() will try to auto-determine
1174 1182 your screen size and will only use up to (screen_size+screen_lines) for
1175 1183 printing, paging after that. That is, if you want auto-detection but need
1176 1184 to reserve the bottom 3 lines of the screen, use screen_lines = -3, and for
1177 1185 auto-detection without any lines reserved simply use screen_lines = 0.
1178 1186
1179 1187 If a string won't fit in the allowed lines, it is sent through the
1180 1188 specified pager command. If none given, look for PAGER in the environment,
1181 1189 and ultimately default to less.
1182 1190
1183 1191 If no system pager works, the string is sent through a 'dumb pager'
1184 1192 written in python, very simplistic.
1185 1193 """
1186 1194
1187 1195 # Ugly kludge, but calling curses.initscr() flat out crashes in emacs
1188 1196 TERM = os.environ.get('TERM','dumb')
1189 1197 if TERM in ['dumb','emacs'] and os.name != 'nt':
1190 1198 print strng
1191 1199 return
1192 1200 # chop off the topmost part of the string we don't want to see
1193 1201 str_lines = strng.split(os.linesep)[start:]
1194 1202 str_toprint = os.linesep.join(str_lines)
1195 1203 num_newlines = len(str_lines)
1196 1204 len_str = len(str_toprint)
1197 1205
1198 1206 # Dumb heuristics to guesstimate number of on-screen lines the string
1199 1207 # takes. Very basic, but good enough for docstrings in reasonable
1200 1208 # terminals. If someone later feels like refining it, it's not hard.
1201 1209 numlines = max(num_newlines,int(len_str/80)+1)
1202 1210
1203 1211 screen_lines_def = 25 # default value if we can't auto-determine
1204 1212
1205 1213 # auto-determine screen size
1206 1214 if screen_lines <= 0:
1207 1215 if TERM=='xterm':
1208 1216 try:
1209 1217 import curses
1210 1218 if hasattr(curses,'initscr'):
1211 1219 use_curses = 1
1212 1220 else:
1213 1221 use_curses = 0
1214 1222 except ImportError:
1215 1223 use_curses = 0
1216 1224 else:
1217 1225 # curses causes problems on many terminals other than xterm.
1218 1226 use_curses = 0
1219 1227 if use_curses:
1220 1228 scr = curses.initscr()
1221 1229 screen_lines_real,screen_cols = scr.getmaxyx()
1222 1230 curses.endwin()
1223 1231 screen_lines += screen_lines_real
1224 1232 #print '***Screen size:',screen_lines_real,'lines x',\
1225 1233 #screen_cols,'columns.' # dbg
1226 1234 else:
1227 1235 screen_lines += screen_lines_def
1228 1236
1229 1237 #print 'numlines',numlines,'screenlines',screen_lines # dbg
1230 1238 if numlines <= screen_lines :
1231 1239 #print '*** normal print' # dbg
1232 1240 print >>Term.cout, str_toprint
1233 1241 else:
1234 1242 # Try to open pager and default to internal one if that fails.
1235 1243 # All failure modes are tagged as 'retval=1', to match the return
1236 1244 # value of a failed system command. If any intermediate attempt
1237 1245 # sets retval to 1, at the end we resort to our own page_dumb() pager.
1238 1246 pager_cmd = get_pager_cmd(pager_cmd)
1239 1247 pager_cmd += ' ' + get_pager_start(pager_cmd,start)
1240 1248 if os.name == 'nt':
1241 1249 if pager_cmd.startswith('type'):
1242 1250 # The default WinXP 'type' command is failing on complex strings.
1243 1251 retval = 1
1244 1252 else:
1245 1253 tmpname = tempfile.mktemp('.txt')
1246 1254 tmpfile = file(tmpname,'wt')
1247 1255 tmpfile.write(strng)
1248 1256 tmpfile.close()
1249 1257 cmd = "%s < %s" % (pager_cmd,tmpname)
1250 1258 if os.system(cmd):
1251 1259 retval = 1
1252 1260 else:
1253 1261 retval = None
1254 1262 os.remove(tmpname)
1255 1263 else:
1256 1264 try:
1257 1265 retval = None
1258 1266 # if I use popen4, things hang. No idea why.
1259 1267 #pager,shell_out = os.popen4(pager_cmd)
1260 1268 pager = os.popen(pager_cmd,'w')
1261 1269 pager.write(strng)
1262 1270 pager.close()
1263 1271 retval = pager.close() # success returns None
1264 1272 except IOError,msg: # broken pipe when user quits
1265 1273 if msg.args == (32,'Broken pipe'):
1266 1274 retval = None
1267 1275 else:
1268 1276 retval = 1
1269 1277 except OSError:
1270 1278 # Other strange problems, sometimes seen in Win2k/cygwin
1271 1279 retval = 1
1272 1280 if retval is not None:
1273 1281 page_dumb(strng,screen_lines=screen_lines)
1274 1282
1275 1283 #----------------------------------------------------------------------------
1276 1284 def page_file(fname,start = 0, pager_cmd = None):
1277 1285 """Page a file, using an optional pager command and starting line.
1278 1286 """
1279 1287
1280 1288 pager_cmd = get_pager_cmd(pager_cmd)
1281 1289 pager_cmd += ' ' + get_pager_start(pager_cmd,start)
1282 1290
1283 1291 try:
1284 1292 if os.environ['TERM'] in ['emacs','dumb']:
1285 1293 raise EnvironmentError
1286 1294 xsys(pager_cmd + ' ' + fname)
1287 1295 except:
1288 1296 try:
1289 1297 if start > 0:
1290 1298 start -= 1
1291 1299 page(open(fname).read(),start)
1292 1300 except:
1293 1301 print 'Unable to show file',`fname`
1294 1302
1295 1303 #----------------------------------------------------------------------------
1296 1304 def snip_print(str,width = 75,print_full = 0,header = ''):
1297 1305 """Print a string snipping the midsection to fit in width.
1298 1306
1299 1307 print_full: mode control:
1300 1308 - 0: only snip long strings
1301 1309 - 1: send to page() directly.
1302 1310 - 2: snip long strings and ask for full length viewing with page()
1303 1311 Return 1 if snipping was necessary, 0 otherwise."""
1304 1312
1305 1313 if print_full == 1:
1306 1314 page(header+str)
1307 1315 return 0
1308 1316
1309 1317 print header,
1310 1318 if len(str) < width:
1311 1319 print str
1312 1320 snip = 0
1313 1321 else:
1314 1322 whalf = int((width -5)/2)
1315 1323 print str[:whalf] + ' <...> ' + str[-whalf:]
1316 1324 snip = 1
1317 1325 if snip and print_full == 2:
1318 1326 if raw_input(header+' Snipped. View (y/n)? [N]').lower() == 'y':
1319 1327 page(str)
1320 1328 return snip
1321 1329
1322 1330 #****************************************************************************
1323 1331 # lists, dicts and structures
1324 1332
1325 1333 def belong(candidates,checklist):
1326 1334 """Check whether a list of items appear in a given list of options.
1327 1335
1328 1336 Returns a list of 1 and 0, one for each candidate given."""
1329 1337
1330 1338 return [x in checklist for x in candidates]
1331 1339
1332 1340 #----------------------------------------------------------------------------
1333 1341 def uniq_stable(elems):
1334 1342 """uniq_stable(elems) -> list
1335 1343
1336 1344 Return from an iterable, a list of all the unique elements in the input,
1337 1345 but maintaining the order in which they first appear.
1338 1346
1339 1347 A naive solution to this problem which just makes a dictionary with the
1340 1348 elements as keys fails to respect the stability condition, since
1341 1349 dictionaries are unsorted by nature.
1342 1350
1343 1351 Note: All elements in the input must be valid dictionary keys for this
1344 1352 routine to work, as it internally uses a dictionary for efficiency
1345 1353 reasons."""
1346 1354
1347 1355 unique = []
1348 1356 unique_dict = {}
1349 1357 for nn in elems:
1350 1358 if nn not in unique_dict:
1351 1359 unique.append(nn)
1352 1360 unique_dict[nn] = None
1353 1361 return unique
1354 1362
1355 1363 #----------------------------------------------------------------------------
1356 1364 class NLprinter:
1357 1365 """Print an arbitrarily nested list, indicating index numbers.
1358 1366
1359 1367 An instance of this class called nlprint is available and callable as a
1360 1368 function.
1361 1369
1362 1370 nlprint(list,indent=' ',sep=': ') -> prints indenting each level by 'indent'
1363 1371 and using 'sep' to separate the index from the value. """
1364 1372
1365 1373 def __init__(self):
1366 1374 self.depth = 0
1367 1375
1368 1376 def __call__(self,lst,pos='',**kw):
1369 1377 """Prints the nested list numbering levels."""
1370 1378 kw.setdefault('indent',' ')
1371 1379 kw.setdefault('sep',': ')
1372 1380 kw.setdefault('start',0)
1373 1381 kw.setdefault('stop',len(lst))
1374 1382 # we need to remove start and stop from kw so they don't propagate
1375 1383 # into a recursive call for a nested list.
1376 1384 start = kw['start']; del kw['start']
1377 1385 stop = kw['stop']; del kw['stop']
1378 1386 if self.depth == 0 and 'header' in kw.keys():
1379 1387 print kw['header']
1380 1388
1381 1389 for idx in range(start,stop):
1382 1390 elem = lst[idx]
1383 1391 if type(elem)==type([]):
1384 1392 self.depth += 1
1385 1393 self.__call__(elem,itpl('$pos$idx,'),**kw)
1386 1394 self.depth -= 1
1387 1395 else:
1388 1396 printpl(kw['indent']*self.depth+'$pos$idx$kw["sep"]$elem')
1389 1397
1390 1398 nlprint = NLprinter()
1391 1399 #----------------------------------------------------------------------------
1392 1400 def all_belong(candidates,checklist):
1393 1401 """Check whether a list of items ALL appear in a given list of options.
1394 1402
1395 1403 Returns a single 1 or 0 value."""
1396 1404
1397 1405 return 1-(0 in [x in checklist for x in candidates])
1398 1406
1399 1407 #----------------------------------------------------------------------------
1400 1408 def sort_compare(lst1,lst2,inplace = 1):
1401 1409 """Sort and compare two lists.
1402 1410
1403 1411 By default it does it in place, thus modifying the lists. Use inplace = 0
1404 1412 to avoid that (at the cost of temporary copy creation)."""
1405 1413 if not inplace:
1406 1414 lst1 = lst1[:]
1407 1415 lst2 = lst2[:]
1408 1416 lst1.sort(); lst2.sort()
1409 1417 return lst1 == lst2
1410 1418
1411 1419 #----------------------------------------------------------------------------
1412 1420 def mkdict(**kwargs):
1413 1421 """Return a dict from a keyword list.
1414 1422
1415 1423 It's just syntactic sugar for making ditcionary creation more convenient:
1416 1424 # the standard way
1417 1425 >>>data = { 'red' : 1, 'green' : 2, 'blue' : 3 }
1418 1426 # a cleaner way
1419 1427 >>>data = dict(red=1, green=2, blue=3)
1420 1428
1421 1429 If you need more than this, look at the Struct() class."""
1422 1430
1423 1431 return kwargs
1424 1432
1425 1433 #----------------------------------------------------------------------------
1426 1434 def list2dict(lst):
1427 1435 """Takes a list of (key,value) pairs and turns it into a dict."""
1428 1436
1429 1437 dic = {}
1430 1438 for k,v in lst: dic[k] = v
1431 1439 return dic
1432 1440
1433 1441 #----------------------------------------------------------------------------
1434 1442 def list2dict2(lst,default=''):
1435 1443 """Takes a list and turns it into a dict.
1436 1444 Much slower than list2dict, but more versatile. This version can take
1437 1445 lists with sublists of arbitrary length (including sclars)."""
1438 1446
1439 1447 dic = {}
1440 1448 for elem in lst:
1441 1449 if type(elem) in (types.ListType,types.TupleType):
1442 1450 size = len(elem)
1443 1451 if size == 0:
1444 1452 pass
1445 1453 elif size == 1:
1446 1454 dic[elem] = default
1447 1455 else:
1448 1456 k,v = elem[0], elem[1:]
1449 1457 if len(v) == 1: v = v[0]
1450 1458 dic[k] = v
1451 1459 else:
1452 1460 dic[elem] = default
1453 1461 return dic
1454 1462
1455 1463 #----------------------------------------------------------------------------
1456 1464 def flatten(seq):
1457 1465 """Flatten a list of lists (NOT recursive, only works for 2d lists)."""
1458 1466
1459 1467 # bug in python??? (YES. Fixed in 2.2, let's leave the kludgy fix in).
1460 1468
1461 1469 # if the x=0 isn't made, a *global* variable x is left over after calling
1462 1470 # this function, with the value of the last element in the return
1463 1471 # list. This does seem like a bug big time to me.
1464 1472
1465 1473 # the problem is fixed with the x=0, which seems to force the creation of
1466 1474 # a local name
1467 1475
1468 1476 x = 0
1469 1477 return [x for subseq in seq for x in subseq]
1470 1478
1471 1479 #----------------------------------------------------------------------------
1472 1480 def get_slice(seq,start=0,stop=None,step=1):
1473 1481 """Get a slice of a sequence with variable step. Specify start,stop,step."""
1474 1482 if stop == None:
1475 1483 stop = len(seq)
1476 1484 item = lambda i: seq[i]
1477 1485 return map(item,xrange(start,stop,step))
1478 1486
1479 1487 #----------------------------------------------------------------------------
1480 1488 def chop(seq,size):
1481 1489 """Chop a sequence into chunks of the given size."""
1482 1490 chunk = lambda i: seq[i:i+size]
1483 1491 return map(chunk,xrange(0,len(seq),size))
1484 1492
1485 1493 #----------------------------------------------------------------------------
1486 1494 def with(object, **args):
1487 1495 """Set multiple attributes for an object, similar to Pascal's with.
1488 1496
1489 1497 Example:
1490 1498 with(jim,
1491 1499 born = 1960,
1492 1500 haircolour = 'Brown',
1493 1501 eyecolour = 'Green')
1494 1502
1495 1503 Credit: Greg Ewing, in
1496 1504 http://mail.python.org/pipermail/python-list/2001-May/040703.html"""
1497 1505
1498 1506 object.__dict__.update(args)
1499 1507
1500 1508 #----------------------------------------------------------------------------
1501 1509 def setattr_list(obj,alist,nspace = None):
1502 1510 """Set a list of attributes for an object taken from a namespace.
1503 1511
1504 1512 setattr_list(obj,alist,nspace) -> sets in obj all the attributes listed in
1505 1513 alist with their values taken from nspace, which must be a dict (something
1506 1514 like locals() will often do) If nspace isn't given, locals() of the
1507 1515 *caller* is used, so in most cases you can omit it.
1508 1516
1509 1517 Note that alist can be given as a string, which will be automatically
1510 1518 split into a list on whitespace. If given as a list, it must be a list of
1511 1519 *strings* (the variable names themselves), not of variables."""
1512 1520
1513 1521 # this grabs the local variables from the *previous* call frame -- that is
1514 1522 # the locals from the function that called setattr_list().
1515 1523 # - snipped from weave.inline()
1516 1524 if nspace is None:
1517 1525 call_frame = sys._getframe().f_back
1518 1526 nspace = call_frame.f_locals
1519 1527
1520 1528 if type(alist) in StringTypes:
1521 1529 alist = alist.split()
1522 1530 for attr in alist:
1523 1531 val = eval(attr,nspace)
1524 1532 setattr(obj,attr,val)
1525 1533
1526 1534 #----------------------------------------------------------------------------
1527 1535 def getattr_list(obj,alist,*args):
1528 1536 """getattr_list(obj,alist[, default]) -> attribute list.
1529 1537
1530 1538 Get a list of named attributes for an object. When a default argument is
1531 1539 given, it is returned when the attribute doesn't exist; without it, an
1532 1540 exception is raised in that case.
1533 1541
1534 1542 Note that alist can be given as a string, which will be automatically
1535 1543 split into a list on whitespace. If given as a list, it must be a list of
1536 1544 *strings* (the variable names themselves), not of variables."""
1537 1545
1538 1546 if type(alist) in StringTypes:
1539 1547 alist = alist.split()
1540 1548 if args:
1541 1549 if len(args)==1:
1542 1550 default = args[0]
1543 1551 return map(lambda attr: getattr(obj,attr,default),alist)
1544 1552 else:
1545 1553 raise ValueError,'getattr_list() takes only one optional argument'
1546 1554 else:
1547 1555 return map(lambda attr: getattr(obj,attr),alist)
1548 1556
1549 1557 #----------------------------------------------------------------------------
1550 1558 def map_method(method,object_list,*argseq,**kw):
1551 1559 """map_method(method,object_list,*args,**kw) -> list
1552 1560
1553 1561 Return a list of the results of applying the methods to the items of the
1554 1562 argument sequence(s). If more than one sequence is given, the method is
1555 1563 called with an argument list consisting of the corresponding item of each
1556 1564 sequence. All sequences must be of the same length.
1557 1565
1558 1566 Keyword arguments are passed verbatim to all objects called.
1559 1567
1560 1568 This is Python code, so it's not nearly as fast as the builtin map()."""
1561 1569
1562 1570 out_list = []
1563 1571 idx = 0
1564 1572 for object in object_list:
1565 1573 try:
1566 1574 handler = getattr(object, method)
1567 1575 except AttributeError:
1568 1576 out_list.append(None)
1569 1577 else:
1570 1578 if argseq:
1571 1579 args = map(lambda lst:lst[idx],argseq)
1572 1580 #print 'ob',object,'hand',handler,'ar',args # dbg
1573 1581 out_list.append(handler(args,**kw))
1574 1582 else:
1575 1583 out_list.append(handler(**kw))
1576 1584 idx += 1
1577 1585 return out_list
1578 1586
1579 1587 #----------------------------------------------------------------------------
1580 1588 # Proposed popitem() extension, written as a method
1581 1589
1582 1590 class NotGiven: pass
1583 1591
1584 1592 def popkey(dct,key,default=NotGiven):
1585 1593 """Return dct[key] and delete dct[key].
1586 1594
1587 1595 If default is given, return it if dct[key] doesn't exist, otherwise raise
1588 1596 KeyError. """
1589 1597
1590 1598 try:
1591 1599 val = dct[key]
1592 1600 except KeyError:
1593 1601 if default is NotGiven:
1594 1602 raise
1595 1603 else:
1596 1604 return default
1597 1605 else:
1598 1606 del dct[key]
1599 1607 return val
1600 1608 #*************************** end of file <genutils.py> **********************
1601 1609
@@ -1,1887 +1,1883 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 IPython -- An enhanced Interactive Python
4 4
5 5 Requires Python 2.1 or newer.
6 6
7 7 This file contains all the classes and helper functions specific to IPython.
8 8
9 $Id: iplib.py 957 2005-12-27 22:33:22Z fperez $
9 $Id: iplib.py 958 2005-12-27 23:17:51Z fperez $
10 10 """
11 11
12 12 #*****************************************************************************
13 13 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de> and
14 14 # Copyright (C) 2001-2005 Fernando Perez. <fperez@colorado.edu>
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 # Note: this code originally subclassed code.InteractiveConsole from the
20 20 # Python standard library. Over time, all of that class has been copied
21 21 # verbatim here for modifications which could not be accomplished by
22 22 # subclassing. At this point, there are no dependencies at all on the code
23 23 # module anymore (it is not even imported). The Python License (sec. 2)
24 24 # allows for this, but it's always nice to acknowledge credit where credit is
25 25 # due.
26 26 #*****************************************************************************
27 27
28 28 #****************************************************************************
29 29 # Modules and globals
30 30
31 31 from __future__ import generators # for 2.2 backwards-compatibility
32 32
33 33 from IPython import Release
34 34 __author__ = '%s <%s>\n%s <%s>' % \
35 35 ( Release.authors['Janko'] + Release.authors['Fernando'] )
36 36 __license__ = Release.license
37 37 __version__ = Release.version
38 38
39 39 # Python standard modules
40 40 import __main__
41 41 import __builtin__
42 42 import bdb
43 43 import codeop
44 44 import cPickle as pickle
45 45 import exceptions
46 46 import glob
47 47 import inspect
48 48 import keyword
49 49 import new
50 50 import os
51 51 import pdb
52 52 import pydoc
53 53 import re
54 54 import shutil
55 55 import string
56 56 import StringIO
57 57 import sys
58 58 import traceback
59 59 import types
60 60
61 61 from pprint import pprint, pformat
62 62
63 63 # IPython's own modules
64 64 import IPython
65 65 from IPython import OInspect,PyColorize,ultraTB
66 66 from IPython.ColorANSI import ColorScheme,ColorSchemeTable # too long names
67 from IPython.FakeModule import FakeModule
68 from IPython.Itpl import Itpl,itpl,printpl,ItplNS,itplns
67 69 from IPython.Logger import Logger
68 70 from IPython.Magic import Magic,magic2python
69 from IPython.usage import cmd_line_usage,interactive_usage
70 71 from IPython.Struct import Struct
71 from IPython.Itpl import Itpl,itpl,printpl,ItplNS,itplns
72 from IPython.FakeModule import FakeModule
73 72 from IPython.background_jobs import BackgroundJobManager
74 from IPython.PyColorize import Parser
73 from IPython.usage import cmd_line_usage,interactive_usage
75 74 from IPython.genutils import *
76 75
77 # Global pointer to the running
78
79 76 # store the builtin raw_input globally, and use this always, in case user code
80 77 # overwrites it (like wx.py.PyShell does)
81 78 raw_input_original = raw_input
82 79
83 80 #****************************************************************************
84 81 # Some utility function definitions
85 82
86 83 def esc_quotes(strng):
87 84 """Return the input string with single and double quotes escaped out"""
88 85
89 86 return strng.replace('"','\\"').replace("'","\\'")
90 87
91 88 def import_fail_info(mod_name,fns=None):
92 89 """Inform load failure for a module."""
93 90
94 91 if fns == None:
95 92 warn("Loading of %s failed.\n" % (mod_name,))
96 93 else:
97 94 warn("Loading of %s from %s failed.\n" % (fns,mod_name))
98 95
99 96 def qw_lol(indata):
100 97 """qw_lol('a b') -> [['a','b']],
101 98 otherwise it's just a call to qw().
102 99
103 100 We need this to make sure the modules_some keys *always* end up as a
104 101 list of lists."""
105 102
106 103 if type(indata) in StringTypes:
107 104 return [qw(indata)]
108 105 else:
109 106 return qw(indata)
110 107
111 108 def ipmagic(arg_s):
112 109 """Call a magic function by name.
113 110
114 111 Input: a string containing the name of the magic function to call and any
115 112 additional arguments to be passed to the magic.
116 113
117 114 ipmagic('name -opt foo bar') is equivalent to typing at the ipython
118 115 prompt:
119 116
120 117 In[1]: %name -opt foo bar
121 118
122 119 To call a magic without arguments, simply use ipmagic('name').
123 120
124 121 This provides a proper Python function to call IPython's magics in any
125 122 valid Python code you can type at the interpreter, including loops and
126 123 compound statements. It is added by IPython to the Python builtin
127 124 namespace upon initialization."""
128 125
129 126 args = arg_s.split(' ',1)
130 127 magic_name = args[0]
131 128 if magic_name.startswith(__IPYTHON__.ESC_MAGIC):
132 129 magic_name = magic_name[1:]
133 130 try:
134 131 magic_args = args[1]
135 132 except IndexError:
136 133 magic_args = ''
137 134 fn = getattr(__IPYTHON__,'magic_'+magic_name,None)
138 135 if fn is None:
139 136 error("Magic function `%s` not found." % magic_name)
140 137 else:
141 138 magic_args = __IPYTHON__.var_expand(magic_args)
142 139 return fn(magic_args)
143 140
144 141 def ipalias(arg_s):
145 142 """Call an alias by name.
146 143
147 144 Input: a string containing the name of the alias to call and any
148 145 additional arguments to be passed to the magic.
149 146
150 147 ipalias('name -opt foo bar') is equivalent to typing at the ipython
151 148 prompt:
152 149
153 150 In[1]: name -opt foo bar
154 151
155 152 To call an alias without arguments, simply use ipalias('name').
156 153
157 154 This provides a proper Python function to call IPython's aliases in any
158 155 valid Python code you can type at the interpreter, including loops and
159 156 compound statements. It is added by IPython to the Python builtin
160 157 namespace upon initialization."""
161 158
162 159 args = arg_s.split(' ',1)
163 160 alias_name = args[0]
164 161 try:
165 162 alias_args = args[1]
166 163 except IndexError:
167 164 alias_args = ''
168 165 if alias_name in __IPYTHON__.alias_table:
169 166 __IPYTHON__.call_alias(alias_name,alias_args)
170 167 else:
171 168 error("Alias `%s` not found." % alias_name)
172 169
173 170 def softspace(file, newvalue):
174 171 """Copied from code.py, to remove the dependency"""
175 172 oldvalue = 0
176 173 try:
177 174 oldvalue = file.softspace
178 175 except AttributeError:
179 176 pass
180 177 try:
181 178 file.softspace = newvalue
182 179 except (AttributeError, TypeError):
183 180 # "attribute-less object" or "read-only attributes"
184 181 pass
185 182 return oldvalue
186 183
187 184
188 185 #****************************************************************************
189 186 # Local use exceptions
190 187 class SpaceInInput(exceptions.Exception): pass
191 188
192 189 class IPythonExit(exceptions.Exception): pass
193 190
194 191 #****************************************************************************
195 192 # Local use classes
196 193 class Bunch: pass
197 194
198 195 class InputList(list):
199 196 """Class to store user input.
200 197
201 198 It's basically a list, but slices return a string instead of a list, thus
202 199 allowing things like (assuming 'In' is an instance):
203 200
204 201 exec In[4:7]
205 202
206 203 or
207 204
208 205 exec In[5:9] + In[14] + In[21:25]"""
209 206
210 207 def __getslice__(self,i,j):
211 208 return ''.join(list.__getslice__(self,i,j))
212 209
213 210 #****************************************************************************
214 211 # Main IPython class
215 212 class InteractiveShell(Logger, Magic):
216 213 """An enhanced console for Python."""
217 214
218 215 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
219 216 user_ns = None,user_global_ns=None,banner2='',
220 217 custom_exceptions=((),None),embedded=False):
221 218
222 219 # Put a reference to self in builtins so that any form of embedded or
223 220 # imported code can test for being inside IPython.
224 221 __builtin__.__IPYTHON__ = self
225 222
226 223 # And load into builtins ipmagic/ipalias as well
227 224 __builtin__.ipmagic = ipmagic
228 225 __builtin__.ipalias = ipalias
229 226
230 227 # Add to __builtin__ other parts of IPython's public API
231 228 __builtin__.ip_set_hook = self.set_hook
232 229
233 230 # Keep in the builtins a flag for when IPython is active. We set it
234 231 # with setdefault so that multiple nested IPythons don't clobber one
235 232 # another. Each will increase its value by one upon being activated,
236 233 # which also gives us a way to determine the nesting level.
237 234 __builtin__.__dict__.setdefault('__IPYTHON__active',0)
238 235
239 236 # Do the intuitively correct thing for quit/exit: we remove the
240 237 # builtins if they exist, and our own prefilter routine will handle
241 238 # these special cases
242 239 try:
243 240 del __builtin__.exit, __builtin__.quit
244 241 except AttributeError:
245 242 pass
246 243
247 244 # We need to know whether the instance is meant for embedding, since
248 245 # global/local namespaces need to be handled differently in that case
249 246 self.embedded = embedded
250 247
251 248 # compiler command
252 249 self.compile = codeop.CommandCompiler()
253 250
254 251 # User input buffer
255 252 self.buffer = []
256 253
257 254 # Default name given in compilation of code
258 255 self.filename = '<ipython console>'
259 256
260 257 # Create the namespace where the user will operate. user_ns is
261 258 # normally the only one used, and it is passed to the exec calls as
262 259 # the locals argument. But we do carry a user_global_ns namespace
263 260 # given as the exec 'globals' argument, This is useful in embedding
264 261 # situations where the ipython shell opens in a context where the
265 262 # distinction between locals and globals is meaningful.
266 263
267 264 # FIXME. For some strange reason, __builtins__ is showing up at user
268 265 # level as a dict instead of a module. This is a manual fix, but I
269 266 # should really track down where the problem is coming from. Alex
270 267 # Schmolck reported this problem first.
271 268
272 269 # A useful post by Alex Martelli on this topic:
273 270 # Re: inconsistent value from __builtins__
274 271 # Von: Alex Martelli <aleaxit@yahoo.com>
275 272 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
276 273 # Gruppen: comp.lang.python
277 274 # Referenzen: 1
278 275
279 276 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
280 277 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
281 278 # > <type 'dict'>
282 279 # > >>> print type(__builtins__)
283 280 # > <type 'module'>
284 281 # > Is this difference in return value intentional?
285 282
286 283 # Well, it's documented that '__builtins__' can be either a dictionary
287 284 # or a module, and it's been that way for a long time. Whether it's
288 285 # intentional (or sensible), I don't know. In any case, the idea is
289 286 # that if you need to access the built-in namespace directly, you
290 287 # should start with "import __builtin__" (note, no 's') which will
291 288 # definitely give you a module. Yeah, it's somewhat confusing:-(.
292 289
293 290 if user_ns is None:
294 291 # Set __name__ to __main__ to better match the behavior of the
295 292 # normal interpreter.
296 293 user_ns = {'__name__' :'__main__',
297 294 '__builtins__' : __builtin__,
298 295 }
299 296
300 297 if user_global_ns is None:
301 298 user_global_ns = {}
302 299
303 300 # Assign namespaces
304 301 # This is the namespace where all normal user variables live
305 302 self.user_ns = user_ns
306 303 # Embedded instances require a separate namespace for globals.
307 304 # Normally this one is unused by non-embedded instances.
308 305 self.user_global_ns = user_global_ns
309 306 # A namespace to keep track of internal data structures to prevent
310 307 # them from cluttering user-visible stuff. Will be updated later
311 308 self.internal_ns = {}
312 309
313 310 # Namespace of system aliases. Each entry in the alias
314 311 # table must be a 2-tuple of the form (N,name), where N is the number
315 312 # of positional arguments of the alias.
316 313 self.alias_table = {}
317 314
318 315 # A table holding all the namespaces IPython deals with, so that
319 316 # introspection facilities can search easily.
320 317 self.ns_table = {'user':user_ns,
321 318 'user_global':user_global_ns,
322 319 'alias':self.alias_table,
323 320 'internal':self.internal_ns,
324 321 'builtin':__builtin__.__dict__
325 322 }
326 323
327 324 # The user namespace MUST have a pointer to the shell itself.
328 325 self.user_ns[name] = self
329 326
330 327 # We need to insert into sys.modules something that looks like a
331 328 # module but which accesses the IPython namespace, for shelve and
332 329 # pickle to work interactively. Normally they rely on getting
333 330 # everything out of __main__, but for embedding purposes each IPython
334 331 # instance has its own private namespace, so we can't go shoving
335 332 # everything into __main__.
336 333
337 334 # note, however, that we should only do this for non-embedded
338 335 # ipythons, which really mimic the __main__.__dict__ with their own
339 336 # namespace. Embedded instances, on the other hand, should not do
340 337 # this because they need to manage the user local/global namespaces
341 338 # only, but they live within a 'normal' __main__ (meaning, they
342 339 # shouldn't overtake the execution environment of the script they're
343 340 # embedded in).
344 341
345 342 if not embedded:
346 343 try:
347 344 main_name = self.user_ns['__name__']
348 345 except KeyError:
349 346 raise KeyError,'user_ns dictionary MUST have a "__name__" key'
350 347 else:
351 348 #print "pickle hack in place" # dbg
352 349 sys.modules[main_name] = FakeModule(self.user_ns)
353 350
354 351 # List of input with multi-line handling.
355 352 # Fill its zero entry, user counter starts at 1
356 353 self.input_hist = InputList(['\n'])
357 354
358 355 # list of visited directories
359 356 try:
360 357 self.dir_hist = [os.getcwd()]
361 358 except IOError, e:
362 359 self.dir_hist = []
363 360
364 361 # dict of output history
365 362 self.output_hist = {}
366 363
367 364 # dict of things NOT to alias (keywords, builtins and some magics)
368 365 no_alias = {}
369 366 no_alias_magics = ['cd','popd','pushd','dhist','alias','unalias']
370 367 for key in keyword.kwlist + no_alias_magics:
371 368 no_alias[key] = 1
372 369 no_alias.update(__builtin__.__dict__)
373 370 self.no_alias = no_alias
374 371
375 372 # make global variables for user access to these
376 373 self.user_ns['_ih'] = self.input_hist
377 374 self.user_ns['_oh'] = self.output_hist
378 375 self.user_ns['_dh'] = self.dir_hist
379 376
380 377 # user aliases to input and output histories
381 378 self.user_ns['In'] = self.input_hist
382 379 self.user_ns['Out'] = self.output_hist
383 380
384 381 # Store the actual shell's name
385 382 self.name = name
386 383
387 384 # Object variable to store code object waiting execution. This is
388 385 # used mainly by the multithreaded shells, but it can come in handy in
389 386 # other situations. No need to use a Queue here, since it's a single
390 387 # item which gets cleared once run.
391 388 self.code_to_run = None
392 389
393 390 # Job manager (for jobs run as background threads)
394 391 self.jobs = BackgroundJobManager()
395 392 # Put the job manager into builtins so it's always there.
396 393 __builtin__.jobs = self.jobs
397 394
398 395 # escapes for automatic behavior on the command line
399 396 self.ESC_SHELL = '!'
400 397 self.ESC_HELP = '?'
401 398 self.ESC_MAGIC = '%'
402 399 self.ESC_QUOTE = ','
403 400 self.ESC_QUOTE2 = ';'
404 401 self.ESC_PAREN = '/'
405 402
406 403 # And their associated handlers
407 404 self.esc_handlers = {self.ESC_PAREN:self.handle_auto,
408 405 self.ESC_QUOTE:self.handle_auto,
409 406 self.ESC_QUOTE2:self.handle_auto,
410 407 self.ESC_MAGIC:self.handle_magic,
411 408 self.ESC_HELP:self.handle_help,
412 409 self.ESC_SHELL:self.handle_shell_escape,
413 410 }
414 411
415 412 # class initializations
416 413 Logger.__init__(self,log_ns = self.user_ns)
417 414 Magic.__init__(self,self)
418 415
419 416 # an ugly hack to get a pointer to the shell, so I can start writing
420 417 # magic code via this pointer instead of the current mixin salad.
421 418 Magic.set_shell(self,self)
422 419
423 420 # Python source parser/formatter for syntax highlighting
424 pyformat = Parser().format
421 pyformat = PyColorize.Parser().format
425 422 self.pycolorize = lambda src: pyformat(src,'str',self.rc['colors'])
426 423
427 424 # hooks holds pointers used for user-side customizations
428 425 self.hooks = Struct()
429 426
430 427 # Set all default hooks, defined in the IPython.hooks module.
431 428 hooks = IPython.hooks
432 429 for hook_name in hooks.__all__:
433 430 self.set_hook(hook_name,getattr(hooks,hook_name))
434 431
435 432 # Flag to mark unconditional exit
436 433 self.exit_now = False
437 434
438 435 self.usage_min = """\
439 436 An enhanced console for Python.
440 437 Some of its features are:
441 438 - Readline support if the readline library is present.
442 439 - Tab completion in the local namespace.
443 440 - Logging of input, see command-line options.
444 441 - System shell escape via ! , eg !ls.
445 442 - Magic commands, starting with a % (like %ls, %pwd, %cd, etc.)
446 443 - Keeps track of locally defined variables via %who, %whos.
447 444 - Show object information with a ? eg ?x or x? (use ?? for more info).
448 445 """
449 446 if usage: self.usage = usage
450 447 else: self.usage = self.usage_min
451 448
452 449 # Storage
453 450 self.rc = rc # This will hold all configuration information
454 451 self.inputcache = []
455 452 self._boundcache = []
456 453 self.pager = 'less'
457 454 # temporary files used for various purposes. Deleted at exit.
458 455 self.tempfiles = []
459 456
460 457 # Keep track of readline usage (later set by init_readline)
461 458 self.has_readline = False
462 459
463 460 # for pushd/popd management
464 461 try:
465 462 self.home_dir = get_home_dir()
466 463 except HomeDirError,msg:
467 464 fatal(msg)
468 465
469 466 self.dir_stack = [os.getcwd().replace(self.home_dir,'~')]
470 467
471 468 # Functions to call the underlying shell.
472 469
473 470 # utility to expand user variables via Itpl
474 471 self.var_expand = lambda cmd: str(ItplNS(cmd.replace('#','\#'),
475 472 self.user_ns))
476 473 # The first is similar to os.system, but it doesn't return a value,
477 474 # and it allows interpolation of variables in the user's namespace.
478 475 self.system = lambda cmd: shell(self.var_expand(cmd),
479 476 header='IPython system call: ',
480 477 verbose=self.rc.system_verbose)
481 478 # These are for getoutput and getoutputerror:
482 479 self.getoutput = lambda cmd: \
483 480 getoutput(self.var_expand(cmd),
484 481 header='IPython system call: ',
485 482 verbose=self.rc.system_verbose)
486 483 self.getoutputerror = lambda cmd: \
487 484 getoutputerror(str(ItplNS(cmd.replace('#','\#'),
488 485 self.user_ns)),
489 486 header='IPython system call: ',
490 487 verbose=self.rc.system_verbose)
491 488
492 489 # RegExp for splitting line contents into pre-char//first
493 490 # word-method//rest. For clarity, each group in on one line.
494 491
495 492 # WARNING: update the regexp if the above escapes are changed, as they
496 493 # are hardwired in.
497 494
498 495 # Don't get carried away with trying to make the autocalling catch too
499 496 # much: it's better to be conservative rather than to trigger hidden
500 497 # evals() somewhere and end up causing side effects.
501 498
502 499 self.line_split = re.compile(r'^([\s*,;/])'
503 500 r'([\?\w\.]+\w*\s*)'
504 501 r'(\(?.*$)')
505 502
506 503 # Original re, keep around for a while in case changes break something
507 504 #self.line_split = re.compile(r'(^[\s*!\?%,/]?)'
508 505 # r'(\s*[\?\w\.]+\w*\s*)'
509 506 # r'(\(?.*$)')
510 507
511 508 # RegExp to identify potential function names
512 509 self.re_fun_name = re.compile(r'[a-zA-Z_]([a-zA-Z0-9_.]*) *$')
513 510 # RegExp to exclude strings with this start from autocalling
514 511 self.re_exclude_auto = re.compile('^[!=()<>,\*/\+-]|^is ')
515 512
516 513 # try to catch also methods for stuff in lists/tuples/dicts: off
517 514 # (experimental). For this to work, the line_split regexp would need
518 515 # to be modified so it wouldn't break things at '['. That line is
519 516 # nasty enough that I shouldn't change it until I can test it _well_.
520 517 #self.re_fun_name = re.compile (r'[a-zA-Z_]([a-zA-Z0-9_.\[\]]*) ?$')
521 518
522 519 # keep track of where we started running (mainly for crash post-mortem)
523 520 self.starting_dir = os.getcwd()
524 521
525 522 # Attributes for Logger mixin class, make defaults here
526 523 self._dolog = False
527 524 self.LOG = ''
528 525 self.LOGDEF = '.InteractiveShell.log'
529 526 self.LOGMODE = 'over'
530 527 self.LOGHEAD = Itpl(
531 528 """#log# Automatic Logger file. *** THIS MUST BE THE FIRST LINE ***
532 529 #log# DO NOT CHANGE THIS LINE OR THE TWO BELOW
533 530 #log# opts = $self.rc.opts
534 531 #log# args = $self.rc.args
535 532 #log# It is safe to make manual edits below here.
536 533 #log#-----------------------------------------------------------------------
537 534 """)
538 535 # Various switches which can be set
539 536 self.CACHELENGTH = 5000 # this is cheap, it's just text
540 537 self.BANNER = "Python %(version)s on %(platform)s\n" % sys.__dict__
541 538 self.banner2 = banner2
542 539
543 540 # TraceBack handlers:
544 541 # Need two, one for syntax errors and one for other exceptions.
545 542 self.SyntaxTB = ultraTB.ListTB(color_scheme='NoColor')
546 543 # This one is initialized with an offset, meaning we always want to
547 544 # remove the topmost item in the traceback, which is our own internal
548 545 # code. Valid modes: ['Plain','Context','Verbose']
549 546 self.InteractiveTB = ultraTB.AutoFormattedTB(mode = 'Plain',
550 547 color_scheme='NoColor',
551 548 tb_offset = 1)
552 549 # and add any custom exception handlers the user may have specified
553 550 self.set_custom_exc(*custom_exceptions)
554 551
555 552 # Object inspector
556 ins_colors = OInspect.InspectColors
557 code_colors = PyColorize.ANSICodeColors
558 self.inspector = OInspect.Inspector(ins_colors,code_colors,'NoColor')
553 self.inspector = OInspect.Inspector(OInspect.InspectColors,
554 PyColorize.ANSICodeColors,
555 'NoColor')
559 556 self.autoindent = False
560 557
561 558 # Make some aliases automatically
562 559 # Prepare list of shell aliases to auto-define
563 560 if os.name == 'posix':
564 561 auto_alias = ('mkdir mkdir', 'rmdir rmdir',
565 562 'mv mv -i','rm rm -i','cp cp -i',
566 563 'cat cat','less less','clear clear',
567 564 # a better ls
568 565 'ls ls -F',
569 566 # long ls
570 567 'll ls -lF',
571 568 # color ls
572 569 'lc ls -F -o --color',
573 570 # ls normal files only
574 571 'lf ls -F -o --color %l | grep ^-',
575 572 # ls symbolic links
576 573 'lk ls -F -o --color %l | grep ^l',
577 574 # directories or links to directories,
578 575 'ldir ls -F -o --color %l | grep /$',
579 576 # things which are executable
580 577 'lx ls -F -o --color %l | grep ^-..x',
581 578 )
582 579 elif os.name in ['nt','dos']:
583 580 auto_alias = ('dir dir /on', 'ls dir /on',
584 581 'ddir dir /ad /on', 'ldir dir /ad /on',
585 582 'mkdir mkdir','rmdir rmdir','echo echo',
586 583 'ren ren','cls cls','copy copy')
587 584 else:
588 585 auto_alias = ()
589 586 self.auto_alias = map(lambda s:s.split(None,1),auto_alias)
590 587 # Call the actual (public) initializer
591 588 self.init_auto_alias()
592 589 # end __init__
593 590
594 591 def set_hook(self,name,hook):
595 592 """set_hook(name,hook) -> sets an internal IPython hook.
596 593
597 594 IPython exposes some of its internal API as user-modifiable hooks. By
598 595 resetting one of these hooks, you can modify IPython's behavior to
599 596 call at runtime your own routines."""
600 597
601 598 # At some point in the future, this should validate the hook before it
602 599 # accepts it. Probably at least check that the hook takes the number
603 600 # of args it's supposed to.
604 601 setattr(self.hooks,name,new.instancemethod(hook,self,self.__class__))
605 602
606 603 def set_custom_exc(self,exc_tuple,handler):
607 604 """set_custom_exc(exc_tuple,handler)
608 605
609 606 Set a custom exception handler, which will be called if any of the
610 607 exceptions in exc_tuple occur in the mainloop (specifically, in the
611 608 runcode() method.
612 609
613 610 Inputs:
614 611
615 612 - exc_tuple: a *tuple* of valid exceptions to call the defined
616 613 handler for. It is very important that you use a tuple, and NOT A
617 614 LIST here, because of the way Python's except statement works. If
618 615 you only want to trap a single exception, use a singleton tuple:
619 616
620 617 exc_tuple == (MyCustomException,)
621 618
622 619 - handler: this must be defined as a function with the following
623 620 basic interface: def my_handler(self,etype,value,tb).
624 621
625 622 This will be made into an instance method (via new.instancemethod)
626 623 of IPython itself, and it will be called if any of the exceptions
627 624 listed in the exc_tuple are caught. If the handler is None, an
628 625 internal basic one is used, which just prints basic info.
629 626
630 627 WARNING: by putting in your own exception handler into IPython's main
631 628 execution loop, you run a very good chance of nasty crashes. This
632 629 facility should only be used if you really know what you are doing."""
633 630
634 631 assert type(exc_tuple)==type(()) , \
635 632 "The custom exceptions must be given AS A TUPLE."
636 633
637 634 def dummy_handler(self,etype,value,tb):
638 635 print '*** Simple custom exception handler ***'
639 636 print 'Exception type :',etype
640 637 print 'Exception value:',value
641 638 print 'Traceback :',tb
642 639 print 'Source code :','\n'.join(self.buffer)
643 640
644 641 if handler is None: handler = dummy_handler
645 642
646 643 self.CustomTB = new.instancemethod(handler,self,self.__class__)
647 644 self.custom_exceptions = exc_tuple
648 645
649 646 def set_custom_completer(self,completer,pos=0):
650 647 """set_custom_completer(completer,pos=0)
651 648
652 649 Adds a new custom completer function.
653 650
654 651 The position argument (defaults to 0) is the index in the completers
655 652 list where you want the completer to be inserted."""
656 653
657 654 newcomp = new.instancemethod(completer,self.Completer,
658 655 self.Completer.__class__)
659 656 self.Completer.matchers.insert(pos,newcomp)
660 657
661 658 def complete(self,text):
662 659 """Return a sorted list of all possible completions on text.
663 660
664 661 Inputs:
665 662
666 663 - text: a string of text to be completed on.
667 664
668 665 This is a wrapper around the completion mechanism, similar to what
669 666 readline does at the command line when the TAB key is hit. By
670 667 exposing it as a method, it can be used by other non-readline
671 668 environments (such as GUIs) for text completion.
672 669
673 670 Simple usage example:
674 671
675 672 In [1]: x = 'hello'
676 673
677 674 In [2]: __IP.complete('x.l')
678 675 Out[2]: ['x.ljust', 'x.lower', 'x.lstrip']"""
679 676
680 677 complete = self.Completer.complete
681 678 state = 0
682 679 # use a dict so we get unique keys, since ipyhton's multiple
683 680 # completers can return duplicates.
684 681 comps = {}
685 682 while True:
686 683 newcomp = complete(text,state)
687 684 if newcomp is None:
688 685 break
689 686 comps[newcomp] = 1
690 687 state += 1
691 688 outcomps = comps.keys()
692 689 outcomps.sort()
693 690 return outcomps
694 691
695 692 def set_completer_frame(self, frame):
696 693 if frame:
697 694 self.Completer.namespace = frame.f_locals
698 695 self.Completer.global_namespace = frame.f_globals
699 696 else:
700 697 self.Completer.namespace = self.user_ns
701 698 self.Completer.global_namespace = self.user_global_ns
702 699
703 700 def post_config_initialization(self):
704 701 """Post configuration init method
705 702
706 703 This is called after the configuration files have been processed to
707 704 'finalize' the initialization."""
708 705
709 706 rc = self.rc
710 707
711 708 # Load readline proper
712 709 if rc.readline:
713 710 self.init_readline()
714 711
715 712 # Set user colors (don't do it in the constructor above so that it
716 713 # doesn't crash if colors option is invalid)
717 714 self.magic_colors(rc.colors)
718 715
719 716 # Load user aliases
720 717 for alias in rc.alias:
721 718 self.magic_alias(alias)
722 719
723 720 # dynamic data that survives through sessions
724 721 # XXX make the filename a config option?
725 722 persist_base = 'persist'
726 723 if rc.profile:
727 724 persist_base += '_%s' % rc.profile
728 725 self.persist_fname = os.path.join(rc.ipythondir,persist_base)
729 726
730 727 try:
731 728 self.persist = pickle.load(file(self.persist_fname))
732 729 except:
733 730 self.persist = {}
734 731
735 732 def init_auto_alias(self):
736 733 """Define some aliases automatically.
737 734
738 735 These are ALL parameter-less aliases"""
739 736 for alias,cmd in self.auto_alias:
740 737 self.alias_table[alias] = (0,cmd)
741 738
742 739 def alias_table_validate(self,verbose=0):
743 740 """Update information about the alias table.
744 741
745 742 In particular, make sure no Python keywords/builtins are in it."""
746 743
747 744 no_alias = self.no_alias
748 745 for k in self.alias_table.keys():
749 746 if k in no_alias:
750 747 del self.alias_table[k]
751 748 if verbose:
752 749 print ("Deleting alias <%s>, it's a Python "
753 750 "keyword or builtin." % k)
754 751
755 752 def set_autoindent(self,value=None):
756 753 """Set the autoindent flag, checking for readline support.
757 754
758 755 If called with no arguments, it acts as a toggle."""
759 756
760 757 if not self.has_readline:
761 758 if os.name == 'posix':
762 759 warn("The auto-indent feature requires the readline library")
763 760 self.autoindent = 0
764 761 return
765 762 if value is None:
766 763 self.autoindent = not self.autoindent
767 764 else:
768 765 self.autoindent = value
769 766
770 767 def rc_set_toggle(self,rc_field,value=None):
771 768 """Set or toggle a field in IPython's rc config. structure.
772 769
773 770 If called with no arguments, it acts as a toggle.
774 771
775 772 If called with a non-existent field, the resulting AttributeError
776 773 exception will propagate out."""
777 774
778 775 rc_val = getattr(self.rc,rc_field)
779 776 if value is None:
780 777 value = not rc_val
781 778 setattr(self.rc,rc_field,value)
782 779
783 780 def user_setup(self,ipythondir,rc_suffix,mode='install'):
784 781 """Install the user configuration directory.
785 782
786 783 Can be called when running for the first time or to upgrade the user's
787 784 .ipython/ directory with the mode parameter. Valid modes are 'install'
788 785 and 'upgrade'."""
789 786
790 787 def wait():
791 788 try:
792 789 raw_input("Please press <RETURN> to start IPython.")
793 790 except EOFError:
794 791 print >> Term.cout
795 792 print '*'*70
796 793
797 794 cwd = os.getcwd() # remember where we started
798 795 glb = glob.glob
799 796 print '*'*70
800 797 if mode == 'install':
801 798 print \
802 799 """Welcome to IPython. I will try to create a personal configuration directory
803 800 where you can customize many aspects of IPython's functionality in:\n"""
804 801 else:
805 802 print 'I am going to upgrade your configuration in:'
806 803
807 804 print ipythondir
808 805
809 806 rcdirend = os.path.join('IPython','UserConfig')
810 807 cfg = lambda d: os.path.join(d,rcdirend)
811 808 try:
812 809 rcdir = filter(os.path.isdir,map(cfg,sys.path))[0]
813 810 except IOError:
814 811 warning = """
815 812 Installation error. IPython's directory was not found.
816 813
817 814 Check the following:
818 815
819 816 The ipython/IPython directory should be in a directory belonging to your
820 817 PYTHONPATH environment variable (that is, it should be in a directory
821 818 belonging to sys.path). You can copy it explicitly there or just link to it.
822 819
823 820 IPython will proceed with builtin defaults.
824 821 """
825 822 warn(warning)
826 823 wait()
827 824 return
828 825
829 826 if mode == 'install':
830 827 try:
831 828 shutil.copytree(rcdir,ipythondir)
832 829 os.chdir(ipythondir)
833 830 rc_files = glb("ipythonrc*")
834 831 for rc_file in rc_files:
835 832 os.rename(rc_file,rc_file+rc_suffix)
836 833 except:
837 834 warning = """
838 835
839 836 There was a problem with the installation:
840 837 %s
841 838 Try to correct it or contact the developers if you think it's a bug.
842 839 IPython will proceed with builtin defaults.""" % sys.exc_info()[1]
843 840 warn(warning)
844 841 wait()
845 842 return
846 843
847 844 elif mode == 'upgrade':
848 845 try:
849 846 os.chdir(ipythondir)
850 847 except:
851 848 print """
852 849 Can not upgrade: changing to directory %s failed. Details:
853 850 %s
854 851 """ % (ipythondir,sys.exc_info()[1])
855 852 wait()
856 853 return
857 854 else:
858 855 sources = glb(os.path.join(rcdir,'[A-Za-z]*'))
859 856 for new_full_path in sources:
860 857 new_filename = os.path.basename(new_full_path)
861 858 if new_filename.startswith('ipythonrc'):
862 859 new_filename = new_filename + rc_suffix
863 860 # The config directory should only contain files, skip any
864 861 # directories which may be there (like CVS)
865 862 if os.path.isdir(new_full_path):
866 863 continue
867 864 if os.path.exists(new_filename):
868 865 old_file = new_filename+'.old'
869 866 if os.path.exists(old_file):
870 867 os.remove(old_file)
871 868 os.rename(new_filename,old_file)
872 869 shutil.copy(new_full_path,new_filename)
873 870 else:
874 871 raise ValueError,'unrecognized mode for install:',`mode`
875 872
876 873 # Fix line-endings to those native to each platform in the config
877 874 # directory.
878 875 try:
879 876 os.chdir(ipythondir)
880 877 except:
881 878 print """
882 879 Problem: changing to directory %s failed.
883 880 Details:
884 881 %s
885 882
886 883 Some configuration files may have incorrect line endings. This should not
887 884 cause any problems during execution. """ % (ipythondir,sys.exc_info()[1])
888 885 wait()
889 886 else:
890 887 for fname in glb('ipythonrc*'):
891 888 try:
892 889 native_line_ends(fname,backup=0)
893 890 except IOError:
894 891 pass
895 892
896 893 if mode == 'install':
897 894 print """
898 895 Successful installation!
899 896
900 897 Please read the sections 'Initial Configuration' and 'Quick Tips' in the
901 898 IPython manual (there are both HTML and PDF versions supplied with the
902 899 distribution) to make sure that your system environment is properly configured
903 900 to take advantage of IPython's features."""
904 901 else:
905 902 print """
906 903 Successful upgrade!
907 904
908 905 All files in your directory:
909 906 %(ipythondir)s
910 907 which would have been overwritten by the upgrade were backed up with a .old
911 908 extension. If you had made particular customizations in those files you may
912 909 want to merge them back into the new files.""" % locals()
913 910 wait()
914 911 os.chdir(cwd)
915 912 # end user_setup()
916 913
917 914 def atexit_operations(self):
918 915 """This will be executed at the time of exit.
919 916
920 917 Saving of persistent data should be performed here. """
921 918
922 919 # input history
923 920 self.savehist()
924 921
925 922 # Cleanup all tempfiles left around
926 923 for tfile in self.tempfiles:
927 924 try:
928 925 os.unlink(tfile)
929 926 except OSError:
930 927 pass
931 928
932 929 # save the "persistent data" catch-all dictionary
933 930 try:
934 931 pickle.dump(self.persist, open(self.persist_fname,"w"))
935 932 except:
936 933 print "*** ERROR *** persistent data saving failed."
937 934
938 935 def savehist(self):
939 936 """Save input history to a file (via readline library)."""
940 937 try:
941 938 self.readline.write_history_file(self.histfile)
942 939 except:
943 940 print 'Unable to save IPython command history to file: ' + \
944 941 `self.histfile`
945 942
946 943 def pre_readline(self):
947 944 """readline hook to be used at the start of each line.
948 945
949 946 Currently it handles auto-indent only."""
950 947
951 948 self.readline.insert_text(' '* self.readline_indent)
952 949
953 950 def init_readline(self):
954 951 """Command history completion/saving/reloading."""
955 952 try:
956 953 import readline
957 954 except ImportError:
958 955 self.has_readline = 0
959 956 self.readline = None
960 957 # no point in bugging windows users with this every time:
961 958 if os.name == 'posix':
962 959 warn('Readline services not available on this platform.')
963 960 else:
964 961 import atexit
965 962 from IPython.completer import IPCompleter
966 963 self.Completer = IPCompleter(self,
967 964 self.user_ns,
968 965 self.user_global_ns,
969 966 self.rc.readline_omit__names,
970 967 self.alias_table)
971 968
972 969 # Platform-specific configuration
973 970 if os.name == 'nt':
974 971 self.readline_startup_hook = readline.set_pre_input_hook
975 972 else:
976 973 self.readline_startup_hook = readline.set_startup_hook
977 974
978 975 # Load user's initrc file (readline config)
979 976 inputrc_name = os.environ.get('INPUTRC')
980 977 if inputrc_name is None:
981 978 home_dir = get_home_dir()
982 979 if home_dir is not None:
983 980 inputrc_name = os.path.join(home_dir,'.inputrc')
984 981 if os.path.isfile(inputrc_name):
985 982 try:
986 983 readline.read_init_file(inputrc_name)
987 984 except:
988 985 warn('Problems reading readline initialization file <%s>'
989 986 % inputrc_name)
990 987
991 988 self.has_readline = 1
992 989 self.readline = readline
993 990 self.readline_indent = 0 # for auto-indenting via readline
994 991 # save this in sys so embedded copies can restore it properly
995 992 sys.ipcompleter = self.Completer.complete
996 993 readline.set_completer(self.Completer.complete)
997 994
998 995 # Configure readline according to user's prefs
999 996 for rlcommand in self.rc.readline_parse_and_bind:
1000 997 readline.parse_and_bind(rlcommand)
1001 998
1002 999 # remove some chars from the delimiters list
1003 1000 delims = readline.get_completer_delims()
1004 1001 delims = delims.translate(string._idmap,
1005 1002 self.rc.readline_remove_delims)
1006 1003 readline.set_completer_delims(delims)
1007 1004 # otherwise we end up with a monster history after a while:
1008 1005 readline.set_history_length(1000)
1009 1006 try:
1010 1007 #print '*** Reading readline history' # dbg
1011 1008 readline.read_history_file(self.histfile)
1012 1009 except IOError:
1013 1010 pass # It doesn't exist yet.
1014 1011
1015 1012 atexit.register(self.atexit_operations)
1016 1013 del atexit
1017 1014
1018 1015 # Configure auto-indent for all platforms
1019 1016 self.set_autoindent(self.rc.autoindent)
1020 1017
1021 1018 def showsyntaxerror(self, filename=None):
1022 1019 """Display the syntax error that just occurred.
1023 1020
1024 1021 This doesn't display a stack trace because there isn't one.
1025 1022
1026 1023 If a filename is given, it is stuffed in the exception instead
1027 1024 of what was there before (because Python's parser always uses
1028 1025 "<string>" when reading from a string).
1029 1026 """
1030 1027 type, value, sys.last_traceback = sys.exc_info()
1031 1028 sys.last_type = type
1032 1029 sys.last_value = value
1033 1030 if filename and type is SyntaxError:
1034 1031 # Work hard to stuff the correct filename in the exception
1035 1032 try:
1036 1033 msg, (dummy_filename, lineno, offset, line) = value
1037 1034 except:
1038 1035 # Not the format we expect; leave it alone
1039 1036 pass
1040 1037 else:
1041 1038 # Stuff in the right filename
1042 1039 try:
1043 1040 # Assume SyntaxError is a class exception
1044 1041 value = SyntaxError(msg, (filename, lineno, offset, line))
1045 1042 except:
1046 1043 # If that failed, assume SyntaxError is a string
1047 1044 value = msg, (filename, lineno, offset, line)
1048 1045 self.SyntaxTB(type,value,[])
1049 1046
1050 1047 def debugger(self):
1051 1048 """Call the pdb debugger."""
1052 1049
1053 1050 if not self.rc.pdb:
1054 1051 return
1055 1052 pdb.pm()
1056 1053
1057 1054 def showtraceback(self,exc_tuple = None,filename=None):
1058 1055 """Display the exception that just occurred."""
1059 1056
1060 1057 # Though this won't be called by syntax errors in the input line,
1061 1058 # there may be SyntaxError cases whith imported code.
1062 1059 if exc_tuple is None:
1063 1060 type, value, tb = sys.exc_info()
1064 1061 else:
1065 1062 type, value, tb = exc_tuple
1066 1063 if type is SyntaxError:
1067 1064 self.showsyntaxerror(filename)
1068 1065 else:
1069 1066 sys.last_type = type
1070 1067 sys.last_value = value
1071 1068 sys.last_traceback = tb
1072 1069 self.InteractiveTB()
1073 1070 if self.InteractiveTB.call_pdb and self.has_readline:
1074 1071 # pdb mucks up readline, fix it back
1075 1072 self.readline.set_completer(self.Completer.complete)
1076 1073
1077 1074 def update_cache(self, line):
1078 1075 """puts line into cache"""
1079 1076 self.inputcache.insert(0, line) # This copies the cache every time ... :-(
1080 1077 if len(self.inputcache) >= self.CACHELENGTH:
1081 1078 self.inputcache.pop() # This doesn't :-)
1082 1079
1083 1080 def mainloop(self,banner=None):
1084 1081 """Creates the local namespace and starts the mainloop.
1085 1082
1086 1083 If an optional banner argument is given, it will override the
1087 1084 internally created default banner."""
1088 1085
1089 1086 if self.rc.c: # Emulate Python's -c option
1090 1087 self.exec_init_cmd()
1091 1088 if banner is None:
1092 1089 if self.rc.banner:
1093 1090 banner = self.BANNER+self.banner2
1094 1091 else:
1095 1092 banner = ''
1096 1093 self.interact(banner)
1097 1094
1098 1095 def exec_init_cmd(self):
1099 1096 """Execute a command given at the command line.
1100 1097
1101 1098 This emulates Python's -c option."""
1102 1099
1103 1100 sys.argv = ['-c']
1104 1101 self.push(self.rc.c)
1105 1102
1106 1103 def embed_mainloop(self,header='',local_ns=None,global_ns=None,stack_depth=0):
1107 1104 """Embeds IPython into a running python program.
1108 1105
1109 1106 Input:
1110 1107
1111 1108 - header: An optional header message can be specified.
1112 1109
1113 1110 - local_ns, global_ns: working namespaces. If given as None, the
1114 1111 IPython-initialized one is updated with __main__.__dict__, so that
1115 1112 program variables become visible but user-specific configuration
1116 1113 remains possible.
1117 1114
1118 1115 - stack_depth: specifies how many levels in the stack to go to
1119 1116 looking for namespaces (when local_ns and global_ns are None). This
1120 1117 allows an intermediate caller to make sure that this function gets
1121 1118 the namespace from the intended level in the stack. By default (0)
1122 1119 it will get its locals and globals from the immediate caller.
1123 1120
1124 1121 Warning: it's possible to use this in a program which is being run by
1125 1122 IPython itself (via %run), but some funny things will happen (a few
1126 1123 globals get overwritten). In the future this will be cleaned up, as
1127 1124 there is no fundamental reason why it can't work perfectly."""
1128 1125
1129 1126 # Get locals and globals from caller
1130 1127 if local_ns is None or global_ns is None:
1131 1128 call_frame = sys._getframe(stack_depth).f_back
1132 1129
1133 1130 if local_ns is None:
1134 1131 local_ns = call_frame.f_locals
1135 1132 if global_ns is None:
1136 1133 global_ns = call_frame.f_globals
1137 1134
1138 1135 # Update namespaces and fire up interpreter
1139 1136 self.user_ns = local_ns
1140 1137 self.user_global_ns = global_ns
1141 1138
1142 1139 # Patch for global embedding to make sure that things don't overwrite
1143 1140 # user globals accidentally. Thanks to Richard <rxe@renre-europe.com>
1144 1141 # FIXME. Test this a bit more carefully (the if.. is new)
1145 1142 if local_ns is None and global_ns is None:
1146 1143 self.user_global_ns.update(__main__.__dict__)
1147 1144
1148 1145 # make sure the tab-completer has the correct frame information, so it
1149 1146 # actually completes using the frame's locals/globals
1150 1147 self.set_completer_frame(call_frame)
1151 1148
1152 1149 self.interact(header)
1153 1150
1154 1151 def interact(self, banner=None):
1155 1152 """Closely emulate the interactive Python console.
1156 1153
1157 1154 The optional banner argument specify the banner to print
1158 1155 before the first interaction; by default it prints a banner
1159 1156 similar to the one printed by the real Python interpreter,
1160 1157 followed by the current class name in parentheses (so as not
1161 1158 to confuse this with the real interpreter -- since it's so
1162 1159 close!).
1163 1160
1164 1161 """
1165 1162 cprt = 'Type "copyright", "credits" or "license" for more information.'
1166 1163 if banner is None:
1167 1164 self.write("Python %s on %s\n%s\n(%s)\n" %
1168 1165 (sys.version, sys.platform, cprt,
1169 1166 self.__class__.__name__))
1170 1167 else:
1171 1168 self.write(banner)
1172 1169
1173 1170 more = 0
1174 1171
1175 1172 # Mark activity in the builtins
1176 1173 __builtin__.__dict__['__IPYTHON__active'] += 1
1177 1174
1178 1175 # compiled regexps for autoindent management
1179 1176 ini_spaces_re = re.compile(r'^(\s+)')
1180 1177 dedent_re = re.compile(r'^\s+raise|^\s+return')
1181 1178
1182 1179 # exit_now is set by a call to %Exit or %Quit
1183 1180 while not self.exit_now:
1184 1181 try:
1185 1182 if more:
1186 1183 prompt = self.outputcache.prompt2
1187 1184 if self.autoindent:
1188 1185 self.readline_startup_hook(self.pre_readline)
1189 1186 else:
1190 1187 prompt = self.outputcache.prompt1
1191 1188 try:
1192 1189 line = self.raw_input(prompt,more)
1193 1190 if self.autoindent:
1194 1191 self.readline_startup_hook(None)
1195 1192 except EOFError:
1196 1193 if self.autoindent:
1197 1194 self.readline_startup_hook(None)
1198 1195 self.write("\n")
1199 1196 self.exit()
1200 1197 except IPythonExit:
1201 1198 self.exit()
1202 1199 else:
1203 1200 more = self.push(line)
1204 1201 # Auto-indent management
1205 1202 if self.autoindent:
1206 1203 if line:
1207 1204 ini_spaces = ini_spaces_re.match(line)
1208 1205 if ini_spaces:
1209 1206 nspaces = ini_spaces.end()
1210 1207 else:
1211 1208 nspaces = 0
1212 1209 self.readline_indent = nspaces
1213 1210
1214 1211 if line[-1] == ':':
1215 1212 self.readline_indent += 4
1216 1213 elif dedent_re.match(line):
1217 1214 self.readline_indent -= 4
1218 1215 else:
1219 1216 self.readline_indent = 0
1220 1217
1221 1218 except KeyboardInterrupt:
1222 1219 self.write("\nKeyboardInterrupt\n")
1223 1220 self.resetbuffer()
1224 1221 more = 0
1225 1222 # keep cache in sync with the prompt counter:
1226 1223 self.outputcache.prompt_count -= 1
1227 1224
1228 1225 if self.autoindent:
1229 1226 self.readline_indent = 0
1230 1227
1231 1228 except bdb.BdbQuit:
1232 1229 warn("The Python debugger has exited with a BdbQuit exception.\n"
1233 1230 "Because of how pdb handles the stack, it is impossible\n"
1234 1231 "for IPython to properly format this particular exception.\n"
1235 1232 "IPython will resume normal operation.")
1236 1233
1237 1234 # We are off again...
1238 1235 __builtin__.__dict__['__IPYTHON__active'] -= 1
1239 1236
1240 1237 def excepthook(self, type, value, tb):
1241 1238 """One more defense for GUI apps that call sys.excepthook.
1242 1239
1243 1240 GUI frameworks like wxPython trap exceptions and call
1244 1241 sys.excepthook themselves. I guess this is a feature that
1245 1242 enables them to keep running after exceptions that would
1246 1243 otherwise kill their mainloop. This is a bother for IPython
1247 1244 which excepts to catch all of the program exceptions with a try:
1248 1245 except: statement.
1249 1246
1250 1247 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
1251 1248 any app directly invokes sys.excepthook, it will look to the user like
1252 1249 IPython crashed. In order to work around this, we can disable the
1253 1250 CrashHandler and replace it with this excepthook instead, which prints a
1254 1251 regular traceback using our InteractiveTB. In this fashion, apps which
1255 1252 call sys.excepthook will generate a regular-looking exception from
1256 1253 IPython, and the CrashHandler will only be triggered by real IPython
1257 1254 crashes.
1258 1255
1259 1256 This hook should be used sparingly, only in places which are not likely
1260 1257 to be true IPython errors.
1261 1258 """
1262 1259
1263 1260 self.InteractiveTB(type, value, tb, tb_offset=0)
1264 1261 if self.InteractiveTB.call_pdb and self.has_readline:
1265 1262 self.readline.set_completer(self.Completer.complete)
1266 1263
1267 1264 def call_alias(self,alias,rest=''):
1268 1265 """Call an alias given its name and the rest of the line.
1269 1266
1270 1267 This function MUST be given a proper alias, because it doesn't make
1271 1268 any checks when looking up into the alias table. The caller is
1272 1269 responsible for invoking it only with a valid alias."""
1273 1270
1274 1271 #print 'ALIAS: <%s>+<%s>' % (alias,rest) # dbg
1275 1272 nargs,cmd = self.alias_table[alias]
1276 1273 # Expand the %l special to be the user's input line
1277 1274 if cmd.find('%l') >= 0:
1278 1275 cmd = cmd.replace('%l',rest)
1279 1276 rest = ''
1280 1277 if nargs==0:
1281 1278 # Simple, argument-less aliases
1282 1279 cmd = '%s %s' % (cmd,rest)
1283 1280 else:
1284 1281 # Handle aliases with positional arguments
1285 1282 args = rest.split(None,nargs)
1286 1283 if len(args)< nargs:
1287 1284 error('Alias <%s> requires %s arguments, %s given.' %
1288 1285 (alias,nargs,len(args)))
1289 1286 return
1290 1287 cmd = '%s %s' % (cmd % tuple(args[:nargs]),' '.join(args[nargs:]))
1291 1288 # Now call the macro, evaluating in the user's namespace
1292 1289 try:
1293 1290 self.system(cmd)
1294 1291 except:
1295 1292 self.showtraceback()
1296 1293
1297 1294 def runlines(self,lines):
1298 1295 """Run a string of one or more lines of source.
1299 1296
1300 1297 This method is capable of running a string containing multiple source
1301 1298 lines, as if they had been entered at the IPython prompt. Since it
1302 1299 exposes IPython's processing machinery, the given strings can contain
1303 1300 magic calls (%magic), special shell access (!cmd), etc."""
1304 1301
1305 1302 # We must start with a clean buffer, in case this is run from an
1306 1303 # interactive IPython session (via a magic, for example).
1307 1304 self.resetbuffer()
1308 1305 lines = lines.split('\n')
1309 1306 more = 0
1310 1307 for line in lines:
1311 1308 # skip blank lines so we don't mess up the prompt counter, but do
1312 1309 # NOT skip even a blank line if we are in a code block (more is
1313 1310 # true)
1314 1311 if line or more:
1315 1312 more = self.push((self.prefilter(line,more)))
1316 1313 # IPython's runsource returns None if there was an error
1317 1314 # compiling the code. This allows us to stop processing right
1318 1315 # away, so the user gets the error message at the right place.
1319 1316 if more is None:
1320 1317 break
1321 1318 # final newline in case the input didn't have it, so that the code
1322 1319 # actually does get executed
1323 1320 if more:
1324 1321 self.push('\n')
1325 1322
1326 1323 def runsource(self, source, filename="<input>", symbol="single"):
1327 1324 """Compile and run some source in the interpreter.
1328 1325
1329 1326 Arguments are as for compile_command().
1330 1327
1331 1328 One several things can happen:
1332 1329
1333 1330 1) The input is incorrect; compile_command() raised an
1334 1331 exception (SyntaxError or OverflowError). A syntax traceback
1335 1332 will be printed by calling the showsyntaxerror() method.
1336 1333
1337 1334 2) The input is incomplete, and more input is required;
1338 1335 compile_command() returned None. Nothing happens.
1339 1336
1340 1337 3) The input is complete; compile_command() returned a code
1341 1338 object. The code is executed by calling self.runcode() (which
1342 1339 also handles run-time exceptions, except for SystemExit).
1343 1340
1344 1341 The return value is:
1345 1342
1346 1343 - True in case 2
1347 1344
1348 1345 - False in the other cases, unless an exception is raised, where
1349 1346 None is returned instead. This can be used by external callers to
1350 1347 know whether to continue feeding input or not.
1351 1348
1352 1349 The return value can be used to decide whether to use sys.ps1 or
1353 1350 sys.ps2 to prompt the next line."""
1354 1351
1355 1352 try:
1356 1353 code = self.compile(source, filename, symbol)
1357 1354 except (OverflowError, SyntaxError, ValueError):
1358 1355 # Case 1
1359 1356 self.showsyntaxerror(filename)
1360 1357 return None
1361 1358
1362 1359 if code is None:
1363 1360 # Case 2
1364 1361 return True
1365 1362
1366 1363 # Case 3
1367 1364 # We store the code object so that threaded shells and
1368 1365 # custom exception handlers can access all this info if needed.
1369 1366 # The source corresponding to this can be obtained from the
1370 1367 # buffer attribute as '\n'.join(self.buffer).
1371 1368 self.code_to_run = code
1372 1369 # now actually execute the code object
1373 1370 if self.runcode(code) == 0:
1374 1371 return False
1375 1372 else:
1376 1373 return None
1377 1374
1378 1375 def runcode(self,code_obj):
1379 1376 """Execute a code object.
1380 1377
1381 1378 When an exception occurs, self.showtraceback() is called to display a
1382 1379 traceback.
1383 1380
1384 1381 Return value: a flag indicating whether the code to be run completed
1385 1382 successfully:
1386 1383
1387 1384 - 0: successful execution.
1388 1385 - 1: an error occurred.
1389 1386 """
1390 1387
1391 1388 # Set our own excepthook in case the user code tries to call it
1392 1389 # directly, so that the IPython crash handler doesn't get triggered
1393 1390 old_excepthook,sys.excepthook = sys.excepthook, self.excepthook
1394 1391 outflag = 1 # happens in more places, so it's easier as default
1395 1392 try:
1396 1393 try:
1397 1394 # Embedded instances require separate global/local namespaces
1398 1395 # so they can see both the surrounding (local) namespace and
1399 1396 # the module-level globals when called inside another function.
1400 1397 if self.embedded:
1401 1398 exec code_obj in self.user_global_ns, self.user_ns
1402 1399 # Normal (non-embedded) instances should only have a single
1403 1400 # namespace for user code execution, otherwise functions won't
1404 1401 # see interactive top-level globals.
1405 1402 else:
1406 1403 exec code_obj in self.user_ns
1407 1404 finally:
1408 1405 # Reset our crash handler in place
1409 1406 sys.excepthook = old_excepthook
1410 1407 except SystemExit:
1411 1408 self.resetbuffer()
1412 1409 self.showtraceback()
1413 1410 warn("Type exit or quit to exit IPython "
1414 1411 "(%Exit or %Quit do so unconditionally).",level=1)
1415 1412 except self.custom_exceptions:
1416 1413 etype,value,tb = sys.exc_info()
1417 1414 self.CustomTB(etype,value,tb)
1418 1415 except:
1419 1416 self.showtraceback()
1420 1417 else:
1421 1418 outflag = 0
1422 1419 if softspace(sys.stdout, 0):
1423 1420 print
1424 1421 # Flush out code object which has been run (and source)
1425 1422 self.code_to_run = None
1426 1423 return outflag
1427 1424
1428 1425 def push(self, line):
1429 1426 """Push a line to the interpreter.
1430 1427
1431 1428 The line should not have a trailing newline; it may have
1432 1429 internal newlines. The line is appended to a buffer and the
1433 1430 interpreter's runsource() method is called with the
1434 1431 concatenated contents of the buffer as source. If this
1435 1432 indicates that the command was executed or invalid, the buffer
1436 1433 is reset; otherwise, the command is incomplete, and the buffer
1437 1434 is left as it was after the line was appended. The return
1438 1435 value is 1 if more input is required, 0 if the line was dealt
1439 1436 with in some way (this is the same as runsource()).
1440 1437
1441 1438 """
1442 1439 self.buffer.append(line)
1443 source = "\n".join(self.buffer)
1444 more = self.runsource(source, self.filename)
1440 more = self.runsource('\n'.join(self.buffer), self.filename)
1445 1441 if not more:
1446 1442 self.resetbuffer()
1447 1443 return more
1448 1444
1449 1445 def resetbuffer(self):
1450 1446 """Reset the input buffer."""
1451 1447 self.buffer[:] = []
1452 1448
1453 1449 def raw_input(self,prompt='',continue_prompt=False):
1454 1450 """Write a prompt and read a line.
1455 1451
1456 1452 The returned line does not include the trailing newline.
1457 1453 When the user enters the EOF key sequence, EOFError is raised.
1458 1454
1459 1455 Optional inputs:
1460 1456
1461 1457 - prompt(''): a string to be printed to prompt the user.
1462 1458
1463 1459 - continue_prompt(False): whether this line is the first one or a
1464 1460 continuation in a sequence of inputs.
1465 1461 """
1466 1462
1467 1463 line = raw_input_original(prompt)
1468 1464 # Try to be reasonably smart about not re-indenting pasted input more
1469 1465 # than necessary. We do this by trimming out the auto-indent initial
1470 1466 # spaces, if the user's actual input started itself with whitespace.
1471 1467 if self.autoindent:
1472 1468 line2 = line[self.readline_indent:]
1473 1469 if line2[0:1] in (' ','\t'):
1474 1470 line = line2
1475 1471 return self.prefilter(line,continue_prompt)
1476 1472
1477 1473 def split_user_input(self,line):
1478 1474 """Split user input into pre-char, function part and rest."""
1479 1475
1480 1476 lsplit = self.line_split.match(line)
1481 1477 if lsplit is None: # no regexp match returns None
1482 1478 try:
1483 1479 iFun,theRest = line.split(None,1)
1484 1480 except ValueError:
1485 1481 iFun,theRest = line,''
1486 1482 pre = re.match('^(\s*)(.*)',line).groups()[0]
1487 1483 else:
1488 1484 pre,iFun,theRest = lsplit.groups()
1489 1485
1490 1486 #print 'line:<%s>' % line # dbg
1491 1487 #print 'pre <%s> iFun <%s> rest <%s>' % (pre,iFun.strip(),theRest) # dbg
1492 1488 return pre,iFun.strip(),theRest
1493 1489
1494 1490 def _prefilter(self, line, continue_prompt):
1495 1491 """Calls different preprocessors, depending on the form of line."""
1496 1492
1497 1493 # All handlers *must* return a value, even if it's blank ('').
1498 1494
1499 1495 # Lines are NOT logged here. Handlers should process the line as
1500 1496 # needed, update the cache AND log it (so that the input cache array
1501 1497 # stays synced).
1502 1498
1503 1499 # This function is _very_ delicate, and since it's also the one which
1504 1500 # determines IPython's response to user input, it must be as efficient
1505 1501 # as possible. For this reason it has _many_ returns in it, trying
1506 1502 # always to exit as quickly as it can figure out what it needs to do.
1507 1503
1508 1504 # This function is the main responsible for maintaining IPython's
1509 1505 # behavior respectful of Python's semantics. So be _very_ careful if
1510 1506 # making changes to anything here.
1511 1507
1512 1508 #.....................................................................
1513 1509 # Code begins
1514 1510
1515 1511 #if line.startswith('%crash'): raise RuntimeError,'Crash now!' # dbg
1516 1512
1517 1513 # save the line away in case we crash, so the post-mortem handler can
1518 1514 # record it
1519 1515 self._last_input_line = line
1520 1516
1521 1517 #print '***line: <%s>' % line # dbg
1522 1518
1523 1519 # the input history needs to track even empty lines
1524 1520 if not line.strip():
1525 1521 if not continue_prompt:
1526 1522 self.outputcache.prompt_count -= 1
1527 1523 return self.handle_normal('',continue_prompt)
1528 1524
1529 1525 # print '***cont',continue_prompt # dbg
1530 1526 # special handlers are only allowed for single line statements
1531 1527 if continue_prompt and not self.rc.multi_line_specials:
1532 1528 return self.handle_normal(line,continue_prompt)
1533 1529
1534 1530 # For the rest, we need the structure of the input
1535 1531 pre,iFun,theRest = self.split_user_input(line)
1536 1532 #print 'pre <%s> iFun <%s> rest <%s>' % (pre,iFun,theRest) # dbg
1537 1533
1538 1534 # First check for explicit escapes in the last/first character
1539 1535 handler = None
1540 1536 if line[-1] == self.ESC_HELP:
1541 1537 handler = self.esc_handlers.get(line[-1]) # the ? can be at the end
1542 1538 if handler is None:
1543 1539 # look at the first character of iFun, NOT of line, so we skip
1544 1540 # leading whitespace in multiline input
1545 1541 handler = self.esc_handlers.get(iFun[0:1])
1546 1542 if handler is not None:
1547 1543 return handler(line,continue_prompt,pre,iFun,theRest)
1548 1544 # Emacs ipython-mode tags certain input lines
1549 1545 if line.endswith('# PYTHON-MODE'):
1550 1546 return self.handle_emacs(line,continue_prompt)
1551 1547
1552 1548 # Next, check if we can automatically execute this thing
1553 1549
1554 1550 # Allow ! in multi-line statements if multi_line_specials is on:
1555 1551 if continue_prompt and self.rc.multi_line_specials and \
1556 1552 iFun.startswith(self.ESC_SHELL):
1557 1553 return self.handle_shell_escape(line,continue_prompt,
1558 1554 pre=pre,iFun=iFun,
1559 1555 theRest=theRest)
1560 1556
1561 1557 # Let's try to find if the input line is a magic fn
1562 1558 oinfo = None
1563 1559 if hasattr(self,'magic_'+iFun):
1564 1560 oinfo = self._ofind(iFun) # FIXME - _ofind is part of Magic
1565 1561 if oinfo['ismagic']:
1566 1562 # Be careful not to call magics when a variable assignment is
1567 1563 # being made (ls='hi', for example)
1568 1564 if self.rc.automagic and \
1569 1565 (len(theRest)==0 or theRest[0] not in '!=()<>,') and \
1570 1566 (self.rc.multi_line_specials or not continue_prompt):
1571 1567 return self.handle_magic(line,continue_prompt,
1572 1568 pre,iFun,theRest)
1573 1569 else:
1574 1570 return self.handle_normal(line,continue_prompt)
1575 1571
1576 1572 # If the rest of the line begins with an (in)equality, assginment or
1577 1573 # function call, we should not call _ofind but simply execute it.
1578 1574 # This avoids spurious geattr() accesses on objects upon assignment.
1579 1575 #
1580 1576 # It also allows users to assign to either alias or magic names true
1581 1577 # python variables (the magic/alias systems always take second seat to
1582 1578 # true python code).
1583 1579 if theRest and theRest[0] in '!=()':
1584 1580 return self.handle_normal(line,continue_prompt)
1585 1581
1586 1582 if oinfo is None:
1587 1583 oinfo = self._ofind(iFun) # FIXME - _ofind is part of Magic
1588 1584
1589 1585 if not oinfo['found']:
1590 1586 if iFun in ('quit','exit'):
1591 1587 raise IPythonExit
1592 1588 return self.handle_normal(line,continue_prompt)
1593 1589 else:
1594 1590 #print 'iFun <%s> rest <%s>' % (iFun,theRest) # dbg
1595 1591 if oinfo['isalias']:
1596 1592 return self.handle_alias(line,continue_prompt,
1597 1593 pre,iFun,theRest)
1598 1594
1599 1595 if self.rc.autocall and \
1600 1596 not self.re_exclude_auto.match(theRest) and \
1601 1597 self.re_fun_name.match(iFun) and \
1602 1598 callable(oinfo['obj']) :
1603 1599 #print 'going auto' # dbg
1604 1600 return self.handle_auto(line,continue_prompt,pre,iFun,theRest)
1605 1601 else:
1606 1602 #print 'was callable?', callable(oinfo['obj']) # dbg
1607 1603 return self.handle_normal(line,continue_prompt)
1608 1604
1609 1605 # If we get here, we have a normal Python line. Log and return.
1610 1606 return self.handle_normal(line,continue_prompt)
1611 1607
1612 1608 def _prefilter_dumb(self, line, continue_prompt):
1613 1609 """simple prefilter function, for debugging"""
1614 1610 return self.handle_normal(line,continue_prompt)
1615 1611
1616 1612 # Set the default prefilter() function (this can be user-overridden)
1617 1613 prefilter = _prefilter
1618 1614
1619 1615 def handle_normal(self,line,continue_prompt=None,
1620 1616 pre=None,iFun=None,theRest=None):
1621 1617 """Handle normal input lines. Use as a template for handlers."""
1622 1618
1623 1619 self.log(line,continue_prompt)
1624 1620 self.update_cache(line)
1625 1621 return line
1626 1622
1627 1623 def handle_alias(self,line,continue_prompt=None,
1628 1624 pre=None,iFun=None,theRest=None):
1629 1625 """Handle alias input lines. """
1630 1626
1631 1627 theRest = esc_quotes(theRest)
1632 1628 line_out = "%s%s.call_alias('%s','%s')" % (pre,self.name,iFun,theRest)
1633 1629 self.log(line_out,continue_prompt)
1634 1630 self.update_cache(line_out)
1635 1631 return line_out
1636 1632
1637 1633 def handle_shell_escape(self, line, continue_prompt=None,
1638 1634 pre=None,iFun=None,theRest=None):
1639 1635 """Execute the line in a shell, empty return value"""
1640 1636
1641 1637 #print 'line in :', `line` # dbg
1642 1638 # Example of a special handler. Others follow a similar pattern.
1643 1639 if continue_prompt: # multi-line statements
1644 1640 if iFun.startswith('!!'):
1645 1641 print 'SyntaxError: !! is not allowed in multiline statements'
1646 1642 return pre
1647 1643 else:
1648 1644 cmd = ("%s %s" % (iFun[1:],theRest)).replace('"','\\"')
1649 1645 line_out = '%s%s.system("%s")' % (pre,self.name,cmd)
1650 1646 #line_out = ('%s%s.system(' % (pre,self.name)) + repr(cmd) + ')'
1651 1647 else: # single-line input
1652 1648 if line.startswith('!!'):
1653 1649 # rewrite iFun/theRest to properly hold the call to %sx and
1654 1650 # the actual command to be executed, so handle_magic can work
1655 1651 # correctly
1656 1652 theRest = '%s %s' % (iFun[2:],theRest)
1657 1653 iFun = 'sx'
1658 1654 return self.handle_magic('%ssx %s' % (self.ESC_MAGIC,line[2:]),
1659 1655 continue_prompt,pre,iFun,theRest)
1660 1656 else:
1661 1657 cmd = esc_quotes(line[1:])
1662 1658 line_out = '%s.system("%s")' % (self.name,cmd)
1663 1659 #line_out = ('%s.system(' % self.name) + repr(cmd)+ ')'
1664 1660 # update cache/log and return
1665 1661 self.log(line_out,continue_prompt)
1666 1662 self.update_cache(line_out) # readline cache gets normal line
1667 1663 #print 'line out r:', `line_out` # dbg
1668 1664 #print 'line out s:', line_out # dbg
1669 1665 return line_out
1670 1666
1671 1667 def handle_magic(self, line, continue_prompt=None,
1672 1668 pre=None,iFun=None,theRest=None):
1673 1669 """Execute magic functions.
1674 1670
1675 1671 Also log them with a prepended # so the log is clean Python."""
1676 1672
1677 1673 cmd = '%sipmagic("%s")' % (pre,esc_quotes('%s %s' % (iFun,theRest)))
1678 1674 self.log(cmd,continue_prompt)
1679 1675 self.update_cache(line)
1680 1676 #print 'in handle_magic, cmd=<%s>' % cmd # dbg
1681 1677 return cmd
1682 1678
1683 1679 def handle_auto(self, line, continue_prompt=None,
1684 1680 pre=None,iFun=None,theRest=None):
1685 1681 """Hande lines which can be auto-executed, quoting if requested."""
1686 1682
1687 1683 #print 'pre <%s> iFun <%s> rest <%s>' % (pre,iFun,theRest) # dbg
1688 1684
1689 1685 # This should only be active for single-line input!
1690 1686 if continue_prompt:
1691 1687 return line
1692 1688
1693 1689 if pre == self.ESC_QUOTE:
1694 1690 # Auto-quote splitting on whitespace
1695 1691 newcmd = '%s("%s")' % (iFun,'", "'.join(theRest.split()) )
1696 1692 elif pre == self.ESC_QUOTE2:
1697 1693 # Auto-quote whole string
1698 1694 newcmd = '%s("%s")' % (iFun,theRest)
1699 1695 else:
1700 1696 # Auto-paren
1701 1697 if theRest[0:1] in ('=','['):
1702 1698 # Don't autocall in these cases. They can be either
1703 1699 # rebindings of an existing callable's name, or item access
1704 1700 # for an object which is BOTH callable and implements
1705 1701 # __getitem__.
1706 1702 return '%s %s' % (iFun,theRest)
1707 1703 if theRest.endswith(';'):
1708 1704 newcmd = '%s(%s);' % (iFun.rstrip(),theRest[:-1])
1709 1705 else:
1710 1706 newcmd = '%s(%s)' % (iFun.rstrip(),theRest)
1711 1707
1712 1708 print >>Term.cout, self.outputcache.prompt1.auto_rewrite() + newcmd
1713 1709 # log what is now valid Python, not the actual user input (without the
1714 1710 # final newline)
1715 1711 self.log(newcmd,continue_prompt)
1716 1712 return newcmd
1717 1713
1718 1714 def handle_help(self, line, continue_prompt=None,
1719 1715 pre=None,iFun=None,theRest=None):
1720 1716 """Try to get some help for the object.
1721 1717
1722 1718 obj? or ?obj -> basic information.
1723 1719 obj?? or ??obj -> more details.
1724 1720 """
1725 1721
1726 1722 # We need to make sure that we don't process lines which would be
1727 1723 # otherwise valid python, such as "x=1 # what?"
1728 1724 try:
1729 1725 codeop.compile_command(line)
1730 1726 except SyntaxError:
1731 1727 # We should only handle as help stuff which is NOT valid syntax
1732 1728 if line[0]==self.ESC_HELP:
1733 1729 line = line[1:]
1734 1730 elif line[-1]==self.ESC_HELP:
1735 1731 line = line[:-1]
1736 1732 self.log('#?'+line)
1737 1733 self.update_cache(line)
1738 1734 if line:
1739 1735 self.magic_pinfo(line)
1740 1736 else:
1741 1737 page(self.usage,screen_lines=self.rc.screen_length)
1742 1738 return '' # Empty string is needed here!
1743 1739 except:
1744 1740 # Pass any other exceptions through to the normal handler
1745 1741 return self.handle_normal(line,continue_prompt)
1746 1742 else:
1747 1743 # If the code compiles ok, we should handle it normally
1748 1744 return self.handle_normal(line,continue_prompt)
1749 1745
1750 1746 def handle_emacs(self,line,continue_prompt=None,
1751 1747 pre=None,iFun=None,theRest=None):
1752 1748 """Handle input lines marked by python-mode."""
1753 1749
1754 1750 # Currently, nothing is done. Later more functionality can be added
1755 1751 # here if needed.
1756 1752
1757 1753 # The input cache shouldn't be updated
1758 1754
1759 1755 return line
1760 1756
1761 1757 def write(self,data):
1762 1758 """Write a string to the default output"""
1763 1759 Term.cout.write(data)
1764 1760
1765 1761 def write_err(self,data):
1766 1762 """Write a string to the default error output"""
1767 1763 Term.cerr.write(data)
1768 1764
1769 1765 def exit(self):
1770 1766 """Handle interactive exit.
1771 1767
1772 1768 This method sets the exit_now attribute."""
1773 1769
1774 1770 if self.rc.confirm_exit:
1775 1771 if ask_yes_no('Do you really want to exit ([y]/n)?','y'):
1776 1772 self.exit_now = True
1777 1773 else:
1778 1774 self.exit_now = True
1779 1775 return self.exit_now
1780 1776
1781 1777 def safe_execfile(self,fname,*where,**kw):
1782 1778 fname = os.path.expanduser(fname)
1783 1779
1784 1780 # find things also in current directory
1785 1781 dname = os.path.dirname(fname)
1786 1782 if not sys.path.count(dname):
1787 1783 sys.path.append(dname)
1788 1784
1789 1785 try:
1790 1786 xfile = open(fname)
1791 1787 except:
1792 1788 print >> Term.cerr, \
1793 1789 'Could not open file <%s> for safe execution.' % fname
1794 1790 return None
1795 1791
1796 1792 kw.setdefault('islog',0)
1797 1793 kw.setdefault('quiet',1)
1798 1794 kw.setdefault('exit_ignore',0)
1799 1795 first = xfile.readline()
1800 1796 _LOGHEAD = str(self.LOGHEAD).split('\n',1)[0].strip()
1801 1797 xfile.close()
1802 1798 # line by line execution
1803 1799 if first.startswith(_LOGHEAD) or kw['islog']:
1804 1800 print 'Loading log file <%s> one line at a time...' % fname
1805 1801 if kw['quiet']:
1806 1802 stdout_save = sys.stdout
1807 1803 sys.stdout = StringIO.StringIO()
1808 1804 try:
1809 1805 globs,locs = where[0:2]
1810 1806 except:
1811 1807 try:
1812 1808 globs = locs = where[0]
1813 1809 except:
1814 1810 globs = locs = globals()
1815 1811 badblocks = []
1816 1812
1817 1813 # we also need to identify indented blocks of code when replaying
1818 1814 # logs and put them together before passing them to an exec
1819 1815 # statement. This takes a bit of regexp and look-ahead work in the
1820 1816 # file. It's easiest if we swallow the whole thing in memory
1821 1817 # first, and manually walk through the lines list moving the
1822 1818 # counter ourselves.
1823 1819 indent_re = re.compile('\s+\S')
1824 1820 xfile = open(fname)
1825 1821 filelines = xfile.readlines()
1826 1822 xfile.close()
1827 1823 nlines = len(filelines)
1828 1824 lnum = 0
1829 1825 while lnum < nlines:
1830 1826 line = filelines[lnum]
1831 1827 lnum += 1
1832 1828 # don't re-insert logger status info into cache
1833 1829 if line.startswith('#log#'):
1834 1830 continue
1835 1831 elif line.startswith('#%s'% self.ESC_MAGIC):
1836 1832 self.update_cache(line[1:])
1837 1833 line = magic2python(line)
1838 1834 elif line.startswith('#!'):
1839 1835 self.update_cache(line[1:])
1840 1836 else:
1841 1837 # build a block of code (maybe a single line) for execution
1842 1838 block = line
1843 1839 try:
1844 1840 next = filelines[lnum] # lnum has already incremented
1845 1841 except:
1846 1842 next = None
1847 1843 while next and indent_re.match(next):
1848 1844 block += next
1849 1845 lnum += 1
1850 1846 try:
1851 1847 next = filelines[lnum]
1852 1848 except:
1853 1849 next = None
1854 1850 # now execute the block of one or more lines
1855 1851 try:
1856 1852 exec block in globs,locs
1857 1853 self.update_cache(block.rstrip())
1858 1854 except SystemExit:
1859 1855 pass
1860 1856 except:
1861 1857 badblocks.append(block.rstrip())
1862 1858 if kw['quiet']: # restore stdout
1863 1859 sys.stdout.close()
1864 1860 sys.stdout = stdout_save
1865 1861 print 'Finished replaying log file <%s>' % fname
1866 1862 if badblocks:
1867 1863 print >> sys.stderr, ('\nThe following lines/blocks in file '
1868 1864 '<%s> reported errors:' % fname)
1869 1865
1870 1866 for badline in badblocks:
1871 1867 print >> sys.stderr, badline
1872 1868 else: # regular file execution
1873 1869 try:
1874 1870 execfile(fname,*where)
1875 1871 except SyntaxError:
1876 1872 etype, evalue = sys.exc_info()[0:2]
1877 1873 self.SyntaxTB(etype,evalue,[])
1878 1874 warn('Failure executing file: <%s>' % fname)
1879 1875 except SystemExit,status:
1880 1876 if not kw['exit_ignore']:
1881 1877 self.InteractiveTB()
1882 1878 warn('Failure executing file: <%s>' % fname)
1883 1879 except:
1884 1880 self.InteractiveTB()
1885 1881 warn('Failure executing file: <%s>' % fname)
1886 1882
1887 1883 #************************* end of file <iplib.py> *****************************
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
General Comments 0
You need to be logged in to leave comments. Login now