##// END OF EJS Templates
Reorganized the directory for ipython/ to have its own dir, which is a bit...
fperez -
r0:6f629fcc
parent child Browse files
Show More

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

@@ -0,0 +1,155 b''
1 # -*- coding: utf-8 -*-
2 """Tools for coloring text in ANSI terminals.
3
4 $Id: ColorANSI.py 410 2004-11-04 07:58:17Z fperez $"""
5
6 #*****************************************************************************
7 # Copyright (C) 2002-2004 Fernando Perez. <fperez@colorado.edu>
8 #
9 # Distributed under the terms of the BSD License. The full license is in
10 # the file COPYING, distributed as part of this software.
11 #*****************************************************************************
12
13 from IPython import Release
14 __author__ = '%s <%s>' % Release.authors['Fernando']
15 __license__ = Release.license
16
17 __all__ = ['TermColors','InputTermColors','ColorScheme','ColorSchemeTable']
18
19 import os
20 from UserDict import UserDict
21
22 from IPython.Struct import Struct
23
24 def make_color_table(in_class):
25 """Build a set of color attributes in a class.
26
27 Helper function for building the *TermColors classes."""
28
29 color_templates = (
30 ("Black" , "0;30"),
31 ("Red" , "0;31"),
32 ("Green" , "0;32"),
33 ("Brown" , "0;33"),
34 ("Blue" , "0;34"),
35 ("Purple" , "0;35"),
36 ("Cyan" , "0;36"),
37 ("LightGray" , "0;37"),
38 ("DarkGray" , "1;30"),
39 ("LightRed" , "1;31"),
40 ("LightGreen" , "1;32"),
41 ("Yellow" , "1;33"),
42 ("LightBlue" , "1;34"),
43 ("LightPurple" , "1;35"),
44 ("LightCyan" , "1;36"),
45 ("White" , "1;37"), )
46
47 for name,value in color_templates:
48 setattr(in_class,name,in_class._base % value)
49
50 class TermColors:
51 """Color escape sequences.
52
53 This class defines the escape sequences for all the standard (ANSI?)
54 colors in terminals. Also defines a NoColor escape which is just the null
55 string, suitable for defining 'dummy' color schemes in terminals which get
56 confused by color escapes.
57
58 This class should be used as a mixin for building color schemes."""
59
60 NoColor = '' # for color schemes in color-less terminals.
61 Normal = '\033[0m' # Reset normal coloring
62 _base = '\033[%sm' # Template for all other colors
63
64 # Build the actual color table as a set of class attributes:
65 make_color_table(TermColors)
66
67 class InputTermColors:
68 """Color escape sequences for input prompts.
69
70 This class is similar to TermColors, but the escapes are wrapped in \001
71 and \002 so that readline can properly know the length of each line and
72 can wrap lines accordingly. Use this class for any colored text which
73 needs to be used in input prompts, such as in calls to raw_input().
74
75 This class defines the escape sequences for all the standard (ANSI?)
76 colors in terminals. Also defines a NoColor escape which is just the null
77 string, suitable for defining 'dummy' color schemes in terminals which get
78 confused by color escapes.
79
80 This class should be used as a mixin for building color schemes."""
81
82 NoColor = '' # for color schemes in color-less terminals.
83 Normal = '\001\033[0m\002' # Reset normal coloring
84 _base = '\001\033[%sm\002' # Template for all other colors
85
86 # Build the actual color table as a set of class attributes:
87 make_color_table(InputTermColors)
88
89 class ColorScheme:
90 """Generic color scheme class. Just a name and a Struct."""
91 def __init__(self,__scheme_name_,colordict=None,**colormap):
92 self.name = __scheme_name_
93 if colordict is None:
94 self.colors = Struct(**colormap)
95 else:
96 self.colors = Struct(colordict)
97
98 class ColorSchemeTable(UserDict):
99 """General class to handle tables of color schemes.
100
101 It's basically a dict of color schemes with a couple of shorthand
102 attributes and some convenient methods.
103
104 active_scheme_name -> obvious
105 active_colors -> actual color table of the active scheme"""
106
107 def __init__(self,scheme_list=None,default_scheme=''):
108 """Create a table of color schemes.
109
110 The table can be created empty and manually filled or it can be
111 created with a list of valid color schemes AND the specification for
112 the default active scheme.
113 """
114
115 UserDict.__init__(self)
116 if scheme_list is None:
117 self.active_scheme_name = ''
118 self.active_colors = None
119 else:
120 if default_scheme == '':
121 raise ValueError,'you must specify the default color scheme'
122 for scheme in scheme_list:
123 self.add_scheme(scheme)
124 self.set_active_scheme(default_scheme)
125
126 def add_scheme(self,new_scheme):
127 """Add a new color scheme to the table."""
128 if not isinstance(new_scheme,ColorScheme):
129 raise ValueError,'ColorSchemeTable only accepts ColorScheme instances'
130 self[new_scheme.name] = new_scheme
131
132 def set_active_scheme(self,scheme,case_sensitive=0):
133 """Set the currently active scheme.
134
135 Names are by default compared in a case-insensitive way, but this can
136 be changed by setting the parameter case_sensitive to true."""
137
138 scheme_list = self.keys()
139 if case_sensitive:
140 valid_schemes = scheme_list
141 scheme_test = scheme
142 else:
143 valid_schemes = [s.lower() for s in scheme_list]
144 scheme_test = scheme.lower()
145 try:
146 scheme_idx = valid_schemes.index(scheme_test)
147 except ValueError:
148 raise ValueError,'Unrecognized color scheme: ' + scheme + \
149 '\nValid schemes: '+str(scheme_list).replace("'', ",'')
150 else:
151 active = scheme_list[scheme_idx]
152 self.active_scheme_name = active
153 self.active_colors = self[active].colors
154 # Now allow using '' as an index for the current active scheme
155 self[''] = self[active]
@@ -0,0 +1,116 b''
1 # -*- coding: utf-8 -*-
2 """Configuration loader
3
4 $Id: ConfigLoader.py 525 2005-02-19 10:53:12Z fperez $"""
5
6 #*****************************************************************************
7 # Copyright (C) 2001-2004 Fernando Perez. <fperez@colorado.edu>
8 #
9 # Distributed under the terms of the BSD License. The full license is in
10 # the file COPYING, distributed as part of this software.
11 #*****************************************************************************
12
13 from IPython import Release
14 __author__ = '%s <%s>' % Release.authors['Fernando']
15 __license__ = Release.license
16
17 import os
18 from pprint import pprint
19 import exceptions
20
21 from IPython import ultraTB
22 from IPython.Struct import Struct
23 from IPython.genutils import *
24
25 class ConfigLoaderError(exceptions.Exception):
26 """Exception for ConfigLoader class."""
27
28 def __init__(self,args=None):
29 self.args = args
30
31 class ConfigLoader:
32
33 """Configuration file loader capable of handling recursive inclusions and
34 with parametrized conflict resolution for multiply found keys."""
35
36 def __init__(self,conflict=None,field_sep=None,reclimit=15):
37
38 """The reclimit parameter controls the number of recursive
39 configuration file inclusions. This way we can stop early on (before
40 python's own recursion limit is hit) if there is a circular
41 inclusion.
42
43 - conflict: dictionary for conflict resolutions (see Struct.merge())
44
45 """
46 self.conflict = conflict
47 self.field_sep = field_sep
48 self.reset(reclimit)
49
50 def reset(self,reclimit=15):
51 self.reclimit = reclimit
52 self.recdepth = 0
53 self.included = []
54
55 def load(self,fname,convert=None,recurse_key='',incpath = '.',**kw):
56 """Load a configuration file, return the resulting Struct.
57
58 Call: load_config(fname,convert=None,conflict=None,recurse_key='')
59
60 - fname: file to load from.
61 - convert: dictionary of type conversions (see read_dict())
62 - recurse_key: keyword in dictionary to trigger recursive file
63 inclusions.
64 """
65
66 if self.recdepth > self.reclimit:
67 raise ConfigLoaderError, 'maximum recursive inclusion of rcfiles '+\
68 'exceeded: ' + `self.recdepth` + \
69 '.\nMaybe you have a circular chain of inclusions?'
70 self.recdepth += 1
71 fname = filefind(fname,incpath)
72 data = Struct()
73 # avoid including the same file more than once
74 if fname in self.included:
75 return data
76 Xinfo = ultraTB.AutoFormattedTB()
77 if convert==None and recurse_key : convert = {qwflat:recurse_key}
78 # for production, change warn to 0:
79 data.merge(read_dict(fname,convert,fs=self.field_sep,strip=1,
80 warn=0,no_empty=0,**kw))
81 # keep track of successfully loaded files
82 self.included.append(fname)
83 if recurse_key in data.keys():
84 for incfilename in data[recurse_key]:
85 found=0
86 try:
87 incfile = filefind(incfilename,incpath)
88 except IOError:
89 if os.name in ['nt','dos']:
90 try:
91 # Try again with '.ini' extension
92 incfilename += '.ini'
93 incfile = filefind(incfilename,incpath)
94 except IOError:
95 found = 0
96 else:
97 found = 1
98 else:
99 found = 0
100 else:
101 found = 1
102 if found:
103 try:
104 data.merge(self.load(incfile,convert,recurse_key,
105 incpath,**kw),
106 self.conflict)
107 except:
108 Xinfo()
109 warn('Problem loading included file: '+
110 `incfilename` + '. Ignoring it...')
111 else:
112 warn('File `%s` not found. Included by %s' % (incfilename,fname))
113
114 return data
115
116 # end ConfigLoader
@@ -0,0 +1,109 b''
1 # -*- coding: utf-8 -*-
2 """sys.excepthook for IPython itself, leaves a detailed report on disk.
3
4 $Id: CrashHandler.py 410 2004-11-04 07:58:17Z fperez $"""
5
6 #*****************************************************************************
7 # Copyright (C) 2001-2004 Fernando Perez. <fperez@colorado.edu>
8 #
9 # Distributed under the terms of the BSD License. The full license is in
10 # the file COPYING, distributed as part of this software.
11 #*****************************************************************************
12
13 from IPython import Release
14 __author__ = '%s <%s>' % Release.authors['Fernando']
15 __license__ = Release.license
16 __version__ = Release.version
17
18 #****************************************************************************
19 # Required modules
20
21 # From the standard library
22 import os,sys
23 from pprint import pprint,pformat
24
25 # Homebrewed
26 from IPython.genutils import *
27 from IPython.Itpl import Itpl,itpl,printpl
28 from IPython import ultraTB
29 from IPython.ultraTB import ColorScheme,ColorSchemeTable # too long names
30
31 #****************************************************************************
32 class CrashHandler:
33 """sys.excepthook for IPython itself, leaves a detailed report on disk."""
34
35 def __init__(self,IP):
36 self.IP = IP # IPython instance
37 self.bug_contact = Release.authors['Fernando'][0]
38 self.mailto = Release.authors['Fernando'][1]
39
40 def __call__(self,etype, evalue, etb):
41
42 # Report tracebacks shouldn't use color in general (safer for users)
43 color_scheme = 'NoColor'
44
45 # Use this ONLY for developer debugging (keep commented out for release)
46 #color_scheme = 'Linux' # dbg
47
48 try:
49 rptdir = self.IP.rc.ipythondir
50 except:
51 rptdir = os.getcwd()
52 if not os.path.isdir(rptdir):
53 rptdir = os.getcwd()
54 self.report_name = os.path.join(rptdir,'IPython_crash_report.txt')
55 self.TBhandler = ultraTB.VerboseTB(color_scheme=color_scheme,long_header=1)
56 traceback = self.TBhandler.text(etype,evalue,etb,context=31)
57
58 # print traceback to screen
59 print >> sys.stderr, traceback
60
61 # and generate a complete report on disk
62 try:
63 report = open(self.report_name,'w')
64 except:
65 print >> sys.stderr, 'Could not create crash report on disk.'
66 return
67
68 msg = itpl('\n'+'*'*70+'\n'
69 """
70 Oops, IPython crashed. We do our best to make it stable, but...
71
72 A crash report was automatically generated with the following information:
73 - A verbatim copy of the traceback above this text.
74 - A copy of your input history during this session.
75 - Data on your current IPython configuration.
76
77 It was left in the file named:
78 \t'$self.report_name'
79 If you can email this file to the developers, the information in it will help
80 them in understanding and correcting the problem.
81
82 You can mail it to $self.bug_contact at $self.mailto
83 with the subject 'IPython Crash Report'.
84
85 If you want to do it now, the following command will work (under Unix):
86 mail -s 'IPython Crash Report' $self.mailto < $self.report_name
87
88 To ensure accurate tracking of this issue, please file a report about it at:
89 http://www.scipy.net/roundup/ipython (IPython's online bug tracker).
90 """)
91 print >> sys.stderr, msg
92
93 sec_sep = '\n\n'+'*'*75+'\n\n'
94 report.write('*'*75+'\n\n'+'IPython post-mortem report\n\n')
95 report.write('IPython version: %s \n\n' % __version__)
96 report.write('Platform info : os.name -> %s, sys.platform -> %s' %
97 (os.name,sys.platform) )
98 report.write(sec_sep+'Current user configuration structure:\n\n')
99 report.write(pformat(self.IP.rc.dict()))
100 report.write(sec_sep+'Crash traceback:\n\n' + traceback)
101 try:
102 report.write(sec_sep+"History of session input:")
103 for line in self.IP.user_ns['_ih']:
104 report.write(line)
105 report.write('\n*** Last line of input (may not be in above history):\n')
106 report.write(self.IP._last_input_line+'\n')
107 except:
108 pass
109 report.close()
This diff has been collapsed as it changes many lines, (671 lines changed) Show them Hide them
@@ -0,0 +1,671 b''
1 # -*- coding: utf-8 -*-
2 """DPyGetOpt -- Demiurge Python GetOptions Module
3
4 $Id: DPyGetOpt.py 389 2004-10-09 07:59:30Z fperez $
5
6 This module is modeled after perl's Getopt::Long module-- which
7 is, in turn, modeled after GNU's extended getopt() function.
8
9 Upon instantiation, the option specification should be a sequence
10 (list) of option definitions.
11
12 Options that take no arguments should simply contain the name of
13 the option. If a ! is post-pended, the option can be negated by
14 prepending 'no'; ie 'debug!' specifies that -debug and -nodebug
15 should be accepted.
16
17 Mandatory arguments to options are specified using a postpended
18 '=' + a type specifier. '=s' specifies a mandatory string
19 argument, '=i' specifies a mandatory integer argument, and '=f'
20 specifies a mandatory real number. In all cases, the '=' can be
21 substituted with ':' to specify that the argument is optional.
22
23 Dashes '-' in option names are allowed.
24
25 If an option has the character '@' postpended (after the
26 argumentation specification), it can appear multiple times within
27 each argument list that is processed. The results will be stored
28 in a list.
29
30 The option name can actually be a list of names separated by '|'
31 characters; ie-- 'foo|bar|baz=f@' specifies that all -foo, -bar,
32 and -baz options that appear on within the parsed argument list
33 must have a real number argument and that the accumulated list
34 of values will be available under the name 'foo'
35
36 $Id: DPyGetOpt.py 389 2004-10-09 07:59:30Z fperez $"""
37
38 #*****************************************************************************
39 #
40 # Copyright (c) 2001 Bill Bumgarner <bbum@friday.com>
41 #
42 #
43 # Published under the terms of the MIT license, hereby reproduced:
44 #
45 # Permission is hereby granted, free of charge, to any person obtaining a copy
46 # of this software and associated documentation files (the "Software"), to
47 # deal in the Software without restriction, including without limitation the
48 # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
49 # sell copies of the Software, and to permit persons to whom the Software is
50 # furnished to do so, subject to the following conditions:
51 #
52 # The above copyright notice and this permission notice shall be included in
53 # all copies or substantial portions of the Software.
54 #
55 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
56 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
57 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
58 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
59 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
60 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
61 # IN THE SOFTWARE.
62 #
63 #*****************************************************************************
64
65 __author__ = 'Bill Bumgarner <bbum@friday.com>'
66 __license__ = 'MIT'
67 __version__ = '1.2'
68
69 # Modified to use re instead of regex and regsub modules.
70 # 2001/5/7, Jonathan Hogg <jonathan@onegoodidea.com>
71
72 import string
73 import re
74 import sys
75 import types
76
77 arg_error = 'DPyGetOpt Argument Error'
78 spec_error = 'DPyGetOpt Specification Error'
79 term_error = 'DPyGetOpt Termination Error'
80
81 specificationExpr = re.compile('(?P<required>.)(?P<type>.)(?P<multi>@?)')
82
83 ArgRequired = 'Requires an Argument'
84 ArgOptional = 'Argument Optional'
85
86 # The types modules is not used for these identifiers because there
87 # is no identifier for 'boolean' or 'generic'
88 StringArgType = 'String Argument Type'
89 IntegerArgType = 'Integer Argument Type'
90 RealArgType = 'Real Argument Type'
91 BooleanArgType = 'Boolean Argument Type'
92 GenericArgType = 'Generic Argument Type'
93
94 # dictionary of conversion functions-- boolean and generic options
95 # do not accept arguments and do not need conversion functions;
96 # the identity function is used purely for convenience.
97 ConversionFunctions = {
98 StringArgType : lambda x: x,
99 IntegerArgType : string.atoi,
100 RealArgType : string.atof,
101 BooleanArgType : lambda x: x,
102 GenericArgType : lambda x: x,
103 }
104
105 class DPyGetOpt:
106
107 def __init__(self, spec = None, terminators = ['--']):
108 """
109 Declare and intialize instance variables
110
111 Yes, declaration is not necessary... but one of the things
112 I sorely miss from C/Obj-C is the concept of having an
113 interface definition that clearly declares all instance
114 variables and methods without providing any implementation
115 details. it is a useful reference!
116
117 all instance variables are initialized to 0/Null/None of
118 the appropriate type-- not even the default value...
119 """
120
121 # sys.stderr.write(string.join(spec) + "\n")
122
123 self.allowAbbreviations = 1 # boolean, 1 if abbreviations will
124 # be expanded
125 self.freeValues = [] # list, contains free values
126 self.ignoreCase = 0 # boolean, YES if ignoring case
127 self.needsParse = 0 # boolean, YES if need to reparse parameter spec
128 self.optionNames = {} # dict, all option names-- value is index of tuple
129 self.optionStartExpr = None # regexp defining the start of an option (ie; '-', '--')
130 self.optionTuples = [] # list o' tuples containing defn of options AND aliases
131 self.optionValues = {} # dict, option names (after alias expansion) -> option value(s)
132 self.orderMixed = 0 # boolean, YES if options can be mixed with args
133 self.posixCompliance = 0 # boolean, YES indicates posix like behaviour
134 self.spec = [] # list, raw specs (in case it must be reparsed)
135 self.terminators = terminators # list, strings that terminate argument processing
136 self.termValues = [] # list, values after terminator
137 self.terminator = None # full name of terminator that ended
138 # option processing
139
140 # set up defaults
141 self.setPosixCompliance()
142 self.setIgnoreCase()
143 self.setAllowAbbreviations()
144
145 # parse spec-- if present
146 if spec:
147 self.parseConfiguration(spec)
148
149 def setPosixCompliance(self, aFlag = 0):
150 """
151 Enables and disables posix compliance.
152
153 When enabled, '+' can be used as an option prefix and free
154 values can be mixed with options.
155 """
156 self.posixCompliance = aFlag
157 self.needsParse = 1
158
159 if self.posixCompliance:
160 self.optionStartExpr = re.compile('(--|-)(?P<option>[A-Za-z0-9_-]+)(?P<arg>=.*)?')
161 self.orderMixed = 0
162 else:
163 self.optionStartExpr = re.compile('(--|-|\+)(?P<option>[A-Za-z0-9_-]+)(?P<arg>=.*)?')
164 self.orderMixed = 1
165
166 def isPosixCompliant(self):
167 """
168 Returns the value of the posix compliance flag.
169 """
170 return self.posixCompliance
171
172 def setIgnoreCase(self, aFlag = 1):
173 """
174 Enables and disables ignoring case during option processing.
175 """
176 self.needsParse = 1
177 self.ignoreCase = aFlag
178
179 def ignoreCase(self):
180 """
181 Returns 1 if the option processor will ignore case when
182 processing options.
183 """
184 return self.ignoreCase
185
186 def setAllowAbbreviations(self, aFlag = 1):
187 """
188 Enables and disables the expansion of abbreviations during
189 option processing.
190 """
191 self.allowAbbreviations = aFlag
192
193 def willAllowAbbreviations(self):
194 """
195 Returns 1 if abbreviated options will be automatically
196 expanded to the non-abbreviated form (instead of causing an
197 unrecognized option error).
198 """
199 return self.allowAbbreviations
200
201 def addTerminator(self, newTerm):
202 """
203 Adds newTerm as terminator of option processing.
204
205 Whenever the option processor encounters one of the terminators
206 during option processing, the processing of options terminates
207 immediately, all remaining options are stored in the termValues
208 instance variable and the full name of the terminator is stored
209 in the terminator instance variable.
210 """
211 self.terminators = self.terminators + [newTerm]
212
213 def _addOption(self, oTuple):
214 """
215 Adds the option described by oTuple (name, (type, mode,
216 default), alias) to optionTuples. Adds index keyed under name
217 to optionNames. Raises spec_error if name already in
218 optionNames
219 """
220 (name, (type, mode, default, multi), realName) = oTuple
221
222 # verify name and add to option names dictionary
223 if self.optionNames.has_key(name):
224 if realName:
225 raise spec_error, 'Alias \'' + name + '\' for \'' + realName + \
226 '\' already used for another option or alias.'
227 else:
228 raise spec_error, 'Option named \'' + name + \
229 '\' specified more than once. Specification: ' + option
230
231 # validated. add to optionNames
232 self.optionNames[name] = self.tupleIndex
233 self.tupleIndex = self.tupleIndex + 1
234
235 # add to optionTuples
236 self.optionTuples = self.optionTuples + [oTuple]
237
238 # if type is boolean, add negation
239 if type == BooleanArgType:
240 alias = 'no' + name
241 specTuple = (type, mode, 0, multi)
242 oTuple = (alias, specTuple, name)
243
244 # verify name and add to option names dictionary
245 if self.optionNames.has_key(alias):
246 if realName:
247 raise spec_error, 'Negated alias \'' + name + '\' for \'' + realName + \
248 '\' already used for another option or alias.'
249 else:
250 raise spec_error, 'Negated option named \'' + name + \
251 '\' specified more than once. Specification: ' + option
252
253 # validated. add to optionNames
254 self.optionNames[alias] = self.tupleIndex
255 self.tupleIndex = self.tupleIndex + 1
256
257 # add to optionTuples
258 self.optionTuples = self.optionTuples + [oTuple]
259
260 def addOptionConfigurationTuple(self, oTuple):
261 (name, argSpec, realName) = oTuple
262 if self.ignoreCase:
263 name = string.lower(name)
264 if realName:
265 realName = string.lower(realName)
266 else:
267 realName = name
268
269 oTuple = (name, argSpec, realName)
270
271 # add option
272 self._addOption(oTuple)
273
274 def addOptionConfigurationTuples(self, oTuple):
275 if type(oTuple) is ListType:
276 for t in oTuple:
277 self.addOptionConfigurationTuple(t)
278 else:
279 self.addOptionConfigurationTuple(oTuple)
280
281 def parseConfiguration(self, spec):
282 # destroy previous stored information + store raw spec
283 self.spec = spec
284 self.optionTuples = []
285 self.optionNames = {}
286 self.tupleIndex = 0
287
288 tupleIndex = 0
289
290 # create some regex's for parsing each spec
291 splitExpr = \
292 re.compile('(?P<names>\w+[-A-Za-z0-9|]*)?(?P<spec>!|[=:][infs]@?)?')
293 for option in spec:
294 # push to lower case (does not negatively affect
295 # specification)
296 if self.ignoreCase:
297 option = string.lower(option)
298
299 # break into names, specification
300 match = splitExpr.match(option)
301 if match is None:
302 raise spec_error, 'Invalid specification {' + option + '}'
303
304 names = match.group('names')
305 specification = match.group('spec')
306
307 # break name into name, aliases
308 nlist = string.split(names, '|')
309
310 # get name
311 name = nlist[0]
312 aliases = nlist[1:]
313
314 # specificationExpr = regex.symcomp('\(<required>.\)\(<type>.\)\(<multi>@?\)')
315 if not specification:
316 #spec tuple is ('type', 'arg mode', 'default value', 'multiple')
317 argType = GenericArgType
318 argMode = None
319 argDefault = 1
320 argMultiple = 0
321 elif specification == '!':
322 argType = BooleanArgType
323 argMode = None
324 argDefault = 1
325 argMultiple = 0
326 else:
327 # parse
328 match = specificationExpr.match(specification)
329 if match is None:
330 # failed to parse, die
331 raise spec_error, 'Invalid configuration for option \'' + option + '\''
332
333 # determine mode
334 required = match.group('required')
335 if required == '=':
336 argMode = ArgRequired
337 elif required == ':':
338 argMode = ArgOptional
339 else:
340 raise spec_error, 'Unknown requirement configuration \'' + required + '\''
341
342 # determine type
343 type = match.group('type')
344 if type == 's':
345 argType = StringArgType
346 argDefault = ''
347 elif type == 'i':
348 argType = IntegerArgType
349 argDefault = 1
350 elif type == 'f' or type == 'n':
351 argType = RealArgType
352 argDefault = 1
353 else:
354 raise spec_error, 'Unknown type specifier \'' + type + '\''
355
356 # determine quantity
357 if match.group('multi') == '@':
358 argMultiple = 1
359 else:
360 argMultiple = 0
361 ## end else (of not specification)
362
363 # construct specification tuple
364 specTuple = (argType, argMode, argDefault, argMultiple)
365
366 # add the option-- option tuple is (name, specTuple, real name)
367 oTuple = (name, specTuple, name)
368 self._addOption(oTuple)
369
370 for alias in aliases:
371 # drop to all lower (if configured to do so)
372 if self.ignoreCase:
373 alias = string.lower(alias)
374 # create configuration tuple
375 oTuple = (alias, specTuple, name)
376 # add
377 self._addOption(oTuple)
378
379 # successfully parsed....
380 self.needsParse = 0
381
382 def _getArgTuple(self, argName):
383 """
384 Returns a list containing all the specification tuples that
385 match argName. If none match, None is returned. If one
386 matches, a list with one tuple is returned. If more than one
387 match, a list containing all the tuples that matched is
388 returned.
389
390 In other words, this function does not pass judgement upon the
391 validity of multiple matches.
392 """
393 # is it in the optionNames dict?
394
395 try:
396 # sys.stderr.write(argName + string.join(self.optionNames.keys()) + "\n")
397
398 # yes, get index
399 tupleIndex = self.optionNames[argName]
400 # and return tuple as element of list
401 return [self.optionTuples[tupleIndex]]
402 except KeyError:
403 # are abbreviations allowed?
404 if not self.allowAbbreviations:
405 # No! terefore, this cannot be valid argument-- nothing found
406 return None
407
408 # argName might be an abbreviation (and, abbreviations must
409 # be allowed... or this would not have been reached!)
410
411 # create regex for argName
412 argExpr = re.compile('^' + argName)
413
414 tuples = filter(lambda x, argExpr=argExpr: argExpr.search(x[0]) is not None,
415 self.optionTuples)
416
417 if not len(tuples):
418 return None
419 else:
420 return tuples
421
422 def _isTerminator(self, optionName):
423 """
424 Returns the full name of the terminator if optionName is a valid
425 terminator. If it is, sets self.terminator to the full name of
426 the terminator.
427
428 If more than one terminator matched, raises a term_error with a
429 string describing the ambiguity.
430 """
431
432 # sys.stderr.write(optionName + "\n")
433 # sys.stderr.write(repr(self.terminators))
434
435 if optionName in self.terminators:
436 self.terminator = optionName
437 elif not self.allowAbbreviations:
438 return None
439
440 # regex thing in bogus
441 # termExpr = regex.compile('^' + optionName)
442
443 terms = filter(lambda x, on=optionName: string.find(x,on) == 0, self.terminators)
444
445 if not len(terms):
446 return None
447 elif len(terms) > 1:
448 raise term_error, 'Ambiguous terminator \'' + optionName + \
449 '\' matches ' + repr(terms)
450
451 self.terminator = terms[0]
452 return self.terminator
453
454 def processArguments(self, args = None):
455 """
456 Processes args, a list of arguments (including options).
457
458 If args is the same as sys.argv, automatically trims the first
459 argument (the executable name/path).
460
461 If an exception is not raised, the argument list was parsed
462 correctly.
463
464 Upon successful completion, the freeValues instance variable
465 will contain all the arguments that were not associated with an
466 option in the order they were encountered. optionValues is a
467 dictionary containing the value of each option-- the method
468 valueForOption() can be used to query this dictionary.
469 terminator will contain the argument encountered that terminated
470 option processing (or None, if a terminator was never
471 encountered) and termValues will contain all of the options that
472 appeared after the Terminator (or an empty list).
473 """
474
475 if hasattr(sys, "argv") and args == sys.argv:
476 args = sys.argv[1:]
477
478 max = len(args) # maximum index + 1
479 self.freeValues = [] # array to hold return values
480 self.optionValues= {}
481 index = 0 # initial index
482 self.terminator = None
483 self.termValues = []
484
485 while index < max:
486 # obtain argument
487 arg = args[index]
488 # increment index -- REMEMBER; it is NOW incremented
489 index = index + 1
490
491 # terminate immediately if option terminator encountered
492 if self._isTerminator(arg):
493 self.freeValues = self.freeValues + args[index:]
494 self.termValues = args[index:]
495 return
496
497 # is this possibly an option?
498 match = self.optionStartExpr.match(arg)
499 if match is None:
500 # not an option-- add to freeValues
501 self.freeValues = self.freeValues + [arg]
502 if not self.orderMixed:
503 # mixing not allowed; add rest of args as freeValues
504 self.freeValues = self.freeValues + args[index:]
505 # return to caller
506 return
507 else:
508 continue
509
510 # grab name
511 optName = match.group('option')
512
513 # obtain next argument-- index has already been incremented
514 nextArg = match.group('arg')
515 if nextArg:
516 nextArg = nextArg[1:]
517 index = index - 1 # put it back
518 else:
519 try:
520 nextArg = args[index]
521 except:
522 nextArg = None
523
524 # transpose to lower case, if necessary
525 if self.ignoreCase:
526 optName = string.lower(optName)
527
528 # obtain defining tuple
529 tuples = self._getArgTuple(optName)
530
531 if tuples == None:
532 raise arg_error, 'Illegal option \'' + arg + '\''
533 elif len(tuples) > 1:
534 raise arg_error, 'Ambiguous option \'' + arg + '\'; matches ' + \
535 repr(map(lambda x: x[0], tuples))
536 else:
537 config = tuples[0]
538
539 # config is now set to the configuration tuple for the
540 # argument
541 (fullName, spec, realName) = config
542 (optType, optMode, optDefault, optMultiple) = spec
543
544 # if opt mode required, but nextArg is none, raise an error
545 if (optMode == ArgRequired):
546 if (not nextArg) or self._isTerminator(nextArg):
547 # print nextArg
548 raise arg_error, 'Option \'' + arg + \
549 '\' requires an argument of type ' + optType
550
551 if (not optMode == None) and nextArg and (not self._isTerminator(nextArg)):
552 # nextArg defined, option configured to possibly consume arg
553 try:
554 # grab conversion function-- the try is more for internal diagnostics
555 func = ConversionFunctions[optType]
556 try:
557 optionValue = func(nextArg)
558 index = index + 1
559 except:
560 # only raise conversion error if REQUIRED to consume argument
561 if optMode == ArgRequired:
562 raise arg_error, 'Invalid argument to option \'' + arg + \
563 '\'; should be \'' + optType + '\''
564 else:
565 optionValue = optDefault
566 except arg_error:
567 raise arg_error, sys.exc_value
568 except:
569 raise arg_error, '(' + arg + \
570 ') Conversion function for \'' + optType + '\' not found.'
571 else:
572 optionValue = optDefault
573
574 # add value to options dictionary
575 if optMultiple:
576 # can be multiple values
577 try:
578 # try to append element
579 self.optionValues[realName] = self.optionValues[realName] + [optionValue]
580 except:
581 # failed-- must not exist; add it
582 self.optionValues[realName] = [optionValue]
583 else:
584 # only one value per
585 if self.isPosixCompliant and self.optionValues.has_key(realName):
586 raise arg_error, 'Argument \'' + arg + '\' occurs multiple times.'
587
588 self.optionValues[realName] = optionValue
589
590 def valueForOption(self, optionName, defaultValue = None):
591 """
592 Return the value associated with optionName. If optionName was
593 not encountered during parsing of the arguments, returns the
594 defaultValue (which defaults to None).
595 """
596 try:
597 optionValue = self.optionValues[optionName]
598 except:
599 optionValue = defaultValue
600
601 return optionValue
602
603 ##
604 ## test/example section
605 ##
606 test_error = 'Test Run Amok!'
607 def _test():
608 """
609 A relatively complete test suite.
610 """
611 try:
612 DPyGetOpt(['foo', 'bar=s', 'foo'])
613 except:
614 print 'EXCEPTION (should be \'foo\' already used..): ' + sys.exc_value
615
616 try:
617 DPyGetOpt(['foo|bar|apple=s@', 'baz|apple!'])
618 except:
619 print 'EXCEPTION (should be duplicate alias/name error): ' + sys.exc_value
620
621 x = DPyGetOpt(['apple|atlas=i@', 'application|executable=f@'])
622 try:
623 x.processArguments(['-app', '29.3'])
624 except:
625 print 'EXCEPTION (should be ambiguous argument): ' + sys.exc_value
626
627 x = DPyGetOpt(['foo'], ['antigravity', 'antithesis'])
628 try:
629 x.processArguments(['-foo', 'anti'])
630 except:
631 print 'EXCEPTION (should be ambiguous terminator): ' + sys.exc_value
632
633 profile = ['plain-option',
634 'boolean-option!',
635 'list-of-integers=i@',
636 'list-real-option|list-real-alias|list-real-pseudonym=f@',
637 'optional-string-option:s',
638 'abbreviated-string-list=s@']
639
640 terminators = ['terminator']
641
642 args = ['-plain-option',
643 '+noboolean-option',
644 '--list-of-integers', '1',
645 '+list-of-integers', '2',
646 '-list-of-integers', '3',
647 'freeargone',
648 '-list-real-option', '1.1',
649 '+list-real-alias', '1.2',
650 '--list-real-pseudonym', '1.3',
651 'freeargtwo',
652 '-abbreviated-string-list', 'String1',
653 '--abbreviated-s', 'String2',
654 '-abbrev', 'String3',
655 '-a', 'String4',
656 '-optional-string-option',
657 'term',
658 'next option should look like an invalid arg',
659 '-a']
660
661
662 print 'Using profile: ' + repr(profile)
663 print 'With terminator: ' + repr(terminators)
664 print 'Processing arguments: ' + repr(args)
665
666 go = DPyGetOpt(profile, terminators)
667 go.processArguments(args)
668
669 print 'Options (and values): ' + repr(go.optionValues)
670 print 'free args: ' + repr(go.freeValues)
671 print 'term args: ' + repr(go.termValues)
@@ -0,0 +1,53 b''
1 # -*- coding: utf-8 -*-
2 """
3 Pdb debugger class.
4
5 Modified from the standard pdb.Pdb class to avoid including readline, so that
6 the command line completion of other programs which include this isn't
7 damaged.
8
9 In the future, this class will be expanded with improvements over the standard
10 pdb.
11
12 The code in this file is mainly lifted out of cmd.py in Python 2.2, with minor
13 changes. Licensing should therefore be under the standard Python terms. For
14 details on the PSF (Python Software Foundation) standard license, see:
15
16 http://www.python.org/2.2.3/license.html
17
18 $Id: Debugger.py 590 2005-05-30 06:26:51Z fperez $"""
19
20 from IPython import Release
21 __author__ = '%s <%s>' % Release.authors['Fernando']
22 __license__ = 'Python'
23
24 import pdb,bdb,cmd,os,sys
25
26 class Pdb(pdb.Pdb):
27 """Modified Pdb class, does not load readline."""
28 def __init__(self):
29 bdb.Bdb.__init__(self)
30 cmd.Cmd.__init__(self,completekey=None) # don't load readline
31 self.prompt = '(Pdb) '
32 self.aliases = {}
33
34 # Read $HOME/.pdbrc and ./.pdbrc
35 self.rcLines = []
36 if os.environ.has_key('HOME'):
37 envHome = os.environ['HOME']
38 try:
39 rcFile = open(os.path.join(envHome, ".pdbrc"))
40 except IOError:
41 pass
42 else:
43 for line in rcFile.readlines():
44 self.rcLines.append(line)
45 rcFile.close()
46 try:
47 rcFile = open(".pdbrc")
48 except IOError:
49 pass
50 else:
51 for line in rcFile.readlines():
52 self.rcLines.append(line)
53 rcFile.close()
@@ -0,0 +1,270 b''
1 # -*- coding: utf-8 -*-
2 """Modified input prompt for executing files.
3
4 We define a special input line filter to allow typing lines which begin with
5 '~', '/' or '.'. If one of those strings is encountered, it is automatically
6 executed.
7
8 $Id: InterpreterExec.py 573 2005-04-08 08:38:09Z fperez $"""
9
10 #*****************************************************************************
11 # Copyright (C) 2004 W.J. van der Laan <gnufnork@hetdigitalegat.nl>
12 # Copyright (C) 2004 Fernando Perez <fperez@colorado.edu>
13 #
14 # Distributed under the terms of the BSD License. The full license is in
15 # the file COPYING, distributed as part of this software.
16 #*****************************************************************************
17
18 from IPython import Release
19 __author__ = 'W.J. van der Laan <gnufnork@hetdigitalegat.nl>, '\
20 '%s <%s>' % Release.authors['Fernando']
21 __license__ = Release.license
22
23 def prefilter_shell(self,line,continuation):
24 """Alternate prefilter, modified for shell-like functionality.
25
26 - Execute all lines beginning with '~', '/' or '.'
27 - $var=cmd <=> %sc var=cmd
28 - $$var=cmd <=> %sc -l var=cmd
29 """
30
31 if line:
32 l0 = line[0]
33 if l0 in '~/.':
34 return self._prefilter("!%s"%line,continuation)
35 elif l0=='$':
36 lrest = line[1:]
37 if lrest.startswith('$'):
38 # $$var=cmd <=> %sc -l var=cmd
39 return self._prefilter("%ssc -l %s" % (self.ESC_MAGIC,lrest[1:]),
40 continuation)
41 else:
42 # $var=cmd <=> %sc var=cmd
43 return self._prefilter("%ssc %s" % (self.ESC_MAGIC,lrest),
44 continuation)
45 else:
46 return self._prefilter(line,continuation)
47 else:
48 return self._prefilter(line,continuation)
49
50 # Rebind this to be the new IPython prefilter:
51 from IPython.iplib import InteractiveShell
52 InteractiveShell.prefilter = prefilter_shell
53 # Clean up the namespace.
54 del InteractiveShell,prefilter_shell
55
56 # Provide pysh and further shell-oriented services
57 import os,sys,shutil
58 from IPython.genutils import system,shell,getoutput,getoutputerror
59
60 # Short aliases for getting shell output as a string and a list
61 sout = getoutput
62 lout = lambda cmd: getoutput(cmd,split=1)
63
64 # Empty function, meant as a docstring holder so help(pysh) works.
65 def pysh():
66 """Pysh is a set of modules and extensions to IPython which make shell-like
67 usage with Python syntax more convenient. Keep in mind that pysh is NOT a
68 full-blown shell, so don't try to make it your /etc/passwd entry!
69
70 In particular, it has no job control, so if you type Ctrl-Z (under Unix),
71 you'll suspend pysh itself, not the process you just started.
72
73 Since pysh is really nothing but a customized IPython, you should
74 familiarize yourself with IPython's features. This brief help mainly
75 documents areas in which pysh differs from the normal IPython.
76
77 ALIASES
78 -------
79 All of your $PATH has been loaded as IPython aliases, so you should be
80 able to type any normal system command and have it executed. See %alias?
81 and %unalias? for details on the alias facilities.
82
83 SPECIAL SYNTAX
84 --------------
85 Any lines which begin with '~', '/' and '.' will be executed as shell
86 commands instead of as Python code. The special escapes below are also
87 recognized. !cmd is valid in single or multi-line input, all others are
88 only valid in single-line input:
89
90 !cmd - pass 'cmd' directly to the shell
91 !!cmd - execute 'cmd' and return output as a list (split on '\\n')
92 $var=cmd - capture output of cmd into var, as a string
93 $$var=cmd - capture output of cmd into var, as a list (split on '\\n')
94
95 The $/$$ syntaxes make Python variables from system output, which you can
96 later use for further scripting. The converse is also possible: when
97 executing an alias or calling to the system via !/!!, you can expand any
98 python variable or expression by prepending it with $. Full details of
99 the allowed syntax can be found in Python's PEP 215.
100
101 A few brief examples will illustrate these:
102
103 fperez[~/test]|3> !ls *s.py
104 scopes.py strings.py
105
106 ls is an internal alias, so there's no need to use !:
107 fperez[~/test]|4> ls *s.py
108 scopes.py* strings.py
109
110 !!ls will return the output into a Python variable:
111 fperez[~/test]|5> !!ls *s.py
112 <5> ['scopes.py', 'strings.py']
113 fperez[~/test]|6> print _5
114 ['scopes.py', 'strings.py']
115
116 $ and $$ allow direct capture to named variables:
117 fperez[~/test]|7> $astr = ls *s.py
118 fperez[~/test]|8> astr
119 <8> 'scopes.py\\nstrings.py'
120
121 fperez[~/test]|9> $$alist = ls *s.py
122 fperez[~/test]|10> alist
123 <10> ['scopes.py', 'strings.py']
124
125 alist is now a normal python list you can loop over. Using $ will expand
126 back the python values when alias calls are made:
127 fperez[~/test]|11> for f in alist:
128 |..> print 'file',f,
129 |..> wc -l $f
130 |..>
131 file scopes.py 13 scopes.py
132 file strings.py 4 strings.py
133
134 Note that you may need to protect your variables with braces if you want
135 to append strings to their names. To copy all files in alist to .bak
136 extensions, you must use:
137 fperez[~/test]|12> for f in alist:
138 |..> cp $f ${f}.bak
139
140 If you try using $f.bak, you'll get an AttributeError exception saying
141 that your string object doesn't have a .bak attribute. This is because
142 the $ expansion mechanism allows you to expand full Python expressions:
143 fperez[~/test]|13> echo "sys.platform is: $sys.platform"
144 sys.platform is: linux2
145
146 IPython's input history handling is still active, which allows you to
147 rerun a single block of multi-line input by simply using exec:
148 fperez[~/test]|14> $$alist = ls *.eps
149 fperez[~/test]|15> exec _i11
150 file image2.eps 921 image2.eps
151 file image.eps 921 image.eps
152
153 While these are new special-case syntaxes, they are designed to allow very
154 efficient use of the shell with minimal typing. At an interactive shell
155 prompt, conciseness of expression wins over readability.
156
157 USEFUL FUNCTIONS AND MODULES
158 ----------------------------
159 The os, sys and shutil modules from the Python standard library are
160 automatically loaded. Some additional functions, useful for shell usage,
161 are listed below. You can request more help about them with '?'.
162
163 shell - execute a command in the underlying system shell
164 system - like shell(), but return the exit status of the command
165 sout - capture the output of a command as a string
166 lout - capture the output of a command as a list (split on '\\n')
167 getoutputerror - capture (output,error) of a shell command
168
169 sout/lout are the functional equivalents of $/$$. They are provided to
170 allow you to capture system output in the middle of true python code,
171 function definitions, etc (where $ and $$ are invalid).
172
173 DIRECTORY MANAGEMENT
174 --------------------
175 Since each command passed by pysh to the underlying system is executed in
176 a subshell which exits immediately, you can NOT use !cd to navigate the
177 filesystem.
178
179 Pysh provides its own builtin '%cd' magic command to move in the
180 filesystem (the % is not required with automagic on). It also maintains a
181 list of visited directories (use %dhist to see it) and allows direct
182 switching to any of them. Type 'cd?' for more details.
183
184 %pushd, %popd and %dirs are provided for directory stack handling.
185
186 PROMPT CUSTOMIZATION
187 --------------------
188
189 The supplied ipythonrc-pysh profile comes with an example of a very
190 colored and detailed prompt, mainly to serve as an illustration. The
191 valid escape sequences, besides color names, are:
192
193 \\# - Prompt number.
194 \\D - Dots, as many as there are digits in \\# (so they align).
195 \\w - Current working directory (cwd).
196 \\W - Basename of current working directory.
197 \\XN - Where N=0..5. N terms of the cwd, with $HOME written as ~.
198 \\YN - Where N=0..5. Like XN, but if ~ is term N+1 it's also shown.
199 \\u - Username.
200 \\H - Full hostname.
201 \\h - Hostname up to first '.'
202 \\$ - Root symbol ($ or #).
203 \\t - Current time, in H:M:S format.
204 \\v - IPython release version.
205 \\n - Newline.
206 \\r - Carriage return.
207 \\\\ - An explicitly escaped '\\'.
208
209 You can configure your prompt colors using any ANSI color escape. Each
210 color escape sets the color for any subsequent text, until another escape
211 comes in and changes things. The valid color escapes are:
212
213 \\C_Black
214 \\C_Blue
215 \\C_Brown
216 \\C_Cyan
217 \\C_DarkGray
218 \\C_Green
219 \\C_LightBlue
220 \\C_LightCyan
221 \\C_LightGray
222 \\C_LightGreen
223 \\C_LightPurple
224 \\C_LightRed
225 \\C_Purple
226 \\C_Red
227 \\C_White
228 \\C_Yellow
229 \\C_Normal - Stop coloring, defaults to your terminal settings.
230 """
231 pass
232
233 # Configure a few things. Much of this is fairly hackish, since IPython
234 # doesn't really expose a clean API for it. Be careful if you start making
235 # many modifications here.
236
237 print """\
238 Welcome to pysh, a set of extensions to IPython for shell usage.
239 help(pysh) -> help on the installed shell extensions and syntax.
240 """
241
242 # Set the 'cd' command to quiet mode, a more shell-like behavior
243 __IPYTHON__.default_option('cd','-q')
244
245 # Load all of $PATH as aliases
246 if os.name == 'posix':
247 # %rehash is very fast, but it doesn't check for executability, it simply
248 # dumps everything in $PATH as an alias. Use rehashx if you want more
249 # checks.
250 __IPYTHON__.magic_rehash()
251 else:
252 # Windows users: the list of extensions considered executable is read from
253 # the environment variable 'pathext'. If this is undefined, IPython
254 # defaults to EXE, COM and BAT.
255 # %rehashx is the one which does extension analysis, at the cost of
256 # being much slower than %rehash.
257 __IPYTHON__.magic_rehashx()
258
259 # Remove %sc,%sx if present as aliases
260 __IPYTHON__.magic_unalias('sc')
261 __IPYTHON__.magic_unalias('sx')
262
263 # We need different criteria for line-splitting, so that aliases such as
264 # 'gnome-terminal' are interpreted as a single alias instead of variable
265 # 'gnome' minus variable 'terminal'.
266 import re
267 __IPYTHON__.line_split = re.compile(r'^(\s*)([\?\w\.\-\+]+\w*\s*)(\(?.*$)')
268
269 # Namespace cleanup
270 del re
@@ -0,0 +1,91 b''
1 # -*- coding: utf-8 -*-
2 """Modified input prompt for entering text with >>> or ... at the start.
3
4 We define a special input line filter to allow typing lines which begin with
5 '>>> ' or '... '. These two strings, if present at the start of the input
6 line, are stripped. This allows for direct pasting of code from examples such
7 as those available in the standard Python tutorial.
8
9 Normally pasting such code is one chunk is impossible because of the
10 extraneous >>> and ..., requiring one to do a line by line paste with careful
11 removal of those characters. This module allows pasting that kind of
12 multi-line examples in one pass.
13
14 Here is an 'screenshot' of a section of the tutorial pasted into IPython with
15 this feature enabled:
16
17 In [1]: >>> def fib2(n): # return Fibonacci series up to n
18 ...: ... '''Return a list containing the Fibonacci series up to n.'''
19 ...: ... result = []
20 ...: ... a, b = 0, 1
21 ...: ... while b < n:
22 ...: ... result.append(b) # see below
23 ...: ... a, b = b, a+b
24 ...: ... return result
25 ...:
26
27 In [2]: fib2(10)
28 Out[2]: [1, 1, 2, 3, 5, 8]
29
30 The >>> and ... are stripped from the input so that the python interpreter
31 only sees the real part of the code.
32
33 All other input is processed normally.
34 """
35 #*****************************************************************************
36 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
37 #
38 # Distributed under the terms of the BSD License. The full license is in
39 # the file COPYING, distributed as part of this software.
40 #*****************************************************************************
41
42 from IPython import Release
43 __author__ = '%s <%s>' % Release.authors['Fernando']
44 __license__ = Release.license
45
46 # This file is an example of how to modify IPython's line-processing behavior
47 # without touching the internal code. We'll define an alternate pre-processing
48 # stage which allows a special form of input (which is invalid Python syntax)
49 # for certain quantities, rewrites a line of proper Python in those cases, and
50 # then passes it off to IPython's normal processor for further work.
51
52 # With this kind of customization, IPython can be adapted for many
53 # special-purpose scenarios providing alternate input syntaxes.
54
55 # This file can be imported like a regular module.
56
57 # IPython has a prefilter() function that analyzes each input line. We redefine
58 # it here to first pre-process certain forms of input
59
60 # The prototype of any alternate prefilter must be like this one (the name
61 # doesn't matter):
62 # - line is a string containing the user input line.
63 # - continuation is a parameter which tells us if we are processing a first line of
64 # user input or the second or higher of a multi-line statement.
65
66 def prefilter_paste(self,line,continuation):
67 """Alternate prefilter for input of pasted code from an interpreter.
68 """
69
70 from re import match
71
72 if match(r'^>>> |^\.\.\. ',line):
73 # In the end, always call the default IPython _prefilter() function.
74 # Note that self must be passed explicitly, b/c we're calling the
75 # unbound class method (since this method will overwrite the instance
76 # prefilter())
77 return self._prefilter(line[4:],continuation)
78 elif line.strip() == '...':
79 return self._prefilter('',continuation)
80 else:
81 return self._prefilter(line,continuation)
82
83 # Rebind this to be the new IPython prefilter:
84 from IPython.iplib import InteractiveShell
85 InteractiveShell.prefilter = prefilter_paste
86
87 # Clean up the namespace.
88 del InteractiveShell,prefilter_paste
89
90 # Just a heads up at the console
91 print '*** Pasting of code with ">>>" or "..." has been enabled.'
@@ -0,0 +1,83 b''
1 # -*- coding: utf-8 -*-
2 """Modified input prompt for entering quantities with units.
3
4 Modify the behavior of the interactive interpreter to allow direct input of
5 quantities with units without having to make a function call.
6
7 Now the following forms are accepted:
8
9 x = 4 m
10 y = -.45e3 m/s
11 g = 9.8 m/s**2
12 a = 2.3 m/s^2 # ^ -> ** automatically
13
14 All other input is processed normally.
15 """
16 #*****************************************************************************
17 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
18 #
19 # Distributed under the terms of the BSD License. The full license is in
20 # the file COPYING, distributed as part of this software.
21 #*****************************************************************************
22
23 from IPython import Release
24 __author__ = '%s <%s>' % Release.authors['Fernando']
25 __license__ = Release.license
26
27 # This file is an example of how to modify IPython's line-processing behavior
28 # without touching the internal code. We'll define an alternate pre-processing
29 # stage which allows a special form of input (which is invalid Python syntax)
30 # for certain quantities, rewrites a line of proper Python in those cases, and
31 # then passes it off to IPython's normal processor for further work.
32
33 # With this kind of customization, IPython can be adapted for many
34 # special-purpose scenarios providing alternate input syntaxes.
35
36 # This file can be imported like a regular module.
37
38 # IPython has a prefilter() function that analyzes each input line. We redefine
39 # it here to first pre-process certain forms of input
40
41 # The prototype of any alternate prefilter must be like this one (the name
42 # doesn't matter):
43 # - line is a string containing the user input line.
44 # - continuation is a parameter which tells us if we are processing a first line of
45 # user input or the second or higher of a multi-line statement.
46
47 def prefilter_PQ(self,line,continuation):
48 """Alternate prefilter for input of PhysicalQuantityInteractive objects.
49
50 This assumes that the function PhysicalQuantityInteractive() has been
51 imported."""
52
53 from re import match
54 from IPython.iplib import InteractiveShell
55
56 # This regexp is what does the real work
57 unit_split = match(r'\s*(\w+)\s*=\s*(-?\d*\.?\d*[eE]?-?\d*)\s+([a-zA-Z].*)',
58 line)
59
60 # If special input was ecnountered, process it:
61 if unit_split:
62 var,val,units = unit_split.groups()
63 if var and val and units:
64 units = units.replace('^','**')
65 # Now a valid line needs to be constructed for IPython to process:
66 line = var +" = PhysicalQuantityInteractive(" + val + ", '" + \
67 units + "')"
68 #print 'New line:',line # dbg
69
70 # In the end, always call the default IPython _prefilter() function. Note
71 # that self must be passed explicitly, b/c we're calling the unbound class
72 # method (since this method will overwrite the instance prefilter())
73 return InteractiveShell._prefilter(self,line,continuation)
74
75 # Rebind this to be the new IPython prefilter:
76 from IPython.iplib import InteractiveShell
77 InteractiveShell.prefilter = prefilter_PQ
78
79 # Clean up the namespace.
80 del InteractiveShell,prefilter_PQ
81
82 # Just a heads up at the console
83 print '*** Simplified input for physical quantities enabled.'
@@ -0,0 +1,88 b''
1 # -*- coding: utf-8 -*-
2 """Modify the PhysicalQuantities class for more convenient interactive use.
3
4 Also redefine some math functions to operate on PhysQties with no need for
5 special method syntax. This just means moving them out to the global
6 namespace.
7
8 This module should always be loaded *after* math or Numeric, so it can
9 overwrite math functions with the versions that handle units."""
10
11 #*****************************************************************************
12 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
13 #
14 # Distributed under the terms of the BSD License. The full license is in
15 # the file COPYING, distributed as part of this software.
16 #*****************************************************************************
17
18 from IPython import Release
19 __author__ = '%s <%s>' % Release.authors['Fernando']
20 __license__ = Release.license
21
22 from Scientific.Physics.PhysicalQuantities import PhysicalQuantity
23
24 # This code can be set up to work with Numeric or with math for providing the
25 # mathematical functions. Uncomment the one you prefer to use below.
26
27 # If you use math, sin(x) won't work for x an array, only float or PhysQty
28 import math
29
30 # If you use Numeric, sin(x) works for x a float, PhysQty an array.
31 #import Numeric as math
32
33 class PhysicalQuantityFunction:
34 """Generic function wrapper for PhysicalQuantity instances.
35
36 Calls functions from either the math library or the instance's methods as
37 required. Allows using sin(theta) or sqrt(v**2) syntax irrespective of
38 whether theta is a pure number or a PhysicalQuantity.
39
40 This is *slow*. It's meant for convenient interactive use, not for
41 speed."""
42
43 def __init__(self,name):
44 self.name = name
45
46 def __call__(self,x):
47 if isinstance(x,PhysicalQuantity):
48 return PhysicalQuantity.__dict__[self.name](x)
49 else:
50 return math.__dict__[self.name](x)
51
52 class PhysicalQuantityInteractive(PhysicalQuantity):
53 """Physical quantity with units - modified for Interactive use.
54
55 Basically, the __str__ and __repr__ methods have been swapped for more
56 convenient interactive use. Powers are shown as ^ instead of ** and only 4
57 significant figures are shown.
58
59 Also adds the following aliases for commonly used methods:
60 b = PhysicalQuantity.inBaseUnits
61 u = PhysicalQuantity.inUnitsOf
62
63 These are useful when doing a lot of interactive calculations.
64 """
65
66 # shorthands for the most useful unit conversions
67 b = PhysicalQuantity.inBaseUnits # so you can just type x.b to get base units
68 u = PhysicalQuantity.inUnitsOf
69
70 # This can be done, but it can get dangerous when coupled with IPython's
71 # auto-calling. Everything ends up shown in baseunits and things like x*2
72 # get automatically converted to k(*2), which doesn't work.
73 # Probably not a good idea in general...
74 #__call__ = b
75
76 def __str__(self):
77 return PhysicalQuantity.__repr__(self)
78
79 def __repr__(self):
80 value = '%.4G' % self.value
81 units = self.unit.name().replace('**','^')
82 return value + ' ' + units
83
84 # implement the methods defined in PhysicalQuantity as PhysicalQuantityFunctions
85 sin = PhysicalQuantityFunction('sin')
86 cos = PhysicalQuantityFunction('cos')
87 tan = PhysicalQuantityFunction('tan')
88 sqrt = PhysicalQuantityFunction('sqrt')
@@ -0,0 +1,13 b''
1 # -*- coding: utf-8 -*-
2 """This directory is meant for special-purpose extensions to IPython.
3
4 This can include things which alter the syntax processing stage (see
5 PhysicalQ_Input for an example of how to do this).
6
7 Any file located here can be called with an 'execfile =' option as
8
9 execfile = Extensions/filename.py
10
11 since the IPython directory itself is already part of the search path for
12 files listed as 'execfile ='.
13 """
@@ -0,0 +1,41 b''
1 # -*- coding: utf-8 -*-
2 """
3 Extension for printing Numeric Arrays in flexible ways.
4 """
5
6 def num_display(self,arg):
7 """Display method for printing which treats Numeric arrays specially.
8 """
9
10 # Non-numpy variables are printed using the system default
11 if type(arg) != ArrayType:
12 self._display(arg)
13 return
14 # Otherwise, we do work.
15 format = __IPYTHON__.runtime_rc.numarray_print_format
16 print 'NumPy array, format:',format
17 # Here is where all the printing logic needs to be implemented
18 print arg # nothing yet :)
19
20
21 def magic_format(self,parameter_s=''):
22 """Specifies format of numerical output.
23
24 This command is similar to Ocave's format command.
25 """
26
27 valid_formats = ['long','short']
28
29 if parameter_s in valid_formats:
30 self.runtime_rc.numarray_print_format = parameter_s
31 print 'Numeric output format is now:',parameter_s
32 else:
33 print 'Invalid format:',parameter_s
34 print 'Valid formats:',valid_formats
35
36 # setup default format
37 __IPYTHON__.runtime_rc.numarray_print_format = 'long'
38
39 # Bind our new functions to the interpreter
40 __IPYTHON__.__class__.magic_format = magic_format
41 __IPYTHON__.hooks.display = num_display
@@ -0,0 +1,48 b''
1 # -*- coding: utf-8 -*-
2 """
3 Class which mimics a module.
4
5 Needed to allow pickle to correctly resolve namespaces during IPython
6 sessions.
7
8 $Id: FakeModule.py 410 2004-11-04 07:58:17Z fperez $"""
9
10 #*****************************************************************************
11 # Copyright (C) 2002-2004 Fernando Perez. <fperez@colorado.edu>
12 #
13 # Distributed under the terms of the BSD License. The full license is in
14 # the file COPYING, distributed as part of this software.
15 #*****************************************************************************
16
17 class FakeModule:
18 """Simple class with attribute access to fake a module.
19
20 This is not meant to replace a module, but to allow inserting a fake
21 module in sys.modules so that systems which rely on run-time module
22 importing (like shelve and pickle) work correctly in interactive IPython
23 sessions.
24
25 Do NOT use this code for anything other than this IPython private hack."""
26
27 def __init__(self,adict):
28
29 # It seems pydoc (and perhaps others) needs any module instance to
30 # implement a __nonzero__ method, so we add it if missing:
31 if '__nonzero__' not in adict:
32 def __nonzero__():
33 return 1
34 adict['__nonzero__'] = __nonzero__
35
36 self.__dict__ = adict
37
38 def __getattr__(self,key):
39 try:
40 return self.__dict__[key]
41 except KeyError, e:
42 raise AttributeError("FakeModule object has no attribute %s" % e)
43
44 def __str__(self):
45 return "<IPython.FakeModule instance>"
46
47 def __repr__(self):
48 return str(self)
@@ -0,0 +1,198 b''
1 # -*- coding: utf-8 -*-
2 """Word completion for GNU readline 2.0.
3
4 ---------------------------------------------------------------------------
5 NOTE: This version is a re-implementation of rlcompleter with selectable
6 namespace.
7
8 The problem with rlcompleter is that it's hardwired to work with
9 __main__.__dict__, and in some cases one may have 'sandboxed' namespaces. So
10 this class is a ripoff of rlcompleter, with the namespace to work in as an
11 optional parameter.
12
13 This class can be used just like rlcompleter, but the Completer class now has
14 a constructor with the optional 'namespace' parameter.
15
16 A patch has been submitted to Python@sourceforge for these changes to go in
17 the standard Python distribution.
18
19 The patch went in for Python 2.3. Once IPython drops support for Python 2.2,
20 this file can be significantly reduced.
21 ---------------------------------------------------------------------------
22
23 Original rlcompleter documentation:
24
25 This requires the latest extension to the readline module (the
26 completes keywords, built-ins and globals in __main__; when completing
27 NAME.NAME..., it evaluates (!) the expression up to the last dot and
28 completes its attributes.
29
30 It's very cool to do "import string" type "string.", hit the
31 completion key (twice), and see the list of names defined by the
32 string module!
33
34 Tip: to use the tab key as the completion key, call
35
36 readline.parse_and_bind("tab: complete")
37
38 Notes:
39
40 - Exceptions raised by the completer function are *ignored* (and
41 generally cause the completion to fail). This is a feature -- since
42 readline sets the tty device in raw (or cbreak) mode, printing a
43 traceback wouldn't work well without some complicated hoopla to save,
44 reset and restore the tty state.
45
46 - The evaluation of the NAME.NAME... form may cause arbitrary
47 application defined code to be executed if an object with a
48 __getattr__ hook is found. Since it is the responsibility of the
49 application (or the user) to enable this feature, I consider this an
50 acceptable risk. More complicated expressions (e.g. function calls or
51 indexing operations) are *not* evaluated.
52
53 - GNU readline is also used by the built-in functions input() and
54 raw_input(), and thus these also benefit/suffer from the completer
55 features. Clearly an interactive application can benefit by
56 specifying its own completer function and using raw_input() for all
57 its input.
58
59 - When the original stdin is not a tty device, GNU readline is never
60 used, and this module (and the readline module) are silently inactive.
61
62 """
63
64 #*****************************************************************************
65 #
66 # Since this file is essentially a minimally modified copy of the rlcompleter
67 # module which is part of the standard Python distribution, I assume that the
68 # proper procedure is to maintain its copyright as belonging to the Python
69 # Software Foundation:
70 #
71 # Copyright (C) 2001 Python Software Foundation, www.python.org
72 #
73 # Distributed under the terms of the Python Software Foundation license.
74 #
75 # Full text available at:
76 #
77 # http://www.python.org/2.1/license.html
78 #
79 #*****************************************************************************
80
81 import readline
82 import __builtin__
83 import __main__
84
85 __all__ = ["Completer"]
86
87 class Completer:
88 def __init__(self, namespace = None):
89 """Create a new completer for the command line.
90
91 Completer([namespace]) -> completer instance.
92
93 If unspecified, the default namespace where completions are performed
94 is __main__ (technically, __main__.__dict__). Namespaces should be
95 given as dictionaries.
96
97 Completer instances should be used as the completion mechanism of
98 readline via the set_completer() call:
99
100 readline.set_completer(Completer(my_namespace).complete)
101 """
102
103 if namespace and type(namespace) != type({}):
104 raise TypeError,'namespace must be a dictionary'
105
106 # Don't bind to namespace quite yet, but flag whether the user wants a
107 # specific namespace or to use __main__.__dict__. This will allow us
108 # to bind to __main__.__dict__ at completion time, not now.
109 if namespace is None:
110 self.use_main_ns = 1
111 else:
112 self.use_main_ns = 0
113 self.namespace = namespace
114
115 def complete(self, text, state):
116 """Return the next possible completion for 'text'.
117
118 This is called successively with state == 0, 1, 2, ... until it
119 returns None. The completion should begin with 'text'.
120
121 """
122 if self.use_main_ns:
123 self.namespace = __main__.__dict__
124
125 if state == 0:
126 if "." in text:
127 self.matches = self.attr_matches(text)
128 else:
129 self.matches = self.global_matches(text)
130 try:
131 return self.matches[state]
132 except IndexError:
133 return None
134
135 def global_matches(self, text):
136 """Compute matches when text is a simple name.
137
138 Return a list of all keywords, built-in functions and names currently
139 defined in self.namespace that match.
140
141 """
142 import keyword
143 matches = []
144 n = len(text)
145 for list in [keyword.kwlist,
146 __builtin__.__dict__.keys(),
147 self.namespace.keys()]:
148 for word in list:
149 if word[:n] == text and word != "__builtins__":
150 matches.append(word)
151 return matches
152
153 def attr_matches(self, text):
154 """Compute matches when text contains a dot.
155
156 Assuming the text is of the form NAME.NAME....[NAME], and is
157 evaluatable in self.namespace, it will be evaluated and its attributes
158 (as revealed by dir()) are used as possible completions. (For class
159 instances, class members are are also considered.)
160
161 WARNING: this can still invoke arbitrary C code, if an object
162 with a __getattr__ hook is evaluated.
163
164 """
165 import re
166
167 # Another option, seems to work great. Catches things like ''.<tab>
168 m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text)
169
170 if not m:
171 return []
172 expr, attr = m.group(1, 3)
173 object = eval(expr, self.namespace)
174 words = dir(object)
175 if hasattr(object,'__class__'):
176 words.append('__class__')
177 words.extend(get_class_members(object.__class__))
178 n = len(attr)
179 matches = []
180 for word in words:
181 try:
182 if word[:n] == attr and word != "__builtins__":
183 matches.append("%s.%s" % (expr, word))
184 except:
185 # some badly behaved objects pollute dir() with non-strings,
186 # which cause the completion to fail. This way we skip the
187 # bad entries and can still continue processing the others.
188 pass
189 return matches
190
191 def get_class_members(klass):
192 ret = dir(klass)
193 if hasattr(klass,'__bases__'):
194 for base in klass.__bases__:
195 ret.extend(get_class_members(base))
196 return ret
197
198 readline.set_completer(Completer().complete)
This diff has been collapsed as it changes many lines, (655 lines changed) Show them Hide them
@@ -0,0 +1,655 b''
1 # -*- coding: utf-8 -*-
2 """Improved replacement for the Gnuplot.Gnuplot class.
3
4 This module imports Gnuplot and replaces some of its functionality with
5 improved versions. They add better handling of arrays for plotting and more
6 convenient PostScript generation, plus some fixes for hardcopy().
7
8 It also adds a convenient plot2 method for plotting dictionaries and
9 lists/tuples of arrays.
10
11 This module is meant to be used as a drop-in replacement to the original
12 Gnuplot, so it should be safe to do:
13
14 import IPython.Gnuplot2 as Gnuplot
15
16 $Id: Gnuplot2.py 392 2004-10-09 22:01:51Z fperez $"""
17
18 import string,os,time,types
19 import cStringIO
20 import sys
21 import tempfile
22 import Numeric
23 import Gnuplot as Gnuplot_ori
24 from IPython.genutils import popkey,xsys
25
26 # needed by hardcopy():
27 gp = Gnuplot_ori.gp
28
29 # Patch for Gnuplot.py 1.6 compatibility.
30 # Thanks to Hayden Callow <h.callow@elec.canterbury.ac.nz>
31 try:
32 OptionException = Gnuplot_ori.PlotItems.OptionException
33 except AttributeError:
34 OptionException = Gnuplot_ori.Errors.OptionError
35
36 # exhibit a similar interface to Gnuplot so it can be somewhat drop-in
37 Data = Gnuplot_ori.Data
38 Func = Gnuplot_ori.Func
39 GridData = Gnuplot_ori.GridData
40 PlotItem = Gnuplot_ori.PlotItem
41 PlotItems = Gnuplot_ori.PlotItems
42
43 # Modify some of Gnuplot's functions with improved versions (or bugfixed, in
44 # hardcopy's case). In order to preserve the docstrings at runtime, I've
45 # copied them from the original code.
46
47 # After some significant changes in v 1.7 of Gnuplot.py, we need to do a bit
48 # of version checking.
49
50 if Gnuplot_ori.__version__ <= '1.6':
51 _BaseFileItem = PlotItems.File
52 _BaseTempFileItem = PlotItems.TempFile
53
54 # Fix the File class to add the 'index' option for Gnuplot versions < 1.7
55 class File(_BaseFileItem):
56
57 _option_list = _BaseFileItem._option_list.copy()
58 _option_list.update({
59 'index' : lambda self, index: self.set_option_index(index),
60 })
61
62 # A new initializer is needed b/c we want to add a modified
63 # _option_sequence list which includes 'index' in the right place.
64 def __init__(self,*args,**kw):
65 self._option_sequence = ['binary', 'index', 'using', 'smooth', 'axes',
66 'title', 'with']
67
68 _BaseFileItem.__init__(self,*args,**kw)
69
70 # Let's fix the constructor docstring
71 __newdoc = \
72 """Additional Keyword arguments added by IPython:
73
74 'index=<int>' -- similar to the `index` keyword in Gnuplot.
75 This allows only some of the datasets in a file to be
76 plotted. Datasets within a file are assumed to be separated
77 by _pairs_ of blank lines, and the first one is numbered as
78 0 (similar to C/Python usage)."""
79 __init__.__doc__ = PlotItems.File.__init__.__doc__ + __newdoc
80
81 def set_option_index(self, index):
82 if index is None:
83 self.clear_option('index')
84 elif type(index) in [type(''), type(1)]:
85 self._options['index'] = (index, 'index %s' % index)
86 elif type(index) is type(()):
87 self._options['index'] = (index,'index %s' %
88 string.join(map(repr, index), ':'))
89 else:
90 raise OptionException('index=%s' % (index,))
91
92 # We need a FileClass with a different name from 'File', which is a
93 # factory function in 1.7, so that our String class can subclass FileClass
94 # in any version.
95 _FileClass = File
96
97 else: # Gnuplot.py version 1.7 and greater
98 _FileClass = _BaseFileItem = PlotItems._FileItem
99 _BaseTempFileItem = PlotItems._TempFileItem
100 File = PlotItems.File
101
102 # Now, we can add our generic code which is version independent
103
104 # First some useful utilities
105 def eps_fix_bbox(fname):
106 """Fix the bounding box of an eps file by running ps2eps on it.
107
108 If its name ends in .eps, the original file is removed.
109
110 This is particularly useful for plots made by Gnuplot with square aspect
111 ratio: there is a bug in Gnuplot which makes it generate a bounding box
112 which is far wider than the actual plot.
113
114 This function assumes that ps2eps is installed in your system."""
115
116 # note: ps2ps and eps2eps do NOT work, ONLY ps2eps works correctly. The
117 # others make output with bitmapped fonts, which looks horrible.
118 print 'Fixing eps file: <%s>' % fname
119 xsys('ps2eps -f -q -l %s' % fname)
120 if fname.endswith('.eps'):
121 os.rename(fname+'.eps',fname)
122
123 def is_list1d(x,containers = [types.ListType,types.TupleType]):
124 """Returns true if x appears to be a 1d list/tuple/array.
125
126 The heuristics are: identify Numeric arrays, or lists/tuples whose first
127 element is not itself a list/tuple. This way zipped lists should work like
128 the original Gnuplot. There's no inexpensive way to know if a list doesn't
129 have a composite object after its first element, so that kind of input
130 will produce an error. But it should work well in most cases.
131 """
132 x_type = type(x)
133
134 return x_type == Numeric.ArrayType and len(x.shape)==1 or \
135 (x_type in containers and
136 type(x[0]) not in containers + [Numeric.ArrayType])
137
138 def zip_items(items,titles=None):
139 """zip together neighboring 1-d arrays, and zip standalone ones
140 with their index. Leave other plot items alone."""
141
142 class StandaloneItem(Exception): pass
143
144 def get_titles(titles):
145 """Return the next title and the input titles array.
146
147 The input array may be changed to None when no titles are left to
148 prevent extra unnecessary calls to this function."""
149
150 try:
151 title = titles[tit_ct[0]] # tit_ct[0] is in zip_items'scope
152 except IndexError:
153 titles = None # so we don't enter again
154 title = None
155 else:
156 tit_ct[0] += 1
157 return title,titles
158
159 new_items = []
160
161 if titles:
162 # Initialize counter. It was put in a list as a hack to allow the
163 # nested get_titles to modify it without raising a NameError.
164 tit_ct = [0]
165
166 n = 0 # this loop needs to be done by hand
167 while n < len(items):
168 item = items[n]
169 try:
170 if is_list1d(item):
171 if n==len(items)-1: # last in list
172 raise StandaloneItem
173 else: # check the next item and zip together if needed
174 next_item = items[n+1]
175 if next_item is None:
176 n += 1
177 raise StandaloneItem
178 elif is_list1d(next_item):
179 # this would be best done with an iterator
180 if titles:
181 title,titles = get_titles(titles)
182 else:
183 title = None
184 new_items.append(Data(zip(item,next_item),
185 title=title))
186 n += 1 # avoid double-inclusion of next item
187 else: # can't zip with next, zip with own index list
188 raise StandaloneItem
189 else: # not 1-d array
190 new_items.append(item)
191 except StandaloneItem:
192 if titles:
193 title,titles = get_titles(titles)
194 else:
195 title = None
196 new_items.append(Data(zip(range(len(item)),item),title=title))
197 except AttributeError:
198 new_items.append(item)
199 n+=1
200
201 return new_items
202
203 # And some classes with enhanced functionality.
204 class String(_FileClass):
205 """Make a PlotItem from data in a string with the same format as a File.
206
207 This allows writing data directly inside python scripts using the exact
208 same format and manipulation options which would be used for external
209 files."""
210
211 def __init__(self, data_str, **keyw):
212 """Construct a String object.
213
214 <data_str> is a string formatted exactly like a valid Gnuplot data
215 file would be. All options from the File constructor are valid here.
216
217 Warning: when used for interactive plotting in scripts which exit
218 immediately, you may get an error because the temporary file used to
219 hold the string data was deleted before Gnuplot had a chance to see
220 it. You can work around this problem by putting a raw_input() call at
221 the end of the script.
222
223 This problem does not appear when generating PostScript output, only
224 with Gnuplot windows."""
225
226 self.tmpfile = _BaseTempFileItem()
227 tmpfile = file(self.tmpfile.filename,'w')
228 tmpfile.write(data_str)
229 _BaseFileItem.__init__(self,self.tmpfile,**keyw)
230
231
232 class Gnuplot(Gnuplot_ori.Gnuplot):
233 """Improved Gnuplot class.
234
235 Enhancements: better plot,replot and hardcopy methods. New methods for
236 quick range setting.
237 """
238
239 def xrange(self,min='*',max='*'):
240 """Set xrange. If min/max is omitted, it is set to '*' (auto).
241
242 Note that this is different from the regular Gnuplot behavior, where
243 an unspecified limit means no change. Here any unspecified limit is
244 set to autoscaling, allowing these functions to be used for full
245 autoscaling when called with no arguments.
246
247 To preserve one limit's current value while changing the other, an
248 explicit '' argument must be given as the limit to be kept.
249
250 Similar functions exist for [y{2}z{2}rtuv]range."""
251
252 self('set xrange [%s:%s]' % (min,max))
253
254 def yrange(self,min='*',max='*'):
255 self('set yrange [%s:%s]' % (min,max))
256
257 def zrange(self,min='*',max='*'):
258 self('set zrange [%s:%s]' % (min,max))
259
260 def x2range(self,min='*',max='*'):
261 self('set xrange [%s:%s]' % (min,max))
262
263 def y2range(self,min='*',max='*'):
264 self('set yrange [%s:%s]' % (min,max))
265
266 def z2range(self,min='*',max='*'):
267 self('set zrange [%s:%s]' % (min,max))
268
269 def rrange(self,min='*',max='*'):
270 self('set rrange [%s:%s]' % (min,max))
271
272 def trange(self,min='*',max='*'):
273 self('set trange [%s:%s]' % (min,max))
274
275 def urange(self,min='*',max='*'):
276 self('set urange [%s:%s]' % (min,max))
277
278 def vrange(self,min='*',max='*'):
279 self('set vrange [%s:%s]' % (min,max))
280
281 def set_ps(self,option):
282 """Set an option for the PostScript terminal and reset default term."""
283
284 self('set terminal postscript %s ' % option)
285 self('set terminal %s' % gp.GnuplotOpts.default_term)
286
287 def __plot_ps(self, plot_method,*items, **keyw):
288 """Wrapper for plot/splot/replot, with processing of hardcopy options.
289
290 For internal use only."""
291
292 # Filter out PostScript options which will crash the normal plot/replot
293 psargs = {'filename':None,
294 'mode':None,
295 'eps':None,
296 'enhanced':None,
297 'color':None,
298 'solid':None,
299 'duplexing':None,
300 'fontname':None,
301 'fontsize':None,
302 'debug':0 }
303
304 for k in psargs.keys():
305 if keyw.has_key(k):
306 psargs[k] = keyw[k]
307 del keyw[k]
308
309 # Filter out other options the original plot doesn't know
310 hardcopy = popkey(keyw,'hardcopy',psargs['filename'] is not None)
311 titles = popkey(keyw,'titles',0)
312
313 # the filename keyword should control hardcopy generation, this is an
314 # override switch only which needs to be explicitly set to zero
315 if hardcopy:
316 if psargs['filename'] is None:
317 raise ValueError, \
318 'If you request hardcopy, you must give a filename.'
319
320 # set null output so nothing goes to screen. hardcopy() restores output
321 self('set term dumb')
322 # I don't know how to prevent screen output in Windows
323 if os.name == 'posix':
324 self('set output "/dev/null"')
325
326 new_items = zip_items(items,titles)
327 # plot_method is either plot or replot from the original Gnuplot class:
328 plot_method(self,*new_items,**keyw)
329
330 # Do hardcopy if requested
331 if hardcopy:
332 if psargs['filename'].endswith('.eps'):
333 psargs['eps'] = 1
334 self.hardcopy(**psargs)
335
336 def plot(self, *items, **keyw):
337 """Draw a new plot.
338
339 Clear the current plot and create a new 2-d plot containing
340 the specified items. Each arguments should be of the
341 following types:
342
343 'PlotItem' (e.g., 'Data', 'File', 'Func') -- This is the most
344 flexible way to call plot because the PlotItems can
345 contain suboptions. Moreover, PlotItems can be saved to
346 variables so that their lifetime is longer than one plot
347 command; thus they can be replotted with minimal overhead.
348
349 'string' (e.g., 'sin(x)') -- The string is interpreted as
350 'Func(string)' (a function that is computed by gnuplot).
351
352 Anything else -- The object, which should be convertible to an
353 array, is passed to the 'Data' constructor, and thus
354 plotted as data. If the conversion fails, an exception is
355 raised.
356
357
358 This is a modified version of plot(). Compared to the original in
359 Gnuplot.py, this version has several enhancements, listed below.
360
361
362 Modifications to the input arguments
363 ------------------------------------
364
365 (1-d array means Numeric array, list or tuple):
366
367 (i) Any 1-d array which is NOT followed by another 1-d array, is
368 automatically zipped with range(len(array_1d)). Typing g.plot(y) will
369 plot y against its indices.
370
371 (ii) If two 1-d arrays are contiguous in the argument list, they are
372 automatically zipped together. So g.plot(x,y) plots y vs. x, and
373 g.plot(x1,y1,x2,y2) plots y1 vs. x1 and y2 vs. x2.
374
375 (iii) Any 1-d array which is followed by None is automatically zipped
376 with range(len(array_1d)). In this form, typing g.plot(y1,None,y2)
377 will plot both y1 and y2 against their respective indices (and NOT
378 versus one another). The None prevents zipping y1 and y2 together, and
379 since y2 is unpaired it is automatically zipped to its indices by (i)
380
381 (iv) Any other arguments which don't match these cases are left alone and
382 passed to the code below.
383
384 For lists or tuples, the heuristics used to determine whether they are
385 in fact 1-d is fairly simplistic: their first element is checked, and
386 if it is not a list or tuple itself, it is assumed that the whole
387 object is one-dimensional.
388
389 An additional optional keyword 'titles' has been added: it must be a
390 list of strings to be used as labels for the individual plots which
391 are NOT PlotItem objects (since those objects carry their own labels
392 within).
393
394
395 PostScript generation
396 ---------------------
397
398 This version of plot() also handles automatically the production of
399 PostScript output. The main options are (given as keyword arguments):
400
401 - filename: a string, typically ending in .eps. If given, the plot is
402 sent to this file in PostScript format.
403
404 - hardcopy: this can be set to 0 to override 'filename'. It does not
405 need to be given to produce PostScript, its purpose is to allow
406 switching PostScript output off globally in scripts without having to
407 manually change 'filename' values in multiple calls.
408
409 All other keywords accepted by Gnuplot.hardcopy() are transparently
410 passed, and safely ignored if output is sent to the screen instead of
411 PostScript.
412
413 For example:
414
415 In [1]: x=frange(0,2*pi,npts=100)
416
417 Generate a plot in file 'sin.eps':
418
419 In [2]: plot(x,sin(x),filename = 'sin.eps')
420
421 Plot to screen instead, without having to change the filename:
422
423 In [3]: plot(x,sin(x),filename = 'sin.eps',hardcopy=0)
424
425 Pass the 'color=0' option to hardcopy for monochrome output:
426
427 In [4]: plot(x,sin(x),filename = 'sin.eps',color=0)
428
429 PostScript generation through plot() is useful mainly for scripting
430 uses where you are not interested in interactive plotting. For
431 interactive use, the hardcopy() function is typically more convenient:
432
433 In [5]: plot(x,sin(x))
434
435 In [6]: hardcopy('sin.eps') """
436
437 self.__plot_ps(Gnuplot_ori.Gnuplot.plot,*items,**keyw)
438
439 def plot2(self,arg,**kw):
440 """Plot the entries of a dictionary or a list/tuple of arrays.
441
442 This simple utility calls plot() with a list of Gnuplot.Data objects
443 constructed either from the values of the input dictionary, or the entries
444 in it if it is a tuple or list. Each item gets labeled with the key/index
445 in the Gnuplot legend.
446
447 Each item is plotted by zipping it with a list of its indices.
448
449 Any keywords are passed directly to plot()."""
450
451 if hasattr(arg,'keys'):
452 keys = arg.keys()
453 keys.sort()
454 else:
455 keys = range(len(arg))
456
457 pitems = [Data(zip(range(len(arg[k])),arg[k]),title=`k`) for k in keys]
458 self.plot(*pitems,**kw)
459
460 def splot(self, *items, **keyw):
461 """Draw a new three-dimensional plot.
462
463 Clear the current plot and create a new 3-d plot containing
464 the specified items. Arguments can be of the following types:
465
466 'PlotItem' (e.g., 'Data', 'File', 'Func', 'GridData' ) -- This
467 is the most flexible way to call plot because the
468 PlotItems can contain suboptions. Moreover, PlotItems can
469 be saved to variables so that their lifetime is longer
470 than one plot command--thus they can be replotted with
471 minimal overhead.
472
473 'string' (e.g., 'sin(x*y)') -- The string is interpreted as a
474 'Func()' (a function that is computed by gnuplot).
475
476 Anything else -- The object is converted to a Data() item, and
477 thus plotted as data. Note that each data point should
478 normally have at least three values associated with it
479 (i.e., x, y, and z). If the conversion fails, an
480 exception is raised.
481
482 This is a modified version of splot(). Compared to the original in
483 Gnuplot.py, this version has several enhancements, listed in the
484 plot() documentation.
485 """
486
487 self.__plot_ps(Gnuplot_ori.Gnuplot.splot,*items,**keyw)
488
489 def replot(self, *items, **keyw):
490 """Replot the data, possibly adding new 'PlotItem's.
491
492 Replot the existing graph, using the items in the current
493 itemlist. If arguments are specified, they are interpreted as
494 additional items to be plotted alongside the existing items on
495 the same graph. See 'plot' for details.
496
497 If you want to replot to a postscript file, you MUST give the
498 'filename' keyword argument in each call to replot. The Gnuplot python
499 interface has no way of knowing that your previous call to
500 Gnuplot.plot() was meant for PostScript output."""
501
502 self.__plot_ps(Gnuplot_ori.Gnuplot.replot,*items,**keyw)
503
504 # The original hardcopy has a bug. See fix at the end. The rest of the code
505 # was lifted verbatim from the original, so that people using IPython get the
506 # benefits without having to manually patch Gnuplot.py
507 def hardcopy(self, filename=None,
508 mode=None,
509 eps=None,
510 enhanced=None,
511 color=None,
512 solid=None,
513 duplexing=None,
514 fontname=None,
515 fontsize=None,
516 debug = 0,
517 ):
518 """Create a hardcopy of the current plot.
519
520 Create a postscript hardcopy of the current plot to the
521 default printer (if configured) or to the specified filename.
522
523 Note that gnuplot remembers the postscript suboptions across
524 terminal changes. Therefore if you set, for example, color=1
525 for one hardcopy then the next hardcopy will also be color
526 unless you explicitly choose color=0. Alternately you can
527 force all of the options to their defaults by setting
528 mode='default'. I consider this to be a bug in gnuplot.
529
530 Keyword arguments:
531
532 'filename=<string>' -- if a filename is specified, save the
533 output in that file; otherwise print it immediately
534 using the 'default_lpr' configuration option. If the
535 filename ends in '.eps', EPS mode is automatically
536 selected (like manually specifying eps=1 or mode='eps').
537
538 'mode=<string>' -- set the postscript submode ('landscape',
539 'portrait', 'eps', or 'default'). The default is
540 to leave this option unspecified.
541
542 'eps=<bool>' -- shorthand for 'mode="eps"'; asks gnuplot to
543 generate encapsulated postscript.
544
545 'enhanced=<bool>' -- if set (the default), then generate
546 enhanced postscript, which allows extra features like
547 font-switching, superscripts, and subscripts in axis
548 labels. (Some old gnuplot versions do not support
549 enhanced postscript; if this is the case set
550 gp.GnuplotOpts.prefer_enhanced_postscript=None.)
551
552 'color=<bool>' -- if set, create a plot with color. Default
553 is to leave this option unchanged.
554
555 'solid=<bool>' -- if set, force lines to be solid (i.e., not
556 dashed).
557
558 'duplexing=<string>' -- set duplexing option ('defaultplex',
559 'simplex', or 'duplex'). Only request double-sided
560 printing if your printer can handle it. Actually this
561 option is probably meaningless since hardcopy() can only
562 print a single plot at a time.
563
564 'fontname=<string>' -- set the default font to <string>,
565 which must be a valid postscript font. The default is
566 to leave this option unspecified.
567
568 'fontsize=<double>' -- set the default font size, in
569 postscript points.
570
571 'debug=<bool>' -- print extra debugging information (useful if
572 your PostScript files are misteriously not being created).
573 """
574
575 if filename is None:
576 assert gp.GnuplotOpts.default_lpr is not None, \
577 OptionException('default_lpr is not set, so you can only '
578 'print to a file.')
579 filename = gp.GnuplotOpts.default_lpr
580 lpr_output = 1
581 else:
582 if filename.endswith('.eps'):
583 eps = 1
584 lpr_output = 0
585
586 # Be careful processing the options. If the user didn't
587 # request an option explicitly, do not specify it on the 'set
588 # terminal' line (don't even specify the default value for the
589 # option). This is to avoid confusing older versions of
590 # gnuplot that do not support all of these options. The
591 # exception is 'enhanced', which is just too useful to have to
592 # specify each time!
593
594 setterm = ['set', 'terminal', 'postscript']
595 if eps:
596 assert mode is None or mode=='eps', \
597 OptionException('eps option and mode are incompatible')
598 setterm.append('eps')
599 else:
600 if mode is not None:
601 assert mode in ['landscape', 'portrait', 'eps', 'default'], \
602 OptionException('illegal mode "%s"' % mode)
603 setterm.append(mode)
604 if enhanced is None:
605 enhanced = gp.GnuplotOpts.prefer_enhanced_postscript
606 if enhanced is not None:
607 if enhanced: setterm.append('enhanced')
608 else: setterm.append('noenhanced')
609 if color is not None:
610 if color: setterm.append('color')
611 else: setterm.append('monochrome')
612 if solid is not None:
613 if solid: setterm.append('solid')
614 else: setterm.append('dashed')
615 if duplexing is not None:
616 assert duplexing in ['defaultplex', 'simplex', 'duplex'], \
617 OptionException('illegal duplexing mode "%s"' % duplexing)
618 setterm.append(duplexing)
619 if fontname is not None:
620 setterm.append('"%s"' % fontname)
621 if fontsize is not None:
622 setterm.append('%s' % fontsize)
623
624 self(string.join(setterm))
625 self.set_string('output', filename)
626 # replot the current figure (to the printer):
627 self.refresh()
628
629 # fperez. Ugly kludge: often for some reason the file is NOT created
630 # and we must reissue the creation commands. I have no idea why!
631 if not lpr_output:
632 #print 'Hardcopy <%s>' % filename # dbg
633 maxtries = 20
634 delay = 0.1 # delay (in seconds) between print attempts
635 for i in range(maxtries):
636 time.sleep(0.05) # safety, very small delay
637 if os.path.isfile(filename):
638 if debug:
639 print 'Hardcopy to file <%s> success at attempt #%s.' \
640 % (filename,i+1)
641 break
642 time.sleep(delay)
643 # try again, issue all commands just in case
644 self(string.join(setterm))
645 self.set_string('output', filename)
646 self.refresh()
647 if not os.path.isfile(filename):
648 print >> sys.stderr,'ERROR: Tried %s times and failed to '\
649 'create hardcopy file `%s`' % (maxtries,filename)
650
651 # reset the terminal to its `default' setting:
652 self('set terminal %s' % gp.GnuplotOpts.default_term)
653 self.set_string('output')
654
655 #********************** End of file <Gnuplot2.py> ************************
@@ -0,0 +1,148 b''
1 # -*- coding: utf-8 -*-
2 """Interactive functions and magic functions for Gnuplot usage.
3
4 This requires the Gnuplot.py module for interfacing python with Gnuplot, which
5 can be downloaded from:
6
7 http://gnuplot-py.sourceforge.net/
8
9 See gphelp() below for details on the services offered by this module.
10
11 Inspired by a suggestion/request from Arnd Baecker.
12
13 $Id: GnuplotInteractive.py 389 2004-10-09 07:59:30Z fperez $"""
14
15 __all__ = ['Gnuplot','gp','gp_new','plot','plot2','splot','replot',
16 'hardcopy','gpdata','gpfile','gpstring','gpfunc','gpgrid',
17 'gphelp']
18
19 import IPython.GnuplotRuntime as GRun
20 from IPython.genutils import page,warn
21
22 # Set global names for interactive use
23 Gnuplot = GRun.Gnuplot
24 gp_new = GRun.gp_new
25 gp = GRun.gp
26 plot = gp.plot
27 plot2 = gp.plot2
28 splot = gp.splot
29 replot = gp.replot
30 hardcopy = gp.hardcopy
31
32 # Accessors for the main plot object constructors:
33 gpdata = Gnuplot.Data
34 gpfile = Gnuplot.File
35 gpstring = Gnuplot.String
36 gpfunc = Gnuplot.Func
37 gpgrid = Gnuplot.GridData
38
39 def gphelp():
40 """Print information about the Gnuplot facilities in IPython."""
41
42 page("""
43 IPython provides an interface to access the Gnuplot scientific plotting
44 system, in an environment similar to that of Mathematica or Matlab.
45
46 New top-level global objects
47 ----------------------------
48
49 Please see their respective docstrings for further details.
50
51 - gp: a running Gnuplot instance. You can access its methods as
52 gp.<method>. gp(`a string`) will execute the given string as if it had been
53 typed in an interactive gnuplot window.
54
55 - plot, splot, replot and hardcopy: aliases to the methods of the same name in
56 the global running Gnuplot instance gp. These allow you to simply type:
57
58 In [1]: plot(x,sin(x),title='Sin(x)') # assuming x is a Numeric array
59
60 and obtain a plot of sin(x) vs x with the title 'Sin(x)'.
61
62 - gp_new: a function which returns a new Gnuplot instance. This can be used to
63 have multiple Gnuplot instances running in your session to compare different
64 plots, each in a separate window.
65
66 - Gnuplot: alias to the Gnuplot2 module, an improved drop-in replacement for
67 the original Gnuplot.py. Gnuplot2 needs Gnuplot but redefines several of its
68 functions with improved versions (Gnuplot2 comes with IPython).
69
70 - gpdata, gpfile, gpstring, gpfunc, gpgrid: aliases to Gnuplot.Data,
71 Gnuplot.File, Gnuplot.String, Gnuplot.Func and Gnuplot.GridData
72 respectively. These functions create objects which can then be passed to the
73 plotting commands. See the Gnuplot.py documentation for details.
74
75 Keep in mind that all commands passed to a Gnuplot instance are executed in
76 the Gnuplot namespace, where no Python variables exist. For example, for
77 plotting sin(x) vs x as above, typing
78
79 In [2]: gp('plot x,sin(x)')
80
81 would not work. Instead, you would get the plot of BOTH the functions 'x' and
82 'sin(x)', since Gnuplot doesn't know about the 'x' Python array. The plot()
83 method lives in python and does know about these variables.
84
85
86 New magic functions
87 -------------------
88
89 %gpc: pass one command to Gnuplot and execute it or open a Gnuplot shell where
90 each line of input is executed.
91
92 %gp_set_default: reset the value of IPython's global Gnuplot instance.""")
93
94 # Code below is all for IPython use
95 # Define the magic functions for communicating with the above gnuplot instance.
96 def magic_gpc(self,parameter_s=''):
97 """Execute a gnuplot command or open a gnuplot shell.
98
99 Usage (omit the % if automagic is on). There are two ways to use it:
100
101 1) %gpc 'command' -> passes 'command' directly to the gnuplot instance.
102
103 2) %gpc -> will open up a prompt (gnuplot>>>) which takes input like the
104 standard gnuplot interactive prompt. If you need to type a multi-line
105 command, use \\ at the end of each intermediate line.
106
107 Upon exiting of the gnuplot sub-shell, you return to your IPython
108 session (the gnuplot sub-shell can be invoked as many times as needed).
109 """
110
111 if parameter_s.strip():
112 self.shell.gnuplot(parameter_s)
113 else:
114 self.shell.gnuplot.interact()
115
116 def magic_gp_set_default(self,parameter_s=''):
117 """Set the default gnuplot instance accessed by the %gp magic function.
118
119 %gp_set_default name
120
121 Call with the name of the new instance at the command line. If you want to
122 set this instance in your own code (using an embedded IPython, for
123 example), simply set the variable __IPYTHON__.gnuplot to your own gnuplot
124 instance object."""
125
126 gname = parameter_s.strip()
127 G = eval(gname,self.shell.user_ns)
128 self.shell.gnuplot = G
129 self.shell.user_ns.update({'plot':G.plot,'splot':G.splot,'plot2':G.plot2,
130 'replot':G.replot,'hardcopy':G.hardcopy})
131
132 try:
133 __IPYTHON__
134 except NameError:
135 pass
136 else:
137 # make the global Gnuplot instance known to IPython
138 __IPYTHON__.gnuplot = GRun.gp
139 __IPYTHON__.gnuplot.shell_first_time = 1
140
141 print """*** Type `gphelp` for help on the Gnuplot integration features."""
142
143 # Add the new magic functions to the class dict
144 from IPython.iplib import InteractiveShell
145 InteractiveShell.magic_gpc = magic_gpc
146 InteractiveShell.magic_gp_set_default = magic_gp_set_default
147
148 #********************** End of file <GnuplotInteractive.py> *******************
@@ -0,0 +1,147 b''
1 # -*- coding: utf-8 -*-
2 """Basic Gnuplot functionality for inclusion in other code.
3
4 This module creates a running Gnuplot instance called 'gp' and builds other
5 convenient globals for quick use in running scripts. It is intended to allow
6 you to script plotting tasks in Python with a minimum of effort. A typical
7 usage would be:
8
9 import IPython.GnuplotRuntime as GP # or some other short name
10 GP.gp.plot(GP.File('your_data.dat'))
11
12
13 This module exposes the following objects:
14
15 - gp: a running Gnuplot instance. You can access its methods as
16 gp.<method>. gp(`a string`) will execute the given string as if it had been
17 typed in an interactive gnuplot window.
18
19 - gp_new: a function which returns a new Gnuplot instance. This can be used to
20 have multiple Gnuplot instances running in your session to compare different
21 plots.
22
23 - Gnuplot: alias to the Gnuplot2 module, an improved drop-in replacement for
24 the original Gnuplot.py. Gnuplot2 needs Gnuplot but redefines several of its
25 functions with improved versions (Gnuplot2 comes with IPython).
26
27 - Data: alias to Gnuplot.Data, makes a PlotItem from array data.
28
29 - File: alias to Gnuplot.File, makes a PlotItem from a file.
30
31 - String: alias to Gnuplot.String, makes a PlotItem from a string formatted
32 exactly like a file for Gnuplot.File would be.
33
34 - Func: alias to Gnuplot.Func, makes a PlotItem from a function string.
35
36 - GridData: alias to Gnuplot.GridData, makes a PlotItem from grid data.
37
38 - pm3d_config: a string with Gnuplot commands to set up the pm3d mode for
39 surface plotting. You can activate it simply by calling gp(pm3d_config).
40
41 - eps_fix_bbox: A Unix-only function to fix eps files with bad bounding boxes
42 (which Gnuplot generates when the plot size is set to square).
43
44 This requires the Gnuplot.py module for interfacing Python with Gnuplot, which
45 can be downloaded from:
46
47 http://gnuplot-py.sourceforge.net/
48
49 Inspired by a suggestion/request from Arnd Baecker.
50
51 $Id: GnuplotRuntime.py 389 2004-10-09 07:59:30Z fperez $"""
52
53 __all__ = ['Gnuplot','gp','gp_new','Data','File','Func','GridData',
54 'pm3d_config','eps_fix_bbox']
55
56 import os,tempfile,sys
57 from IPython.genutils import getoutput
58
59 #---------------------------------------------------------------------------
60 # Notes on mouse support for Gnuplot.py
61
62 # If you do not have a mouse-enabled gnuplot, set gnuplot_mouse to 0. If you
63 # use gnuplot, you should really grab a recent, mouse enabled copy. It is an
64 # extremely useful feature. Mouse support is official as of gnuplot 4.0,
65 # released in April 2004.
66
67 # For the mouse features to work correctly, you MUST set your Gnuplot.py
68 # module to use temporary files instead of 'inline data' for data
69 # communication. Note that this is the default, so unless you've manually
70 # fiddled with it you should be ok. If you need to make changes, in the
71 # Gnuplot module directory, loook for the gp_unix.py file and make sure the
72 # prefer_inline_data variable is set to 0. If you set it to 1 Gnuplot.py will
73 # try to pass the data to gnuplot via standard input, which completely
74 # confuses the mouse control system (even though it may be a bit faster than
75 # using temp files).
76
77 # As of Gnuplot.py v1.7, a new option was added to use FIFOs (pipes). This
78 # mechanism, while fast, also breaks the mouse system. You must therefore set
79 # the variable prefer_fifo_data to 0 in gp_unix.py.
80
81 tmpname = tempfile.mktemp()
82 open(tmpname,'w').write('set mouse')
83 gnu_out = getoutput('gnuplot '+ tmpname)
84 os.unlink(tmpname)
85 if gnu_out: # Gnuplot won't print anything if it has mouse support
86 print "*** Your version of Gnuplot appears not to have mouse support."
87 gnuplot_mouse = 0
88 else:
89 gnuplot_mouse = 1
90 del tmpname,gnu_out
91
92 # Default state for persistence of new gnuplot instances
93 if os.name in ['nt','dos'] or sys.platform == 'cygwin':
94 gnuplot_persist = 0
95 else:
96 gnuplot_persist = 1
97
98 import IPython.Gnuplot2 as Gnuplot
99
100 class NotGiven: pass
101
102 def gp_new(mouse=NotGiven,persist=NotGiven):
103 """Return a new Gnuplot instance.
104
105 The instance returned uses the improved methods defined in Gnuplot2.
106
107 Options (boolean):
108
109 - mouse: if unspecified, the module global gnuplot_mouse is used.
110
111 - persist: if unspecified, the module global gnuplot_persist is used."""
112
113 if mouse is NotGiven:
114 mouse = gnuplot_mouse
115 if persist is NotGiven:
116 persist = gnuplot_persist
117 g = Gnuplot.Gnuplot(persist=persist)
118 if mouse:
119 g('set mouse')
120 return g
121
122 # Global-level names.
123
124 # A global Gnuplot instance for interactive use:
125 gp = gp_new()
126
127 # Accessors for the main plot object constructors:
128 Data = Gnuplot.Data
129 File = Gnuplot.File
130 Func = Gnuplot.Func
131 String = Gnuplot.String
132 GridData = Gnuplot.GridData
133
134 # A Unix-only function to fix eps files with bad bounding boxes (which Gnuplot
135 # generates when the plot size is set to square):
136 eps_fix_bbox = Gnuplot.eps_fix_bbox
137
138 # String for configuring pm3d. Simply call g(pm3d_config) to execute it. pm3d
139 # is a very nice mode for plotting colormaps on surfaces. Modify the defaults
140 # below to suit your taste.
141 pm3d_config = """
142 set pm3d solid
143 set hidden3d
144 unset surface
145 set isosamples 50
146 """
147 #******************** End of file <GnuplotRuntime.py> ******************
@@ -0,0 +1,253 b''
1 # -*- coding: utf-8 -*-
2 """String interpolation for Python (by Ka-Ping Yee, 14 Feb 2000).
3
4 This module lets you quickly and conveniently interpolate values into
5 strings (in the flavour of Perl or Tcl, but with less extraneous
6 punctuation). You get a bit more power than in the other languages,
7 because this module allows subscripting, slicing, function calls,
8 attribute lookup, or arbitrary expressions. Variables and expressions
9 are evaluated in the namespace of the caller.
10
11 The itpl() function returns the result of interpolating a string, and
12 printpl() prints out an interpolated string. Here are some examples:
13
14 from Itpl import printpl
15 printpl("Here is a $string.")
16 printpl("Here is a $module.member.")
17 printpl("Here is an $object.member.")
18 printpl("Here is a $functioncall(with, arguments).")
19 printpl("Here is an ${arbitrary + expression}.")
20 printpl("Here is an $array[3] member.")
21 printpl("Here is a $dictionary['member'].")
22
23 The filter() function filters a file object so that output through it
24 is interpolated. This lets you produce the illusion that Python knows
25 how to do interpolation:
26
27 import Itpl
28 sys.stdout = Itpl.filter()
29 f = "fancy"
30 print "Isn't this $f?"
31 print "Standard output has been replaced with a $sys.stdout object."
32 sys.stdout = Itpl.unfilter()
33 print "Okay, back $to $normal."
34
35 Under the hood, the Itpl class represents a string that knows how to
36 interpolate values. An instance of the class parses the string once
37 upon initialization; the evaluation and substitution can then be done
38 each time the instance is evaluated with str(instance). For example:
39
40 from Itpl import Itpl
41 s = Itpl("Here is $foo.")
42 foo = 5
43 print str(s)
44 foo = "bar"
45 print str(s)
46
47 $Id: Itpl.py 542 2005-03-18 09:16:04Z fperez $
48 """ # ' -> close an open quote for stupid emacs
49
50 #*****************************************************************************
51 #
52 # Copyright (c) 2001 Ka-Ping Yee <ping@lfw.org>
53 #
54 #
55 # Published under the terms of the MIT license, hereby reproduced:
56 #
57 # Permission is hereby granted, free of charge, to any person obtaining a copy
58 # of this software and associated documentation files (the "Software"), to
59 # deal in the Software without restriction, including without limitation the
60 # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
61 # sell copies of the Software, and to permit persons to whom the Software is
62 # furnished to do so, subject to the following conditions:
63 #
64 # The above copyright notice and this permission notice shall be included in
65 # all copies or substantial portions of the Software.
66 #
67 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
68 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
69 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
70 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
71 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
72 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
73 # IN THE SOFTWARE.
74 #
75 #*****************************************************************************
76
77 __author__ = 'Ka-Ping Yee <ping@lfw.org>'
78 __license__ = 'MIT'
79
80 import sys, string
81 from types import StringType
82 from tokenize import tokenprog
83
84 class ItplError(ValueError):
85 def __init__(self, text, pos):
86 self.text = text
87 self.pos = pos
88 def __str__(self):
89 return "unfinished expression in %s at char %d" % (
90 repr(self.text), self.pos)
91
92 def matchorfail(text, pos):
93 match = tokenprog.match(text, pos)
94 if match is None:
95 raise ItplError(text, pos)
96 return match, match.end()
97
98 class Itpl:
99 """Class representing a string with interpolation abilities.
100
101 Upon creation, an instance works out what parts of the format
102 string are literal and what parts need to be evaluated. The
103 evaluation and substitution happens in the namespace of the
104 caller when str(instance) is called."""
105
106 def __init__(self, format):
107 """The single argument to this constructor is a format string.
108
109 The format string is parsed according to the following rules:
110
111 1. A dollar sign and a name, possibly followed by any of:
112 - an open-paren, and anything up to the matching paren
113 - an open-bracket, and anything up to the matching bracket
114 - a period and a name
115 any number of times, is evaluated as a Python expression.
116
117 2. A dollar sign immediately followed by an open-brace, and
118 anything up to the matching close-brace, is evaluated as
119 a Python expression.
120
121 3. Outside of the expressions described in the above two rules,
122 two dollar signs in a row give you one literal dollar sign."""
123
124 if type(format) != StringType:
125 raise TypeError, "needs string initializer"
126 self.format = format
127
128 namechars = "abcdefghijklmnopqrstuvwxyz" \
129 "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
130 chunks = []
131 pos = 0
132
133 while 1:
134 dollar = string.find(format, "$", pos)
135 if dollar < 0: break
136 nextchar = format[dollar+1]
137
138 if nextchar == "{":
139 chunks.append((0, format[pos:dollar]))
140 pos, level = dollar+2, 1
141 while level:
142 match, pos = matchorfail(format, pos)
143 tstart, tend = match.regs[3]
144 token = format[tstart:tend]
145 if token == "{": level = level+1
146 elif token == "}": level = level-1
147 chunks.append((1, format[dollar+2:pos-1]))
148
149 elif nextchar in namechars:
150 chunks.append((0, format[pos:dollar]))
151 match, pos = matchorfail(format, dollar+1)
152 while pos < len(format):
153 if format[pos] == "." and \
154 pos+1 < len(format) and format[pos+1] in namechars:
155 match, pos = matchorfail(format, pos+1)
156 elif format[pos] in "([":
157 pos, level = pos+1, 1
158 while level:
159 match, pos = matchorfail(format, pos)
160 tstart, tend = match.regs[3]
161 token = format[tstart:tend]
162 if token[0] in "([": level = level+1
163 elif token[0] in ")]": level = level-1
164 else: break
165 chunks.append((1, format[dollar+1:pos]))
166
167 else:
168 chunks.append((0, format[pos:dollar+1]))
169 pos = dollar + 1 + (nextchar == "$")
170
171 if pos < len(format): chunks.append((0, format[pos:]))
172 self.chunks = chunks
173
174 def __repr__(self):
175 return "<Itpl %s >" % repr(self.format)
176
177 def __str__(self):
178 """Evaluate and substitute the appropriate parts of the string."""
179
180 # We need to skip enough frames to get to the actual caller outside of
181 # Itpl.
182 frame = sys._getframe(1)
183 while frame.f_globals["__name__"] == __name__: frame = frame.f_back
184 loc, glob = frame.f_locals, frame.f_globals
185
186 result = []
187 for live, chunk in self.chunks:
188 if live: result.append(str(eval(chunk,glob,loc)))
189 else: result.append(chunk)
190
191 return ''.join(result)
192
193 class ItplNS(Itpl):
194 """Class representing a string with interpolation abilities.
195
196 This inherits from Itpl, but at creation time a namespace is provided
197 where the evaluation will occur. The interpolation becomes a bit more
198 efficient, as no traceback needs to be extracte. It also allows the
199 caller to supply a different namespace for the interpolation to occur than
200 its own."""
201
202 def __init__(self, format,globals,locals=None):
203 """ItplNS(format,globals[,locals]) -> interpolating string instance.
204
205 This constructor, besides a format string, takes a globals dictionary
206 and optionally a locals (which defaults to globals if not provided).
207
208 For further details, see the Itpl constructor."""
209
210 if locals is None:
211 locals = globals
212 self.globals = globals
213 self.locals = locals
214 Itpl.__init__(self,format)
215
216 def __str__(self):
217 """Evaluate and substitute the appropriate parts of the string."""
218 glob = self.globals
219 loc = self.locals
220 result = []
221 for live, chunk in self.chunks:
222 if live: result.append(str(eval(chunk,glob,loc)))
223 else: result.append(chunk)
224 return ''.join(result)
225
226 # utilities for fast printing
227 def itpl(text): return str(Itpl(text))
228 def printpl(text): print itpl(text)
229 # versions with namespace
230 def itplns(text,globals,locals=None): return str(ItplNS(text,globals,locals))
231 def printplns(text,globals,locals=None): print itplns(text,globals,locals)
232
233 class ItplFile:
234 """A file object that filters each write() through an interpolator."""
235 def __init__(self, file): self.file = file
236 def __repr__(self): return "<interpolated " + repr(self.file) + ">"
237 def __getattr__(self, attr): return getattr(self.file, attr)
238 def write(self, text): self.file.write(str(Itpl(text)))
239
240 def filter(file=sys.stdout):
241 """Return an ItplFile that filters writes to the given file object.
242
243 'file = filter(file)' replaces 'file' with a filtered object that
244 has a write() method. When called with no argument, this creates
245 a filter to sys.stdout."""
246 return ItplFile(file)
247
248 def unfilter(ifile=None):
249 """Return the original file that corresponds to the given ItplFile.
250
251 'file = unfilter(file)' undoes the effect of 'file = filter(file)'.
252 'sys.stdout = unfilter()' undoes the effect of 'sys.stdout = filter()'."""
253 return ifile and ifile.file or sys.stdout.file
@@ -0,0 +1,185 b''
1 # -*- coding: utf-8 -*-
2 """
3 Logger class for IPython's logging facilities.
4
5 $Id: Logger.py 430 2004-11-30 08:52:05Z fperez $
6 """
7
8 #*****************************************************************************
9 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de> and
10 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
11 #
12 # Distributed under the terms of the BSD License. The full license is in
13 # the file COPYING, distributed as part of this software.
14 #*****************************************************************************
15
16 #****************************************************************************
17 # Modules and globals
18
19 from IPython import Release
20 __author__ = '%s <%s>\n%s <%s>' % \
21 ( Release.authors['Janko'] + Release.authors['Fernando'] )
22 __license__ = Release.license
23
24 # Python standard modules
25 import os,sys,glob
26
27 # Homebrewed
28 from IPython.genutils import *
29
30 #****************************************************************************
31 # FIXME: The logger class shouldn't be a mixin, it throws too many things into
32 # the InteractiveShell namespace. Rather make it a standalone tool, and create
33 # a Logger instance in InteractiveShell that uses it. Doing this will require
34 # tracking down a *lot* of nasty uses of the Logger attributes in
35 # InteractiveShell, but will clean up things quite a bit.
36
37 class Logger:
38 """A Logfile Mixin class with different policies for file creation"""
39
40 # FIXME: once this isn't a mixin, log_ns should just be 'namespace', since the
41 # names won't collide anymore.
42 def __init__(self,log_ns):
43 self._i00,self._i,self._ii,self._iii = '','','',''
44 self.do_full_cache = 0 # FIXME. There's also a do_full.. in OutputCache
45 self.log_ns = log_ns
46 # defaults
47 self.LOGMODE = 'backup'
48 self.defname = 'logfile'
49
50 def create_log(self,header='',fname='',defname='.Logger.log'):
51 """Generate a new log-file with a default header"""
52 if fname:
53 self.LOG = fname
54
55 if self.LOG:
56 self.logfname = self.LOG
57 else:
58 self.logfname = defname
59
60 if self.LOGMODE == 'over':
61 if os.path.isfile(self.logfname):
62 os.remove(self.logfname)
63 self.logfile = open(self.logfname,'w')
64 if self.LOGMODE == 'backup':
65 if os.path.isfile(self.logfname):
66 backup_logname = self.logfname+'~'
67 # Manually remove any old backup, since os.rename may fail
68 # under Windows.
69 if os.path.isfile(backup_logname):
70 os.remove(backup_logname)
71 os.rename(self.logfname,backup_logname)
72 self.logfile = open(self.logfname,'w')
73 elif self.LOGMODE == 'global':
74 self.logfname = os.path.join(self.home_dir, self.defname)
75 self.logfile = open(self.logfname, 'a')
76 self.LOG = self.logfname
77 elif self.LOGMODE == 'rotate':
78 if os.path.isfile(self.logfname):
79 if os.path.isfile(self.logfname+'.001~'):
80 old = glob.glob(self.logfname+'.*~')
81 old.sort()
82 old.reverse()
83 for f in old:
84 root, ext = os.path.splitext(f)
85 num = int(ext[1:-1])+1
86 os.rename(f, root+'.'+`num`.zfill(3)+'~')
87 os.rename(self.logfname, self.logfname+'.001~')
88 self.logfile = open(self.logfname,'w')
89 elif self.LOGMODE == 'append':
90 self.logfile = open(self.logfname,'a')
91
92 if self.LOGMODE != 'append':
93 self.logfile.write(header)
94 self.logfile.flush()
95
96 def logstart(self, header='',parameter_s = ''):
97 if not hasattr(self, 'LOG'):
98 logfname = self.LOG or parameter_s or './'+self.defname
99 self.create_log(header,logfname)
100 elif parameter_s and hasattr(self,'logfname') and \
101 parameter_s != self.logfname:
102 self.close_log()
103 self.create_log(header,parameter_s)
104
105 self._dolog = 1
106
107 def switch_log(self,val):
108 """Switch logging on/off. val should be ONLY 0 or 1."""
109
110 if not val in [0,1]:
111 raise ValueError, \
112 'Call switch_log ONLY with 0 or 1 as argument, not with:',val
113
114 label = {0:'OFF',1:'ON'}
115
116 try:
117 _ = self.logfile
118 except AttributeError:
119 print """
120 Logging hasn't been started yet (use %logstart for that).
121
122 %logon/%logoff are for temporarily starting and stopping logging for a logfile
123 which already exists. But you must first start the logging process with
124 %logstart (optionally giving a logfile name)."""
125
126 else:
127 if self._dolog == val:
128 print 'Logging is already',label[val]
129 else:
130 print 'Switching logging',label[val]
131 self._dolog = 1 - self._dolog
132
133 def logstate(self):
134 """Print a status message about the logger."""
135 try:
136 logfile = self.logfname
137 except:
138 print 'Logging has not been activated.'
139 else:
140 state = self._dolog and 'active' or 'temporarily suspended'
141 print """
142 File:\t%s
143 Mode:\t%s
144 State:\t%s """ % (logfile,self.LOGMODE,state)
145
146
147 def log(self, line,continuation=None):
148 """Write the line to a log and create input cache variables _i*."""
149
150 # update the auto _i tables
151 #print '***logging line',line # dbg
152 #print '***cache_count', self.outputcache.prompt_count # dbg
153 input_hist = self.log_ns['_ih']
154 if not continuation and line:
155 self._iii = self._ii
156 self._ii = self._i
157 self._i = self._i00
158 # put back the final \n of every input line
159 self._i00 = line+'\n'
160 #print 'Logging input:<%s>' % line # dbg
161 input_hist.append(self._i00)
162
163 # hackish access to top-level namespace to create _i1,_i2... dynamically
164 to_main = {'_i':self._i,'_ii':self._ii,'_iii':self._iii}
165 if self.do_full_cache:
166 in_num = self.outputcache.prompt_count
167 # add blank lines if the input cache fell out of sync. This can happen
168 # for embedded instances which get killed via C-D and then get resumed.
169 while in_num >= len(input_hist):
170 input_hist.append('\n')
171 new_i = '_i%s' % in_num
172 if continuation:
173 self._i00 = '%s%s\n' % (self.log_ns[new_i],line)
174 input_hist[in_num] = self._i00
175 to_main[new_i] = self._i00
176 self.log_ns.update(to_main)
177
178 if self._dolog and line:
179 self.logfile.write(line+'\n')
180 self.logfile.flush()
181
182 def close_log(self):
183 if hasattr(self, 'logfile'):
184 self.logfile.close()
185 self.logfname = ''
This diff has been collapsed as it changes many lines, (2490 lines changed) Show them Hide them
@@ -0,0 +1,2490 b''
1 # -*- coding: utf-8 -*-
2 """Magic functions for InteractiveShell.
3
4 $Id: Magic.py 583 2005-05-13 21:20:33Z fperez $"""
5
6 #*****************************************************************************
7 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de> and
8 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
9 #
10 # Distributed under the terms of the BSD License. The full license is in
11 # the file COPYING, distributed as part of this software.
12 #*****************************************************************************
13
14 #****************************************************************************
15 # Modules and globals
16
17 from IPython import Release
18 __author__ = '%s <%s>\n%s <%s>' % \
19 ( Release.authors['Janko'] + Release.authors['Fernando'] )
20 __license__ = Release.license
21
22 # Python standard modules
23 import __builtin__
24 import os,sys,inspect,pydoc,re,tempfile,shlex,pdb,bdb,time
25 try:
26 import profile,pstats
27 except ImportError:
28 profile = pstats = None
29 from getopt import getopt
30 from pprint import pprint, pformat
31 from cStringIO import StringIO
32
33 # Homebrewed
34 from IPython.Struct import Struct
35 from IPython.Itpl import Itpl, itpl, printpl,itplns
36 from IPython.FakeModule import FakeModule
37 from IPython import OInspect
38 from IPython.genutils import *
39
40 # Globals to be set later by Magic constructor
41 MAGIC_PREFIX = ''
42 MAGIC_ESCAPE = ''
43
44 #***************************************************************************
45 # Utility functions
46 def magic2python(cmd):
47 """Convert a command string of magic syntax to valid Python code."""
48
49 if cmd.startswith('#'+MAGIC_ESCAPE) or \
50 cmd.startswith(MAGIC_ESCAPE):
51 if cmd[0]=='#':
52 cmd = cmd[1:]
53 # we need to return the proper line end later
54 if cmd[-1] == '\n':
55 endl = '\n'
56 else:
57 endl = ''
58 try:
59 func,args = cmd[1:].split(' ',1)
60 except:
61 func,args = cmd[1:].rstrip(),''
62 args = args.replace('"','\\"').replace("'","\\'").rstrip()
63 return '%s%s ("%s")%s' % (MAGIC_PREFIX,func,args,endl)
64 else:
65 return cmd
66
67 def on_off(tag):
68 """Return an ON/OFF string for a 1/0 input. Simple utility function."""
69 return ['OFF','ON'][tag]
70
71 def get_py_filename(name):
72 """Return a valid python filename in the current directory.
73
74 If the given name is not a file, it adds '.py' and searches again.
75 Raises IOError with an informative message if the file isn't found."""
76
77 name = os.path.expanduser(name)
78 if not os.path.isfile(name) and not name.endswith('.py'):
79 name += '.py'
80 if os.path.isfile(name):
81 return name
82 else:
83 raise IOError,'File `%s` not found.' % name
84
85 # Try to use shlex.split for converting an input string into a sys.argv-type
86 # list. This appeared in Python 2.3, so here's a quick backport for 2.2.
87 try:
88 shlex_split = shlex.split
89 except AttributeError:
90 _quotesre = re.compile(r'[\'"](.*)[\'"]')
91 _wordchars = ('abcdfeghijklmnopqrstuvwxyz'
92 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-.~*?'
93 'ßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ'
94 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ%s'
95 % os.sep)
96
97 def shlex_split(s):
98 """Simplified backport to Python 2.2 of shlex.split().
99
100 This is a quick and dirty hack, since the shlex module under 2.2 lacks
101 several of the features needed to really match the functionality of
102 shlex.split() in 2.3."""
103
104 lex = shlex.shlex(StringIO(s))
105 # Try to get options, extensions and path separators as characters
106 lex.wordchars = _wordchars
107 lex.commenters = ''
108 # Make a list out of the lexer by hand, since in 2.2 it's not an
109 # iterator.
110 lout = []
111 while 1:
112 token = lex.get_token()
113 if token == '':
114 break
115 # Try to handle quoted tokens correctly
116 quotes = _quotesre.match(token)
117 if quotes:
118 token = quotes.group(1)
119 lout.append(token)
120 return lout
121
122 #****************************************************************************
123 # Utility classes
124 class Macro:
125 """Simple class to store the value of macros as strings.
126
127 This allows us to later exec them by checking when something is an
128 instance of this class."""
129
130 def __init__(self,cmds):
131 """Build a macro from a list of commands."""
132
133 # Since the list may include multi-line entries, first make sure that
134 # they've been all broken up before passing it to magic2python
135 cmdlist = map(magic2python,''.join(cmds).split('\n'))
136 self.value = '\n'.join(cmdlist)
137
138 def __str__(self):
139 return self.value
140
141 #***************************************************************************
142 # Main class implementing Magic functionality
143 class Magic:
144 """Magic functions for InteractiveShell.
145
146 Shell functions which can be reached as %function_name. All magic
147 functions should accept a string, which they can parse for their own
148 needs. This can make some functions easier to type, eg `%cd ../`
149 vs. `%cd("../")`
150
151 ALL definitions MUST begin with the prefix magic_. The user won't need it
152 at the command line, but it is is needed in the definition. """
153
154 # class globals
155 auto_status = ['Automagic is OFF, % prefix IS needed for magic functions.',
156 'Automagic is ON, % prefix NOT needed for magic functions.']
157
158 #......................................................................
159 # some utility functions
160
161 def __init__(self,shell):
162 # XXX This is hackish, clean up later to avoid these messy globals
163 global MAGIC_PREFIX, MAGIC_ESCAPE
164
165 self.options_table = {}
166 MAGIC_PREFIX = shell.name+'.magic_'
167 MAGIC_ESCAPE = shell.ESC_MAGIC
168 if profile is None:
169 self.magic_prun = self.profile_missing_notice
170
171 def profile_missing_notice(self, *args, **kwargs):
172 error("""\
173 The profile module could not be found. If you are a Debian user,
174 it has been removed from the standard Debian package because of its non-free
175 license. To use profiling, please install"python2.3-profiler" from non-free.""")
176
177 def default_option(self,fn,optstr):
178 """Make an entry in the options_table for fn, with value optstr"""
179
180 if fn not in self.lsmagic():
181 error("%s is not a magic function" % fn)
182 self.options_table[fn] = optstr
183
184 def lsmagic(self):
185 """Return a list of currently available magic functions.
186
187 Gives a list of the bare names after mangling (['ls','cd', ...], not
188 ['magic_ls','magic_cd',...]"""
189
190 # FIXME. This needs a cleanup, in the way the magics list is built.
191
192 # magics in class definition
193 class_magic = lambda fn: fn.startswith('magic_') and \
194 callable(Magic.__dict__[fn])
195 # in instance namespace (run-time user additions)
196 inst_magic = lambda fn: fn.startswith('magic_') and \
197 callable(self.__dict__[fn])
198 # and bound magics by user (so they can access self):
199 inst_bound_magic = lambda fn: fn.startswith('magic_') and \
200 callable(self.__class__.__dict__[fn])
201 magics = filter(class_magic,Magic.__dict__.keys()) + \
202 filter(inst_magic,self.__dict__.keys()) + \
203 filter(inst_bound_magic,self.__class__.__dict__.keys())
204 out = []
205 for fn in magics:
206 out.append(fn.replace('magic_','',1))
207 out.sort()
208 return out
209
210 def set_shell(self,shell):
211 self.shell = shell
212 self.alias_table = shell.alias_table
213
214 def extract_input_slices(self,slices):
215 """Return as a string a set of input history slices.
216
217 The set of slices is given as a list of strings (like ['1','4:8','9'],
218 since this function is for use by magic functions which get their
219 arguments as strings."""
220
221 cmds = []
222 for chunk in slices:
223 if ':' in chunk:
224 ini,fin = map(int,chunk.split(':'))
225 else:
226 ini = int(chunk)
227 fin = ini+1
228 cmds.append(self.shell.input_hist[ini:fin])
229 return cmds
230
231 def _ofind(self,oname):
232 """Find an object in the available namespaces.
233
234 self._ofind(oname) -> dict with keys: found,obj,ospace,ismagic
235
236 Has special code to detect magic functions.
237 """
238
239 oname = oname.strip()
240
241 # Namespaces to search in:
242 user_ns = self.shell.user_ns
243 internal_ns = self.shell.internal_ns
244 builtin_ns = __builtin__.__dict__
245 alias_ns = self.shell.alias_table
246
247 # Put them in a list. The order is important so that we find things in
248 # the same order that Python finds them.
249 namespaces = [ ('Interactive',user_ns),
250 ('IPython internal',internal_ns),
251 ('Python builtin',builtin_ns),
252 ('Alias',alias_ns),
253 ]
254
255 # initialize results to 'null'
256 found = 0; obj = None; ospace = None; ds = None;
257 ismagic = 0; isalias = 0
258
259 # Look for the given name by splitting it in parts. If the head is
260 # found, then we look for all the remaining parts as members, and only
261 # declare success if we can find them all.
262 oname_parts = oname.split('.')
263 oname_head, oname_rest = oname_parts[0],oname_parts[1:]
264 for nsname,ns in namespaces:
265 try:
266 obj = ns[oname_head]
267 except KeyError:
268 continue
269 else:
270 for part in oname_rest:
271 try:
272 obj = getattr(obj,part)
273 except:
274 # Blanket except b/c some badly implemented objects
275 # allow __getattr__ to raise exceptions other than
276 # AttributeError, which then crashes IPython.
277 break
278 else:
279 # If we finish the for loop (no break), we got all members
280 found = 1
281 ospace = nsname
282 if ns == alias_ns:
283 isalias = 1
284 break # namespace loop
285
286 # Try to see if it's magic
287 if not found:
288 if oname.startswith(self.shell.ESC_MAGIC):
289 oname = oname[1:]
290 obj = getattr(self,'magic_'+oname,None)
291 if obj is not None:
292 found = 1
293 ospace = 'IPython internal'
294 ismagic = 1
295
296 # Last try: special-case some literals like '', [], {}, etc:
297 if not found and oname_head in ["''",'""','[]','{}','()']:
298 obj = eval(oname_head)
299 found = 1
300 ospace = 'Interactive'
301
302 return {'found':found, 'obj':obj, 'namespace':ospace,
303 'ismagic':ismagic, 'isalias':isalias}
304
305 def arg_err(self,func):
306 """Print docstring if incorrect arguments were passed"""
307 print 'Error in arguments:'
308 print OInspect.getdoc(func)
309
310
311 def format_latex(self,str):
312 """Format a string for latex inclusion."""
313
314 # Characters that need to be escaped for latex:
315 escape_re = re.compile(r'(%|_|\$)',re.MULTILINE)
316 # Magic command names as headers:
317 cmd_name_re = re.compile(r'^(%s.*?):' % self.shell.ESC_MAGIC,
318 re.MULTILINE)
319 # Magic commands
320 cmd_re = re.compile(r'(?P<cmd>%s.+?\b)(?!\}\}:)' % self.shell.ESC_MAGIC,
321 re.MULTILINE)
322 # Paragraph continue
323 par_re = re.compile(r'\\$',re.MULTILINE)
324
325 str = cmd_name_re.sub(r'\n\\texttt{\\textsl{\\large \1}}:',str)
326 str = cmd_re.sub(r'\\texttt{\g<cmd>}',str)
327 str = par_re.sub(r'\\\\',str)
328 str = escape_re.sub(r'\\\1',str)
329 return str
330
331 def format_screen(self,str):
332 """Format a string for screen printing.
333
334 This removes some latex-type format codes."""
335 # Paragraph continue
336 par_re = re.compile(r'\\$',re.MULTILINE)
337 str = par_re.sub('',str)
338 return str
339
340 def parse_options(self,arg_str,opt_str,*long_opts,**kw):
341 """Parse options passed to an argument string.
342
343 The interface is similar to that of getopt(), but it returns back a
344 Struct with the options as keys and the stripped argument string still
345 as a string.
346
347 arg_str is quoted as a true sys.argv vector by calling on the fly a
348 python process in a subshell. This allows us to easily expand
349 variables, glob files, quote arguments, etc, with all the power and
350 correctness of the underlying system shell.
351
352 Options:
353 -mode: default 'string'. If given as 'list', the argument string is
354 returned as a list (split on whitespace) instead of a string.
355
356 -list_all: put all option values in lists. Normally only options
357 appearing more than once are put in a list."""
358
359 # inject default options at the beginning of the input line
360 caller = sys._getframe(1).f_code.co_name.replace('magic_','')
361 arg_str = '%s %s' % (self.options_table.get(caller,''),arg_str)
362
363 mode = kw.get('mode','string')
364 if mode not in ['string','list']:
365 raise ValueError,'incorrect mode given: %s' % mode
366 # Get options
367 list_all = kw.get('list_all',0)
368
369 # Check if we have more than one argument to warrant extra processing:
370 odict = {} # Dictionary with options
371 args = arg_str.split()
372 if len(args) >= 1:
373 # If the list of inputs only has 0 or 1 thing in it, there's no
374 # need to look for options
375 argv = shlex_split(arg_str)
376 # Do regular option processing
377 opts,args = getopt(argv,opt_str,*long_opts)
378 for o,a in opts:
379 if o.startswith('--'):
380 o = o[2:]
381 else:
382 o = o[1:]
383 try:
384 odict[o].append(a)
385 except AttributeError:
386 odict[o] = [odict[o],a]
387 except KeyError:
388 if list_all:
389 odict[o] = [a]
390 else:
391 odict[o] = a
392
393 # Prepare opts,args for return
394 opts = Struct(odict)
395 if mode == 'string':
396 args = ' '.join(args)
397
398 return opts,args
399
400 #......................................................................
401 # And now the actual magic functions
402
403 # Functions for IPython shell work (vars,funcs, config, etc)
404 def magic_lsmagic(self, parameter_s = ''):
405 """List currently available magic functions."""
406 mesc = self.shell.ESC_MAGIC
407 print 'Available magic functions:\n'+mesc+\
408 (' '+mesc).join(self.lsmagic())
409 print '\n' + Magic.auto_status[self.shell.rc.automagic]
410 return None
411
412 def magic_magic(self, parameter_s = ''):
413 """Print information about the magic function system."""
414
415 mode = ''
416 try:
417 if parameter_s.split()[0] == '-latex':
418 mode = 'latex'
419 except:
420 pass
421
422 magic_docs = []
423 for fname in self.lsmagic():
424 mname = 'magic_' + fname
425 for space in (Magic,self,self.__class__):
426 try:
427 fn = space.__dict__[mname]
428 except KeyError:
429 pass
430 else:
431 break
432 magic_docs.append('%s%s:\n\t%s\n' %(self.shell.ESC_MAGIC,
433 fname,fn.__doc__))
434 magic_docs = ''.join(magic_docs)
435
436 if mode == 'latex':
437 print self.format_latex(magic_docs)
438 return
439 else:
440 magic_docs = self.format_screen(magic_docs)
441
442 outmsg = """
443 IPython's 'magic' functions
444 ===========================
445
446 The magic function system provides a series of functions which allow you to
447 control the behavior of IPython itself, plus a lot of system-type
448 features. All these functions are prefixed with a % character, but parameters
449 are given without parentheses or quotes.
450
451 NOTE: If you have 'automagic' enabled (via the command line option or with the
452 %automagic function), you don't need to type in the % explicitly. By default,
453 IPython ships with automagic on, so you should only rarely need the % escape.
454
455 Example: typing '%cd mydir' (without the quotes) changes you working directory
456 to 'mydir', if it exists.
457
458 You can define your own magic functions to extend the system. See the supplied
459 ipythonrc and example-magic.py files for details (in your ipython
460 configuration directory, typically $HOME/.ipython/).
461
462 You can also define your own aliased names for magic functions. In your
463 ipythonrc file, placing a line like:
464
465 execute __IPYTHON__.magic_pf = __IPYTHON__.magic_profile
466
467 will define %pf as a new name for %profile.
468
469 You can also call magics in code using the ipmagic() function, which IPython
470 automatically adds to the builtin namespace. Type 'ipmagic?' for details.
471
472 For a list of the available magic functions, use %lsmagic. For a description
473 of any of them, type %magic_name?, e.g. '%cd?'.
474
475 Currently the magic system has the following functions:\n"""
476
477 mesc = self.shell.ESC_MAGIC
478 outmsg = ("%s\n%s\n\nSummary of magic functions (from %slsmagic):"
479 "\n\n%s%s\n\n%s" % (outmsg,
480 magic_docs,mesc,mesc,
481 (' '+mesc).join(self.lsmagic()),
482 Magic.auto_status[self.shell.rc.automagic] ) )
483
484 page(outmsg,screen_lines=self.shell.rc.screen_length)
485
486 def magic_automagic(self, parameter_s = ''):
487 """Make magic functions callable without having to type the initial %.
488
489 Toggles on/off (when off, you must call it as %automagic, of
490 course). Note that magic functions have lowest priority, so if there's
491 a variable whose name collides with that of a magic fn, automagic
492 won't work for that function (you get the variable instead). However,
493 if you delete the variable (del var), the previously shadowed magic
494 function becomes visible to automagic again."""
495
496 rc = self.shell.rc
497 rc.automagic = not rc.automagic
498 print '\n' + Magic.auto_status[rc.automagic]
499
500 def magic_autocall(self, parameter_s = ''):
501 """Make functions callable without having to type parentheses.
502
503 This toggles the autocall command line option on and off."""
504
505 rc = self.shell.rc
506 rc.autocall = not rc.autocall
507 print "Automatic calling is:",['OFF','ON'][rc.autocall]
508
509 def magic_autoindent(self, parameter_s = ''):
510 """Toggle autoindent on/off (if available)."""
511
512 self.shell.set_autoindent()
513 print "Automatic indentation is:",['OFF','ON'][self.shell.autoindent]
514
515 def magic_system_verbose(self, parameter_s = ''):
516 """Toggle verbose printing of system calls on/off."""
517
518 self.shell.rc_set_toggle('system_verbose')
519 print "System verbose printing is:",\
520 ['OFF','ON'][self.shell.rc.system_verbose]
521
522 def magic_history(self, parameter_s = ''):
523 """Print input history (_i<n> variables), with most recent last.
524
525 %history [-n] -> print at most 40 inputs (some may be multi-line)\\
526 %history [-n] n -> print at most n inputs\\
527 %history [-n] n1 n2 -> print inputs between n1 and n2 (n2 not included)\\
528
529 Each input's number <n> is shown, and is accessible as the
530 automatically generated variable _i<n>. Multi-line statements are
531 printed starting at a new line for easy copy/paste.
532
533 If option -n is used, input numbers are not printed. This is useful if
534 you want to get a printout of many lines which can be directly pasted
535 into a text editor.
536
537 This feature is only available if numbered prompts are in use."""
538
539 if not self.do_full_cache:
540 print 'This feature is only available if numbered prompts are in use.'
541 return
542 opts,args = self.parse_options(parameter_s,'n',mode='list')
543
544 default_length = 40
545 if len(args) == 0:
546 final = self.outputcache.prompt_count
547 init = max(1,final-default_length)
548 elif len(args) == 1:
549 final = self.outputcache.prompt_count
550 init = max(1,final-int(args[0]))
551 elif len(args) == 2:
552 init,final = map(int,args)
553 else:
554 warn('%hist takes 0, 1 or 2 arguments separated by spaces.')
555 print self.magic_hist.__doc__
556 return
557 width = len(str(final))
558 line_sep = ['','\n']
559 input_hist = self.shell.input_hist
560 print_nums = not opts.has_key('n')
561 for in_num in range(init,final):
562 inline = input_hist[in_num]
563 multiline = inline.count('\n') > 1
564 if print_nums:
565 print str(in_num).ljust(width)+':'+ line_sep[multiline],
566 if inline.startswith('#'+self.shell.ESC_MAGIC) or \
567 inline.startswith('#!'):
568 print inline[1:],
569 else:
570 print inline,
571
572 def magic_hist(self, parameter_s=''):
573 """Alternate name for %history."""
574 return self.magic_history(parameter_s)
575
576 def magic_p(self, parameter_s=''):
577 """Just a short alias for Python's 'print'."""
578 exec 'print ' + parameter_s in self.shell.user_ns
579
580 def magic_r(self, parameter_s=''):
581 """Repeat previous input.
582
583 If given an argument, repeats the previous command which starts with
584 the same string, otherwise it just repeats the previous input.
585
586 Shell escaped commands (with ! as first character) are not recognized
587 by this system, only pure python code and magic commands.
588 """
589
590 start = parameter_s.strip()
591 esc_magic = self.shell.ESC_MAGIC
592 # Identify magic commands even if automagic is on (which means
593 # the in-memory version is different from that typed by the user).
594 if self.shell.rc.automagic:
595 start_magic = esc_magic+start
596 else:
597 start_magic = start
598 # Look through the input history in reverse
599 for n in range(len(self.shell.input_hist)-2,0,-1):
600 input = self.shell.input_hist[n]
601 # skip plain 'r' lines so we don't recurse to infinity
602 if input != 'ipmagic("r")\n' and \
603 (input.startswith(start) or input.startswith(start_magic)):
604 #print 'match',`input` # dbg
605 if input.startswith(esc_magic):
606 input = magic2python(input)
607 #print 'modified',`input` # dbg
608 print 'Executing:',input,
609 exec input in self.shell.user_ns
610 return
611 print 'No previous input matching `%s` found.' % start
612
613 def magic_page(self, parameter_s=''):
614 """Pretty print the object and display it through a pager.
615
616 If no parameter is given, use _ (last output)."""
617 # After a function contributed by Olivier Aubert, slightly modified.
618
619 oname = parameter_s and parameter_s or '_'
620 info = self._ofind(oname)
621 if info['found']:
622 page(pformat(info['obj']))
623 else:
624 print 'Object `%s` not found' % oname
625
626 def magic_profile(self, parameter_s=''):
627 """Print your currently active IPyhton profile."""
628 if self.shell.rc.profile:
629 printpl('Current IPython profile: $self.shell.rc.profile.')
630 else:
631 print 'No profile active.'
632
633 def _inspect(self,meth,oname,**kw):
634 """Generic interface to the inspector system.
635
636 This function is meant to be called by pdef, pdoc & friends."""
637
638 oname = oname.strip()
639 info = Struct(self._ofind(oname))
640 if info.found:
641 pmethod = getattr(self.shell.inspector,meth)
642 formatter = info.ismagic and self.format_screen or None
643 if meth == 'pdoc':
644 pmethod(info.obj,oname,formatter)
645 elif meth == 'pinfo':
646 pmethod(info.obj,oname,formatter,info,**kw)
647 else:
648 pmethod(info.obj,oname)
649 else:
650 print 'Object `%s` not found.' % oname
651 return 'not found' # so callers can take other action
652
653 def magic_pdef(self, parameter_s=''):
654 """Print the definition header for any callable object.
655
656 If the object is a class, print the constructor information."""
657 self._inspect('pdef',parameter_s)
658
659 def magic_pdoc(self, parameter_s=''):
660 """Print the docstring for an object.
661
662 If the given object is a class, it will print both the class and the
663 constructor docstrings."""
664 self._inspect('pdoc',parameter_s)
665
666 def magic_psource(self, parameter_s=''):
667 """Print (or run through pager) the source code for an object."""
668 self._inspect('psource',parameter_s)
669
670 def magic_pfile(self, parameter_s=''):
671 """Print (or run through pager) the file where an object is defined.
672
673 The file opens at the line where the object definition begins. IPython
674 will honor the environment variable PAGER if set, and otherwise will
675 do its best to print the file in a convenient form.
676
677 If the given argument is not an object currently defined, IPython will
678 try to interpret it as a filename (automatically adding a .py extension
679 if needed). You can thus use %pfile as a syntax highlighting code
680 viewer."""
681
682 # first interpret argument as an object name
683 out = self._inspect('pfile',parameter_s)
684 # if not, try the input as a filename
685 if out == 'not found':
686 try:
687 filename = get_py_filename(parameter_s)
688 except IOError,msg:
689 print msg
690 return
691 page(self.shell.inspector.format(file(filename).read()))
692
693 def magic_pinfo(self, parameter_s=''):
694 """Provide detailed information about an object.
695
696 '%pinfo object' is just a synonym for object? or ?object."""
697
698 #print 'pinfo par: <%s>' % parameter_s # dbg
699
700 # detail_level: 0 -> obj? , 1 -> obj??
701 detail_level = 0
702 # We need to detect if we got called as 'pinfo pinfo foo', which can
703 # happen if the user types 'pinfo foo?' at the cmd line.
704 pinfo,qmark1,oname,qmark2 = \
705 re.match('(pinfo )?(\?*)(.*?)(\??$)',parameter_s).groups()
706 if pinfo or qmark1 or qmark2:
707 detail_level = 1
708 self._inspect('pinfo',oname,detail_level=detail_level)
709
710 def magic_who_ls(self, parameter_s=''):
711 """Return a sorted list of all interactive variables.
712
713 If arguments are given, only variables of types matching these
714 arguments are returned."""
715
716 user_ns = self.shell.user_ns
717 out = []
718 typelist = parameter_s.split()
719 for i in self.shell.user_ns.keys():
720 if not (i.startswith('_') or i.startswith('_i')) \
721 and not (self.internal_ns.has_key(i) or
722 self.user_config_ns.has_key(i)):
723 if typelist:
724 if type(user_ns[i]).__name__ in typelist:
725 out.append(i)
726 else:
727 out.append(i)
728 out.sort()
729 return out
730
731 def magic_who(self, parameter_s=''):
732 """Print all interactive variables, with some minimal formatting.
733
734 If any arguments are given, only variables whose type matches one of
735 these are printed. For example:
736
737 %who function str
738
739 will only list functions and strings, excluding all other types of
740 variables. To find the proper type names, simply use type(var) at a
741 command line to see how python prints type names. For example:
742
743 In [1]: type('hello')\\
744 Out[1]: <type 'str'>
745
746 indicates that the type name for strings is 'str'.
747
748 %who always excludes executed names loaded through your configuration
749 file and things which are internal to IPython.
750
751 This is deliberate, as typically you may load many modules and the
752 purpose of %who is to show you only what you've manually defined."""
753
754 varlist = self.magic_who_ls(parameter_s)
755 if not varlist:
756 print 'Interactive namespace is empty.'
757 return
758
759 # if we have variables, move on...
760
761 # stupid flushing problem: when prompts have no separators, stdout is
762 # getting lost. I'm starting to think this is a python bug. I'm having
763 # to force a flush with a print because even a sys.stdout.flush
764 # doesn't seem to do anything!
765
766 count = 0
767 for i in varlist:
768 print i+'\t',
769 count += 1
770 if count > 8:
771 count = 0
772 print
773 sys.stdout.flush() # FIXME. Why the hell isn't this flushing???
774
775 print # well, this does force a flush at the expense of an extra \n
776
777 def magic_whos(self, parameter_s=''):
778 """Like %who, but gives some extra information about each variable.
779
780 The same type filtering of %who can be applied here.
781
782 For all variables, the type is printed. Additionally it prints:
783
784 - For {},[],(): their length.
785
786 - For Numeric arrays, a summary with shape, number of elements,
787 typecode and size in memory.
788
789 - Everything else: a string representation, snipping their middle if
790 too long."""
791
792 varnames = self.magic_who_ls(parameter_s)
793 if not varnames:
794 print 'Interactive namespace is empty.'
795 return
796
797 # if we have variables, move on...
798
799 # for these types, show len() instead of data:
800 seq_types = [types.DictType,types.ListType,types.TupleType]
801
802 # for Numeric arrays, display summary info
803 try:
804 import Numeric
805 except ImportError:
806 array_type = None
807 else:
808 array_type = Numeric.ArrayType.__name__
809
810 # Find all variable names and types so we can figure out column sizes
811 get_vars = lambda i: self.locals[i]
812 type_name = lambda v: type(v).__name__
813 varlist = map(get_vars,varnames)
814 typelist = map(type_name,varlist)
815 # column labels and # of spaces as separator
816 varlabel = 'Variable'
817 typelabel = 'Type'
818 datalabel = 'Data/Info'
819 colsep = 3
820 # variable format strings
821 vformat = "$vname.ljust(varwidth)$vtype.ljust(typewidth)"
822 vfmt_short = '$vstr[:25]<...>$vstr[-25:]'
823 aformat = "%s: %s elems, type `%s`, %s bytes"
824 # find the size of the columns to format the output nicely
825 varwidth = max(max(map(len,varnames)), len(varlabel)) + colsep
826 typewidth = max(max(map(len,typelist)), len(typelabel)) + colsep
827 # table header
828 print varlabel.ljust(varwidth) + typelabel.ljust(typewidth) + \
829 ' '+datalabel+'\n' + '-'*(varwidth+typewidth+len(datalabel)+1)
830 # and the table itself
831 kb = 1024
832 Mb = 1048576 # kb**2
833 for vname,var,vtype in zip(varnames,varlist,typelist):
834 print itpl(vformat),
835 if vtype in seq_types:
836 print len(var)
837 elif vtype==array_type:
838 vshape = str(var.shape).replace(',','').replace(' ','x')[1:-1]
839 vsize = Numeric.size(var)
840 vbytes = vsize*var.itemsize()
841 if vbytes < 100000:
842 print aformat % (vshape,vsize,var.typecode(),vbytes)
843 else:
844 print aformat % (vshape,vsize,var.typecode(),vbytes),
845 if vbytes < Mb:
846 print '(%s kb)' % (vbytes/kb,)
847 else:
848 print '(%s Mb)' % (vbytes/Mb,)
849 else:
850 vstr = str(var)
851 if len(vstr) < 50:
852 print vstr
853 else:
854 printpl(vfmt_short)
855
856 def magic_reset(self, parameter_s=''):
857 """Resets the namespace by removing all names defined by the user.
858
859 Input/Output history are left around in case you need them."""
860
861 ans = raw_input(
862 "Once deleted, variables cannot be recovered. Proceed (y/n)? ")
863 if not ans.lower() == 'y':
864 print 'Nothing done.'
865 return
866 for i in self.magic_who_ls():
867 del(self.locals[i])
868
869 def magic_config(self,parameter_s=''):
870 """Show IPython's internal configuration."""
871
872 page('Current configuration structure:\n'+
873 pformat(self.shell.rc.dict()))
874
875 def magic_logstart(self,parameter_s=''):
876 """Start logging anywhere in a session.
877
878 %logstart [log_name [log_mode]]
879
880 If no name is given, it defaults to a file named 'ipython.log' in your
881 current directory, in 'rotate' mode (see below).
882
883 '%logstart name' saves to file 'name' in 'backup' mode. It saves your
884 history up to that point and then continues logging.
885
886 %logstart takes a second optional parameter: logging mode. This can be one
887 of (note that the modes are given unquoted):\\
888 over: overwrite existing log.\\
889 backup: rename (if exists) to name~ and start name.\\
890 append: well, that says it.\\
891 rotate: create rotating logs name.1~, name.2~, etc.
892 """
893
894 #FIXME. This function should all be moved to the Logger class.
895
896 valid_modes = qw('over backup append rotate')
897 if self.LOG:
898 print 'Logging is already in place. Logfile:',self.LOG
899 return
900
901 par = parameter_s.strip()
902 if not par:
903 logname = self.LOGDEF
904 logmode = 'rotate' # use rotate for the auto-generated logs
905 else:
906 try:
907 logname,logmode = par.split()
908 except:
909 try:
910 logname = par
911 logmode = 'backup'
912 except:
913 warn('Usage: %log [log_name [log_mode]]')
914 return
915 if not logmode in valid_modes:
916 warn('Logging NOT activated.\n'
917 'Usage: %log [log_name [log_mode]]\n'
918 'Valid modes: '+str(valid_modes))
919 return
920
921 # If we made it this far, I think we're ok:
922 print 'Activating auto-logging.'
923 print 'Current session state plus future input saved to:',logname
924 print 'Logging mode: ',logmode
925 # put logname into rc struct as if it had been called on the command line,
926 # so it ends up saved in the log header
927 # Save it in case we need to restore it...
928 old_logfile = self.shell.rc.opts.get('logfile','')
929 logname = os.path.expanduser(logname)
930 self.shell.rc.opts.logfile = logname
931 self.LOGMODE = logmode # FIXME: this should be set through a function.
932 try:
933 header = str(self.LOGHEAD)
934 self.create_log(header,logname)
935 self.logstart(header,logname)
936 except:
937 self.LOG = '' # we are NOT logging, something went wrong
938 self.shell.rc.opts.logfile = old_logfile
939 warn("Couldn't start log: "+str(sys.exc_info()[1]))
940 else: # log input history up to this point
941 self.logfile.write(self.shell.user_ns['_ih'][1:])
942 self.logfile.flush()
943
944 def magic_logoff(self,parameter_s=''):
945 """Temporarily stop logging.
946
947 You must have previously started logging."""
948 self.switch_log(0)
949
950 def magic_logon(self,parameter_s=''):
951 """Restart logging.
952
953 This function is for restarting logging which you've temporarily
954 stopped with %logoff. For starting logging for the first time, you
955 must use the %logstart function, which allows you to specify an
956 optional log filename."""
957
958 self.switch_log(1)
959
960 def magic_logstate(self,parameter_s=''):
961 """Print the status of the logging system."""
962
963 self.logstate()
964
965 def magic_pdb(self, parameter_s=''):
966 """Control the calling of the pdb interactive debugger.
967
968 Call as '%pdb on', '%pdb 1', '%pdb off' or '%pdb 0'. If called without
969 argument it works as a toggle.
970
971 When an exception is triggered, IPython can optionally call the
972 interactive pdb debugger after the traceback printout. %pdb toggles
973 this feature on and off."""
974
975 par = parameter_s.strip().lower()
976
977 if par:
978 try:
979 pdb = {'off':0,'0':0,'on':1,'1':1}[par]
980 except KeyError:
981 print 'Incorrect argument. Use on/1, off/0 or nothing for a toggle.'
982 return
983 else:
984 self.shell.InteractiveTB.call_pdb = pdb
985 else:
986 self.shell.InteractiveTB.call_pdb = 1 - self.shell.InteractiveTB.call_pdb
987 print 'Automatic pdb calling has been turned',\
988 on_off(self.shell.InteractiveTB.call_pdb)
989
990
991 def magic_prun(self, parameter_s ='',user_mode=1,
992 opts=None,arg_lst=None,prog_ns=None):
993
994 """Run a statement through the python code profiler.
995
996 Usage:\\
997 %prun [options] statement
998
999 The given statement (which doesn't require quote marks) is run via the
1000 python profiler in a manner similar to the profile.run() function.
1001 Namespaces are internally managed to work correctly; profile.run
1002 cannot be used in IPython because it makes certain assumptions about
1003 namespaces which do not hold under IPython.
1004
1005 Options:
1006
1007 -l <limit>: you can place restrictions on what or how much of the
1008 profile gets printed. The limit value can be:
1009
1010 * A string: only information for function names containing this string
1011 is printed.
1012
1013 * An integer: only these many lines are printed.
1014
1015 * A float (between 0 and 1): this fraction of the report is printed
1016 (for example, use a limit of 0.4 to see the topmost 40% only).
1017
1018 You can combine several limits with repeated use of the option. For
1019 example, '-l __init__ -l 5' will print only the topmost 5 lines of
1020 information about class constructors.
1021
1022 -r: return the pstats.Stats object generated by the profiling. This
1023 object has all the information about the profile in it, and you can
1024 later use it for further analysis or in other functions.
1025
1026 Since magic functions have a particular form of calling which prevents
1027 you from writing something like:\\
1028 In [1]: p = %prun -r print 4 # invalid!\\
1029 you must instead use IPython's automatic variables to assign this:\\
1030 In [1]: %prun -r print 4 \\
1031 Out[1]: <pstats.Stats instance at 0x8222cec>\\
1032 In [2]: stats = _
1033
1034 If you really need to assign this value via an explicit function call,
1035 you can always tap directly into the true name of the magic function
1036 by using the ipmagic function (which IPython automatically adds to the
1037 builtins):\\
1038 In [3]: stats = ipmagic('prun','-r print 4')
1039
1040 You can type ipmagic? for more details on ipmagic.
1041
1042 -s <key>: sort profile by given key. You can provide more than one key
1043 by using the option several times: '-s key1 -s key2 -s key3...'. The
1044 default sorting key is 'time'.
1045
1046 The following is copied verbatim from the profile documentation
1047 referenced below:
1048
1049 When more than one key is provided, additional keys are used as
1050 secondary criteria when the there is equality in all keys selected
1051 before them.
1052
1053 Abbreviations can be used for any key names, as long as the
1054 abbreviation is unambiguous. The following are the keys currently
1055 defined:
1056
1057 Valid Arg Meaning\\
1058 "calls" call count\\
1059 "cumulative" cumulative time\\
1060 "file" file name\\
1061 "module" file name\\
1062 "pcalls" primitive call count\\
1063 "line" line number\\
1064 "name" function name\\
1065 "nfl" name/file/line\\
1066 "stdname" standard name\\
1067 "time" internal time
1068
1069 Note that all sorts on statistics are in descending order (placing
1070 most time consuming items first), where as name, file, and line number
1071 searches are in ascending order (i.e., alphabetical). The subtle
1072 distinction between "nfl" and "stdname" is that the standard name is a
1073 sort of the name as printed, which means that the embedded line
1074 numbers get compared in an odd way. For example, lines 3, 20, and 40
1075 would (if the file names were the same) appear in the string order
1076 "20" "3" and "40". In contrast, "nfl" does a numeric compare of the
1077 line numbers. In fact, sort_stats("nfl") is the same as
1078 sort_stats("name", "file", "line").
1079
1080 -T <filename>: save profile results as shown on screen to a text
1081 file. The profile is still shown on screen.
1082
1083 -D <filename>: save (via dump_stats) profile statistics to given
1084 filename. This data is in a format understod by the pstats module, and
1085 is generated by a call to the dump_stats() method of profile
1086 objects. The profile is still shown on screen.
1087
1088 If you want to run complete programs under the profiler's control, use
1089 '%run -p [prof_opts] filename.py [args to program]' where prof_opts
1090 contains profiler specific options as described here.
1091
1092 You can read the complete documentation for the profile module with:\\
1093 In [1]: import profile; profile.help() """
1094
1095 opts_def = Struct(D=[''],l=[],s=['time'],T=[''])
1096 # protect user quote marks
1097 parameter_s = parameter_s.replace('"',r'\"').replace("'",r"\'")
1098
1099 if user_mode: # regular user call
1100 opts,arg_str = self.parse_options(parameter_s,'D:l:rs:T:',
1101 list_all=1)
1102 namespace = self.shell.user_ns
1103 else: # called to run a program by %run -p
1104 try:
1105 filename = get_py_filename(arg_lst[0])
1106 except IOError,msg:
1107 error(msg)
1108 return
1109
1110 arg_str = 'execfile(filename,prog_ns)'
1111 namespace = locals()
1112
1113 opts.merge(opts_def)
1114
1115 prof = profile.Profile()
1116 try:
1117 prof = prof.runctx(arg_str,namespace,namespace)
1118 sys_exit = ''
1119 except SystemExit:
1120 sys_exit = """*** SystemExit exception caught in code being profiled."""
1121
1122 stats = pstats.Stats(prof).strip_dirs().sort_stats(*opts.s)
1123
1124 lims = opts.l
1125 if lims:
1126 lims = [] # rebuild lims with ints/floats/strings
1127 for lim in opts.l:
1128 try:
1129 lims.append(int(lim))
1130 except ValueError:
1131 try:
1132 lims.append(float(lim))
1133 except ValueError:
1134 lims.append(lim)
1135
1136 # trap output
1137 sys_stdout = sys.stdout
1138 stdout_trap = StringIO()
1139 try:
1140 sys.stdout = stdout_trap
1141 stats.print_stats(*lims)
1142 finally:
1143 sys.stdout = sys_stdout
1144 output = stdout_trap.getvalue()
1145 output = output.rstrip()
1146
1147 page(output,screen_lines=self.shell.rc.screen_length)
1148 print sys_exit,
1149
1150 dump_file = opts.D[0]
1151 text_file = opts.T[0]
1152 if dump_file:
1153 prof.dump_stats(dump_file)
1154 print '\n*** Profile stats marshalled to file',\
1155 `dump_file`+'.',sys_exit
1156 if text_file:
1157 file(text_file,'w').write(output)
1158 print '\n*** Profile printout saved to text file',\
1159 `text_file`+'.',sys_exit
1160
1161 if opts.has_key('r'):
1162 return stats
1163 else:
1164 return None
1165
1166 def magic_run(self, parameter_s ='',runner=None):
1167 """Run the named file inside IPython as a program.
1168
1169 Usage:\\
1170 %run [-n -i -t [-N<N>] -d [-b<N>] -p [profile options]] file [args]
1171
1172 Parameters after the filename are passed as command-line arguments to
1173 the program (put in sys.argv). Then, control returns to IPython's
1174 prompt.
1175
1176 This is similar to running at a system prompt:\\
1177 $ python file args\\
1178 but with the advantage of giving you IPython's tracebacks, and of
1179 loading all variables into your interactive namespace for further use
1180 (unless -p is used, see below).
1181
1182 The file is executed in a namespace initially consisting only of
1183 __name__=='__main__' and sys.argv constructed as indicated. It thus
1184 sees its environment as if it were being run as a stand-alone
1185 program. But after execution, the IPython interactive namespace gets
1186 updated with all variables defined in the program (except for __name__
1187 and sys.argv). This allows for very convenient loading of code for
1188 interactive work, while giving each program a 'clean sheet' to run in.
1189
1190 Options:
1191
1192 -n: __name__ is NOT set to '__main__', but to the running file's name
1193 without extension (as python does under import). This allows running
1194 scripts and reloading the definitions in them without calling code
1195 protected by an ' if __name__ == "__main__" ' clause.
1196
1197 -i: run the file in IPython's namespace instead of an empty one. This
1198 is useful if you are experimenting with code written in a text editor
1199 which depends on variables defined interactively.
1200
1201 -e: ignore sys.exit() calls or SystemExit exceptions in the script
1202 being run. This is particularly useful if IPython is being used to
1203 run unittests, which always exit with a sys.exit() call. In such
1204 cases you are interested in the output of the test results, not in
1205 seeing a traceback of the unittest module.
1206
1207 -t: print timing information at the end of the run. IPython will give
1208 you an estimated CPU time consumption for your script, which under
1209 Unix uses the resource module to avoid the wraparound problems of
1210 time.clock(). Under Unix, an estimate of time spent on system tasks
1211 is also given (for Windows platforms this is reported as 0.0).
1212
1213 If -t is given, an additional -N<N> option can be given, where <N>
1214 must be an integer indicating how many times you want the script to
1215 run. The final timing report will include total and per run results.
1216
1217 For example (testing the script uniq_stable.py):
1218
1219 In [1]: run -t uniq_stable
1220
1221 IPython CPU timings (estimated):\\
1222 User : 0.19597 s.\\
1223 System: 0.0 s.\\
1224
1225 In [2]: run -t -N5 uniq_stable
1226
1227 IPython CPU timings (estimated):\\
1228 Total runs performed: 5\\
1229 Times : Total Per run\\
1230 User : 0.910862 s, 0.1821724 s.\\
1231 System: 0.0 s, 0.0 s.
1232
1233 -d: run your program under the control of pdb, the Python debugger.
1234 This allows you to execute your program step by step, watch variables,
1235 etc. Internally, what IPython does is similar to calling:
1236
1237 pdb.run('execfile("YOURFILENAME")')
1238
1239 with a breakpoint set on line 1 of your file. You can change the line
1240 number for this automatic breakpoint to be <N> by using the -bN option
1241 (where N must be an integer). For example:
1242
1243 %run -d -b40 myscript
1244
1245 will set the first breakpoint at line 40 in myscript.py. Note that
1246 the first breakpoint must be set on a line which actually does
1247 something (not a comment or docstring) for it to stop execution.
1248
1249 When the pdb debugger starts, you will see a (Pdb) prompt. You must
1250 first enter 'c' (without qoutes) to start execution up to the first
1251 breakpoint.
1252
1253 Entering 'help' gives information about the use of the debugger. You
1254 can easily see pdb's full documentation with "import pdb;pdb.help()"
1255 at a prompt.
1256
1257 -p: run program under the control of the Python profiler module (which
1258 prints a detailed report of execution times, function calls, etc).
1259
1260 You can pass other options after -p which affect the behavior of the
1261 profiler itself. See the docs for %prun for details.
1262
1263 In this mode, the program's variables do NOT propagate back to the
1264 IPython interactive namespace (because they remain in the namespace
1265 where the profiler executes them).
1266
1267 Internally this triggers a call to %prun, see its documentation for
1268 details on the options available specifically for profiling."""
1269
1270 # get arguments and set sys.argv for program to be run.
1271 opts,arg_lst = self.parse_options(parameter_s,'nidtN:b:pD:l:rs:T:e',
1272 mode='list',list_all=1)
1273
1274 try:
1275 filename = get_py_filename(arg_lst[0])
1276 except IndexError:
1277 warn('you must provide at least a filename.')
1278 print '\n%run:\n',OInspect.getdoc(self.magic_run)
1279 return
1280 except IOError,msg:
1281 error(msg)
1282 return
1283
1284 # Control the response to exit() calls made by the script being run
1285 exit_ignore = opts.has_key('e')
1286
1287 # Make sure that the running script gets a proper sys.argv as if it
1288 # were run from a system shell.
1289 save_argv = sys.argv # save it for later restoring
1290 sys.argv = [filename]+ arg_lst[1:] # put in the proper filename
1291
1292 if opts.has_key('i'):
1293 prog_ns = self.shell.user_ns
1294 __name__save = self.shell.user_ns['__name__']
1295 prog_ns['__name__'] = '__main__'
1296 else:
1297 if opts.has_key('n'):
1298 name = os.path.splitext(os.path.basename(filename))[0]
1299 else:
1300 name = '__main__'
1301 prog_ns = {'__name__':name}
1302
1303 # pickle fix. See iplib for an explanation
1304 sys.modules[prog_ns['__name__']] = FakeModule(prog_ns)
1305
1306 stats = None
1307 try:
1308 if opts.has_key('p'):
1309 stats = self.magic_prun('',0,opts,arg_lst,prog_ns)
1310 else:
1311 if opts.has_key('d'):
1312 deb = pdb.Pdb()
1313 # reset Breakpoint state, which is moronically kept
1314 # in a class
1315 bdb.Breakpoint.next = 1
1316 bdb.Breakpoint.bplist = {}
1317 bdb.Breakpoint.bpbynumber = [None]
1318 # Set an initial breakpoint to stop execution
1319 maxtries = 10
1320 bp = int(opts.get('b',[1])[0])
1321 checkline = deb.checkline(filename,bp)
1322 if not checkline:
1323 for bp in range(bp+1,bp+maxtries+1):
1324 if deb.checkline(filename,bp):
1325 break
1326 else:
1327 msg = ("\nI failed to find a valid line to set "
1328 "a breakpoint\n"
1329 "after trying up to line: %s.\n"
1330 "Please set a valid breakpoint manually "
1331 "with the -b option." % bp)
1332 error(msg)
1333 return
1334 # if we find a good linenumber, set the breakpoint
1335 deb.do_break('%s:%s' % (filename,bp))
1336 # Start file run
1337 print "NOTE: Enter 'c' at the",
1338 print "(Pdb) prompt to start your script."
1339 deb.run('execfile("%s")' % filename,prog_ns)
1340 else:
1341 if runner is None:
1342 runner = self.shell.safe_execfile
1343 if opts.has_key('t'):
1344 try:
1345 nruns = int(opts['N'][0])
1346 if nruns < 1:
1347 error('Number of runs must be >=1')
1348 return
1349 except (KeyError):
1350 nruns = 1
1351 if nruns == 1:
1352 t0 = clock2()
1353 runner(filename,prog_ns,prog_ns,exit_ignore=exit_ignore)
1354 t1 = clock2()
1355 t_usr = t1[0]-t0[0]
1356 t_sys = t1[1]-t1[1]
1357 print "\nIPython CPU timings (estimated):"
1358 print " User : %10s s." % t_usr
1359 print " System: %10s s." % t_sys
1360 else:
1361 runs = range(nruns)
1362 t0 = clock2()
1363 for nr in runs:
1364 runner(filename,prog_ns,prog_ns,exit_ignore=exit_ignore)
1365 t1 = clock2()
1366 t_usr = t1[0]-t0[0]
1367 t_sys = t1[1]-t1[1]
1368 print "\nIPython CPU timings (estimated):"
1369 print "Total runs performed:",nruns
1370 print " Times : %10s %10s" % ('Total','Per run')
1371 print " User : %10s s, %10s s." % (t_usr,t_usr/nruns)
1372 print " System: %10s s, %10s s." % (t_sys,t_sys/nruns)
1373
1374 else:
1375 runner(filename,prog_ns,prog_ns,exit_ignore=exit_ignore)
1376 if opts.has_key('i'):
1377 self.shell.user_ns['__name__'] = __name__save
1378 else:
1379 # update IPython interactive namespace
1380 del prog_ns['__name__']
1381 self.shell.user_ns.update(prog_ns)
1382 finally:
1383 sys.argv = save_argv
1384 return stats
1385
1386 def magic_runlog(self, parameter_s =''):
1387 """Run files as logs.
1388
1389 Usage:\\
1390 %runlog file1 file2 ...
1391
1392 Run the named files (treating them as log files) in sequence inside
1393 the interpreter, and return to the prompt. This is much slower than
1394 %run because each line is executed in a try/except block, but it
1395 allows running files with syntax errors in them.
1396
1397 Normally IPython will guess when a file is one of its own logfiles, so
1398 you can typically use %run even for logs. This shorthand allows you to
1399 force any file to be treated as a log file."""
1400
1401 for f in parameter_s.split():
1402 self.shell.safe_execfile(f,self.shell.user_ns,
1403 self.shell.user_ns,islog=1)
1404
1405 def magic_time(self,parameter_s = ''):
1406 """Time execution of a Python statement or expression.
1407
1408 The CPU and wall clock times are printed, and the value of the
1409 expression (if any) is returned. Note that under Win32, system time
1410 is always reported as 0, since it can not be measured.
1411
1412 This function provides very basic timing functionality. In Python
1413 2.3, the timeit module offers more control and sophistication, but for
1414 now IPython supports Python 2.2, so we can not rely on timeit being
1415 present.
1416
1417 Some examples:
1418
1419 In [1]: time 2**128
1420 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1421 Wall time: 0.00
1422 Out[1]: 340282366920938463463374607431768211456L
1423
1424 In [2]: n = 1000000
1425
1426 In [3]: time sum(range(n))
1427 CPU times: user 1.20 s, sys: 0.05 s, total: 1.25 s
1428 Wall time: 1.37
1429 Out[3]: 499999500000L
1430
1431 In [4]: time print 'hello world'
1432 hello world
1433 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1434 Wall time: 0.00
1435 """
1436
1437 # fail immediately if the given expression can't be compiled
1438 try:
1439 mode = 'eval'
1440 code = compile(parameter_s,'<timed eval>',mode)
1441 except SyntaxError:
1442 mode = 'exec'
1443 code = compile(parameter_s,'<timed exec>',mode)
1444 # skew measurement as little as possible
1445 glob = self.shell.user_ns
1446 clk = clock2
1447 wtime = time.time
1448 # time execution
1449 wall_st = wtime()
1450 if mode=='eval':
1451 st = clk()
1452 out = eval(code,glob)
1453 end = clk()
1454 else:
1455 st = clk()
1456 exec code in glob
1457 end = clk()
1458 out = None
1459 wall_end = wtime()
1460 # Compute actual times and report
1461 wall_time = wall_end-wall_st
1462 cpu_user = end[0]-st[0]
1463 cpu_sys = end[1]-st[1]
1464 cpu_tot = cpu_user+cpu_sys
1465 print "CPU times: user %.2f s, sys: %.2f s, total: %.2f s" % \
1466 (cpu_user,cpu_sys,cpu_tot)
1467 print "Wall time: %.2f" % wall_time
1468 return out
1469
1470 def magic_macro(self,parameter_s = ''):
1471 """Define a set of input lines as a macro for future re-execution.
1472
1473 Usage:\\
1474 %macro name n1:n2 n3:n4 ... n5 .. n6 ...
1475
1476 This will define a global variable called `name` which is a string
1477 made of joining the slices and lines you specify (n1,n2,... numbers
1478 above) from your input history into a single string. This variable
1479 acts like an automatic function which re-executes those lines as if
1480 you had typed them. You just type 'name' at the prompt and the code
1481 executes.
1482
1483 Note that the slices use the standard Python slicing notation (5:8
1484 means include lines numbered 5,6,7).
1485
1486 For example, if your history contains (%hist prints it):
1487
1488 44: x=1\\
1489 45: y=3\\
1490 46: z=x+y\\
1491 47: print x\\
1492 48: a=5\\
1493 49: print 'x',x,'y',y\\
1494
1495 you can create a macro with lines 44 through 47 (included) and line 49
1496 called my_macro with:
1497
1498 In [51]: %macro my_macro 44:48 49
1499
1500 Now, typing `my_macro` (without quotes) will re-execute all this code
1501 in one pass.
1502
1503 You don't need to give the line-numbers in order, and any given line
1504 number can appear multiple times. You can assemble macros with any
1505 lines from your input history in any order.
1506
1507 The macro is a simple object which holds its value in an attribute,
1508 but IPython's display system checks for macros and executes them as
1509 code instead of printing them when you type their name.
1510
1511 You can view a macro's contents by explicitly printing it with:
1512
1513 'print macro_name'.
1514
1515 For one-off cases which DON'T contain magic function calls in them you
1516 can obtain similar results by explicitly executing slices from your
1517 input history with:
1518
1519 In [60]: exec In[44:48]+In[49]"""
1520
1521 args = parameter_s.split()
1522 name,ranges = args[0], args[1:]
1523 #print 'rng',ranges # dbg
1524 cmds = self.extract_input_slices(ranges)
1525 macro = Macro(cmds)
1526 self.shell.user_ns.update({name:macro})
1527 print 'Macro `%s` created. To execute, type its name (without quotes).' % name
1528 print 'Macro contents:'
1529 print str(macro).rstrip(),
1530
1531 def magic_save(self,parameter_s = ''):
1532 """Save a set of lines to a given filename.
1533
1534 Usage:\\
1535 %save filename n1:n2 n3:n4 ... n5 .. n6 ...
1536
1537 This function uses the same syntax as %macro for line extraction, but
1538 instead of creating a macro it saves the resulting string to the
1539 filename you specify.
1540
1541 It adds a '.py' extension to the file if you don't do so yourself, and
1542 it asks for confirmation before overwriting existing files."""
1543
1544 args = parameter_s.split()
1545 fname,ranges = args[0], args[1:]
1546 if not fname.endswith('.py'):
1547 fname += '.py'
1548 if os.path.isfile(fname):
1549 ans = raw_input('File `%s` exists. Overwrite (y/[N])? ' % fname)
1550 if ans.lower() not in ['y','yes']:
1551 print 'Operation cancelled.'
1552 return
1553 cmds = ''.join(self.extract_input_slices(ranges))
1554 f = file(fname,'w')
1555 f.write(cmds)
1556 f.close()
1557 print 'The following commands were written to file `%s`:' % fname
1558 print cmds
1559
1560 def magic_ed(self,parameter_s = ''):
1561 """Alias to %edit."""
1562 return self.magic_edit(parameter_s)
1563
1564 def magic_edit(self,parameter_s = '',last_call=['','']):
1565 """Bring up an editor and execute the resulting code.
1566
1567 Usage:
1568 %edit [options] [args]
1569
1570 %edit runs IPython's editor hook. The default version of this hook is
1571 set to call the __IPYTHON__.rc.editor command. This is read from your
1572 environment variable $EDITOR. If this isn't found, it will default to
1573 vi under Linux/Unix and to notepad under Windows. See the end of this
1574 docstring for how to change the editor hook.
1575
1576 You can also set the value of this editor via the command line option
1577 '-editor' or in your ipythonrc file. This is useful if you wish to use
1578 specifically for IPython an editor different from your typical default
1579 (and for Windows users who typically don't set environment variables).
1580
1581 This command allows you to conveniently edit multi-line code right in
1582 your IPython session.
1583
1584 If called without arguments, %edit opens up an empty editor with a
1585 temporary file and will execute the contents of this file when you
1586 close it (don't forget to save it!).
1587
1588 Options:
1589
1590 -p: this will call the editor with the same data as the previous time
1591 it was used, regardless of how long ago (in your current session) it
1592 was.
1593
1594 -x: do not execute the edited code immediately upon exit. This is
1595 mainly useful if you are editing programs which need to be called with
1596 command line arguments, which you can then do using %run.
1597
1598 Arguments:
1599
1600 If arguments are given, the following possibilites exist:
1601
1602 - The arguments are numbers or pairs of colon-separated numbers (like
1603 1 4:8 9). These are interpreted as lines of previous input to be
1604 loaded into the editor. The syntax is the same of the %macro command.
1605
1606 - If the argument doesn't start with a number, it is evaluated as a
1607 variable and its contents loaded into the editor. You can thus edit
1608 any string which contains python code (including the result of
1609 previous edits).
1610
1611 - If the argument is the name of an object (other than a string),
1612 IPython will try to locate the file where it was defined and open the
1613 editor at the point where it is defined. You can use `%edit function`
1614 to load an editor exactly at the point where 'function' is defined,
1615 edit it and have the file be executed automatically.
1616
1617 Note: opening at an exact line is only supported under Unix, and some
1618 editors (like kedit and gedit up to Gnome 2.8) do not understand the
1619 '+NUMBER' parameter necessary for this feature. Good editors like
1620 (X)Emacs, vi, jed, pico and joe all do.
1621
1622 - If the argument is not found as a variable, IPython will look for a
1623 file with that name (adding .py if necessary) and load it into the
1624 editor. It will execute its contents with execfile() when you exit,
1625 loading any code in the file into your interactive namespace.
1626
1627 After executing your code, %edit will return as output the code you
1628 typed in the editor (except when it was an existing file). This way
1629 you can reload the code in further invocations of %edit as a variable,
1630 via _<NUMBER> or Out[<NUMBER>], where <NUMBER> is the prompt number of
1631 the output.
1632
1633 Note that %edit is also available through the alias %ed.
1634
1635 This is an example of creating a simple function inside the editor and
1636 then modifying it. First, start up the editor:
1637
1638 In [1]: ed\\
1639 Editing... done. Executing edited code...\\
1640 Out[1]: 'def foo():\\n print "foo() was defined in an editing session"\\n'
1641
1642 We can then call the function foo():
1643
1644 In [2]: foo()\\
1645 foo() was defined in an editing session
1646
1647 Now we edit foo. IPython automatically loads the editor with the
1648 (temporary) file where foo() was previously defined:
1649
1650 In [3]: ed foo\\
1651 Editing... done. Executing edited code...
1652
1653 And if we call foo() again we get the modified version:
1654
1655 In [4]: foo()\\
1656 foo() has now been changed!
1657
1658 Here is an example of how to edit a code snippet successive
1659 times. First we call the editor:
1660
1661 In [8]: ed\\
1662 Editing... done. Executing edited code...\\
1663 hello\\
1664 Out[8]: "print 'hello'\\n"
1665
1666 Now we call it again with the previous output (stored in _):
1667
1668 In [9]: ed _\\
1669 Editing... done. Executing edited code...\\
1670 hello world\\
1671 Out[9]: "print 'hello world'\\n"
1672
1673 Now we call it with the output #8 (stored in _8, also as Out[8]):
1674
1675 In [10]: ed _8\\
1676 Editing... done. Executing edited code...\\
1677 hello again\\
1678 Out[10]: "print 'hello again'\\n"
1679
1680
1681 Changing the default editor hook:
1682
1683 If you wish to write your own editor hook, you can put it in a
1684 configuration file which you load at startup time. The default hook
1685 is defined in the IPython.hooks module, and you can use that as a
1686 starting example for further modifications. That file also has
1687 general instructions on how to set a new hook for use once you've
1688 defined it."""
1689
1690 # FIXME: This function has become a convoluted mess. It needs a
1691 # ground-up rewrite with clean, simple logic.
1692
1693 def make_filename(arg):
1694 "Make a filename from the given args"
1695 try:
1696 filename = get_py_filename(arg)
1697 except IOError:
1698 if args.endswith('.py'):
1699 filename = arg
1700 else:
1701 filename = None
1702 return filename
1703
1704 # custom exceptions
1705 class DataIsObject(Exception): pass
1706
1707 opts,args = self.parse_options(parameter_s,'px')
1708
1709 # Default line number value
1710 lineno = None
1711 if opts.has_key('p'):
1712 args = '_%s' % last_call[0]
1713 if not self.shell.user_ns.has_key(args):
1714 args = last_call[1]
1715
1716 # use last_call to remember the state of the previous call, but don't
1717 # let it be clobbered by successive '-p' calls.
1718 try:
1719 last_call[0] = self.shell.outputcache.prompt_count
1720 if not opts.has_key('p'):
1721 last_call[1] = parameter_s
1722 except:
1723 pass
1724
1725 # by default this is done with temp files, except when the given
1726 # arg is a filename
1727 use_temp = 1
1728
1729 if re.match(r'\d',args):
1730 # Mode where user specifies ranges of lines, like in %macro.
1731 # This means that you can't edit files whose names begin with
1732 # numbers this way. Tough.
1733 ranges = args.split()
1734 data = ''.join(self.extract_input_slices(ranges))
1735 elif args.endswith('.py'):
1736 filename = make_filename(args)
1737 data = ''
1738 use_temp = 0
1739 elif args:
1740 try:
1741 # Load the parameter given as a variable. If not a string,
1742 # process it as an object instead (below)
1743
1744 #print '*** args',args,'type',type(args) # dbg
1745 data = eval(args,self.shell.user_ns)
1746 if not type(data) in StringTypes:
1747 raise DataIsObject
1748 except (NameError,SyntaxError):
1749 # given argument is not a variable, try as a filename
1750 filename = make_filename(args)
1751 if filename is None:
1752 warn("Argument given (%s) can't be found as a variable "
1753 "or as a filename." % args)
1754 return
1755 data = ''
1756 use_temp = 0
1757 except DataIsObject:
1758 # For objects, try to edit the file where they are defined
1759 try:
1760 filename = inspect.getabsfile(data)
1761 datafile = 1
1762 except TypeError:
1763 filename = make_filename(args)
1764 datafile = 1
1765 warn('Could not find file where `%s` is defined.\n'
1766 'Opening a file named `%s`' % (args,filename))
1767 # Now, make sure we can actually read the source (if it was in
1768 # a temp file it's gone by now).
1769 if datafile:
1770 try:
1771 lineno = inspect.getsourcelines(data)[1]
1772 except IOError:
1773 filename = make_filename(args)
1774 if filename is None:
1775 warn('The file `%s` where `%s` was defined cannot '
1776 'be read.' % (filename,data))
1777 return
1778 use_temp = 0
1779 else:
1780 data = ''
1781
1782 if use_temp:
1783 filename = tempfile.mktemp('.py')
1784 self.shell.tempfiles.append(filename)
1785
1786 if data and use_temp:
1787 tmp_file = open(filename,'w')
1788 tmp_file.write(data)
1789 tmp_file.close()
1790
1791 # do actual editing here
1792 print 'Editing...',
1793 sys.stdout.flush()
1794 self.shell.hooks.editor(filename,lineno)
1795 if opts.has_key('x'): # -x prevents actual execution
1796 print
1797 else:
1798 print 'done. Executing edited code...'
1799 try:
1800 execfile(filename,self.shell.user_ns)
1801 except IOError,msg:
1802 if msg.filename == filename:
1803 warn('File not found. Did you forget to save?')
1804 return
1805 else:
1806 self.shell.showtraceback()
1807 except:
1808 self.shell.showtraceback()
1809 if use_temp:
1810 contents = open(filename).read()
1811 return contents
1812
1813 def magic_xmode(self,parameter_s = ''):
1814 """Switch modes for the exception handlers.
1815
1816 Valid modes: Plain, Context and Verbose.
1817
1818 If called without arguments, acts as a toggle."""
1819
1820 new_mode = parameter_s.strip().capitalize()
1821 try:
1822 self.InteractiveTB.set_mode(mode = new_mode)
1823 print 'Exception reporting mode:',self.InteractiveTB.mode
1824 except:
1825 warn('Error changing exception modes.\n' + str(sys.exc_info()[1]))
1826
1827 def magic_colors(self,parameter_s = ''):
1828 """Switch color scheme for prompts, info system and exception handlers.
1829
1830 Currently implemented schemes: NoColor, Linux, LightBG.
1831
1832 Color scheme names are not case-sensitive."""
1833
1834 new_scheme = parameter_s.strip()
1835 if not new_scheme:
1836 print 'You must specify a color scheme.'
1837 return
1838 # Under Windows, check for Gary Bishop's readline, which is necessary
1839 # for ANSI coloring
1840 if os.name in ['nt','dos']:
1841 try:
1842 import readline
1843 except ImportError:
1844 has_readline = 0
1845 else:
1846 try:
1847 readline.GetOutputFile()
1848 except AttributeError:
1849 has_readline = 0
1850 else:
1851 has_readline = 1
1852 if not has_readline:
1853 msg = """\
1854 Proper color support under MS Windows requires Gary Bishop's readline library.
1855 You can find it at:
1856 http://sourceforge.net/projects/uncpythontools
1857 Gary's readline needs the ctypes module, from:
1858 http://starship.python.net/crew/theller/ctypes
1859
1860 Defaulting color scheme to 'NoColor'"""
1861 new_scheme = 'NoColor'
1862 warn(msg)
1863
1864 # Set prompt colors
1865 try:
1866 self.shell.outputcache.set_colors(new_scheme)
1867 except:
1868 warn('Error changing prompt color schemes.\n'
1869 + str(sys.exc_info()[1]))
1870 else:
1871 self.shell.rc.colors = \
1872 self.shell.outputcache.color_table.active_scheme_name
1873 # Set exception colors
1874 try:
1875 self.shell.InteractiveTB.set_colors(scheme = new_scheme)
1876 self.shell.SyntaxTB.set_colors(scheme = new_scheme)
1877 except:
1878 warn('Error changing exception color schemes.\n'
1879 + str(sys.exc_info()[1]))
1880 # Set info (for 'object?') colors
1881 if self.shell.rc.color_info:
1882 try:
1883 self.shell.inspector.set_active_scheme(new_scheme)
1884 except:
1885 warn('Error changing object inspector color schemes.\n'
1886 + str(sys.exc_info()[1]))
1887 else:
1888 self.shell.inspector.set_active_scheme('NoColor')
1889
1890 def magic_color_info(self,parameter_s = ''):
1891 """Toggle color_info.
1892
1893 The color_info configuration parameter controls whether colors are
1894 used for displaying object details (by things like %psource, %pfile or
1895 the '?' system). This function toggles this value with each call.
1896
1897 Note that unless you have a fairly recent pager (less works better
1898 than more) in your system, using colored object information displays
1899 will not work properly. Test it and see."""
1900
1901 self.shell.rc.color_info = 1 - self.shell.rc.color_info
1902 self.magic_colors(self.shell.rc.colors)
1903 print 'Object introspection functions have now coloring:',
1904 print ['OFF','ON'][self.shell.rc.color_info]
1905
1906 def magic_Pprint(self, parameter_s=''):
1907 """Toggle pretty printing on/off."""
1908
1909 self.shell.outputcache.Pprint = 1 - self.shell.outputcache.Pprint
1910 print 'Pretty printing has been turned', \
1911 ['OFF','ON'][self.shell.outputcache.Pprint]
1912
1913 def magic_Exit(self, parameter_s=''):
1914 """Exit IPython without confirmation."""
1915
1916 self.shell.exit_now = True
1917
1918 def magic_Quit(self, parameter_s=''):
1919 """Exit IPython without confirmation (like %Exit)."""
1920
1921 self.shell.exit_now = True
1922
1923 #......................................................................
1924 # Functions to implement unix shell-type things
1925
1926 def magic_alias(self, parameter_s = ''):
1927 """Define an alias for a system command.
1928
1929 '%alias alias_name cmd' defines 'alias_name' as an alias for 'cmd'
1930
1931 Then, typing 'alias_name params' will execute the system command 'cmd
1932 params' (from your underlying operating system).
1933
1934 Aliases have lower precedence than magic functions and Python normal
1935 variables, so if 'foo' is both a Python variable and an alias, the
1936 alias can not be executed until 'del foo' removes the Python variable.
1937
1938 You can use the %l specifier in an alias definition to represent the
1939 whole line when the alias is called. For example:
1940
1941 In [2]: alias all echo "Input in brackets: <%l>"\\
1942 In [3]: all hello world\\
1943 Input in brackets: <hello world>
1944
1945 You can also define aliases with parameters using %s specifiers (one
1946 per parameter):
1947
1948 In [1]: alias parts echo first %s second %s\\
1949 In [2]: %parts A B\\
1950 first A second B\\
1951 In [3]: %parts A\\
1952 Incorrect number of arguments: 2 expected.\\
1953 parts is an alias to: 'echo first %s second %s'
1954
1955 Note that %l and %s are mutually exclusive. You can only use one or
1956 the other in your aliases.
1957
1958 Aliases expand Python variables just like system calls using ! or !!
1959 do: all expressions prefixed with '$' get expanded. For details of
1960 the semantic rules, see PEP-215:
1961 http://www.python.org/peps/pep-0215.html. This is the library used by
1962 IPython for variable expansion. If you want to access a true shell
1963 variable, an extra $ is necessary to prevent its expansion by IPython:
1964
1965 In [6]: alias show echo\\
1966 In [7]: PATH='A Python string'\\
1967 In [8]: show $PATH\\
1968 A Python string\\
1969 In [9]: show $$PATH\\
1970 /usr/local/lf9560/bin:/usr/local/intel/compiler70/ia32/bin:...
1971
1972 You can use the alias facility to acess all of $PATH. See the %rehash
1973 and %rehashx functions, which automatically create aliases for the
1974 contents of your $PATH.
1975
1976 If called with no parameters, %alias prints the current alias table."""
1977
1978 par = parameter_s.strip()
1979 if not par:
1980 if self.shell.rc.automagic:
1981 prechar = ''
1982 else:
1983 prechar = self.shell.ESC_MAGIC
1984 print 'Alias\t\tSystem Command\n'+'-'*30
1985 atab = self.shell.alias_table
1986 aliases = atab.keys()
1987 aliases.sort()
1988 for alias in aliases:
1989 print prechar+alias+'\t\t'+atab[alias][1]
1990 print '-'*30+'\nTotal number of aliases:',len(aliases)
1991 return
1992 try:
1993 alias,cmd = par.split(None,1)
1994 except:
1995 print OInspect.getdoc(self.magic_alias)
1996 else:
1997 nargs = cmd.count('%s')
1998 if nargs>0 and cmd.find('%l')>=0:
1999 error('The %s and %l specifiers are mutually exclusive '
2000 'in alias definitions.')
2001 else: # all looks OK
2002 self.shell.alias_table[alias] = (nargs,cmd)
2003 self.shell.alias_table_validate(verbose=1)
2004 # end magic_alias
2005
2006 def magic_unalias(self, parameter_s = ''):
2007 """Remove an alias"""
2008
2009 aname = parameter_s.strip()
2010 if aname in self.shell.alias_table:
2011 del self.shell.alias_table[aname]
2012
2013 def magic_rehash(self, parameter_s = ''):
2014 """Update the alias table with all entries in $PATH.
2015
2016 This version does no checks on execute permissions or whether the
2017 contents of $PATH are truly files (instead of directories or something
2018 else). For such a safer (but slower) version, use %rehashx."""
2019
2020 # This function (and rehashx) manipulate the alias_table directly
2021 # rather than calling magic_alias, for speed reasons. A rehash on a
2022 # typical Linux box involves several thousand entries, so efficiency
2023 # here is a top concern.
2024
2025 path = filter(os.path.isdir,os.environ['PATH'].split(os.pathsep))
2026 alias_table = self.shell.alias_table
2027 for pdir in path:
2028 for ff in os.listdir(pdir):
2029 # each entry in the alias table must be (N,name), where
2030 # N is the number of positional arguments of the alias.
2031 alias_table[ff] = (0,ff)
2032 # Make sure the alias table doesn't contain keywords or builtins
2033 self.shell.alias_table_validate()
2034 # Call again init_auto_alias() so we get 'rm -i' and other modified
2035 # aliases since %rehash will probably clobber them
2036 self.shell.init_auto_alias()
2037
2038 def magic_rehashx(self, parameter_s = ''):
2039 """Update the alias table with all executable files in $PATH.
2040
2041 This version explicitly checks that every entry in $PATH is a file
2042 with execute access (os.X_OK), so it is much slower than %rehash.
2043
2044 Under Windows, it checks executability as a match agains a
2045 '|'-separated string of extensions, stored in the IPython config
2046 variable win_exec_ext. This defaults to 'exe|com|bat'. """
2047
2048 path = filter(os.path.isdir,os.environ['PATH'].split(os.pathsep))
2049 alias_table = self.shell.alias_table
2050
2051 if os.name == 'posix':
2052 isexec = lambda fname:os.path.isfile(fname) and \
2053 os.access(fname,os.X_OK)
2054 else:
2055
2056 try:
2057 winext = os.environ['pathext'].replace(';','|').replace('.','')
2058 except KeyError:
2059 winext = 'exe|com|bat'
2060
2061 execre = re.compile(r'(.*)\.(%s)$' % winext,re.IGNORECASE)
2062 isexec = lambda fname:os.path.isfile(fname) and execre.match(fname)
2063 savedir = os.getcwd()
2064 try:
2065 # write the whole loop for posix/Windows so we don't have an if in
2066 # the innermost part
2067 if os.name == 'posix':
2068 for pdir in path:
2069 os.chdir(pdir)
2070 for ff in os.listdir(pdir):
2071 if isexec(ff):
2072 # each entry in the alias table must be (N,name),
2073 # where N is the number of positional arguments of the
2074 # alias.
2075 alias_table[ff] = (0,ff)
2076 else:
2077 for pdir in path:
2078 os.chdir(pdir)
2079 for ff in os.listdir(pdir):
2080 if isexec(ff):
2081 alias_table[execre.sub(r'\1',ff)] = (0,ff)
2082 # Make sure the alias table doesn't contain keywords or builtins
2083 self.shell.alias_table_validate()
2084 # Call again init_auto_alias() so we get 'rm -i' and other
2085 # modified aliases since %rehashx will probably clobber them
2086 self.shell.init_auto_alias()
2087 finally:
2088 os.chdir(savedir)
2089
2090 def magic_pwd(self, parameter_s = ''):
2091 """Return the current working directory path."""
2092 return os.getcwd()
2093
2094 def magic_cd(self, parameter_s=''):
2095 """Change the current working directory.
2096
2097 This command automatically maintains an internal list of directories
2098 you visit during your IPython session, in the variable _dh. The
2099 command %dhist shows this history nicely formatted.
2100
2101 Usage:
2102
2103 cd 'dir': changes to directory 'dir'.
2104
2105 cd -: changes to the last visited directory.
2106
2107 cd -<n>: changes to the n-th directory in the directory history.
2108
2109 cd -b <bookmark_name>: jump to a bookmark set by %bookmark
2110 (note: cd <bookmark_name> is enough if there is no
2111 directory <bookmark_name>, but a bookmark with the name exists.)
2112
2113 Options:
2114
2115 -q: quiet. Do not print the working directory after the cd command is
2116 executed. By default IPython's cd command does print this directory,
2117 since the default prompts do not display path information.
2118
2119 Note that !cd doesn't work for this purpose because the shell where
2120 !command runs is immediately discarded after executing 'command'."""
2121
2122 parameter_s = parameter_s.strip()
2123 bkms = self.shell.persist.get("bookmarks",{})
2124
2125 numcd = re.match(r'(-)(\d+)$',parameter_s)
2126 # jump in directory history by number
2127 if numcd:
2128 nn = int(numcd.group(2))
2129 try:
2130 ps = self.shell.user_ns['_dh'][nn]
2131 except IndexError:
2132 print 'The requested directory does not exist in history.'
2133 return
2134 else:
2135 opts = {}
2136 else:
2137 opts,ps = self.parse_options(parameter_s,'qb',mode='string')
2138 # jump to previous
2139 if ps == '-':
2140 try:
2141 ps = self.shell.user_ns['_dh'][-2]
2142 except IndexError:
2143 print 'No previous directory to change to.'
2144 return
2145 # jump to bookmark
2146 elif opts.has_key('b') or (bkms.has_key(ps) and not os.path.isdir(ps)):
2147 if bkms.has_key(ps):
2148 target = bkms[ps]
2149 print '(bookmark:%s) -> %s' % (ps,target)
2150 ps = target
2151 else:
2152 if bkms:
2153 error("Bookmark '%s' not found. "
2154 "Use '%bookmark -l' to see your bookmarks." % ps)
2155 else:
2156 print "Bookmarks not set - use %bookmark <bookmarkname>"
2157 return
2158
2159 # at this point ps should point to the target dir
2160 if ps:
2161 try:
2162 os.chdir(os.path.expanduser(ps))
2163 except OSError:
2164 print sys.exc_info()[1]
2165 else:
2166 self.shell.user_ns['_dh'].append(os.getcwd())
2167 else:
2168 os.chdir(self.home_dir)
2169 self.shell.user_ns['_dh'].append(os.getcwd())
2170 if not 'q' in opts:
2171 print self.shell.user_ns['_dh'][-1]
2172
2173 def magic_dhist(self, parameter_s=''):
2174 """Print your history of visited directories.
2175
2176 %dhist -> print full history\\
2177 %dhist n -> print last n entries only\\
2178 %dhist n1 n2 -> print entries between n1 and n2 (n1 not included)\\
2179
2180 This history is automatically maintained by the %cd command, and
2181 always available as the global list variable _dh. You can use %cd -<n>
2182 to go to directory number <n>."""
2183
2184 dh = self.shell.user_ns['_dh']
2185 if parameter_s:
2186 try:
2187 args = map(int,parameter_s.split())
2188 except:
2189 self.arg_err(Magic.magic_dhist)
2190 return
2191 if len(args) == 1:
2192 ini,fin = max(len(dh)-(args[0]),0),len(dh)
2193 elif len(args) == 2:
2194 ini,fin = args
2195 else:
2196 self.arg_err(Magic.magic_dhist)
2197 return
2198 else:
2199 ini,fin = 0,len(dh)
2200 nlprint(dh,
2201 header = 'Directory history (kept in _dh)',
2202 start=ini,stop=fin)
2203
2204 def magic_env(self, parameter_s=''):
2205 """List environment variables."""
2206
2207 # environ is an instance of UserDict
2208 return os.environ.data
2209
2210 def magic_pushd(self, parameter_s=''):
2211 """Place the current dir on stack and change directory.
2212
2213 Usage:\\
2214 %pushd ['dirname']
2215
2216 %pushd with no arguments does a %pushd to your home directory.
2217 """
2218 if parameter_s == '': parameter_s = '~'
2219 if len(self.dir_stack)>0 and os.path.expanduser(parameter_s) != \
2220 os.path.expanduser(self.dir_stack[0]):
2221 try:
2222 self.magic_cd(parameter_s)
2223 self.dir_stack.insert(0,os.getcwd().replace(self.home_dir,'~'))
2224 self.magic_dirs()
2225 except:
2226 print 'Invalid directory'
2227 else:
2228 print 'You are already there!'
2229
2230 def magic_popd(self, parameter_s=''):
2231 """Change to directory popped off the top of the stack.
2232 """
2233 if len (self.dir_stack) > 1:
2234 self.dir_stack.pop(0)
2235 self.magic_cd(self.dir_stack[0])
2236 print self.dir_stack[0]
2237 else:
2238 print "You can't remove the starting directory from the stack:",\
2239 self.dir_stack
2240
2241 def magic_dirs(self, parameter_s=''):
2242 """Return the current directory stack."""
2243
2244 return self.dir_stack[:]
2245
2246 def magic_sc(self, parameter_s=''):
2247 """Shell capture - execute a shell command and capture its output.
2248
2249 %sc [options] varname=command
2250
2251 IPython will run the given command using commands.getoutput(), and
2252 will then update the user's interactive namespace with a variable
2253 called varname, containing the value of the call. Your command can
2254 contain shell wildcards, pipes, etc.
2255
2256 The '=' sign in the syntax is mandatory, and the variable name you
2257 supply must follow Python's standard conventions for valid names.
2258
2259 Options:
2260
2261 -l: list output. Split the output on newlines into a list before
2262 assigning it to the given variable. By default the output is stored
2263 as a single string.
2264
2265 -v: verbose. Print the contents of the variable.
2266
2267 In most cases you should not need to split as a list, because the
2268 returned value is a special type of string which can automatically
2269 provide its contents either as a list (split on newlines) or as a
2270 space-separated string. These are convenient, respectively, either
2271 for sequential processing or to be passed to a shell command.
2272
2273 For example:
2274
2275 # Capture into variable a
2276 In [9]: sc a=ls *py
2277
2278 # a is a string with embedded newlines
2279 In [10]: a
2280 Out[10]: 'setup.py\nwin32_manual_post_install.py'
2281
2282 # which can be seen as a list:
2283 In [11]: a.l
2284 Out[11]: ['setup.py', 'win32_manual_post_install.py']
2285
2286 # or as a whitespace-separated string:
2287 In [12]: a.s
2288 Out[12]: 'setup.py win32_manual_post_install.py'
2289
2290 # a.s is useful to pass as a single command line:
2291 In [13]: !wc -l $a.s
2292 146 setup.py
2293 130 win32_manual_post_install.py
2294 276 total
2295
2296 # while the list form is useful to loop over:
2297 In [14]: for f in a.l:
2298 ....: !wc -l $f
2299 ....:
2300 146 setup.py
2301 130 win32_manual_post_install.py
2302
2303 Similiarly, the lists returned by the -l option are also special, in
2304 the sense that you can equally invoke the .s attribute on them to
2305 automatically get a whitespace-separated string from their contents:
2306
2307 In [1]: sc -l b=ls *py
2308
2309 In [2]: b
2310 Out[2]: ['setup.py', 'win32_manual_post_install.py']
2311
2312 In [3]: b.s
2313 Out[3]: 'setup.py win32_manual_post_install.py'
2314
2315 In summary, both the lists and strings used for ouptut capture have
2316 the following special attributes:
2317
2318 .l (or .list) : value as list.
2319 .n (or .nlstr): value as newline-separated string.
2320 .s (or .spstr): value as space-separated string.
2321 """
2322
2323 opts,args = self.parse_options(parameter_s,'lv')
2324 # Try to get a variable name and command to run
2325 try:
2326 # the variable name must be obtained from the parse_options
2327 # output, which uses shlex.split to strip options out.
2328 var,_ = args.split('=',1)
2329 var = var.strip()
2330 # But the the command has to be extracted from the original input
2331 # parameter_s, not on what parse_options returns, to avoid the
2332 # quote stripping which shlex.split performs on it.
2333 _,cmd = parameter_s.split('=',1)
2334 except ValueError:
2335 var,cmd = '',''
2336 if not var:
2337 error('you must specify a variable to assign the command to.')
2338 return
2339 # If all looks ok, proceed
2340 out,err = self.shell.getoutputerror(cmd)
2341 if err:
2342 print >> Term.cerr,err
2343 if opts.has_key('l'):
2344 out = SList(out.split('\n'))
2345 else:
2346 out = LSString(out)
2347 if opts.has_key('v'):
2348 print '%s ==\n%s' % (var,pformat(out))
2349 self.shell.user_ns.update({var:out})
2350
2351 def magic_sx(self, parameter_s=''):
2352 """Shell execute - run a shell command and capture its output.
2353
2354 %sx command
2355
2356 IPython will run the given command using commands.getoutput(), and
2357 return the result formatted as a list (split on '\\n'). Since the
2358 output is _returned_, it will be stored in ipython's regular output
2359 cache Out[N] and in the '_N' automatic variables.
2360
2361 Notes:
2362
2363 1) If an input line begins with '!!', then %sx is automatically
2364 invoked. That is, while:
2365 !ls
2366 causes ipython to simply issue system('ls'), typing
2367 !!ls
2368 is a shorthand equivalent to:
2369 %sx ls
2370
2371 2) %sx differs from %sc in that %sx automatically splits into a list,
2372 like '%sc -l'. The reason for this is to make it as easy as possible
2373 to process line-oriented shell output via further python commands.
2374 %sc is meant to provide much finer control, but requires more
2375 typing.
2376
2377 3) Just like %sc -l, this is a list with special attributes:
2378
2379 .l (or .list) : value as list.
2380 .n (or .nlstr): value as newline-separated string.
2381 .s (or .spstr): value as whitespace-separated string.
2382
2383 This is very useful when trying to use such lists as arguments to
2384 system commands."""
2385
2386 if parameter_s:
2387 out,err = self.shell.getoutputerror(parameter_s)
2388 if err:
2389 print >> Term.cerr,err
2390 return SList(out.split('\n'))
2391
2392 def magic_bg(self, parameter_s=''):
2393 """Run a job in the background, in a separate thread.
2394
2395 For example,
2396
2397 %bg myfunc(x,y,z=1)
2398
2399 will execute 'myfunc(x,y,z=1)' in a background thread. As soon as the
2400 execution starts, a message will be printed indicating the job
2401 number. If your job number is 5, you can use
2402
2403 myvar = jobs.result(5) or myvar = jobs[5].result
2404
2405 to assign this result to variable 'myvar'.
2406
2407 IPython has a job manager, accessible via the 'jobs' object. You can
2408 type jobs? to get more information about it, and use jobs.<TAB> to see
2409 its attributes. All attributes not starting with an underscore are
2410 meant for public use.
2411
2412 In particular, look at the jobs.new() method, which is used to create
2413 new jobs. This magic %bg function is just a convenience wrapper
2414 around jobs.new(), for expression-based jobs. If you want to create a
2415 new job with an explicit function object and arguments, you must call
2416 jobs.new() directly.
2417
2418 The jobs.new docstring also describes in detail several important
2419 caveats associated with a thread-based model for background job
2420 execution. Type jobs.new? for details.
2421
2422 You can check the status of all jobs with jobs.status().
2423
2424 The jobs variable is set by IPython into the Python builtin namespace.
2425 If you ever declare a variable named 'jobs', you will shadow this
2426 name. You can either delete your global jobs variable to regain
2427 access to the job manager, or make a new name and assign it manually
2428 to the manager (stored in IPython's namespace). For example, to
2429 assign the job manager to the Jobs name, use:
2430
2431 Jobs = __builtins__.jobs"""
2432
2433 self.shell.jobs.new(parameter_s,self.shell.user_ns)
2434
2435 def magic_bookmark(self, parameter_s=''):
2436 """Manage IPython's bookmark system.
2437
2438 %bookmark <name> - set bookmark to current dir
2439 %bookmark <name> <dir> - set bookmark to <dir>
2440 %bookmark -l - list all bookmarks
2441 %bookmark -d <name> - remove bookmark
2442 %bookmark -r - remove all bookmarks
2443
2444 You can later on access a bookmarked folder with:
2445 %cd -b <name>
2446 or simply '%cd <name>' if there is no directory called <name> AND
2447 there is such a bookmark defined.
2448
2449 Your bookmarks persist through IPython sessions, but they are
2450 associated with each profile."""
2451
2452 opts,args = self.parse_options(parameter_s,'drl',mode='list')
2453 if len(args) > 2:
2454 error('You can only give at most two arguments')
2455 return
2456
2457 bkms = self.shell.persist.get('bookmarks',{})
2458
2459 if opts.has_key('d'):
2460 try:
2461 todel = args[0]
2462 except IndexError:
2463 error('You must provide a bookmark to delete')
2464 else:
2465 try:
2466 del bkms[todel]
2467 except:
2468 error("Can't delete bookmark '%s'" % todel)
2469 elif opts.has_key('r'):
2470 bkms = {}
2471 elif opts.has_key('l'):
2472 bks = bkms.keys()
2473 bks.sort()
2474 if bks:
2475 size = max(map(len,bks))
2476 else:
2477 size = 0
2478 fmt = '%-'+str(size)+'s -> %s'
2479 print 'Current bookmarks:'
2480 for bk in bks:
2481 print fmt % (bk,bkms[bk])
2482 else:
2483 if not args:
2484 error("You must specify the bookmark name")
2485 elif len(args)==1:
2486 bkms[args[0]] = os.getcwd()
2487 elif len(args)==2:
2488 bkms[args[0]] = args[1]
2489 self.persist['bookmarks'] = bkms
2490 # end Magic
@@ -0,0 +1,398 b''
1 # -*- coding: utf-8 -*-
2 """Tools for inspecting Python objects.
3
4 Uses syntax highlighting for presenting the various information elements.
5
6 Similar in spirit to the inspect module, but all calls take a name argument to
7 reference the name under which an object is being read.
8
9 $Id: OInspect.py 575 2005-04-08 14:16:44Z fperez $
10 """
11
12 #*****************************************************************************
13 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
14 #
15 # Distributed under the terms of the BSD License. The full license is in
16 # the file COPYING, distributed as part of this software.
17 #*****************************************************************************
18
19 from IPython import Release
20 __author__ = '%s <%s>' % Release.authors['Fernando']
21 __license__ = Release.license
22
23 __all__ = ['Inspector','InspectColors']
24
25 # stdlib modules
26 import inspect,linecache,types,StringIO,string
27
28 # IPython's own
29 from IPython.Itpl import itpl
30 from IPython.genutils import page,indent,Term
31 from IPython import PyColorize
32 from IPython.ColorANSI import *
33
34 #****************************************************************************
35 # Builtin color schemes
36
37 Colors = TermColors # just a shorthand
38
39 # Build a few color schemes
40 NoColor = ColorScheme(
41 'NoColor',{
42 'header' : Colors.NoColor,
43 'normal' : Colors.NoColor # color off (usu. Colors.Normal)
44 } )
45
46 LinuxColors = ColorScheme(
47 'Linux',{
48 'header' : Colors.LightRed,
49 'normal' : Colors.Normal # color off (usu. Colors.Normal)
50 } )
51
52 LightBGColors = ColorScheme(
53 'LightBG',{
54 'header' : Colors.Red,
55 'normal' : Colors.Normal # color off (usu. Colors.Normal)
56 } )
57
58 # Build table of color schemes (needed by the parser)
59 InspectColors = ColorSchemeTable([NoColor,LinuxColors,LightBGColors],
60 'Linux')
61
62 #****************************************************************************
63 # Auxiliary functions
64 def getdoc(obj):
65 """Stable wrapper around inspect.getdoc.
66
67 This can't crash because of attribute problems.
68
69 It also attempts to call a getdoc() method on the given object. This
70 allows objects which provide their docstrings via non-standard mechanisms
71 (like Pyro proxies) to still be inspected by ipython's ? system."""
72
73 ds = None # default return value
74 try:
75 ds = inspect.getdoc(obj)
76 except:
77 # Harden against an inspect failure, which can occur with
78 # SWIG-wrapped extensions.
79 pass
80 # Allow objects to offer customized documentation via a getdoc method:
81 try:
82 ds2 = obj.getdoc()
83 except:
84 pass
85 else:
86 # if we get extra info, we add it to the normal docstring.
87 if ds is None:
88 ds = ds2
89 else:
90 ds = '%s\n%s' % (ds,ds2)
91 return ds
92
93 #****************************************************************************
94 # Class definitions
95
96 class myStringIO(StringIO.StringIO):
97 """Adds a writeln method to normal StringIO."""
98 def writeln(self,*arg,**kw):
99 """Does a write() and then a write('\n')"""
100 self.write(*arg,**kw)
101 self.write('\n')
102
103 class Inspector:
104 def __init__(self,color_table,code_color_table,scheme):
105 self.color_table = color_table
106 self.parser = PyColorize.Parser(code_color_table,out='str')
107 self.format = self.parser.format
108 self.set_active_scheme(scheme)
109
110 def __getargspec(self,obj):
111 """Get the names and default values of a function's arguments.
112
113 A tuple of four things is returned: (args, varargs, varkw, defaults).
114 'args' is a list of the argument names (it may contain nested lists).
115 'varargs' and 'varkw' are the names of the * and ** arguments or None.
116 'defaults' is an n-tuple of the default values of the last n arguments.
117
118 Modified version of inspect.getargspec from the Python Standard
119 Library."""
120
121 if inspect.isfunction(obj):
122 func_obj = obj
123 elif inspect.ismethod(obj):
124 func_obj = obj.im_func
125 else:
126 raise TypeError, 'arg is not a Python function'
127 args, varargs, varkw = inspect.getargs(func_obj.func_code)
128 return args, varargs, varkw, func_obj.func_defaults
129
130 def __getdef(self,obj,oname=''):
131 """Return the definition header for any callable object.
132
133 If any exception is generated, None is returned instead and the
134 exception is suppressed."""
135
136 try:
137 return oname + inspect.formatargspec(*self.__getargspec(obj))
138 except:
139 return None
140
141 def __head(self,h):
142 """Return a header string with proper colors."""
143 return '%s%s%s' % (self.color_table.active_colors.header,h,
144 self.color_table.active_colors.normal)
145
146 def set_active_scheme(self,scheme):
147 self.color_table.set_active_scheme(scheme)
148 self.parser.color_table.set_active_scheme(scheme)
149
150 def noinfo(self,msg,oname):
151 """Generic message when no information is found."""
152 print 'No %s found' % msg,
153 if oname:
154 print 'for %s' % oname
155 else:
156 print
157
158 def pdef(self,obj,oname=''):
159 """Print the definition header for any callable object.
160
161 If the object is a class, print the constructor information."""
162
163 if not callable(obj):
164 print 'Object is not callable.'
165 return
166
167 header = ''
168 if type(obj) is types.ClassType:
169 header = self.__head('Class constructor information:\n')
170 obj = obj.__init__
171 elif type(obj) is types.InstanceType:
172 obj = obj.__call__
173
174 output = self.__getdef(obj,oname)
175 if output is None:
176 self.noinfo('definition header',oname)
177 else:
178 print >>Term.cout, header,self.format(output),
179
180 def pdoc(self,obj,oname='',formatter = None):
181 """Print the docstring for any object.
182
183 Optional:
184 -formatter: a function to run the docstring through for specially
185 formatted docstrings."""
186
187 head = self.__head # so that itpl can find it even if private
188 ds = getdoc(obj)
189 if formatter:
190 ds = formatter(ds)
191 if type(obj) is types.ClassType:
192 init_ds = getdoc(obj.__init__)
193 output = itpl('$head("Class Docstring:")\n'
194 '$indent(ds)\n'
195 '$head("Constructor Docstring"):\n'
196 '$indent(init_ds)')
197 elif type(obj) is types.InstanceType and hasattr(obj,'__call__'):
198 call_ds = getdoc(obj.__call__)
199 if call_ds:
200 output = itpl('$head("Class Docstring:")\n$indent(ds)\n'
201 '$head("Calling Docstring:")\n$indent(call_ds)')
202 else:
203 output = ds
204 else:
205 output = ds
206 if output is None:
207 self.noinfo('documentation',oname)
208 return
209 page(output)
210
211 def psource(self,obj,oname=''):
212 """Print the source code for an object."""
213
214 # Flush the source cache because inspect can return out-of-date source
215 linecache.checkcache()
216 try:
217 src = inspect.getsource(obj)
218 except:
219 self.noinfo('source',oname)
220 else:
221 page(self.format(src))
222
223 def pfile(self,obj,oname=''):
224 """Show the whole file where an object was defined."""
225 try:
226 sourcelines,lineno = inspect.getsourcelines(obj)
227 except:
228 self.noinfo('file',oname)
229 else:
230 # run contents of file through pager starting at line
231 # where the object is defined
232 page(self.format(open(inspect.getabsfile(obj)).read()),lineno)
233
234 def pinfo(self,obj,oname='',formatter=None,info=None,detail_level=0):
235 """Show detailed information about an object.
236
237 Optional arguments:
238
239 - oname: name of the variable pointing to the object.
240
241 - formatter: special formatter for docstrings (see pdoc)
242
243 - info: a structure with some information fields which may have been
244 precomputed already.
245
246 - detail_level: if set to 1, more information is given.
247 """
248
249 obj_type = type(obj)
250
251 header = self.__head
252 if info is None:
253 ismagic = 0
254 isalias = 0
255 ospace = ''
256 else:
257 ismagic = info.ismagic
258 isalias = info.isalias
259 ospace = info.namespace
260 # Get docstring, special-casing aliases:
261 if isalias:
262 ds = "Alias to the system command:\n %s" % obj[1]
263 else:
264 ds = getdoc(obj)
265 if formatter is not None:
266 ds = formatter(ds)
267
268 # store output in a list which gets joined with \n at the end.
269 out = myStringIO()
270
271 string_max = 200 # max size of strings to show (snipped if longer)
272 shalf = int((string_max -5)/2)
273
274 if ismagic:
275 obj_type_name = 'Magic function'
276 elif isalias:
277 obj_type_name = 'System alias'
278 else:
279 obj_type_name = obj_type.__name__
280 out.writeln(header('Type:\t\t')+obj_type_name)
281
282 try:
283 bclass = obj.__class__
284 out.writeln(header('Base Class:\t')+str(bclass))
285 except: pass
286
287 # String form, but snip if too long in ? form (full in ??)
288 try:
289 ostr = str(obj)
290 str_head = 'String Form:'
291 if not detail_level and len(ostr)>string_max:
292 ostr = ostr[:shalf] + ' <...> ' + ostr[-shalf:]
293 ostr = ("\n" + " " * len(str_head.expandtabs())).\
294 join(map(string.strip,ostr.split("\n")))
295 if ostr.find('\n') > -1:
296 # Print multi-line strings starting at the next line.
297 str_sep = '\n'
298 else:
299 str_sep = '\t'
300 out.writeln("%s%s%s" % (header(str_head),str_sep,ostr))
301 except:
302 pass
303
304 if ospace:
305 out.writeln(header('Namespace:\t')+ospace)
306
307 # Length (for strings and lists)
308 try:
309 length = str(len(obj))
310 out.writeln(header('Length:\t\t')+length)
311 except: pass
312
313 # Filename where object was defined
314 try:
315 file = inspect.getabsfile(obj)
316 if file.endswith('<string>'):
317 file = 'Dynamically generated function. No source code available.'
318 out.writeln(header('File:\t\t')+file)
319 except: pass
320
321 # reconstruct the function definition and print it:
322 defln = self.__getdef(obj,oname)
323 if defln:
324 out.write(header('Definition:\t')+self.format(defln))
325
326 # Docstrings only in detail 0 mode, since source contains them (we
327 # avoid repetitions). If source fails, we add them back, see below.
328 if ds and detail_level == 0:
329 out.writeln(header('Docstring:\n') + indent(ds))
330
331 # Original source code for any callable
332 if detail_level:
333 # Flush the source cache because inspect can return out-of-date source
334 linecache.checkcache()
335 try:
336 source = self.format(inspect.getsource(obj))
337 out.write(header('Source:\n')+source.rstrip())
338 except:
339 if ds:
340 out.writeln(header('Docstring:\n') + indent(ds))
341
342 # Constructor docstring for classes
343 if obj_type is types.ClassType:
344 # reconstruct the function definition and print it:
345 try:
346 obj_init = obj.__init__
347 except AttributeError:
348 init_def = init_ds = None
349 else:
350 init_def = self.__getdef(obj_init,oname)
351 init_ds = getdoc(obj_init)
352
353 if init_def or init_ds:
354 out.writeln(header('\nConstructor information:'))
355 if init_def:
356 out.write(header('Definition:\t')+ self.format(init_def))
357 if init_ds:
358 out.writeln(header('Docstring:\n') + indent(init_ds))
359 # and class docstring for instances:
360 elif obj_type is types.InstanceType:
361
362 # First, check whether the instance docstring is identical to the
363 # class one, and print it separately if they don't coincide. In
364 # most cases they will, but it's nice to print all the info for
365 # objects which use instance-customized docstrings.
366 if ds:
367 class_ds = getdoc(obj.__class__)
368 if class_ds and ds != class_ds:
369 out.writeln(header('Class Docstring:\n') +
370 indent(class_ds))
371
372 # Next, try to show constructor docstrings
373 try:
374 init_ds = getdoc(obj.__init__)
375 except AttributeError:
376 init_ds = None
377 if init_ds:
378 out.writeln(header('Constructor Docstring:\n') +
379 indent(init_ds))
380
381 # Call form docstring for callable instances
382 if hasattr(obj,'__call__'):
383 out.writeln(header('Callable:\t')+'Yes')
384 call_def = self.__getdef(obj.__call__,oname)
385 if call_def is None:
386 out.write(header('Call def:\t')+
387 'Calling definition not available.')
388 else:
389 out.write(header('Call def:\t')+self.format(call_def))
390 call_ds = getdoc(obj.__call__)
391 if call_ds:
392 out.writeln(header('Call docstring:\n') + indent(call_ds))
393
394 # Finally send to printer/pager
395 output = out.getvalue()
396 if output:
397 page(output)
398 # end pinfo
@@ -0,0 +1,262 b''
1 # -*- coding: utf-8 -*-
2 """Class to trap stdout and stderr and log them separately.
3
4 $Id: OutputTrap.py 542 2005-03-18 09:16:04Z fperez $"""
5
6 #*****************************************************************************
7 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
8 #
9 # Distributed under the terms of the BSD License. The full license is in
10 # the file COPYING, distributed as part of this software.
11 #*****************************************************************************
12
13 from IPython import Release
14 __author__ = '%s <%s>' % Release.authors['Fernando']
15 __license__ = Release.license
16
17 import exceptions,sys
18 from cStringIO import StringIO
19
20 class OutputTrapError(exceptions.Exception):
21 """Exception for OutputTrap class."""
22
23 def __init__(self,args=None):
24 exceptions.Exception.__init__(self)
25 self.args = args
26
27 class OutputTrap:
28
29 """Class to trap standard output and standard error. They get logged in
30 StringIO objects which are available as <instance>.out and
31 <instance>.err. The class also offers summary methods which format this
32 data a bit.
33
34 A word of caution: because it blocks messages, using this class can make
35 debugging very tricky. If you are having bizarre problems silently, try
36 turning your output traps off for a while. You can call the constructor
37 with the parameter debug=1 for these cases. This turns actual trapping
38 off, but you can keep the rest of your code unchanged (this has already
39 been a life saver).
40
41 Example:
42
43 # config: trapper with a line of dots as log separator (final '\\n' needed)
44 config = OutputTrap('Config','Out ','Err ','.'*80+'\\n')
45
46 # start trapping output
47 config.trap_all()
48
49 # now all output is logged ...
50 # do stuff...
51
52 # output back to normal:
53 config.release_all()
54
55 # print all that got logged:
56 print config.summary()
57
58 # print individual raw data:
59 print config.out.getvalue()
60 print config.err.getvalue()
61 """
62
63 def __init__(self,name='Generic Output Trap',
64 out_head='Standard Output. ',err_head='Standard Error. ',
65 sum_sep='\n',debug=0,trap_out=0,trap_err=0,
66 quiet_out=0,quiet_err=0):
67 self.name = name
68 self.out_head = out_head
69 self.err_head = err_head
70 self.sum_sep = sum_sep
71 self.out = StringIO()
72 self.err = StringIO()
73 self.out_save = None
74 self.err_save = None
75 self.debug = debug
76 self.quiet_out = quiet_out
77 self.quiet_err = quiet_err
78 if trap_out:
79 self.trap_out()
80 if trap_err:
81 self.trap_err()
82
83 def trap_out(self):
84 """Trap and log stdout."""
85 if sys.stdout is self.out:
86 raise OutputTrapError,'You are already trapping stdout.'
87 if not self.debug:
88 self._out_save = sys.stdout
89 sys.stdout = self.out
90
91 def release_out(self):
92 """Release stdout."""
93 if not self.debug:
94 if not sys.stdout is self.out:
95 raise OutputTrapError,'You are not trapping stdout.'
96 sys.stdout = self._out_save
97 self.out_save = None
98
99 def summary_out(self):
100 """Return as a string the log from stdout."""
101 out = self.out.getvalue()
102 if out:
103 if self.quiet_out:
104 return out
105 else:
106 return self.out_head + 'Log by '+ self.name + ':\n' + out
107 else:
108 return ''
109
110 def flush_out(self):
111 """Flush the stdout log. All data held in the log is lost."""
112
113 self.out.close()
114 self.out = StringIO()
115
116 def trap_err(self):
117 """Trap and log stderr."""
118 if sys.stderr is self.err:
119 raise OutputTrapError,'You are already trapping stderr.'
120 if not self.debug:
121 self._err_save = sys.stderr
122 sys.stderr = self.err
123
124 def release_err(self):
125 """Release stderr."""
126 if not self.debug:
127 if not sys.stderr is self.err:
128 raise OutputTrapError,'You are not trapping stderr.'
129 sys.stderr = self._err_save
130 self.err_save = None
131
132 def summary_err(self):
133 """Return as a string the log from stderr."""
134 err = self.err.getvalue()
135 if err:
136 if self.quiet_err:
137 return err
138 else:
139 return self.err_head + 'Log by '+ self.name + ':\n' + err
140 else:
141 return ''
142
143 def flush_err(self):
144 """Flush the stdout log. All data held in the log is lost."""
145
146 self.err.close()
147 self.err = StringIO()
148
149 def trap_all(self):
150 """Trap and log both stdout and stderr.
151
152 Cacthes and discards OutputTrapError exceptions raised."""
153 try:
154 self.trap_out()
155 except OutputTrapError:
156 pass
157 try:
158 self.trap_err()
159 except OutputTrapError:
160 pass
161
162 def release_all(self):
163 """Release both stdout and stderr.
164
165 Cacthes and discards OutputTrapError exceptions raised."""
166 try:
167 self.release_out()
168 except OutputTrapError:
169 pass
170 try:
171 self.release_err()
172 except OutputTrapError:
173 pass
174
175 def summary_all(self):
176 """Return as a string the log from stdout and stderr, prepending a separator
177 to each (defined in __init__ as sum_sep)."""
178 sum = ''
179 sout = self.summary_out()
180 if sout:
181 sum += self.sum_sep + sout
182 serr = self.summary_err()
183 if serr:
184 sum += '\n'+self.sum_sep + serr
185 return sum
186
187 def flush_all(self):
188 """Flush stdout and stderr"""
189 self.flush_out()
190 self.flush_err()
191
192 # a few shorthands
193 trap = trap_all
194 release = release_all
195 summary = summary_all
196 flush = flush_all
197 # end OutputTrap
198
199
200 #****************************************************************************
201 # Module testing. Incomplete, I'm lazy...
202
203 def _test_all():
204
205 """Module testing functions, activated when the module is called as a
206 script (not imported)."""
207
208 # Put tests for this module in here.
209 # Define them as nested functions so they don't clobber the
210 # pydoc-generated docs
211
212 def _test_():
213 name = ''
214 print '#'*50+'\nRunning test for ' + name
215 # ...
216 print 'Finished test for '+ name +'\n'+'#'*50
217
218 def _test_OutputTrap():
219 trap = OutputTrap(name = 'Test Trap', sum_sep = '.'*50+'\n',
220 out_head = 'SOut. ', err_head = 'SErr. ')
221
222 name = 'OutputTrap class'
223 print '#'*50+'\nRunning test for ' + name
224 print 'Trapping out'
225 trap.trap_out()
226 print >>sys.stdout, '>>stdout. stdout is trapped.'
227 print >>sys.stderr, '>>stderr. stdout is trapped.'
228 trap.release_out()
229 print trap.summary_out()
230
231 print 'Trapping err'
232 trap.trap_err()
233 print >>sys.stdout, '>>stdout. stderr is trapped.'
234 print >>sys.stderr, '>>stderr. stderr is trapped.'
235 trap.release_err()
236 print trap.summary_err()
237
238 print 'Trapping all (no flushing)'
239 trap.trap_all()
240 print >>sys.stdout, '>>stdout. stdout/err is trapped.'
241 print >>sys.stderr, '>>stderr. stdout/err is trapped.'
242 trap.release_all()
243 print trap.summary_all()
244
245 print 'Trapping all (flushing first)'
246 trap.flush()
247 trap.trap_all()
248 print >>sys.stdout, '>>stdout. stdout/err is trapped.'
249 print >>sys.stderr, '>>stderr. stdout/err is trapped.'
250 trap.release_all()
251 print trap.summary_all()
252 print 'Finished test for '+ name +'\n'+'#'*50
253
254 # call the actual tests here:
255 _test_OutputTrap()
256
257
258 if __name__=="__main__":
259 # _test_all() # XXX BROKEN.
260 pass
261
262 #************************ end of file <OutputTrap.py> ************************
This diff has been collapsed as it changes many lines, (574 lines changed) Show them Hide them
@@ -0,0 +1,574 b''
1 # -*- coding: utf-8 -*-
2 """
3 Classes for handling input/output prompts.
4
5 $Id: Prompts.py 564 2005-03-26 22:43:58Z fperez $"""
6
7 #*****************************************************************************
8 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
9 #
10 # Distributed under the terms of the BSD License. The full license is in
11 # the file COPYING, distributed as part of this software.
12 #*****************************************************************************
13
14 from IPython import Release
15 __author__ = '%s <%s>' % Release.authors['Fernando']
16 __license__ = Release.license
17 __version__ = Release.version
18
19 #****************************************************************************
20 # Required modules
21 import __builtin__
22 import os,sys,socket
23 import time
24 from pprint import pprint,pformat
25
26 # IPython's own
27 from IPython.genutils import *
28 from IPython.Struct import Struct
29 from IPython.Magic import Macro
30 from IPython.Itpl import ItplNS
31 from IPython import ColorANSI
32
33 #****************************************************************************
34 #Color schemes for Prompts.
35
36 PromptColors = ColorANSI.ColorSchemeTable()
37 InputColors = ColorANSI.InputTermColors # just a shorthand
38 Colors = ColorANSI.TermColors # just a shorthand
39
40 PromptColors.add_scheme(ColorANSI.ColorScheme(
41 'NoColor',
42 in_prompt = InputColors.NoColor, # Input prompt
43 in_number = InputColors.NoColor, # Input prompt number
44 in_prompt2 = InputColors.NoColor, # Continuation prompt
45 in_normal = InputColors.NoColor, # color off (usu. Colors.Normal)
46
47 out_prompt = Colors.NoColor, # Output prompt
48 out_number = Colors.NoColor, # Output prompt number
49
50 normal = Colors.NoColor # color off (usu. Colors.Normal)
51 ))
52 # make some schemes as instances so we can copy them for modification easily:
53 __PColLinux = ColorANSI.ColorScheme(
54 'Linux',
55 in_prompt = InputColors.Green,
56 in_number = InputColors.LightGreen,
57 in_prompt2 = InputColors.Green,
58 in_normal = InputColors.Normal, # color off (usu. Colors.Normal)
59
60 out_prompt = Colors.Red,
61 out_number = Colors.LightRed,
62
63 normal = Colors.Normal
64 )
65 # Don't forget to enter it into the table!
66 PromptColors.add_scheme(__PColLinux)
67 # Slightly modified Linux for light backgrounds
68 __PColLightBG = ColorANSI.ColorScheme('LightBG',**__PColLinux.colors.dict().copy())
69
70 __PColLightBG.colors.update(
71 in_prompt = InputColors.Blue,
72 in_number = InputColors.LightBlue,
73 in_prompt2 = InputColors.Blue
74 )
75 PromptColors.add_scheme(__PColLightBG)
76
77 del Colors,InputColors
78
79 #-----------------------------------------------------------------------------
80 def multiple_replace(dict, text):
81 """ Replace in 'text' all occurences of any key in the given
82 dictionary by its corresponding value. Returns the new string."""
83
84 # Function by Xavier Defrang, originally found at:
85 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/81330
86
87 # Create a regular expression from the dictionary keys
88 regex = re.compile("(%s)" % "|".join(map(re.escape, dict.keys())))
89 # For each match, look-up corresponding value in dictionary
90 return regex.sub(lambda mo: dict[mo.string[mo.start():mo.end()]], text)
91
92 #-----------------------------------------------------------------------------
93 # Special characters that can be used in prompt templates, mainly bash-like
94
95 # If $HOME isn't defined (Windows), make it an absurd string so that it can
96 # never be expanded out into '~'. Basically anything which can never be a
97 # reasonable directory name will do, we just want the $HOME -> '~' operation
98 # to become a no-op. We pre-compute $HOME here so it's not done on every
99 # prompt call.
100
101 # FIXME:
102
103 # - This should be turned into a class which does proper namespace management,
104 # since the prompt specials need to be evaluated in a certain namespace.
105 # Currently it's just globals, which need to be managed manually by code
106 # below.
107
108 # - I also need to split up the color schemes from the prompt specials
109 # somehow. I don't have a clean design for that quite yet.
110
111 HOME = os.environ.get("HOME","//////:::::ZZZZZ,,,~~~")
112
113 # We precompute a few more strings here for the prompt_specials, which are
114 # fixed once ipython starts. This reduces the runtime overhead of computing
115 # prompt strings.
116 USER = os.environ.get("USER")
117 HOSTNAME = socket.gethostname()
118 HOSTNAME_SHORT = HOSTNAME.split(".")[0]
119 ROOT_SYMBOL = "$#"[os.name=='nt' or os.getuid()==0]
120
121 prompt_specials_color = {
122 # Prompt/history count
123 '%n' : '${self.col_num}' '${self.cache.prompt_count}' '${self.col_p}',
124 '\\#': '${self.col_num}' '${self.cache.prompt_count}' '${self.col_p}',
125 # Prompt/history count, with the actual digits replaced by dots. Used
126 # mainly in continuation prompts (prompt_in2)
127 '\\D': '${"."*len(str(self.cache.prompt_count))}',
128 # Current working directory
129 '\\w': '${os.getcwd()}',
130 # Current time
131 '\\t' : '${time.strftime("%H:%M:%S")}',
132 # Basename of current working directory.
133 # (use os.sep to make this portable across OSes)
134 '\\W' : '${os.getcwd().split("%s")[-1]}' % os.sep,
135 # These X<N> are an extension to the normal bash prompts. They return
136 # N terms of the path, after replacing $HOME with '~'
137 '\\X0': '${os.getcwd().replace("%s","~")}' % HOME,
138 '\\X1': '${self.cwd_filt(1)}',
139 '\\X2': '${self.cwd_filt(2)}',
140 '\\X3': '${self.cwd_filt(3)}',
141 '\\X4': '${self.cwd_filt(4)}',
142 '\\X5': '${self.cwd_filt(5)}',
143 # Y<N> are similar to X<N>, but they show '~' if it's the directory
144 # N+1 in the list. Somewhat like %cN in tcsh.
145 '\\Y0': '${self.cwd_filt2(0)}',
146 '\\Y1': '${self.cwd_filt2(1)}',
147 '\\Y2': '${self.cwd_filt2(2)}',
148 '\\Y3': '${self.cwd_filt2(3)}',
149 '\\Y4': '${self.cwd_filt2(4)}',
150 '\\Y5': '${self.cwd_filt2(5)}',
151 # Hostname up to first .
152 '\\h': HOSTNAME_SHORT,
153 # Full hostname
154 '\\H': HOSTNAME,
155 # Username of current user
156 '\\u': USER,
157 # Escaped '\'
158 '\\\\': '\\',
159 # Newline
160 '\\n': '\n',
161 # Carriage return
162 '\\r': '\r',
163 # Release version
164 '\\v': __version__,
165 # Root symbol ($ or #)
166 '\\$': ROOT_SYMBOL,
167 }
168
169 # A copy of the prompt_specials dictionary but with all color escapes removed,
170 # so we can correctly compute the prompt length for the auto_rewrite method.
171 prompt_specials_nocolor = prompt_specials_color.copy()
172 prompt_specials_nocolor['%n'] = '${self.cache.prompt_count}'
173 prompt_specials_nocolor['\\#'] = '${self.cache.prompt_count}'
174
175 # Add in all the InputTermColors color escapes as valid prompt characters.
176 # They all get added as \\C_COLORNAME, so that we don't have any conflicts
177 # with a color name which may begin with a letter used by any other of the
178 # allowed specials. This of course means that \\C will never be allowed for
179 # anything else.
180 input_colors = ColorANSI.InputTermColors
181 for _color in dir(input_colors):
182 if _color[0] != '_':
183 c_name = '\\C_'+_color
184 prompt_specials_color[c_name] = getattr(input_colors,_color)
185 prompt_specials_nocolor[c_name] = ''
186
187 # we default to no color for safety. Note that prompt_specials is a global
188 # variable used by all prompt objects.
189 prompt_specials = prompt_specials_nocolor
190
191 #-----------------------------------------------------------------------------
192 def str_safe(arg):
193 """Convert to a string, without ever raising an exception.
194
195 If str(arg) fails, <ERROR: ... > is returned, where ... is the exception
196 error message."""
197
198 try:
199 return str(arg)
200 except Exception,msg:
201 return '<ERROR: %s>' % msg
202
203 class BasePrompt:
204 """Interactive prompt similar to Mathematica's."""
205 def __init__(self,cache,sep,prompt,pad_left=False):
206
207 # Hack: we access information about the primary prompt through the
208 # cache argument. We need this, because we want the secondary prompt
209 # to be aligned with the primary one. Color table info is also shared
210 # by all prompt classes through the cache. Nice OO spaghetti code!
211 self.cache = cache
212 self.sep = sep
213
214 # regexp to count the number of spaces at the end of a prompt
215 # expression, useful for prompt auto-rewriting
216 self.rspace = re.compile(r'(\s*)$')
217 # Flag to left-pad prompt strings to match the length of the primary
218 # prompt
219 self.pad_left = pad_left
220 # Set template to create each actual prompt (where numbers change)
221 self.p_template = prompt
222 self.set_p_str()
223
224 def set_p_str(self):
225 """ Set the interpolating prompt strings.
226
227 This must be called every time the color settings change, because the
228 prompt_specials global may have changed."""
229
230 import os,time # needed in locals for prompt string handling
231 loc = locals()
232 self.p_str = ItplNS('%s%s%s' %
233 ('${self.sep}${self.col_p}',
234 multiple_replace(prompt_specials, self.p_template),
235 '${self.col_norm}'),self.cache.user_ns,loc)
236
237 self.p_str_nocolor = ItplNS(multiple_replace(prompt_specials_nocolor,
238 self.p_template),
239 self.cache.user_ns,loc)
240
241 def write(self,msg): # dbg
242 sys.stdout.write(msg)
243 return ''
244
245 def __str__(self):
246 """Return a string form of the prompt.
247
248 This for is useful for continuation and output prompts, since it is
249 left-padded to match lengths with the primary one (if the
250 self.pad_left attribute is set)."""
251
252 out_str = str_safe(self.p_str)
253 if self.pad_left:
254 # We must find the amount of padding required to match lengths,
255 # taking the color escapes (which are invisible on-screen) into
256 # account.
257 esc_pad = len(out_str) - len(str_safe(self.p_str_nocolor))
258 format = '%%%ss' % (len(str(self.cache.last_prompt))+esc_pad)
259 return format % out_str
260 else:
261 return out_str
262
263 # these path filters are put in as methods so that we can control the
264 # namespace where the prompt strings get evaluated
265 def cwd_filt(self,depth):
266 """Return the last depth elements of the current working directory.
267
268 $HOME is always replaced with '~'.
269 If depth==0, the full path is returned."""
270
271 cwd = os.getcwd().replace(HOME,"~")
272 out = os.sep.join(cwd.split(os.sep)[-depth:])
273 if out:
274 return out
275 else:
276 return os.sep
277
278 def cwd_filt2(self,depth):
279 """Return the last depth elements of the current working directory.
280
281 $HOME is always replaced with '~'.
282 If depth==0, the full path is returned."""
283
284 cwd = os.getcwd().replace(HOME,"~").split(os.sep)
285 if '~' in cwd and len(cwd) == depth+1:
286 depth += 1
287 out = os.sep.join(cwd[-depth:])
288 if out:
289 return out
290 else:
291 return os.sep
292
293 class Prompt1(BasePrompt):
294 """Input interactive prompt similar to Mathematica's."""
295
296 def __init__(self,cache,sep='\n',prompt='In [\\#]: ',pad_left=True):
297 BasePrompt.__init__(self,cache,sep,prompt,pad_left)
298
299 def set_colors(self):
300 self.set_p_str()
301 Colors = self.cache.color_table.active_colors # shorthand
302 self.col_p = Colors.in_prompt
303 self.col_num = Colors.in_number
304 self.col_norm = Colors.in_normal
305 # We need a non-input version of these escapes for the '--->'
306 # auto-call prompts used in the auto_rewrite() method.
307 self.col_p_ni = self.col_p.replace('\001','').replace('\002','')
308 self.col_norm_ni = Colors.normal
309
310 def __str__(self):
311 self.cache.prompt_count += 1
312 self.cache.last_prompt = str_safe(self.p_str_nocolor).split('\n')[-1]
313 return str_safe(self.p_str)
314
315 def auto_rewrite(self):
316 """Print a string of the form '--->' which lines up with the previous
317 input string. Useful for systems which re-write the user input when
318 handling automatically special syntaxes."""
319
320 curr = str(self.cache.last_prompt)
321 nrspaces = len(self.rspace.search(curr).group())
322 return '%s%s>%s%s' % (self.col_p_ni,'-'*(len(curr)-nrspaces-1),
323 ' '*nrspaces,self.col_norm_ni)
324
325 class PromptOut(BasePrompt):
326 """Output interactive prompt similar to Mathematica's."""
327
328 def __init__(self,cache,sep='',prompt='Out[\\#]: ',pad_left=True):
329 BasePrompt.__init__(self,cache,sep,prompt,pad_left)
330 if not self.p_template:
331 self.__str__ = lambda: ''
332
333 def set_colors(self):
334 self.set_p_str()
335 Colors = self.cache.color_table.active_colors # shorthand
336 self.col_p = Colors.out_prompt
337 self.col_num = Colors.out_number
338 self.col_norm = Colors.normal
339
340 class Prompt2(BasePrompt):
341 """Interactive continuation prompt."""
342
343 def __init__(self,cache,prompt=' .\\D.: ',pad_left=True):
344 self.cache = cache
345 self.p_template = prompt
346 self.pad_left = pad_left
347 self.set_p_str()
348
349 def set_p_str(self):
350 import os,time # needed in locals for prompt string handling
351 loc = locals()
352 self.p_str = ItplNS('%s%s%s' %
353 ('${self.col_p2}',
354 multiple_replace(prompt_specials, self.p_template),
355 '$self.col_norm'),
356 self.cache.user_ns,loc)
357 self.p_str_nocolor = ItplNS(multiple_replace(prompt_specials_nocolor,
358 self.p_template),
359 self.cache.user_ns,loc)
360
361 def set_colors(self):
362 self.set_p_str()
363 Colors = self.cache.color_table.active_colors
364 self.col_p2 = Colors.in_prompt2
365 self.col_norm = Colors.in_normal
366 # FIXME (2004-06-16) HACK: prevent crashes for users who haven't
367 # updated their prompt_in2 definitions. Remove eventually.
368 self.col_p = Colors.out_prompt
369 self.col_num = Colors.out_number
370
371 #-----------------------------------------------------------------------------
372 class CachedOutput:
373 """Class for printing output from calculations while keeping a cache of
374 reults. It dynamically creates global variables prefixed with _ which
375 contain these results.
376
377 Meant to be used as a sys.displayhook replacement, providing numbered
378 prompts and cache services.
379
380 Initialize with initial and final values for cache counter (this defines
381 the maximum size of the cache."""
382
383 def __init__(self,cache_size,Pprint,colors='NoColor',input_sep='\n',
384 output_sep='\n',output_sep2='',user_ns={},
385 ps1 = None, ps2 = None,ps_out = None,
386 input_hist = None,pad_left=True):
387
388 cache_size_min = 20
389 if cache_size <= 0:
390 self.do_full_cache = 0
391 cache_size = 0
392 elif cache_size < cache_size_min:
393 self.do_full_cache = 0
394 cache_size = 0
395 warn('caching was disabled (min value for cache size is %s).' %
396 cache_size_min,level=3)
397 else:
398 self.do_full_cache = 1
399
400 self.cache_size = cache_size
401 self.input_sep = input_sep
402
403 # we need a reference to the user-level namespace
404 self.user_ns = user_ns
405 # and to the user's input
406 self.input_hist = input_hist
407
408 # Set input prompt strings and colors
409 if cache_size == 0:
410 if ps1.find('%n') > -1 or ps1.find('\\#') > -1: ps1 = '>>> '
411 if ps2.find('%n') > -1 or ps2.find('\\#') > -1: ps2 = '... '
412 self.ps1_str = self._set_prompt_str(ps1,'In [\\#]: ','>>> ')
413 self.ps2_str = self._set_prompt_str(ps2,' .\\D.: ','... ')
414 self.ps_out_str = self._set_prompt_str(ps_out,'Out[\\#]: ','')
415
416 self.prompt1 = Prompt1(self,sep=input_sep,prompt=self.ps1_str,
417 pad_left=pad_left)
418 self.prompt2 = Prompt2(self,prompt=self.ps2_str,pad_left=pad_left)
419 self.prompt_out = PromptOut(self,sep='',prompt=self.ps_out_str,
420 pad_left=pad_left)
421 self.color_table = PromptColors
422 self.set_colors(colors)
423
424 # other more normal stuff
425 # b/c each call to the In[] prompt raises it by 1, even the first.
426 self.prompt_count = 0
427 self.cache_count = 1
428 # Store the last prompt string each time, we need it for aligning
429 # continuation and auto-rewrite prompts
430 self.last_prompt = ''
431 self.entries = [None] # output counter starts at 1 for the user
432 self.Pprint = Pprint
433 self.output_sep = output_sep
434 self.output_sep2 = output_sep2
435 self._,self.__,self.___ = '','',''
436 self.pprint_types = map(type,[(),[],{}])
437
438 # these are deliberately global:
439 to_user_ns = {'_':self._,'__':self.__,'___':self.___}
440 self.user_ns.update(to_user_ns)
441
442 def _set_prompt_str(self,p_str,cache_def,no_cache_def):
443 if p_str is None:
444 if self.do_full_cache:
445 return cache_def
446 else:
447 return no_cache_def
448 else:
449 return p_str
450
451 def set_colors(self,colors):
452 """Set the active color scheme and configure colors for the three
453 prompt subsystems."""
454
455 # FIXME: the prompt_specials global should be gobbled inside this
456 # class instead. Do it when cleaning up the whole 3-prompt system.
457 global prompt_specials
458 if colors.lower()=='nocolor':
459 prompt_specials = prompt_specials_nocolor
460 else:
461 prompt_specials = prompt_specials_color
462
463 self.color_table.set_active_scheme(colors)
464 self.prompt1.set_colors()
465 self.prompt2.set_colors()
466 self.prompt_out.set_colors()
467
468 def __call__(self,arg=None):
469 """Printing with history cache management.
470
471 This is invoked everytime the interpreter needs to print, and is
472 activated by setting the variable sys.displayhook to it."""
473
474 # If something injected a '_' variable in __builtin__, delete
475 # ipython's automatic one so we don't clobber that. gettext() in
476 # particular uses _, so we need to stay away from it.
477 if '_' in __builtin__.__dict__:
478 try:
479 del self.user_ns['_']
480 except KeyError:
481 pass
482 if arg is not None:
483 # first handle the cache and counters
484 self.update(arg)
485 # do not print output if input ends in ';'
486 if self.input_hist[self.prompt_count].endswith(';\n'):
487 return
488 # don't use print, puts an extra space
489 Term.cout.write(self.output_sep)
490 if self.do_full_cache:
491 Term.cout.write(str(self.prompt_out))
492
493 if isinstance(arg,Macro):
494 print 'Executing Macro...'
495 # in case the macro takes a long time to execute
496 Term.cout.flush()
497 exec arg.value in self.user_ns
498 return None
499
500 # and now call a possibly user-defined print mechanism
501 self.display(arg)
502 Term.cout.write(self.output_sep2)
503 Term.cout.flush()
504
505 def _display(self,arg):
506 """Default printer method, uses pprint.
507
508 This can be over-ridden by the users to implement special formatting
509 of certain types of output."""
510
511 if self.Pprint:
512 # The following is an UGLY kludge, b/c python fails to properly
513 # identify instances of classes imported in the user namespace
514 # (they have different memory locations, I guess). Structs are
515 # essentially dicts but pprint doesn't know what to do with them.
516 try:
517 if arg.__class__.__module__ == 'Struct' and \
518 arg.__class__.__name__ == 'Struct':
519 out = 'Struct:\n%s' % pformat(arg.dict())
520 else:
521 out = pformat(arg)
522 except:
523 out = pformat(arg)
524 if '\n' in out:
525 # So that multi-line strings line up with the left column of
526 # the screen, instead of having the output prompt mess up
527 # their first line.
528 Term.cout.write('\n')
529 print >>Term.cout, out
530 else:
531 print >>Term.cout, arg
532
533 # Assign the default display method:
534 display = _display
535
536 def update(self,arg):
537 #print '***cache_count', self.cache_count # dbg
538 if self.cache_count >= self.cache_size and self.do_full_cache:
539 self.flush()
540 # Don't overwrite '_' and friends if '_' is in __builtin__ (otherwise
541 # we cause buggy behavior for things like gettext).
542 if '_' not in __builtin__.__dict__:
543 self.___ = self.__
544 self.__ = self._
545 self._ = arg
546 self.user_ns.update({'_':self._,'__':self.__,'___':self.___})
547
548 # hackish access to top-level namespace to create _1,_2... dynamically
549 to_main = {}
550 if self.do_full_cache:
551 self.cache_count += 1
552 self.entries.append(arg)
553 new_result = '_'+`self.prompt_count`
554 to_main[new_result] = self.entries[-1]
555 self.user_ns.update(to_main)
556 self.user_ns['_oh'][self.prompt_count] = arg
557
558 def flush(self):
559 if not self.do_full_cache:
560 raise ValueError,"You shouldn't have reached the cache flush "\
561 "if full caching is not enabled!"
562 warn('Output cache limit (currently '+\
563 `self.cache_count`+' entries) hit.\n'
564 'Flushing cache and resetting history counter...\n'
565 'The only history variables available will be _,__,___ and _1\n'
566 'with the current result.')
567 # delete auto-generated vars from global namespace
568 for n in range(1,self.prompt_count + 1):
569 key = '_'+`n`
570 try:
571 del self.user_ns[key]
572 except: pass
573 self.prompt_count = 1
574 self.cache_count = 1
@@ -0,0 +1,255 b''
1 # -*- coding: utf-8 -*-
2 """
3 Class and program to colorize python source code for ANSI terminals.
4
5 Based on an HTML code highlighter by Jurgen Hermann found at:
6 http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52298
7
8 Modifications by Fernando Perez (fperez@colorado.edu).
9
10 Information on the original HTML highlighter follows:
11
12 MoinMoin - Python Source Parser
13
14 Title:olorize Python source using the built-in tokenizer
15
16 Submitter: Jurgen Hermann
17 Last Updated:2001/04/06
18
19 Version no:1.2
20
21 Description:
22
23 This code is part of MoinMoin (http://moin.sourceforge.net/) and converts
24 Python source code to HTML markup, rendering comments, keywords,
25 operators, numeric and string literals in different colors.
26
27 It shows how to use the built-in keyword, token and tokenize modules to
28 scan Python source code and re-emit it with no changes to its original
29 formatting (which is the hard part).
30
31 $Id: PyColorize.py 485 2005-01-27 19:15:39Z fperez $"""
32
33 __all__ = ['ANSICodeColors','Parser']
34
35 _scheme_default = 'Linux'
36
37 # Imports
38 import string, sys, os, cStringIO
39 import keyword, token, tokenize
40
41 from IPython.ColorANSI import *
42
43 #############################################################################
44 ### Python Source Parser (does Hilighting)
45 #############################################################################
46
47 _KEYWORD = token.NT_OFFSET + 1
48 _TEXT = token.NT_OFFSET + 2
49
50 #****************************************************************************
51 # Builtin color schemes
52
53 Colors = TermColors # just a shorthand
54
55 # Build a few color schemes
56 NoColor = ColorScheme(
57 'NoColor',{
58 token.NUMBER : Colors.NoColor,
59 token.OP : Colors.NoColor,
60 token.STRING : Colors.NoColor,
61 tokenize.COMMENT : Colors.NoColor,
62 token.NAME : Colors.NoColor,
63 token.ERRORTOKEN : Colors.NoColor,
64
65 _KEYWORD : Colors.NoColor,
66 _TEXT : Colors.NoColor,
67
68 'normal' : Colors.NoColor # color off (usu. Colors.Normal)
69 } )
70
71 LinuxColors = ColorScheme(
72 'Linux',{
73 token.NUMBER : Colors.LightCyan,
74 token.OP : Colors.Yellow,
75 token.STRING : Colors.LightBlue,
76 tokenize.COMMENT : Colors.LightRed,
77 token.NAME : Colors.White,
78 token.ERRORTOKEN : Colors.Red,
79
80 _KEYWORD : Colors.LightGreen,
81 _TEXT : Colors.Yellow,
82
83 'normal' : Colors.Normal # color off (usu. Colors.Normal)
84 } )
85
86 LightBGColors = ColorScheme(
87 'LightBG',{
88 token.NUMBER : Colors.Cyan,
89 token.OP : Colors.Blue,
90 token.STRING : Colors.Blue,
91 tokenize.COMMENT : Colors.Red,
92 token.NAME : Colors.Black,
93 token.ERRORTOKEN : Colors.Red,
94
95 _KEYWORD : Colors.Green,
96 _TEXT : Colors.Blue,
97
98 'normal' : Colors.Normal # color off (usu. Colors.Normal)
99 } )
100
101 # Build table of color schemes (needed by the parser)
102 ANSICodeColors = ColorSchemeTable([NoColor,LinuxColors,LightBGColors],
103 _scheme_default)
104
105 class Parser:
106 """ Format colored Python source.
107 """
108
109 def __init__(self, color_table=None,out = sys.stdout):
110 """ Create a parser with a specified color table and output channel.
111
112 Call format() to process code.
113 """
114 self.color_table = color_table and color_table or ANSICodeColors
115 self.out = out
116
117 def format(self, raw, out = None, scheme = ''):
118 """ Parse and send the colored source.
119
120 If out and scheme are not specified, the defaults (given to
121 constructor) are used.
122
123 out should be a file-type object. Optionally, out can be given as the
124 string 'str' and the parser will automatically return the output in a
125 string."""
126
127 self.raw = string.strip(string.expandtabs(raw))
128 string_output = 0
129 if out == 'str' or self.out == 'str':
130 out_old = self.out
131 self.out = cStringIO.StringIO()
132 string_output = 1
133 elif out is not None:
134 self.out = out
135 # local shorthand
136 colors = self.color_table[scheme].colors
137 self.colors = colors # put in object so __call__ sees it
138 # store line offsets in self.lines
139 self.lines = [0, 0]
140 pos = 0
141 while 1:
142 pos = string.find(self.raw, '\n', pos) + 1
143 if not pos: break
144 self.lines.append(pos)
145 self.lines.append(len(self.raw))
146
147 # parse the source and write it
148 self.pos = 0
149 text = cStringIO.StringIO(self.raw)
150 #self.out.write('<pre><font face="Courier New">')
151 try:
152 tokenize.tokenize(text.readline, self)
153 except tokenize.TokenError, ex:
154 msg = ex[0]
155 line = ex[1][0]
156 self.out.write("%s\n\n*** ERROR: %s%s%s\n" %
157 (colors[token.ERRORTOKEN],
158 msg, self.raw[self.lines[line]:],
159 colors.normal)
160 )
161 self.out.write(colors.normal+'\n')
162 if string_output:
163 output = self.out.getvalue()
164 self.out = out_old
165 return output
166
167 def __call__(self, toktype, toktext, (srow,scol), (erow,ecol), line):
168 """ Token handler, with syntax highlighting."""
169
170 # local shorthand
171 colors = self.colors
172
173 # line separator, so this works across platforms
174 linesep = os.linesep
175
176 # calculate new positions
177 oldpos = self.pos
178 newpos = self.lines[srow] + scol
179 self.pos = newpos + len(toktext)
180
181 # handle newlines
182 if toktype in [token.NEWLINE, tokenize.NL]:
183 self.out.write(linesep)
184 return
185
186 # send the original whitespace, if needed
187 if newpos > oldpos:
188 self.out.write(self.raw[oldpos:newpos])
189
190 # skip indenting tokens
191 if toktype in [token.INDENT, token.DEDENT]:
192 self.pos = newpos
193 return
194
195 # map token type to a color group
196 if token.LPAR <= toktype and toktype <= token.OP:
197 toktype = token.OP
198 elif toktype == token.NAME and keyword.iskeyword(toktext):
199 toktype = _KEYWORD
200 color = colors.get(toktype, colors[_TEXT])
201
202 #print '<%s>' % toktext, # dbg
203
204 # Triple quoted strings must be handled carefully so that backtracking
205 # in pagers works correctly. We need color terminators on _each_ line.
206 if linesep in toktext:
207 toktext = toktext.replace(linesep, '%s%s%s' %
208 (colors.normal,linesep,color))
209
210 # send text
211 self.out.write('%s%s%s' % (color,toktext,colors.normal))
212
213 def main():
214 """Colorize a python file using ANSI color escapes and print to stdout.
215
216 Usage:
217 %s [-s scheme] filename
218
219 Options:
220
221 -s scheme: give the color scheme to use. Currently only 'Linux'
222 (default) and 'LightBG' and 'NoColor' are implemented (give without
223 quotes). """
224
225 def usage():
226 print >> sys.stderr, main.__doc__ % sys.argv[0]
227 sys.exit(1)
228
229 # FIXME: rewrite this to at least use getopt
230 try:
231 if sys.argv[1] == '-s':
232 scheme_name = sys.argv[2]
233 del sys.argv[1:3]
234 else:
235 scheme_name = _scheme_default
236
237 except:
238 usage()
239
240 try:
241 fname = sys.argv[1]
242 except:
243 usage()
244
245 # write colorized version to stdout
246 parser = Parser()
247 try:
248 parser.format(file(fname).read(),scheme = scheme_name)
249 except IOError,msg:
250 # if user reads through a pager and quits, don't print traceback
251 if msg.args != (32,'Broken pipe'):
252 raise
253
254 if __name__ == "__main__":
255 main()
@@ -0,0 +1,69 b''
1 # -*- coding: utf-8 -*-
2 """Release data for the IPython project.
3
4 $Id: Release.py 605 2005-06-09 14:09:03Z fperez $"""
5
6 #*****************************************************************************
7 # Copyright (C) 2001-2005 Fernando Perez <fperez@colorado.edu>
8 #
9 # Copyright (c) 2001 Janko Hauser <jhauser@zscout.de> and Nathaniel Gray
10 # <n8gray@caltech.edu>
11 #
12 # Distributed under the terms of the BSD License. The full license is in
13 # the file COPYING, distributed as part of this software.
14 #*****************************************************************************
15
16 # Name of the package for release purposes. This is the name which labels
17 # the tarballs and RPMs made by distutils, so it's best to lowercase it.
18 name = 'ipython'
19
20 # For versions with substrings (like 0.6.7_rc1), use _ but NOT -, since
21 # bdist_rpm chokes on dashes in the version string.
22 version = '0.6.16_cvs'
23
24 description = "An enhanced interactive Python shell."
25
26 long_description = \
27 """
28 IPython provides a replacement for the interactive Python interpreter with
29 extra functionality.
30
31 Main features:
32
33 * Comprehensive object introspection.
34
35 * Input history, persistent across sessions.
36
37 * Caching of output results during a session with automatically generated
38 references.
39
40 * Readline based name completion.
41
42 * Extensible system of 'magic' commands for controlling the environment and
43 performing many tasks related either to IPython or the operating system.
44
45 * Configuration system with easy switching between different setups (simpler
46 than changing $PYTHONSTARTUP environment variables every time).
47
48 * Session logging and reloading.
49
50 * Extensible syntax processing for special purpose situations.
51
52 * Access to the system shell with user-extensible alias system.
53
54 * Easily embeddable in other Python programs.
55
56 * Integrated access to the pdb debugger and the Python profiler. """
57
58 license = 'BSD'
59
60 authors = {'Fernando' : ('Fernando Perez','fperez@colorado.edu'),
61 'Janko' : ('Janko Hauser','jhauser@zscout.de'),
62 'Nathan' : ('Nathaniel Gray','n8gray@caltech.edu')
63 }
64
65 url = 'http://ipython.scipy.org'
66
67 platforms = ['Linux','Mac OSX','Windows XP/2000/NT','Windows 95/98/ME']
68
69 keywords = ['Interactive','Interpreter','Shell']
This diff has been collapsed as it changes many lines, (894 lines changed) Show them Hide them
@@ -0,0 +1,894 b''
1 # -*- coding: utf-8 -*-
2 """IPython Shell classes.
3
4 All the matplotlib support code was co-developed with John Hunter,
5 matplotlib's author.
6
7 $Id: Shell.py 605 2005-06-09 14:09:03Z fperez $"""
8
9 #*****************************************************************************
10 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
11 #
12 # Distributed under the terms of the BSD License. The full license is in
13 # the file COPYING, distributed as part of this software.
14 #*****************************************************************************
15
16 from IPython import Release
17 __author__ = '%s <%s>' % Release.authors['Fernando']
18 __license__ = Release.license
19
20 # Code begins
21 import __main__
22 import __builtin__
23 import sys
24 import os
25 import code
26 import threading
27 import signal
28
29 import IPython
30 from IPython.iplib import InteractiveShell
31 from IPython.ipmaker import make_IPython
32 from IPython.genutils import Term,warn,error,flag_calls
33 from IPython.Struct import Struct
34 from IPython.Magic import Magic
35 from IPython import ultraTB
36
37 # global flag to pass around information about Ctrl-C without exceptions
38 KBINT = False
39
40 # global flag to turn on/off Tk support.
41 USE_TK = False
42
43 #-----------------------------------------------------------------------------
44 # This class is trivial now, but I want to have it in to publish a clean
45 # interface. Later when the internals are reorganized, code that uses this
46 # shouldn't have to change.
47
48 class IPShell:
49 """Create an IPython instance."""
50
51 def __init__(self,argv=None,user_ns=None,debug=1,
52 shell_class=InteractiveShell):
53 self.IP = make_IPython(argv,user_ns=user_ns,debug=debug,
54 shell_class=shell_class)
55
56 def mainloop(self,sys_exit=0,banner=None):
57 self.IP.mainloop(banner)
58 if sys_exit:
59 sys.exit()
60
61 #-----------------------------------------------------------------------------
62 class IPShellEmbed:
63 """Allow embedding an IPython shell into a running program.
64
65 Instances of this class are callable, with the __call__ method being an
66 alias to the embed() method of an InteractiveShell instance.
67
68 Usage (see also the example-embed.py file for a running example):
69
70 ipshell = IPShellEmbed([argv,banner,exit_msg,rc_override])
71
72 - argv: list containing valid command-line options for IPython, as they
73 would appear in sys.argv[1:].
74
75 For example, the following command-line options:
76
77 $ ipython -prompt_in1 'Input <\\#>' -colors LightBG
78
79 would be passed in the argv list as:
80
81 ['-prompt_in1','Input <\\#>','-colors','LightBG']
82
83 - banner: string which gets printed every time the interpreter starts.
84
85 - exit_msg: string which gets printed every time the interpreter exits.
86
87 - rc_override: a dict or Struct of configuration options such as those
88 used by IPython. These options are read from your ~/.ipython/ipythonrc
89 file when the Shell object is created. Passing an explicit rc_override
90 dict with any options you want allows you to override those values at
91 creation time without having to modify the file. This way you can create
92 embeddable instances configured in any way you want without editing any
93 global files (thus keeping your interactive IPython configuration
94 unchanged).
95
96 Then the ipshell instance can be called anywhere inside your code:
97
98 ipshell(header='') -> Opens up an IPython shell.
99
100 - header: string printed by the IPython shell upon startup. This can let
101 you know where in your code you are when dropping into the shell. Note
102 that 'banner' gets prepended to all calls, so header is used for
103 location-specific information.
104
105 For more details, see the __call__ method below.
106
107 When the IPython shell is exited with Ctrl-D, normal program execution
108 resumes.
109
110 This functionality was inspired by a posting on comp.lang.python by cmkl
111 <cmkleffner@gmx.de> on Dec. 06/01 concerning similar uses of pyrepl, and
112 by the IDL stop/continue commands."""
113
114 def __init__(self,argv=None,banner='',exit_msg=None,rc_override=None):
115 """Note that argv here is a string, NOT a list."""
116 self.set_banner(banner)
117 self.set_exit_msg(exit_msg)
118 self.set_dummy_mode(0)
119
120 # sys.displayhook is a global, we need to save the user's original
121 # Don't rely on __displayhook__, as the user may have changed that.
122 self.sys_displayhook_ori = sys.displayhook
123
124 # save readline completer status
125 try:
126 #print 'Save completer',sys.ipcompleter # dbg
127 self.sys_ipcompleter_ori = sys.ipcompleter
128 except:
129 pass # not nested with IPython
130
131 # FIXME. Passing user_ns breaks namespace handling.
132 #self.IP = make_IPython(argv,user_ns=__main__.__dict__)
133 self.IP = make_IPython(argv,rc_override=rc_override,embedded=True)
134
135 self.IP.name_space_init()
136 # mark this as an embedded instance so we know if we get a crash
137 # post-mortem
138 self.IP.rc.embedded = 1
139 # copy our own displayhook also
140 self.sys_displayhook_embed = sys.displayhook
141 # and leave the system's display hook clean
142 sys.displayhook = self.sys_displayhook_ori
143 # don't use the ipython crash handler so that user exceptions aren't
144 # trapped
145 sys.excepthook = ultraTB.FormattedTB(color_scheme = self.IP.rc.colors,
146 mode = self.IP.rc.xmode,
147 call_pdb = self.IP.rc.pdb)
148 self.restore_system_completer()
149
150 def restore_system_completer(self):
151 """Restores the readline completer which was in place.
152
153 This allows embedded IPython within IPython not to disrupt the
154 parent's completion.
155 """
156
157 try:
158 self.IP.readline.set_completer(self.sys_ipcompleter_ori)
159 sys.ipcompleter = self.sys_ipcompleter_ori
160 except:
161 pass
162
163 def __call__(self,header='',local_ns=None,global_ns=None,dummy=None):
164 """Activate the interactive interpreter.
165
166 __call__(self,header='',local_ns=None,global_ns,dummy=None) -> Start
167 the interpreter shell with the given local and global namespaces, and
168 optionally print a header string at startup.
169
170 The shell can be globally activated/deactivated using the
171 set/get_dummy_mode methods. This allows you to turn off a shell used
172 for debugging globally.
173
174 However, *each* time you call the shell you can override the current
175 state of dummy_mode with the optional keyword parameter 'dummy'. For
176 example, if you set dummy mode on with IPShell.set_dummy_mode(1), you
177 can still have a specific call work by making it as IPShell(dummy=0).
178
179 The optional keyword parameter dummy controls whether the call
180 actually does anything. """
181
182 # Allow the dummy parameter to override the global __dummy_mode
183 if dummy or (dummy != 0 and self.__dummy_mode):
184 return
185
186 # Set global subsystems (display,completions) to our values
187 sys.displayhook = self.sys_displayhook_embed
188 if self.IP.has_readline:
189 self.IP.readline.set_completer(self.IP.Completer.complete)
190
191 if self.banner and header:
192 format = '%s\n%s\n'
193 else:
194 format = '%s%s\n'
195 banner = format % (self.banner,header)
196
197 # Call the embedding code with a stack depth of 1 so it can skip over
198 # our call and get the original caller's namespaces.
199 self.IP.embed_mainloop(banner,local_ns,global_ns,stack_depth=1)
200
201 if self.exit_msg:
202 print self.exit_msg
203
204 # Restore global systems (display, completion)
205 sys.displayhook = self.sys_displayhook_ori
206 self.restore_system_completer()
207
208 def set_dummy_mode(self,dummy):
209 """Sets the embeddable shell's dummy mode parameter.
210
211 set_dummy_mode(dummy): dummy = 0 or 1.
212
213 This parameter is persistent and makes calls to the embeddable shell
214 silently return without performing any action. This allows you to
215 globally activate or deactivate a shell you're using with a single call.
216
217 If you need to manually"""
218
219 if dummy not in [0,1]:
220 raise ValueError,'dummy parameter must be 0 or 1'
221 self.__dummy_mode = dummy
222
223 def get_dummy_mode(self):
224 """Return the current value of the dummy mode parameter.
225 """
226 return self.__dummy_mode
227
228 def set_banner(self,banner):
229 """Sets the global banner.
230
231 This banner gets prepended to every header printed when the shell
232 instance is called."""
233
234 self.banner = banner
235
236 def set_exit_msg(self,exit_msg):
237 """Sets the global exit_msg.
238
239 This exit message gets printed upon exiting every time the embedded
240 shell is called. It is None by default. """
241
242 self.exit_msg = exit_msg
243
244 #-----------------------------------------------------------------------------
245 def sigint_handler (signum,stack_frame):
246 """Sigint handler for threaded apps.
247
248 This is a horrible hack to pass information about SIGINT _without_ using
249 exceptions, since I haven't been able to properly manage cross-thread
250 exceptions in GTK/WX. In fact, I don't think it can be done (or at least
251 that's my understanding from a c.l.py thread where this was discussed)."""
252
253 global KBINT
254
255 print '\nKeyboardInterrupt - Press <Enter> to continue.',
256 Term.cout.flush()
257 # Set global flag so that runsource can know that Ctrl-C was hit
258 KBINT = True
259
260 class MTInteractiveShell(InteractiveShell):
261 """Simple multi-threaded shell."""
262
263 # Threading strategy taken from:
264 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/65109, by Brian
265 # McErlean and John Finlay. Modified with corrections by Antoon Pardon,
266 # from the pygtk mailing list, to avoid lockups with system calls.
267
268 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
269 user_ns = None, banner2='',**kw):
270 """Similar to the normal InteractiveShell, but with threading control"""
271
272 IPython.iplib.InteractiveShell.__init__(self,name,usage,rc,user_ns,banner2)
273
274 # Locking control variable
275 self.thread_ready = threading.Condition()
276
277 # Stuff to do at closing time
278 self._kill = False
279 on_kill = kw.get('on_kill')
280 if on_kill is None:
281 on_kill = []
282 # Check that all things to kill are callable:
283 for t in on_kill:
284 if not callable(t):
285 raise TypeError,'on_kill must be a list of callables'
286 self.on_kill = on_kill
287
288 def runsource(self, source, filename="<input>", symbol="single"):
289 """Compile and run some source in the interpreter.
290
291 Modified version of code.py's runsource(), to handle threading issues.
292 See the original for full docstring details."""
293
294 global KBINT
295
296 # If Ctrl-C was typed, we reset the flag and return right away
297 if KBINT:
298 KBINT = False
299 return False
300
301 try:
302 code = self.compile(source, filename, symbol)
303 except (OverflowError, SyntaxError, ValueError):
304 # Case 1
305 self.showsyntaxerror(filename)
306 return False
307
308 if code is None:
309 # Case 2
310 return True
311
312 # Case 3
313 # Store code in self, so the execution thread can handle it
314 self.thread_ready.acquire()
315 self.code_to_run_src = source
316 self.code_to_run = code
317 self.thread_ready.wait() # Wait until processed in timeout interval
318 self.thread_ready.release()
319
320 return False
321
322 def runcode(self):
323 """Execute a code object.
324
325 Multithreaded wrapper around IPython's runcode()."""
326
327 # lock thread-protected stuff
328 self.thread_ready.acquire()
329
330 # Install sigint handler
331 try:
332 signal.signal(signal.SIGINT, sigint_handler)
333 except SystemError:
334 # This happens under Windows, which seems to have all sorts
335 # of problems with signal handling. Oh well...
336 pass
337
338 if self._kill:
339 print >>Term.cout, 'Closing threads...',
340 Term.cout.flush()
341 for tokill in self.on_kill:
342 tokill()
343 print >>Term.cout, 'Done.'
344
345 # Run pending code by calling parent class
346 if self.code_to_run is not None:
347 self.thread_ready.notify()
348 InteractiveShell.runcode(self,self.code_to_run)
349
350 # We're done with thread-protected variables
351 self.thread_ready.release()
352 # This MUST return true for gtk threading to work
353 return True
354
355 def kill (self):
356 """Kill the thread, returning when it has been shut down."""
357 self.thread_ready.acquire()
358 self._kill = True
359 self.thread_ready.release()
360
361 class MatplotlibShellBase:
362 """Mixin class to provide the necessary modifications to regular IPython
363 shell classes for matplotlib support.
364
365 Given Python's MRO, this should be used as the FIRST class in the
366 inheritance hierarchy, so that it overrides the relevant methods."""
367
368 def _matplotlib_config(self,name):
369 """Return various items needed to setup the user's shell with matplotlib"""
370
371 # Initialize matplotlib to interactive mode always
372 import matplotlib
373 from matplotlib import backends
374 matplotlib.interactive(True)
375
376 def use(arg):
377 """IPython wrapper for matplotlib's backend switcher.
378
379 In interactive use, we can not allow switching to a different
380 interactive backend, since thread conflicts will most likely crash
381 the python interpreter. This routine does a safety check first,
382 and refuses to perform a dangerous switch. It still allows
383 switching to non-interactive backends."""
384
385 if arg in backends.interactive_bk and arg != self.mpl_backend:
386 m=('invalid matplotlib backend switch.\n'
387 'This script attempted to switch to the interactive '
388 'backend: `%s`\n'
389 'Your current choice of interactive backend is: `%s`\n\n'
390 'Switching interactive matplotlib backends at runtime\n'
391 'would crash the python interpreter, '
392 'and IPython has blocked it.\n\n'
393 'You need to either change your choice of matplotlib backend\n'
394 'by editing your .matplotlibrc file, or run this script as a \n'
395 'standalone file from the command line, not using IPython.\n' %
396 (arg,self.mpl_backend) )
397 raise RuntimeError, m
398 else:
399 self.mpl_use(arg)
400 self.mpl_use._called = True
401
402 self.matplotlib = matplotlib
403
404 # Take control of matplotlib's error handling, which can normally
405 # lock up the python interpreter when raw_input() is called
406 import matplotlib.backends as backend
407 backend.error_msg = error
408
409 # we'll handle the mainloop, tell show not to
410 import matplotlib.backends
411 matplotlib.backends.show._needmain = False
412 self.mpl_backend = matplotlib.rcParams['backend']
413
414 # we also need to block switching of interactive backends by use()
415 self.mpl_use = matplotlib.use
416 self.mpl_use._called = False
417 # overwrite the original matplotlib.use with our wrapper
418 matplotlib.use = use
419
420 # We need to detect at runtime whether show() is called by the user.
421 # For this, we wrap it into a decorator which adds a 'called' flag.
422 backend.draw_if_interactive = flag_calls(backend.draw_if_interactive)
423
424 # This must be imported last in the matplotlib series, after
425 # backend/interactivity choices have been made
426 try:
427 import matplotlib.pylab as pylab
428 self.pylab = pylab
429 self.pylab_name = 'pylab'
430 except ImportError:
431 import matplotlib.matlab as matlab
432 self.pylab = matlab
433 self.pylab_name = 'matlab'
434
435 # Build a user namespace initialized with matplotlib/matlab features.
436 user_ns = {'__name__':'__main__',
437 '__builtins__' : __builtin__ }
438
439 # Be careful not to remove the final \n in the code string below, or
440 # things will break badly with py22 (I think it's a python bug, 2.3 is
441 # OK).
442 pname = self.pylab_name # Python can't interpolate dotted var names
443 exec ("import matplotlib\n"
444 "import matplotlib.%(pname)s as %(pname)s\n"
445 "from matplotlib.%(pname)s import *\n" % locals()) in user_ns
446
447 # Build matplotlib info banner
448 b="""
449 Welcome to pylab, a matplotlib-based Python environment.
450 For more information, type 'help(pylab)'.
451 """
452 return user_ns,b
453
454 def mplot_exec(self,fname,*where,**kw):
455 """Execute a matplotlib script.
456
457 This is a call to execfile(), but wrapped in safeties to properly
458 handle interactive rendering and backend switching."""
459
460 #print '*** Matplotlib runner ***' # dbg
461 # turn off rendering until end of script
462 isInteractive = self.matplotlib.rcParams['interactive']
463 self.matplotlib.interactive(False)
464 self.safe_execfile(fname,*where,**kw)
465 self.matplotlib.interactive(isInteractive)
466 # make rendering call now, if the user tried to do it
467 if self.pylab.draw_if_interactive.called:
468 self.pylab.draw()
469 self.pylab.draw_if_interactive.called = False
470
471 # if a backend switch was performed, reverse it now
472 if self.mpl_use._called:
473 self.matplotlib.rcParams['backend'] = self.mpl_backend
474
475 def magic_run(self,parameter_s=''):
476 Magic.magic_run(self,parameter_s,runner=self.mplot_exec)
477
478 # Fix the docstring so users see the original as well
479 magic_run.__doc__ = "%s\n%s" % (Magic.magic_run.__doc__,
480 "\n *** Modified %run for Matplotlib,"
481 " with proper interactive handling ***")
482
483 # Now we provide 2 versions of a matplotlib-aware IPython base shells, single
484 # and multithreaded. Note that these are meant for internal use, the IPShell*
485 # classes below are the ones meant for public consumption.
486
487 class MatplotlibShell(MatplotlibShellBase,InteractiveShell):
488 """Single-threaded shell with matplotlib support."""
489
490 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
491 user_ns = None, **kw):
492 user_ns,b2 = self._matplotlib_config(name)
493 InteractiveShell.__init__(self,name,usage,rc,user_ns,banner2=b2,**kw)
494
495 class MatplotlibMTShell(MatplotlibShellBase,MTInteractiveShell):
496 """Multi-threaded shell with matplotlib support."""
497
498 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
499 user_ns = None, **kw):
500 user_ns,b2 = self._matplotlib_config(name)
501 MTInteractiveShell.__init__(self,name,usage,rc,user_ns,banner2=b2,**kw)
502
503 #-----------------------------------------------------------------------------
504 # Utility functions for the different GUI enabled IPShell* classes.
505
506 def get_tk():
507 """Tries to import Tkinter and returns a withdrawn Tkinter root
508 window. If Tkinter is already imported or not available, this
509 returns None. This function calls `hijack_tk` underneath.
510 """
511 if not USE_TK or sys.modules.has_key('Tkinter'):
512 return None
513 else:
514 try:
515 import Tkinter
516 except ImportError:
517 return None
518 else:
519 hijack_tk()
520 r = Tkinter.Tk()
521 r.withdraw()
522 return r
523
524 def hijack_tk():
525 """Modifies Tkinter's mainloop with a dummy so when a module calls
526 mainloop, it does not block.
527
528 """
529 def misc_mainloop(self, n=0):
530 pass
531 def tkinter_mainloop(n=0):
532 pass
533
534 import Tkinter
535 Tkinter.Misc.mainloop = misc_mainloop
536 Tkinter.mainloop = tkinter_mainloop
537
538 def update_tk(tk):
539 """Updates the Tkinter event loop. This is typically called from
540 the respective WX or GTK mainloops.
541 """
542 if tk:
543 tk.update()
544
545 def hijack_wx():
546 """Modifies wxPython's MainLoop with a dummy so user code does not
547 block IPython. The hijacked mainloop function is returned.
548 """
549 def dummy_mainloop(*args, **kw):
550 pass
551 import wxPython
552 ver = wxPython.__version__
553 orig_mainloop = None
554 if ver[:3] >= '2.5':
555 import wx
556 if hasattr(wx, '_core_'): core = getattr(wx, '_core_')
557 elif hasattr(wx, '_core'): core = getattr(wx, '_core')
558 else: raise AttributeError('Could not find wx core module')
559 orig_mainloop = core.PyApp_MainLoop
560 core.PyApp_MainLoop = dummy_mainloop
561 elif ver[:3] == '2.4':
562 orig_mainloop = wxPython.wxc.wxPyApp_MainLoop
563 wxPython.wxc.wxPyApp_MainLoop = dummy_mainloop
564 else:
565 warn("Unable to find either wxPython version 2.4 or >= 2.5.")
566 return orig_mainloop
567
568 def hijack_gtk():
569 """Modifies pyGTK's mainloop with a dummy so user code does not
570 block IPython. This function returns the original `gtk.mainloop`
571 function that has been hijacked.
572
573 NOTE: Make sure you import this *AFTER* you call
574 pygtk.require(...).
575 """
576 def dummy_mainloop(*args, **kw):
577 pass
578 import gtk
579 if gtk.pygtk_version >= (2,4,0): orig_mainloop = gtk.main
580 else: orig_mainloop = gtk.mainloop
581 gtk.mainloop = dummy_mainloop
582 gtk.main = dummy_mainloop
583 return orig_mainloop
584
585 #-----------------------------------------------------------------------------
586 # The IPShell* classes below are the ones meant to be run by external code as
587 # IPython instances. Note that unless a specific threading strategy is
588 # desired, the factory function start() below should be used instead (it
589 # selects the proper threaded class).
590
591 class IPShellGTK(threading.Thread):
592 """Run a gtk mainloop() in a separate thread.
593
594 Python commands can be passed to the thread where they will be executed.
595 This is implemented by periodically checking for passed code using a
596 GTK timeout callback."""
597
598 TIMEOUT = 100 # Millisecond interval between timeouts.
599
600 def __init__(self,argv=None,user_ns=None,debug=1,
601 shell_class=MTInteractiveShell):
602
603 import pygtk
604 pygtk.require("2.0")
605 import gtk
606
607 self.gtk = gtk
608 self.gtk_mainloop = hijack_gtk()
609
610 # Allows us to use both Tk and GTK.
611 self.tk = get_tk()
612
613 if gtk.pygtk_version >= (2,4,0): mainquit = self.gtk.main_quit
614 else: mainquit = self.gtk.mainquit
615
616 self.IP = make_IPython(argv,user_ns=user_ns,debug=debug,
617 shell_class=shell_class,
618 on_kill=[mainquit])
619 threading.Thread.__init__(self)
620
621 def run(self):
622 self.IP.mainloop()
623 self.IP.kill()
624
625 def mainloop(self):
626
627 if self.gtk.pygtk_version >= (2,4,0):
628 import gobject
629 gobject.timeout_add(self.TIMEOUT, self.on_timer)
630 else:
631 self.gtk.timeout_add(self.TIMEOUT, self.on_timer)
632
633 if sys.platform != 'win32':
634 try:
635 if self.gtk.gtk_version[0] >= 2:
636 self.gtk.threads_init()
637 except AttributeError:
638 pass
639 except RuntimeError:
640 error('Your pyGTK likely has not been compiled with '
641 'threading support.\n'
642 'The exception printout is below.\n'
643 'You can either rebuild pyGTK with threads, or '
644 'try using \n'
645 'matplotlib with a different backend (like Tk or WX).\n'
646 'Note that matplotlib will most likely not work in its '
647 'current state!')
648 self.IP.InteractiveTB()
649 self.start()
650 self.gtk.threads_enter()
651 self.gtk_mainloop()
652 self.gtk.threads_leave()
653 self.join()
654
655 def on_timer(self):
656 update_tk(self.tk)
657 return self.IP.runcode()
658
659
660 class IPShellWX(threading.Thread):
661 """Run a wx mainloop() in a separate thread.
662
663 Python commands can be passed to the thread where they will be executed.
664 This is implemented by periodically checking for passed code using a
665 GTK timeout callback."""
666
667 TIMEOUT = 100 # Millisecond interval between timeouts.
668
669 def __init__(self,argv=None,user_ns=None,debug=1,
670 shell_class=MTInteractiveShell):
671
672 import wxPython.wx as wx
673
674 threading.Thread.__init__(self)
675 self.wx = wx
676 self.wx_mainloop = hijack_wx()
677
678 # Allows us to use both Tk and GTK.
679 self.tk = get_tk()
680
681 self.IP = make_IPython(argv,user_ns=user_ns,debug=debug,
682 shell_class=shell_class,
683 on_kill=[self.wxexit])
684 self.app = None
685
686 def wxexit(self, *args):
687 if self.app is not None:
688 self.app.agent.timer.Stop()
689 self.app.ExitMainLoop()
690
691 def run(self):
692 self.IP.mainloop()
693 self.IP.kill()
694
695 def mainloop(self):
696
697 self.start()
698
699 class TimerAgent(self.wx.wxMiniFrame):
700 wx = self.wx
701 IP = self.IP
702 tk = self.tk
703 def __init__(self, parent, interval):
704 style = self.wx.wxDEFAULT_FRAME_STYLE | self.wx.wxTINY_CAPTION_HORIZ
705 self.wx.wxMiniFrame.__init__(self, parent, -1, ' ', pos=(200, 200),
706 size=(100, 100),style=style)
707 self.Show(False)
708 self.interval = interval
709 self.timerId = self.wx.wxNewId()
710
711 def StartWork(self):
712 self.timer = self.wx.wxTimer(self, self.timerId)
713 self.wx.EVT_TIMER(self, self.timerId, self.OnTimer)
714 self.timer.Start(self.interval)
715
716 def OnTimer(self, event):
717 update_tk(self.tk)
718 self.IP.runcode()
719
720 class App(self.wx.wxApp):
721 wx = self.wx
722 TIMEOUT = self.TIMEOUT
723 def OnInit(self):
724 'Create the main window and insert the custom frame'
725 self.agent = TimerAgent(None, self.TIMEOUT)
726 self.agent.Show(self.wx.false)
727 self.agent.StartWork()
728 return self.wx.true
729
730 self.app = App(redirect=False)
731 self.wx_mainloop(self.app)
732 self.join()
733
734
735 class IPShellQt(threading.Thread):
736 """Run a Qt event loop in a separate thread.
737
738 Python commands can be passed to the thread where they will be executed.
739 This is implemented by periodically checking for passed code using a
740 Qt timer / slot."""
741
742 TIMEOUT = 100 # Millisecond interval between timeouts.
743
744 def __init__(self,argv=None,user_ns=None,debug=0,
745 shell_class=MTInteractiveShell):
746
747 import qt
748
749 class newQApplication:
750 def __init__( self ):
751 self.QApplication = qt.QApplication
752
753 def __call__( *args, **kwargs ):
754 return qt.qApp
755
756 def exec_loop( *args, **kwargs ):
757 pass
758
759 def __getattr__( self, name ):
760 return getattr( self.QApplication, name )
761
762 qt.QApplication = newQApplication()
763
764 # Allows us to use both Tk and QT.
765 self.tk = get_tk()
766
767 self.IP = make_IPython(argv,user_ns=user_ns,debug=debug,
768 shell_class=shell_class,
769 on_kill=[qt.qApp.exit])
770
771 threading.Thread.__init__(self)
772
773 def run(self):
774 #sys.excepthook = self.IP.excepthook # dbg
775 self.IP.mainloop()
776 self.IP.kill()
777
778 def mainloop(self):
779 import qt, sys
780 if qt.QApplication.startingUp():
781 a = qt.QApplication.QApplication( sys.argv )
782 self.timer = qt.QTimer()
783 qt.QObject.connect( self.timer, qt.SIGNAL( 'timeout()' ), self.on_timer )
784
785 self.start()
786 self.timer.start( self.TIMEOUT, True )
787 while True:
788 if self.IP._kill: break
789 qt.qApp.exec_loop()
790 self.join()
791
792 def on_timer(self):
793 update_tk(self.tk)
794 result = self.IP.runcode()
795 self.timer.start( self.TIMEOUT, True )
796 return result
797
798 # A set of matplotlib public IPython shell classes, for single-threaded
799 # (Tk* and FLTK* backends) and multithreaded (GTK* and WX* backends) use.
800 class IPShellMatplotlib(IPShell):
801 """Subclass IPShell with MatplotlibShell as the internal shell.
802
803 Single-threaded class, meant for the Tk* and FLTK* backends.
804
805 Having this on a separate class simplifies the external driver code."""
806
807 def __init__(self,argv=None,user_ns=None,debug=1):
808 IPShell.__init__(self,argv,user_ns,debug,shell_class=MatplotlibShell)
809
810 class IPShellMatplotlibGTK(IPShellGTK):
811 """Subclass IPShellGTK with MatplotlibMTShell as the internal shell.
812
813 Multi-threaded class, meant for the GTK* backends."""
814
815 def __init__(self,argv=None,user_ns=None,debug=1):
816 IPShellGTK.__init__(self,argv,user_ns,debug,shell_class=MatplotlibMTShell)
817
818 class IPShellMatplotlibWX(IPShellWX):
819 """Subclass IPShellWX with MatplotlibMTShell as the internal shell.
820
821 Multi-threaded class, meant for the WX* backends."""
822
823 def __init__(self,argv=None,user_ns=None,debug=1):
824 IPShellWX.__init__(self,argv,user_ns,debug,shell_class=MatplotlibMTShell)
825
826 class IPShellMatplotlibQt(IPShellQt):
827 """Subclass IPShellQt with MatplotlibMTShell as the internal shell.
828
829 Multi-threaded class, meant for the Qt* backends."""
830
831 def __init__(self,argv=None,user_ns=None,debug=1):
832 IPShellQt.__init__(self,argv,user_ns,debug,shell_class=MatplotlibMTShell)
833
834 #-----------------------------------------------------------------------------
835 # Factory functions to actually start the proper thread-aware shell
836
837 def _matplotlib_shell_class():
838 """Factory function to handle shell class selection for matplotlib.
839
840 The proper shell class to use depends on the matplotlib backend, since
841 each backend requires a different threading strategy."""
842
843 try:
844 import matplotlib
845 except ImportError:
846 error('matplotlib could NOT be imported! Starting normal IPython.')
847 sh_class = IPShell
848 else:
849 backend = matplotlib.rcParams['backend']
850 if backend.startswith('GTK'):
851 sh_class = IPShellMatplotlibGTK
852 elif backend.startswith('WX'):
853 sh_class = IPShellMatplotlibWX
854 elif backend.startswith('Qt'):
855 sh_class = IPShellMatplotlibQt
856 else:
857 sh_class = IPShellMatplotlib
858 #print 'Using %s with the %s backend.' % (sh_class,backend) # dbg
859 return sh_class
860
861 # This is the one which should be called by external code.
862 def start():
863 """Return a running shell instance, dealing with threading options.
864
865 This is a factory function which will instantiate the proper IPython shell
866 based on the user's threading choice. Such a selector is needed because
867 different GUI toolkits require different thread handling details."""
868
869 global USE_TK
870 # Crude sys.argv hack to extract the threading options.
871 if len(sys.argv) > 1:
872 if len(sys.argv) > 2:
873 arg2 = sys.argv[2]
874 if arg2.endswith('-tk'):
875 USE_TK = True
876 arg1 = sys.argv[1]
877 if arg1.endswith('-gthread'):
878 shell = IPShellGTK
879 elif arg1.endswith( '-qthread' ):
880 shell = IPShellQt
881 elif arg1.endswith('-wthread'):
882 shell = IPShellWX
883 elif arg1.endswith('-pylab'):
884 shell = _matplotlib_shell_class()
885 else:
886 shell = IPShell
887 else:
888 shell = IPShell
889 return shell()
890
891 # Some aliases for backwards compatibility
892 IPythonShell = IPShell
893 IPythonShellEmbed = IPShellEmbed
894 #************************ End of file <Shell.py> ***************************
@@ -0,0 +1,376 b''
1 # -*- coding: utf-8 -*-
2 """Mimic C structs with lots of extra functionality.
3
4 $Id: Struct.py 410 2004-11-04 07:58:17Z fperez $"""
5
6 #*****************************************************************************
7 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
8 #
9 # Distributed under the terms of the BSD License. The full license is in
10 # the file COPYING, distributed as part of this software.
11 #*****************************************************************************
12
13 from IPython import Release
14 __author__ = '%s <%s>' % Release.authors['Fernando']
15 __license__ = Release.license
16
17 __all__ = ['Struct']
18
19 import types
20 from IPython.genutils import list2dict2
21
22 class Struct:
23 """Class to mimic C structs but also provide convenient dictionary-like
24 functionality.
25
26 Instances can be initialized with a dictionary, a list of key=value pairs
27 or both. If both are present, the dictionary must come first.
28
29 Because Python classes provide direct assignment to their members, it's
30 easy to overwrite normal methods (S.copy = 1 would destroy access to
31 S.copy()). For this reason, all builtin method names are protected and
32 can't be assigned to. An attempt to do s.copy=1 or s['copy']=1 will raise
33 a KeyError exception. If you really want to, you can bypass this
34 protection by directly assigning to __dict__: s.__dict__['copy']=1 will
35 still work. Doing this will break functionality, though. As in most of
36 Python, namespace protection is weakly enforced, so feel free to shoot
37 yourself if you really want to.
38
39 Note that this class uses more memory and is *much* slower than a regular
40 dictionary, so be careful in situations where memory or performance are
41 critical. But for day to day use it should behave fine. It is particularly
42 convenient for storing configuration data in programs.
43
44 +,+=,- and -= are implemented. +/+= do merges (non-destructive updates),
45 -/-= remove keys from the original. See the method descripitions.
46
47 This class allows a quick access syntax: both s.key and s['key'] are
48 valid. This syntax has a limitation: each 'key' has to be explicitly
49 accessed by its original name. The normal s.key syntax doesn't provide
50 access to the keys via variables whose values evaluate to the desired
51 keys. An example should clarify this:
52
53 Define a dictionary and initialize both with dict and k=v pairs:
54 >>> d={'a':1,'b':2}
55 >>> s=Struct(d,hi=10,ho=20)
56 The return of __repr__ can be used to create a new instance:
57 >>> s
58 Struct({'ho': 20, 'b': 2, 'hi': 10, 'a': 1})
59 __str__ (called by print) shows it's not quite a regular dictionary:
60 >>> print s
61 Struct {a: 1, b: 2, hi: 10, ho: 20}
62 Access by explicitly named key with dot notation:
63 >>> s.a
64 1
65 Or like a dictionary:
66 >>> s['a']
67 1
68 If you want a variable to hold the key value, only dictionary access works:
69 >>> key='hi'
70 >>> s.key
71 Traceback (most recent call last):
72 File "<stdin>", line 1, in ?
73 AttributeError: Struct instance has no attribute 'key'
74 >>> s[key]
75 10
76
77 Another limitation of the s.key syntax (and Struct(key=val)
78 initialization): keys can't be numbers. But numeric keys can be used and
79 accessed using the dictionary syntax. Again, an example:
80
81 This doesn't work:
82 >>> s=Struct(4='hi')
83 SyntaxError: keyword can't be an expression
84 But this does:
85 >>> s=Struct()
86 >>> s[4]='hi'
87 >>> s
88 Struct({4: 'hi'})
89 >>> s[4]
90 'hi'
91 """
92
93 # Attributes to which __setitem__ and __setattr__ will block access.
94 # Note: much of this will be moot in Python 2.2 and will be done in a much
95 # cleaner way.
96 __protected = ('copy dict dictcopy get has_attr has_key items keys '
97 'merge popitem setdefault update values '
98 '__make_dict __dict_invert ').split()
99
100 def __init__(self,dict=None,**kw):
101 """Initialize with a dictionary, another Struct, or by giving
102 explicitly the list of attributes.
103
104 Both can be used, but the dictionary must come first:
105 Struct(dict), Struct(k1=v1,k2=v2) or Struct(dict,k1=v1,k2=v2).
106 """
107 if dict is None:
108 dict = {}
109 if isinstance(dict,Struct):
110 dict = dict.dict()
111 elif dict and type(dict) is not types.DictType:
112 raise TypeError,\
113 'Initialize with a dictionary or key=val pairs.'
114 dict.update(kw)
115 # do the updating by hand to guarantee that we go through the
116 # safety-checked __setitem__
117 for k,v in dict.items():
118 self[k] = v
119
120 def __setitem__(self,key,value):
121 """Used when struct[key] = val calls are made."""
122 if key in Struct.__protected:
123 raise KeyError,'Key '+`key`+' is a protected key of class Struct.'
124 self.__dict__[key] = value
125
126 def __setattr__(self, key, value):
127 """Used when struct.key = val calls are made."""
128 self.__setitem__(key,value)
129
130 def __str__(self):
131 """Gets called by print."""
132
133 return 'Struct('+str(self.__dict__)+')'
134
135 def __repr__(self):
136 """Gets called by repr.
137
138 A Struct can be recreated with S_new=eval(repr(S_old))."""
139 return 'Struct('+str(self.__dict__)+')'
140
141 def __getitem__(self,key):
142 """Allows struct[key] access."""
143 return self.__dict__[key]
144
145 def __contains__(self,key):
146 """Allows use of the 'in' operator."""
147 return self.__dict__.has_key(key)
148
149 def __iadd__(self,other):
150 """S += S2 is a shorthand for S.merge(S2)."""
151 self.merge(other)
152 return self
153
154 def __add__(self,other):
155 """S + S2 -> New Struct made form S and S.merge(S2)"""
156 Sout = self.copy()
157 Sout.merge(other)
158 return Sout
159
160 def __sub__(self,other):
161 """Return S1-S2, where all keys in S2 have been deleted (if present)
162 from S1."""
163 Sout = self.copy()
164 Sout -= other
165 return Sout
166
167 def __isub__(self,other):
168 """Do in place S = S - S2, meaning all keys in S2 have been deleted
169 (if present) from S1."""
170
171 for k in other.keys():
172 if self.has_key(k):
173 del self.__dict__[k]
174
175 def __make_dict(self,__loc_data__,**kw):
176 "Helper function for update and merge. Return a dict from data."
177
178 if __loc_data__ == None:
179 dict = {}
180 elif type(__loc_data__) is types.DictType:
181 dict = __loc_data__
182 elif isinstance(__loc_data__,Struct):
183 dict = __loc_data__.__dict__
184 else:
185 raise TypeError, 'Update with a dict, a Struct or key=val pairs.'
186 if kw:
187 dict.update(kw)
188 return dict
189
190 def __dict_invert(self,dict):
191 """Helper function for merge. Takes a dictionary whose values are
192 lists and returns a dict. with the elements of each list as keys and
193 the original keys as values."""
194
195 outdict = {}
196 for k,lst in dict.items():
197 if type(lst) is types.StringType:
198 lst = lst.split()
199 for entry in lst:
200 outdict[entry] = k
201 return outdict
202
203 def clear(self):
204 """Clear all attributes."""
205 self.__dict__.clear()
206
207 def copy(self):
208 """Return a (shallow) copy of a Struct."""
209 return Struct(self.__dict__.copy())
210
211 def dict(self):
212 """Return the Struct's dictionary."""
213 return self.__dict__
214
215 def dictcopy(self):
216 """Return a (shallow) copy of the Struct's dictionary."""
217 return self.__dict__.copy()
218
219 def popitem(self):
220 """S.popitem() -> (k, v), remove and return some (key, value) pair as
221 a 2-tuple; but raise KeyError if S is empty."""
222 return self.__dict__.popitem()
223
224 def update(self,__loc_data__=None,**kw):
225 """Update (merge) with data from another Struct or from a dictionary.
226 Optionally, one or more key=value pairs can be given at the end for
227 direct update."""
228
229 # The funny name __loc_data__ is to prevent a common variable name which
230 # could be a fieled of a Struct to collide with this parameter. The problem
231 # would arise if the function is called with a keyword with this same name
232 # that a user means to add as a Struct field.
233 newdict = Struct.__make_dict(self,__loc_data__,**kw)
234 for k,v in newdict.items():
235 self[k] = v
236
237 def merge(self,__loc_data__=None,__conflict_solve=None,**kw):
238 """S.merge(data,conflict,k=v1,k=v2,...) -> merge data and k=v into S.
239
240 This is similar to update(), but much more flexible. First, a dict is
241 made from data+key=value pairs. When merging this dict with the Struct
242 S, the optional dictionary 'conflict' is used to decide what to do.
243
244 If conflict is not given, the default behavior is to preserve any keys
245 with their current value (the opposite of the update method's
246 behavior).
247
248 conflict is a dictionary of binary functions which will be used to
249 solve key conflicts. It must have the following structure:
250
251 conflict == { fn1 : [Skey1,Skey2,...], fn2 : [Skey3], etc }
252
253 Values must be lists or whitespace separated strings which are
254 automatically converted to lists of strings by calling string.split().
255
256 Each key of conflict is a function which defines a policy for
257 resolving conflicts when merging with the input data. Each fn must be
258 a binary function which returns the desired outcome for a key
259 conflict. These functions will be called as fn(old,new).
260
261 An example is probably in order. Suppose you are merging the struct S
262 with a dict D and the following conflict policy dict:
263
264 S.merge(D,{fn1:['a','b',4], fn2:'key_c key_d'})
265
266 If the key 'a' is found in both S and D, the merge method will call:
267
268 S['a'] = fn1(S['a'],D['a'])
269
270 As a convenience, merge() provides five (the most commonly needed)
271 pre-defined policies: preserve, update, add, add_flip and add_s. The
272 easiest explanation is their implementation:
273
274 preserve = lambda old,new: old
275 update = lambda old,new: new
276 add = lambda old,new: old + new
277 add_flip = lambda old,new: new + old # note change of order!
278 add_s = lambda old,new: old + ' ' + new # only works for strings!
279
280 You can use those four words (as strings) as keys in conflict instead
281 of defining them as functions, and the merge method will substitute
282 the appropriate functions for you. That is, the call
283
284 S.merge(D,{'preserve':'a b c','add':[4,5,'d'],my_function:[6]})
285
286 will automatically substitute the functions preserve and add for the
287 names 'preserve' and 'add' before making any function calls.
288
289 For more complicated conflict resolution policies, you still need to
290 construct your own functions. """
291
292 data_dict = Struct.__make_dict(self,__loc_data__,**kw)
293
294 # policies for conflict resolution: two argument functions which return
295 # the value that will go in the new struct
296 preserve = lambda old,new: old
297 update = lambda old,new: new
298 add = lambda old,new: old + new
299 add_flip = lambda old,new: new + old # note change of order!
300 add_s = lambda old,new: old + ' ' + new
301
302 # default policy is to keep current keys when there's a conflict
303 conflict_solve = list2dict2(self.keys(),default = preserve)
304
305 # the conflict_solve dictionary is given by the user 'inverted': we
306 # need a name-function mapping, it comes as a function -> names
307 # dict. Make a local copy (b/c we'll make changes), replace user
308 # strings for the three builtin policies and invert it.
309 if __conflict_solve:
310 inv_conflict_solve_user = __conflict_solve.copy()
311 for name, func in [('preserve',preserve), ('update',update),
312 ('add',add), ('add_flip',add_flip), ('add_s',add_s)]:
313 if name in inv_conflict_solve_user.keys():
314 inv_conflict_solve_user[func] = inv_conflict_solve_user[name]
315 del inv_conflict_solve_user[name]
316 conflict_solve.update(Struct.__dict_invert(self,inv_conflict_solve_user))
317 #print 'merge. conflict_solve: '; pprint(conflict_solve) # dbg
318 # after Python 2.2, use iterators: for key in data_dict will then work
319 #print '*'*50,'in merger. conflict_solver:'; pprint(conflict_solve)
320 for key in data_dict.keys():
321 if key not in self:
322 self[key] = data_dict[key]
323 else:
324 self[key] = conflict_solve[key](self[key],data_dict[key])
325
326 def has_key(self,key):
327 """Like has_key() dictionary method."""
328 return self.__dict__.has_key(key)
329
330 def hasattr(self,key):
331 """hasattr function available as a method.
332
333 Implemented like has_key, to make sure that all available keys in the
334 internal dictionary of the Struct appear also as attributes (even
335 numeric keys)."""
336 return self.__dict__.has_key(key)
337
338 def items(self):
339 """Return the items in the Struct's dictionary, in the same format
340 as a call to {}.items()."""
341 return self.__dict__.items()
342
343 def keys(self):
344 """Return the keys in the Struct's dictionary, in the same format
345 as a call to {}.keys()."""
346 return self.__dict__.keys()
347
348 def values(self,keys=None):
349 """Return the values in the Struct's dictionary, in the same format
350 as a call to {}.values().
351
352 Can be called with an optional argument keys, which must be a list or
353 tuple of keys. In this case it returns only the values corresponding
354 to those keys (allowing a form of 'slicing' for Structs)."""
355 if not keys:
356 return self.__dict__.values()
357 else:
358 ret=[]
359 for k in keys:
360 ret.append(self[k])
361 return ret
362
363 def get(self,attr,val=None):
364 """S.get(k[,d]) -> S[k] if S.has_key(k), else d. d defaults to None."""
365 try:
366 return self[attr]
367 except KeyError:
368 return val
369
370 def setdefault(self,attr,val=None):
371 """S.setdefault(k[,d]) -> S.get(k,d), also set S[k]=d if not S.has_key(k)"""
372 if not self.has_key(attr):
373 self[attr] = val
374 return self.get(attr,val)
375 # end class Struct
376
This diff has been collapsed as it changes many lines, (546 lines changed) Show them Hide them
@@ -0,0 +1,546 b''
1 # -*- Mode: Shell-Script -*- Not really, but shows comments correctly
2 # $Id: ipythonrc 596 2005-06-01 17:01:13Z fperez $
3
4 #***************************************************************************
5 #
6 # Configuration file for IPython -- ipythonrc format
7 #
8 # The format of this file is simply one of 'key value' lines.
9 # Lines containing only whitespace at the beginning and then a # are ignored
10 # as comments. But comments can NOT be put on lines with data.
11
12 # The meaning and use of each key are explained below.
13
14 #---------------------------------------------------------------------------
15 # Section: included files
16
17 # Put one or more *config* files (with the syntax of this file) you want to
18 # include. For keys with a unique value the outermost file has precedence. For
19 # keys with multiple values, they all get assembled into a list which then
20 # gets loaded by IPython.
21
22 # In this file, all lists of things should simply be space-separated.
23
24 # This allows you to build hierarchies of files which recursively load
25 # lower-level services. If this is your main ~/.ipython/ipythonrc file, you
26 # should only keep here basic things you always want available. Then you can
27 # include it in every other special-purpose config file you create.
28 include
29
30 #---------------------------------------------------------------------------
31 # Section: startup setup
32
33 # These are mostly things which parallel a command line option of the same
34 # name.
35
36 # Keys in this section should only appear once. If any key from this section
37 # is encountered more than once, the last value remains, all earlier ones get
38 # discarded.
39
40 # Automatic calling of callable objects. If set to true, callable objects are
41 # automatically called when invoked at the command line, even if you don't
42 # type parentheses. IPython adds the parentheses for you. For example:
43
44 #In [1]: str 45
45 #------> str(45)
46 #Out[1]: '45'
47
48 # IPython reprints your line with '---->' indicating that it added
49 # parentheses. While this option is very convenient for interactive use, it
50 # may occasionally cause problems with objects which have side-effects if
51 # called unexpectedly. Set it to 0 if you want to disable it.
52
53 # Note that even with autocall off, you can still use '/' at the start of a
54 # line to treat the first argument on the command line as a function and add
55 # parentheses to it:
56
57 #In [8]: /str 43
58 #------> str(43)
59 #Out[8]: '43'
60
61 autocall 1
62
63 # Auto-indent. IPython can recognize lines ending in ':' and indent the next
64 # line, while also un-indenting automatically after 'raise' or 'return'.
65
66 # This feature uses the readline library, so it will honor your ~/.inputrc
67 # configuration (or whatever file your INPUTRC variable points to). Adding
68 # the following lines to your .inputrc file can make indent/unindenting more
69 # convenient (M-i indents, M-u unindents):
70
71 # $if Python
72 # "\M-i": " "
73 # "\M-u": "\d\d\d\d"
74 # $endif
75
76 # The feature is potentially a bit dangerous, because it can cause problems
77 # with pasting of indented code (the pasted code gets re-indented on each
78 # line). But it's a huge time-saver when working interactively. The magic
79 # function @autoindent allows you to toggle it on/off at runtime.
80
81 autoindent 1
82
83 # Auto-magic. This gives you access to all the magic functions without having
84 # to prepend them with an @ sign. If you define a variable with the same name
85 # as a magic function (say who=1), you will need to access the magic function
86 # with @ (@who in this example). However, if later you delete your variable
87 # (del who), you'll recover the automagic calling form.
88
89 # Considering that many magic functions provide a lot of shell-like
90 # functionality, automagic gives you something close to a full Python+system
91 # shell environment (and you can extend it further if you want).
92
93 automagic 1
94
95 # Size of the output cache. After this many entries are stored, the cache will
96 # get flushed. Depending on the size of your intermediate calculations, you
97 # may have memory problems if you make it too big, since keeping things in the
98 # cache prevents Python from reclaiming the memory for old results. Experiment
99 # with a value that works well for you.
100
101 # If you choose cache_size 0 IPython will revert to python's regular >>>
102 # unnumbered prompt. You will still have _, __ and ___ for your last three
103 # results, but that will be it. No dynamic _1, _2, etc. will be created. If
104 # you are running on a slow machine or with very limited memory, this may
105 # help.
106
107 cache_size 1000
108
109 # Classic mode: Setting 'classic 1' you lose many of IPython niceties,
110 # but that's your choice! Classic 1 -> same as IPython -classic.
111 # Note that this is _not_ the normal python interpreter, it's simply
112 # IPython emulating most of the classic interpreter's behavior.
113 classic 0
114
115 # colors - Coloring option for prompts and traceback printouts.
116
117 # Currently available schemes: NoColor, Linux, LightBG.
118
119 # This option allows coloring the prompts and traceback printouts. This
120 # requires a terminal which can properly handle color escape sequences. If you
121 # are having problems with this, use the NoColor scheme (uses no color escapes
122 # at all).
123
124 # The Linux option works well in linux console type environments: dark
125 # background with light fonts.
126
127 # LightBG is similar to Linux but swaps dark/light colors to be more readable
128 # in light background terminals.
129
130 # keep uncommented only the one you want:
131 colors Linux
132 #colors LightBG
133 #colors NoColor
134
135 ########################
136 # Note to Windows users
137 #
138 # Color and readline support is avaialble to Windows users via Gary Bishop's
139 # readline library. You can find Gary's tools at
140 # http://sourceforge.net/projects/uncpythontools.
141 # Note that his readline module requires in turn the ctypes library, available
142 # at http://starship.python.net/crew/theller/ctypes.
143 ########################
144
145 # color_info: IPython can display information about objects via a set of
146 # functions, and optionally can use colors for this, syntax highlighting
147 # source code and various other elements. This information is passed through a
148 # pager (it defaults to 'less' if $PAGER is not set).
149
150 # If your pager has problems, try to setting it to properly handle escapes
151 # (see the less manpage for detail), or disable this option. The magic
152 # function @color_info allows you to toggle this interactively for testing.
153
154 color_info 1
155
156 # confirm_exit: set to 1 if you want IPython to confirm when you try to exit
157 # with an EOF (Control-d in Unix, Control-Z/Enter in Windows). Note that using
158 # the magic functions @Exit or @Quit you can force a direct exit, bypassing
159 # any confirmation.
160
161 confirm_exit 1
162
163 # Use deep_reload() as a substitute for reload() by default. deep_reload() is
164 # still available as dreload() and appears as a builtin.
165
166 deep_reload 0
167
168 # Which editor to use with the @edit command. If you leave this at 0, IPython
169 # will honor your EDITOR environment variable. Since this editor is invoked on
170 # the fly by ipython and is meant for editing small code snippets, you may
171 # want to use a small, lightweight editor here.
172
173 # For Emacs users, setting up your Emacs server properly as described in the
174 # manual is a good idea. An alternative is to use jed, a very light editor
175 # with much of the feel of Emacs (though not as powerful for heavy-duty work).
176
177 editor 0
178
179 # log 1 -> same as ipython -log. This automatically logs to ./ipython.log
180 log 0
181
182 # Same as ipython -Logfile YourLogfileName.
183 # Don't use with log 1 (use one or the other)
184 logfile ''
185
186 # banner 0 -> same as ipython -nobanner
187 banner 1
188
189 # messages 0 -> same as ipython -nomessages
190 messages 1
191
192 # Automatically call the pdb debugger after every uncaught exception. If you
193 # are used to debugging using pdb, this puts you automatically inside of it
194 # after any call (either in IPython or in code called by it) which triggers an
195 # exception which goes uncaught.
196 pdb 0
197
198 # Enable the pprint module for printing. pprint tends to give a more readable
199 # display (than print) for complex nested data structures.
200 pprint 1
201
202 # Prompt strings
203
204 # Most bash-like escapes can be used to customize IPython's prompts, as well as
205 # a few additional ones which are IPython-specific. All valid prompt escapes
206 # are described in detail in the Customization section of the IPython HTML/PDF
207 # manual.
208
209 # Use \# to represent the current prompt number, and quote them to protect
210 # spaces.
211 prompt_in1 'In [\#]: '
212
213 # \D is replaced by as many dots as there are digits in the
214 # current value of \#.
215 prompt_in2 ' .\D.: '
216
217 prompt_out 'Out[\#]: '
218
219 # Select whether to left-pad the output prompts to match the length of the
220 # input ones. This allows you for example to use a simple '>' as an output
221 # prompt, and yet have the output line up with the input. If set to false,
222 # the output prompts will be unpadded (flush left).
223 prompts_pad_left 1
224
225 # quick 1 -> same as ipython -quick
226 quick 0
227
228 # Use the readline library (1) or not (0). Most users will want this on, but
229 # if you experience strange problems with line management (mainly when using
230 # IPython inside Emacs buffers) you may try disabling it. Not having it on
231 # prevents you from getting command history with the arrow keys, searching and
232 # name completion using TAB.
233
234 readline 1
235
236 # Screen Length: number of lines of your screen. This is used to control
237 # printing of very long strings. Strings longer than this number of lines will
238 # be paged with the less command instead of directly printed.
239
240 # The default value for this is 0, which means IPython will auto-detect your
241 # screen size every time it needs to print. If for some reason this isn't
242 # working well (it needs curses support), specify it yourself. Otherwise don't
243 # change the default.
244
245 screen_length 0
246
247 # Prompt separators for input and output.
248 # Use \n for newline explicitly, without quotes.
249 # Use 0 (like at the cmd line) to turn off a given separator.
250
251 # The structure of prompt printing is:
252 # (SeparateIn)Input....
253 # (SeparateOut)Output...
254 # (SeparateOut2), # that is, no newline is printed after Out2
255 # By choosing these you can organize your output any way you want.
256
257 separate_in \n
258 separate_out 0
259 separate_out2 0
260
261 # 'nosep 1' is a shorthand for '-SeparateIn 0 -SeparateOut 0 -SeparateOut2 0'.
262 # Simply removes all input/output separators, overriding the choices above.
263 nosep 0
264
265 # xmode - Exception reporting mode.
266
267 # Valid modes: Plain, Context and Verbose.
268
269 # Plain: similar to python's normal traceback printing.
270
271 # Context: prints 5 lines of context source code around each line in the
272 # traceback.
273
274 # Verbose: similar to Context, but additionally prints the variables currently
275 # visible where the exception happened (shortening their strings if too
276 # long). This can potentially be very slow, if you happen to have a huge data
277 # structure whose string representation is complex to compute. Your computer
278 # may appear to freeze for a while with cpu usage at 100%. If this occurs, you
279 # can cancel the traceback with Ctrl-C (maybe hitting it more than once).
280
281 #xmode Plain
282 xmode Context
283 #xmode Verbose
284
285 # multi_line_specials: if true, allow magics, aliases and shell escapes (via
286 # !cmd) to be used in multi-line input (like for loops). For example, if you
287 # have this active, the following is valid in IPython:
288 #
289 #In [17]: for i in range(3):
290 # ....: mkdir $i
291 # ....: !touch $i/hello
292 # ....: ls -l $i
293
294 multi_line_specials 1
295
296 #---------------------------------------------------------------------------
297 # Section: Readline configuration (readline is not available for MS-Windows)
298
299 # This is done via the following options:
300
301 # (i) readline_parse_and_bind: this option can appear as many times as you
302 # want, each time defining a string to be executed via a
303 # readline.parse_and_bind() command. The syntax for valid commands of this
304 # kind can be found by reading the documentation for the GNU readline library,
305 # as these commands are of the kind which readline accepts in its
306 # configuration file.
307
308 # The TAB key can be used to complete names at the command line in one of two
309 # ways: 'complete' and 'menu-complete'. The difference is that 'complete' only
310 # completes as much as possible while 'menu-complete' cycles through all
311 # possible completions. Leave the one you prefer uncommented.
312
313 readline_parse_and_bind tab: complete
314 #readline_parse_and_bind tab: menu-complete
315
316 # This binds Control-l to printing the list of all possible completions when
317 # there is more than one (what 'complete' does when hitting TAB twice, or at
318 # the first TAB if show-all-if-ambiguous is on)
319 readline_parse_and_bind "\C-l": possible-completions
320
321 # This forces readline to automatically print the above list when tab
322 # completion is set to 'complete'. You can still get this list manually by
323 # using the key bound to 'possible-completions' (Control-l by default) or by
324 # hitting TAB twice. Turning this on makes the printing happen at the first
325 # TAB.
326 readline_parse_and_bind set show-all-if-ambiguous on
327
328 # If you have TAB set to complete names, you can rebind any key (Control-o by
329 # default) to insert a true TAB character.
330 readline_parse_and_bind "\C-o": tab-insert
331
332 # These commands allow you to indent/unindent easily, with the 4-space
333 # convention of the Python coding standards. Since IPython's internal
334 # auto-indent system also uses 4 spaces, you should not change the number of
335 # spaces in the code below.
336 readline_parse_and_bind "\M-i": " "
337 readline_parse_and_bind "\M-o": "\d\d\d\d"
338 readline_parse_and_bind "\M-I": "\d\d\d\d"
339
340 # Bindings for incremental searches in the history. These searches use the
341 # string typed so far on the command line and search anything in the previous
342 # input history containing them.
343 readline_parse_and_bind "\C-r": reverse-search-history
344 readline_parse_and_bind "\C-s": forward-search-history
345
346 # Bindings for completing the current line in the history of previous
347 # commands. This allows you to recall any previous command by typing its first
348 # few letters and hitting Control-p, bypassing all intermediate commands which
349 # may be in the history (much faster than hitting up-arrow 50 times!)
350 readline_parse_and_bind "\C-p": history-search-backward
351 readline_parse_and_bind "\C-n": history-search-forward
352
353 # I also like to have the same functionality on the plain arrow keys. If you'd
354 # rather have the arrows use all the history (and not just match what you've
355 # typed so far), comment out or delete the next two lines.
356 readline_parse_and_bind "\e[A": history-search-backward
357 readline_parse_and_bind "\e[B": history-search-forward
358
359 # (ii) readline_remove_delims: a string of characters to be removed from the
360 # default word-delimiters list used by readline, so that completions may be
361 # performed on strings which contain them.
362
363 readline_remove_delims -/~
364
365 # (iii) readline_merge_completions: whether to merge the result of all
366 # possible completions or not. If true, IPython will complete filenames,
367 # python names and aliases and return all possible completions. If you set it
368 # to false, each completer is used at a time, and only if it doesn't return
369 # any completions is the next one used.
370
371 # The default order is: [python_matches, file_matches, alias_matches]
372
373 readline_merge_completions 1
374
375 # (iv) readline_omit__names: normally hitting <tab> after a '.' in a name
376 # will complete all attributes of an object, including all the special methods
377 # whose names start with single or double underscores (like __getitem__ or
378 # __class__).
379
380 # This variable allows you to control this completion behavior:
381
382 # readline_omit__names 1 -> completion will omit showing any names starting
383 # with two __, but it will still show names starting with one _.
384
385 # readline_omit__names 2 -> completion will omit all names beginning with one
386 # _ (which obviously means filtering out the double __ ones).
387
388 # Even when this option is set, you can still see those names by explicitly
389 # typing a _ after the period and hitting <tab>: 'name._<tab>' will always
390 # complete attribute names starting with '_'.
391
392 # This option is off by default so that new users see all attributes of any
393 # objects they are dealing with.
394
395 readline_omit__names 0
396
397 #---------------------------------------------------------------------------
398 # Section: modules to be loaded with 'import ...'
399
400 # List, separated by spaces, the names of the modules you want to import
401
402 # Example:
403 # import_mod sys os
404 # will produce internally the statements
405 # import sys
406 # import os
407
408 # Each import is executed in its own try/except block, so if one module
409 # fails to load the others will still be ok.
410
411 import_mod
412
413 #---------------------------------------------------------------------------
414 # Section: modules to import some functions from: 'from ... import ...'
415
416 # List, one per line, the modules for which you want only to import some
417 # functions. Give the module name first and then the name of functions to be
418 # imported from that module.
419
420 # Example:
421
422 # import_some IPython.genutils timing timings
423 # will produce internally the statement
424 # from IPython.genutils import timing, timings
425
426 # timing() and timings() are two IPython utilities for timing the execution of
427 # your own functions, which you may find useful. Just commment out the above
428 # line if you want to test them.
429
430 # If you have more than one modules_some line, each gets its own try/except
431 # block (like modules, see above).
432
433 import_some
434
435 #---------------------------------------------------------------------------
436 # Section: modules to import all from : 'from ... import *'
437
438 # List (same syntax as import_mod above) those modules for which you want to
439 # import all functions. Remember, this is a potentially dangerous thing to do,
440 # since it is very easy to overwrite names of things you need. Use with
441 # caution.
442
443 # Example:
444 # import_all sys os
445 # will produce internally the statements
446 # from sys import *
447 # from os import *
448
449 # As before, each will be called in a separate try/except block.
450
451 import_all
452
453 #---------------------------------------------------------------------------
454 # Section: Python code to execute.
455
456 # Put here code to be explicitly executed (keep it simple!)
457 # Put one line of python code per line. All whitespace is removed (this is a
458 # feature, not a bug), so don't get fancy building loops here.
459 # This is just for quick convenient creation of things you want available.
460
461 # Example:
462 # execute x = 1
463 # execute print 'hello world'; y = z = 'a'
464 # will produce internally
465 # x = 1
466 # print 'hello world'; y = z = 'a'
467 # and each *line* (not each statement, we don't do python syntax parsing) is
468 # executed in its own try/except block.
469
470 execute
471
472 # Note for the adventurous: you can use this to define your own names for the
473 # magic functions, by playing some namespace tricks:
474
475 # execute __IPYTHON__.magic_pf = __IPYTHON__.magic_profile
476
477 # defines @pf as a new name for @profile.
478
479 #---------------------------------------------------------------------------
480 # Section: Pyhton files to load and execute.
481
482 # Put here the full names of files you want executed with execfile(file). If
483 # you want complicated initialization, just write whatever you want in a
484 # regular python file and load it from here.
485
486 # Filenames defined here (which *must* include the extension) are searched for
487 # through all of sys.path. Since IPython adds your .ipython directory to
488 # sys.path, they can also be placed in your .ipython dir and will be
489 # found. Otherwise (if you want to execute things not in .ipyton nor in
490 # sys.path) give a full path (you can use ~, it gets expanded)
491
492 # Example:
493 # execfile file1.py ~/file2.py
494 # will generate
495 # execfile('file1.py')
496 # execfile('_path_to_your_home/file2.py')
497
498 # As before, each file gets its own try/except block.
499
500 execfile
501
502 # If you are feeling adventurous, you can even add functionality to IPython
503 # through here. IPython works through a global variable called __ip which
504 # exists at the time when these files are read. If you know what you are doing
505 # (read the source) you can add functions to __ip in files loaded here.
506
507 # The file example-magic.py contains a simple but correct example. Try it:
508
509 # execfile example-magic.py
510
511 # Look at the examples in IPython/iplib.py for more details on how these magic
512 # functions need to process their arguments.
513
514 #---------------------------------------------------------------------------
515 # Section: aliases for system shell commands
516
517 # Here you can define your own names for system commands. The syntax is
518 # similar to that of the builtin @alias function:
519
520 # alias alias_name command_string
521
522 # The resulting aliases are auto-generated magic functions (hence usable as
523 # @alias_name)
524
525 # For example:
526
527 # alias myls ls -la
528
529 # will define 'myls' as an alias for executing the system command 'ls -la'.
530 # This allows you to customize IPython's environment to have the same aliases
531 # you are accustomed to from your own shell.
532
533 # You can also define aliases with parameters using %s specifiers (one per
534 # parameter):
535
536 # alias parts echo first %s second %s
537
538 # will give you in IPython:
539 # >>> @parts A B
540 # first A second B
541
542 # Use one 'alias' statement per alias you wish to define.
543
544 # alias
545
546 #************************* end of file <ipythonrc> ************************
@@ -0,0 +1,36 b''
1 # -*- Mode: Shell-Script -*- Not really, but shows comments correctly
2 #***************************************************************************
3 #
4 # Configuration file for ipython -- ipythonrc format
5 #
6 # The format of this file is one of 'key value' lines.
7 # Lines containing only whitespace at the beginning and then a # are ignored
8 # as comments. But comments can NOT be put on lines with data.
9 #***************************************************************************
10
11 # This is an example of a 'profile' file which includes a base file and adds
12 # some customizaton for a particular purpose.
13
14 # If this file is found in the user's ~/.ipython directory as ipythonrc-math,
15 # it can be loaded by calling passing the '-profile math' (or '-p math')
16 # option to IPython.
17
18 # This example is a light customization to have ipython have basic math functions
19 # readily available, effectively making the python prompt a very capable scientific
20 # calculator
21
22 # include base config and only add some extras
23 include ipythonrc
24
25 # load the complex math functions but keep them in a separate namespace
26 import_mod cmath
27
28 # from ... import *
29 # load the real math functions in the global namespace for convenience
30 import_all math
31
32 # from ... import ...
33 import_some
34
35 # code to execute
36 execute print "*** math functions available globally, cmath as a module"
@@ -0,0 +1,57 b''
1 # -*- Mode: Shell-Script -*- Not really, but shows comments correctly
2 #***************************************************************************
3 #
4 # Configuration file for ipython -- ipythonrc format
5 #
6 # The format of this file is one of 'key value' lines.
7 # Lines containing only whitespace at the beginning and then a # are ignored
8 # as comments. But comments can NOT be put on lines with data.
9 #***************************************************************************
10
11 # This is an example of a 'profile' file which includes a base file and adds
12 # some customizaton for a particular purpose.
13
14 # If this file is found in the user's ~/.ipython directory as
15 # ipythonrc-numeric, it can be loaded by calling passing the '-profile
16 # numeric' (or '-p numeric') option to IPython.
17
18 # A simple alias numpy -> 'ipython -p numeric' makes life very convenient.
19
20 # This example is meant to load several modules to turn IPython into a very
21 # capable environment for high-end numerical work, similar to IDL or MatLab
22 # but with the beauty and flexibility of the Python language.
23
24 # Load the user's basic configuration
25 include ipythonrc
26
27 # import ...
28
29 # Load Numeric by itself so that 'help Numeric' works
30 import_mod Numeric
31
32 # from ... import *
33 # GnuplotRuntime loads Gnuplot and adds enhancements for use in IPython
34 import_all Numeric IPython.numutils IPython.GnuplotInteractive
35
36 # a simple line at zero, often useful for an x-axis
37 execute xaxis=gpfunc('0',title='',with='lines lt -1')
38
39 # Below are optional things off by default. Uncomment them if desired.
40
41 # MA (MaskedArray) modifies the Numeric printing mechanism so that huge arrays
42 # are only summarized and not printed (which may freeze the machine for a
43 # _long_ time).
44
45 #import_mod MA
46
47
48 # gracePlot is a Python interface to the plotting package Grace.
49 # For more details go to: http://www.idyll.org/~n8gray/code/index.html
50 # Uncomment lines below if you have grace and its python support code
51
52 #import_mod gracePlot
53 #execute grace = gracePlot.gracePlot # alias to make gracePlot instances
54 #execute print '*** grace is an alias for gracePlot.gracePlot'
55
56 # Files to execute
57 execfile
@@ -0,0 +1,43 b''
1 # -*- Mode: Shell-Script -*- Not really, but shows comments correctly
2 #***************************************************************************
3 #
4 # Configuration file for ipython -- ipythonrc format
5 #
6 # The format of this file is one of 'key value' lines.
7 # Lines containing only whitespace at the beginning and then a # are ignored
8 # as comments. But comments can NOT be put on lines with data.
9 #***************************************************************************
10
11 # If this file is found in the user's ~/.ipython directory as
12 # ipythonrc-physics, it can be loaded by calling passing the '-profile
13 # physics' (or '-p physics') option to IPython.
14
15 # This profile loads modules useful for doing interactive calculations with
16 # physical quantities (with units). It relies on modules from Konrad Hinsen's
17 # ScientificPython (http://starship.python.net/crew/hinsen/)
18
19 # First load basic user configuration
20 include ipythonrc
21
22 # import ...
23 # Module with alternate input syntax for PhysicalQuantity objects.
24 import_mod IPython.Extensions.PhysicalQInput
25
26 # from ... import *
27 # math CANNOT be imported after PhysicalQInteractive. It will override the
28 # functions defined there.
29 import_all math IPython.Extensions.PhysicalQInteractive
30
31 # from ... import ...
32 import_some
33
34 # code
35 execute q = PhysicalQuantityInteractive
36 execute g = PhysicalQuantityInteractive('9.8 m/s**2')
37 ececute rad = pi/180.
38 execute print '*** q is an alias for PhysicalQuantityInteractive'
39 execute print '*** g = 9.8 m/s^2 has been defined'
40 execute print '*** rad = pi/180 has been defined'
41
42 # Files to execute
43 execfile
@@ -0,0 +1,94 b''
1 # -*- Mode: Shell-Script -*- Not really, but shows comments correctly
2 #***************************************************************************
3 # Configuration file for ipython -- ipythonrc format
4 #
5 # The format of this file is one of 'key value' lines.
6 # Lines containing only whitespace at the beginning and then a # are ignored
7 # as comments. But comments can NOT be put on lines with data.
8 #***************************************************************************
9
10 # If this file is found in the user's ~/.ipython directory as ipythonrc-pysh,
11 # it can be loaded by calling passing the '-profile pysh' (or '-p pysh')
12 # option to IPython.
13
14 # This profile turns IPython into a lightweight system shell with python
15 # syntax.
16
17 # We only set a few options here, the rest is done in the companion pysh.py
18 # file. In the future _all_ of IPython's configuration will be done via
19 # proper python code.
20
21 ############################################################################
22 # First load common user configuration
23 include ipythonrc
24
25 ############################################################################
26 # Load all the actual syntax extensions for shell-like operation, which live
27 # in the InterpreterExec standard extension.
28 import_all IPython.Extensions.InterpreterExec
29
30 ############################################################################
31 # PROMPTS
32 #
33 # Configure prompt for more shell-like usage.
34
35 # Most bash-like escapes can be used to customize IPython's prompts, as well as
36 # a few additional ones which are IPython-specific. All valid prompt escapes
37 # are described in detail in the Customization section of the IPython HTML/PDF
38 # manual.
39
40 prompt_in1 '\C_LightGreen\u@\h\C_LightBlue[\C_LightCyan\Y1\C_LightBlue]\C_Green|\#> '
41 prompt_in2 '\C_Green|\C_LightGreen\D\C_Green> '
42 prompt_out '<\#> '
43
44 # Here's a more complex prompt, showing the hostname and more path depth (\Y3)
45 #prompt_in1 '\C_LightRed\u\C_Blue@\C_Red\h\C_LightBlue[\C_LightCyan\Y3\C_LightBlue]\C_LightGreen\#> '
46
47 # Select whether to left-pad the output prompts to match the length of the
48 # input ones. This allows you for example to use a simple '>' as an output
49 # prompt, and yet have the output line up with the input. If set to false,
50 # the output prompts will be unpadded (flush left).
51 prompts_pad_left 1
52
53
54 # Remove all blank lines in between prompts, like a normal shell.
55 separate_in 0
56 separate_out 0
57 separate_out2 0
58
59 # Allow special syntax (!, magics and aliases) in multiline input
60 multi_line_specials 1
61
62 ############################################################################
63 # ALIASES
64
65 # Declare some common aliases. Type alias? at an ipython prompt for details on
66 # the syntax, use @unalias to delete existing aliases.
67
68 # Don't go too crazy here, the file pysh.py called below runs @rehash, which
69 # loads ALL of your $PATH as aliases (except for Python keywords and
70 # builtins).
71
72 # Some examples:
73
74 # A simple alias without arguments
75 #alias cl clear
76
77 # An alias which expands the full line before the end of the alias. This
78 # lists only directories:
79 #alias ldir pwd;ls -oF --color %l | grep /$
80
81 # An alias with two positional arguments:
82 #alias parts echo 'First <%s> Second <%s>'
83
84 # In use these two aliases give (note that ldir is already built into IPython
85 # for Unix):
86
87 #fperez[IPython]16> ldir
88 #/usr/local/home/fperez/ipython/ipython/IPython
89 #drwxr-xr-x 2 fperez 4096 Jun 21 01:01 CVS/
90 #drwxr-xr-x 3 fperez 4096 Jun 21 01:10 Extensions/
91 #drwxr-xr-x 3 fperez 4096 Jun 21 01:27 UserConfig/
92
93 #fperez[IPython]17> parts Hello world and goodbye
94 #First <Hello> Second <world> and goodbye
@@ -0,0 +1,43 b''
1 # -*- Mode: Shell-Script -*- Not really, but shows comments correctly
2 #***************************************************************************
3 #
4 # Configuration file for ipython -- ipythonrc format
5 #
6 # The format of this file is one of 'key value' lines.
7 # Lines containing only whitespace at the beginning and then a # are ignored
8 # as comments. But comments can NOT be put on lines with data.
9 #***************************************************************************
10
11 # This is an example of a 'profile' file which includes a base file and adds
12 # some customizaton for a particular purpose.
13
14 # If this file is found in the user's ~/.ipython directory as ipythonrc-scipy,
15 # it can be loaded by calling passing the '-profile scipy' (or '-p scipy')
16 # option to IPython.
17
18 # This example is meant to load several modules to turn ipython into a very
19 # capable environment for high-end numerical work, similar to IDL or MatLab
20 # but with the beauty of the Python language.
21
22 # load our basic configuration with generic options
23 include ipythonrc
24
25 # import ...
26 # Load SciPy by itself so that 'help scipy' works
27 import_mod scipy
28
29 # from ... import ...
30 import_some
31
32 # Now we load all of SciPy
33 # from ... import *
34 import_all scipy IPython.numutils
35
36 # code
37 execute print 'Welcome to the SciPy Scientific Computing Environment.'
38 execute scipy.alter_numeric()
39
40 # File with alternate printer system for Numeric Arrays.
41 # Files in the 'Extensions' directory will be found by IPython automatically
42 # (otherwise give the explicit path):
43 execfile Extensions/numeric_formats.py
@@ -0,0 +1,37 b''
1 # -*- Mode: Shell-Script -*- Not really, but shows comments correctly
2 #***************************************************************************
3 #
4 # Configuration file for ipython -- ipythonrc format
5 #
6 # The format of this file is one of 'key value' lines.
7 # Lines containing only whitespace at the beginning and then a # are ignored
8 # as comments. But comments can NOT be put on lines with data.
9 #***************************************************************************
10
11 # If this file is found in the user's ~/.ipython directory as
12 # ipythonrc-tutorial, it can be loaded by calling passing the '-profile
13 # tutorial' (or '-p tutorial') option to IPython.
14
15 # This profile loads a special input line filter to allow typing lines which
16 # begin with '>>> ' or '... '. These two strings, if present at the start of
17 # the input line, are stripped. This allows for direct pasting of code from
18 # examples such as those available in the standard Python tutorial.
19
20 # First load basic user configuration
21 include ipythonrc
22
23 # import ...
24 # Module with alternate input syntax for pasting python input
25 import_mod IPython.Extensions.InterpreterPasteInput
26
27 # from ... import *
28 import_all
29
30 # from ... import ...
31 import_some
32
33 # code
34 execute
35
36 # Files to execute
37 execfile
@@ -0,0 +1,63 b''
1 # -*- coding: utf-8 -*-
2 """
3 IPython -- An enhanced Interactive Python
4
5 One of Python's nicest features is its interactive interpreter. This allows
6 very fast testing of ideas without the overhead of creating test files as is
7 typical in most programming languages. However, the interpreter supplied with
8 the standard Python distribution is fairly primitive (and IDLE isn't really
9 much better).
10
11 IPython tries to:
12
13 i - provide an efficient environment for interactive work in Python
14 programming. It tries to address what we see as shortcomings of the standard
15 Python prompt, and adds many features to make interactive work much more
16 efficient.
17
18 ii - offer a flexible framework so that it can be used as the base
19 environment for other projects and problems where Python can be the
20 underlying language. Specifically scientific environments like Mathematica,
21 IDL and Mathcad inspired its design, but similar ideas can be useful in many
22 fields. Python is a fabulous language for implementing this kind of system
23 (due to its dynamic and introspective features), and with suitable libraries
24 entire systems could be built leveraging Python's power.
25
26 iii - serve as an embeddable, ready to go interpreter for your own programs.
27
28 IPython requires Python 2.2 or newer.
29
30 $Id: __init__.py 530 2005-03-02 07:11:15Z fperez $"""
31
32 #*****************************************************************************
33 # Copyright (C) 2001-2004 Fernando Perez. <fperez@colorado.edu>
34 #
35 # Distributed under the terms of the BSD License. The full license is in
36 # the file COPYING, distributed as part of this software.
37 #*****************************************************************************
38
39 # Enforce proper version requirements
40 import sys
41 if sys.version[0:3] < '2.2':
42 raise ImportError, 'Python Version 2.2 or above is required.'
43
44 # Define what gets imported with a 'from IPython import *'
45 __all__ = ['deep_reload','genutils','ultraTB','DPyGetOpt','Itpl','hooks',
46 'ConfigLoader','OutputTrap','Release','Struct','Shell']
47
48 # Load __all__ in IPython namespace so that a simple 'import IPython' gives
49 # access to them via IPython.<name>
50 glob,loc = globals(),locals()
51 for name in __all__:
52 __import__(name,glob,loc,[])
53
54 # Release data
55 from IPython import Release # do it explicitly so pydoc can see it - pydoc bug
56 __author__ = '%s <%s>\n%s <%s>\n%s <%s>' % \
57 ( Release.authors['Fernando'] + Release.authors['Janko'] + \
58 Release.authors['Nathan'] )
59 __license__ = Release.license
60 __version__ = Release.version
61
62 # Namespace cleanup
63 del name,glob,loc
This diff has been collapsed as it changes many lines, (504 lines changed) Show them Hide them
@@ -0,0 +1,504 b''
1 # -*- coding: utf-8 -*-
2 """Manage background (threaded) jobs conveniently from an interactive shell.
3
4 This module provides a BackgroundJobManager class. This is the main class
5 meant for public usage, it implements an object which can create and manage
6 new background jobs.
7
8 It also provides the actual job classes managed by these BackgroundJobManager
9 objects, see their docstrings below.
10
11
12 This system was inspired by discussions with B. Granger and the
13 BackgroundCommand class described in the book Python Scripting for
14 Computational Science, by H. P. Langtangen:
15
16 http://folk.uio.no/hpl/scripting
17
18 (although ultimately no code from this text was used, as IPython's system is a
19 separate implementation).
20
21 $Id: background_jobs.py 515 2005-02-15 07:41:41Z fperez $
22 """
23
24 #*****************************************************************************
25 # Copyright (C) 2005 Fernando Perez <fperez@colorado.edu>
26 #
27 # Distributed under the terms of the BSD License. The full license is in
28 # the file COPYING, distributed as part of this software.
29 #*****************************************************************************
30
31 from IPython import Release
32 __author__ = '%s <%s>' % Release.authors['Fernando']
33 __license__ = Release.license
34
35 # Code begins
36 import threading,sys
37
38 from IPython.ultraTB import AutoFormattedTB
39 from IPython.genutils import warn,error
40
41 # declares Python 2.2 compatibility symbols:
42 try:
43 basestring
44 except NameError:
45 import types
46 basestring = (types.StringType, types.UnicodeType)
47 True = 1==1
48 False = 1==0
49
50 class BackgroundJobManager:
51 """Class to manage a pool of backgrounded threaded jobs.
52
53 Below, we assume that 'jobs' is a BackgroundJobManager instance.
54
55 Usage summary (see the method docstrings for details):
56
57 jobs.new(...) -> start a new job
58
59 jobs() or jobs.status() -> print status summary of all jobs
60
61 jobs[N] -> returns job number N.
62
63 foo = jobs[N].result -> assign to variable foo the result of job N
64
65 jobs[N].traceback() -> print the traceback of dead job N
66
67 jobs.remove(N) -> remove (finished) job N
68
69 jobs.flush_finished() -> remove all finished jobs
70
71 As a convenience feature, BackgroundJobManager instances provide the
72 utility result and traceback methods which retrieve the corresponding
73 information from the jobs list:
74
75 jobs.result(N) <--> jobs[N].result
76 jobs.traceback(N) <--> jobs[N].traceback()
77
78 While this appears minor, it allows you to use tab completion
79 interactively on the job manager instance.
80
81 In interactive mode, IPython provides the magic fuction %bg for quick
82 creation of backgrounded expression-based jobs. Type bg? for details."""
83
84 def __init__(self):
85 # Lists for job management
86 self.jobs_run = []
87 self.jobs_comp = []
88 self.jobs_dead = []
89 # A dict of all jobs, so users can easily access any of them
90 self.jobs_all = {}
91 # For reporting
92 self._comp_report = []
93 self._dead_report = []
94 # Store status codes locally for fast lookups
95 self._s_created = BackgroundJobBase.stat_created_c
96 self._s_running = BackgroundJobBase.stat_running_c
97 self._s_completed = BackgroundJobBase.stat_completed_c
98 self._s_dead = BackgroundJobBase.stat_dead_c
99
100 def new(self,func_or_exp,*args,**kwargs):
101 """Add a new background job and start it in a separate thread.
102
103 There are two types of jobs which can be created:
104
105 1. Jobs based on expressions which can be passed to an eval() call.
106 The expression must be given as a string. For example:
107
108 job_manager.new('myfunc(x,y,z=1)'[,glob[,loc]])
109
110 The given expression is passed to eval(), along with the optional
111 global/local dicts provided. If no dicts are given, they are
112 extracted automatically from the caller's frame.
113
114 A Python statement is NOT a valid eval() expression. Basically, you
115 can only use as an eval() argument something which can go on the right
116 of an '=' sign and be assigned to a variable.
117
118 For example,"print 'hello'" is not valid, but '2+3' is.
119
120 2. Jobs given a function object, optionally passing additional
121 positional arguments:
122
123 job_manager.new(myfunc,x,y)
124
125 The function is called with the given arguments.
126
127 If you need to pass keyword arguments to your function, you must
128 supply them as a dict named kw:
129
130 job_manager.new(myfunc,x,y,kw=dict(z=1))
131
132 The reason for this assymmetry is that the new() method needs to
133 maintain access to its own keywords, and this prevents name collisions
134 between arguments to new() and arguments to your own functions.
135
136 In both cases, the result is stored in the job.result field of the
137 background job object.
138
139
140 Notes and caveats:
141
142 1. All threads running share the same standard output. Thus, if your
143 background jobs generate output, it will come out on top of whatever
144 you are currently writing. For this reason, background jobs are best
145 used with silent functions which simply return their output.
146
147 2. Threads also all work within the same global namespace, and this
148 system does not lock interactive variables. So if you send job to the
149 background which operates on a mutable object for a long time, and
150 start modifying that same mutable object interactively (or in another
151 backgrounded job), all sorts of bizarre behaviour will occur.
152
153 3. If a background job is spending a lot of time inside a C extension
154 module which does not release the Python Global Interpreter Lock
155 (GIL), this will block the IPython prompt. This is simply because the
156 Python interpreter can only switch between threads at Python
157 bytecodes. While the execution is inside C code, the interpreter must
158 simply wait unless the extension module releases the GIL.
159
160 4. There is no way, due to limitations in the Python threads library,
161 to kill a thread once it has started."""
162
163 if callable(func_or_exp):
164 kw = kwargs.get('kw',{})
165 job = BackgroundJobFunc(func_or_exp,*args,**kw)
166 elif isinstance(func_or_exp,basestring):
167 if not args:
168 frame = sys._getframe(1)
169 glob, loc = frame.f_globals, frame.f_locals
170 elif len(args)==1:
171 glob = loc = args[0]
172 elif len(args)==2:
173 glob,loc = args
174 else:
175 raise ValueError,\
176 'Expression jobs take at most 2 args (globals,locals)'
177 job = BackgroundJobExpr(func_or_exp,glob,loc)
178 else:
179 raise
180 jkeys = self.jobs_all.keys()
181 if jkeys:
182 job.num = max(jkeys)+1
183 else:
184 job.num = 0
185 self.jobs_run.append(job)
186 self.jobs_all[job.num] = job
187 print 'Starting job # %s in a separate thread.' % job.num
188 job.start()
189 return job
190
191 def __getitem__(self,key):
192 return self.jobs_all[key]
193
194 def __call__(self):
195 """An alias to self.status(),
196
197 This allows you to simply call a job manager instance much like the
198 Unix jobs shell command."""
199
200 return self.status()
201
202 def _update_status(self):
203 """Update the status of the job lists.
204
205 This method moves finished jobs to one of two lists:
206 - self.jobs_comp: jobs which completed successfully
207 - self.jobs_dead: jobs which finished but died.
208
209 It also copies those jobs to corresponding _report lists. These lists
210 are used to report jobs completed/dead since the last update, and are
211 then cleared by the reporting function after each call."""
212
213 run,comp,dead = self._s_running,self._s_completed,self._s_dead
214 jobs_run = self.jobs_run
215 for num in range(len(jobs_run)):
216 job = jobs_run[num]
217 stat = job.stat_code
218 if stat == run:
219 continue
220 elif stat == comp:
221 self.jobs_comp.append(job)
222 self._comp_report.append(job)
223 jobs_run[num] = False
224 elif stat == dead:
225 self.jobs_dead.append(job)
226 self._dead_report.append(job)
227 jobs_run[num] = False
228 self.jobs_run = filter(None,self.jobs_run)
229
230 def _group_report(self,group,name):
231 """Report summary for a given job group.
232
233 Return True if the group had any elements."""
234
235 if group:
236 print '%s jobs:' % name
237 for job in group:
238 print '%s : %s' % (job.num,job)
239 print
240 return True
241
242 def _group_flush(self,group,name):
243 """Flush a given job group
244
245 Return True if the group had any elements."""
246
247 njobs = len(group)
248 if njobs:
249 plural = {1:''}.setdefault(njobs,'s')
250 print 'Flushing %s %s job%s.' % (njobs,name,plural)
251 group[:] = []
252 return True
253
254 def _status_new(self):
255 """Print the status of newly finished jobs.
256
257 Return True if any new jobs are reported.
258
259 This call resets its own state every time, so it only reports jobs
260 which have finished since the last time it was called."""
261
262 self._update_status()
263 new_comp = self._group_report(self._comp_report,'Completed')
264 new_dead = self._group_report(self._dead_report,
265 'Dead, call job.traceback() for details')
266 self._comp_report[:] = []
267 self._dead_report[:] = []
268 return new_comp or new_dead
269
270 def status(self,verbose=0):
271 """Print a status of all jobs currently being managed."""
272
273 self._update_status()
274 self._group_report(self.jobs_run,'Running')
275 self._group_report(self.jobs_comp,'Completed')
276 self._group_report(self.jobs_dead,'Dead')
277 # Also flush the report queues
278 self._comp_report[:] = []
279 self._dead_report[:] = []
280
281 def remove(self,num):
282 """Remove a finished (completed or dead) job."""
283
284 try:
285 job = self.jobs_all[num]
286 except KeyError:
287 error('Job #%s not found' % num)
288 else:
289 stat_code = job.stat_code
290 if stat_code == self._s_running:
291 error('Job #%s is still running, it can not be removed.' % num)
292 return
293 elif stat_code == self._s_completed:
294 self.jobs_comp.remove(job)
295 elif stat_code == self._s_dead:
296 self.jobs_dead.remove(job)
297
298 def flush_finished(self):
299 """Flush all jobs finished (completed and dead) from lists.
300
301 Running jobs are never flushed.
302
303 It first calls _status_new(), to update info. If any jobs have
304 completed since the last _status_new() call, the flush operation
305 aborts."""
306
307 if self._status_new():
308 error('New jobs completed since last '\
309 '_status_new(), aborting flush.')
310 return
311
312 # Remove the finished jobs from the master dict
313 jobs_all = self.jobs_all
314 for job in self.jobs_comp+self.jobs_dead:
315 del(jobs_all[job.num])
316
317 # Now flush these lists completely
318 fl_comp = self._group_flush(self.jobs_comp,'Completed')
319 fl_dead = self._group_flush(self.jobs_dead,'Dead')
320 if not (fl_comp or fl_dead):
321 print 'No jobs to flush.'
322
323 def result(self,num):
324 """result(N) -> return the result of job N."""
325 try:
326 return self.jobs_all[num].result
327 except KeyError:
328 error('Job #%s not found' % num)
329
330 def traceback(self,num):
331 try:
332 self.jobs_all[num].traceback()
333 except KeyError:
334 error('Job #%s not found' % num)
335
336
337 class BackgroundJobBase(threading.Thread):
338 """Base class to build BackgroundJob classes.
339
340 The derived classes must implement:
341
342 - Their own __init__, since the one here raises NotImplementedError. The
343 derived constructor must call self._init() at the end, to provide common
344 initialization.
345
346 - A strform attribute used in calls to __str__.
347
348 - A call() method, which will make the actual execution call and must
349 return a value to be held in the 'result' field of the job object."""
350
351 # Class constants for status, in string and as numerical codes (when
352 # updating jobs lists, we don't want to do string comparisons). This will
353 # be done at every user prompt, so it has to be as fast as possible
354 stat_created = 'Created'; stat_created_c = 0
355 stat_running = 'Running'; stat_running_c = 1
356 stat_completed = 'Completed'; stat_completed_c = 2
357 stat_dead = 'Dead (Exception), call job.traceback() for details'
358 stat_dead_c = -1
359
360 def __init__(self):
361 raise NotImplementedError, \
362 "This class can not be instantiated directly."
363
364 def _init(self):
365 """Common initialization for all BackgroundJob objects"""
366
367 for attr in ['call','strform']:
368 assert hasattr(self,attr), "Missing attribute <%s>" % attr
369
370 # The num tag can be set by an external job manager
371 self.num = None
372
373 self.status = BackgroundJobBase.stat_created
374 self.stat_code = BackgroundJobBase.stat_created_c
375 self.finished = False
376 self.result = '<BackgroundJob has not completed>'
377 # reuse the ipython traceback handler if we can get to it, otherwise
378 # make a new one
379 try:
380 self._make_tb = __IPYTHON__.InteractiveTB.text
381 except:
382 self._make_tb = AutoFormattedTB(mode = 'Context',
383 color_scheme='NoColor',
384 tb_offset = 1).text
385 # Hold a formatted traceback if one is generated.
386 self._tb = None
387
388 threading.Thread.__init__(self)
389
390 def __str__(self):
391 return self.strform
392
393 def __repr__(self):
394 return '<BackgroundJob: %s>' % self.strform
395
396 def traceback(self):
397 print self._tb
398
399 def run(self):
400 try:
401 self.status = BackgroundJobBase.stat_running
402 self.stat_code = BackgroundJobBase.stat_running_c
403 self.result = self.call()
404 except:
405 self.status = BackgroundJobBase.stat_dead
406 self.stat_code = BackgroundJobBase.stat_dead_c
407 self.finished = None
408 self.result = ('<BackgroundJob died, call job.traceback() for details>')
409 self._tb = self._make_tb()
410 else:
411 self.status = BackgroundJobBase.stat_completed
412 self.stat_code = BackgroundJobBase.stat_completed_c
413 self.finished = True
414
415 class BackgroundJobExpr(BackgroundJobBase):
416 """Evaluate an expression as a background job (uses a separate thread)."""
417
418 def __init__(self,expression,glob=None,loc=None):
419 """Create a new job from a string which can be fed to eval().
420
421 global/locals dicts can be provided, which will be passed to the eval
422 call."""
423
424 # fail immediately if the given expression can't be compiled
425 self.code = compile(expression,'<BackgroundJob compilation>','eval')
426
427 if glob is None:
428 glob = {}
429 if loc is None:
430 loc = {}
431
432 self.expression = self.strform = expression
433 self.glob = glob
434 self.loc = loc
435 self._init()
436
437 def call(self):
438 return eval(self.code,self.glob,self.loc)
439
440 class BackgroundJobFunc(BackgroundJobBase):
441 """Run a function call as a background job (uses a separate thread)."""
442
443 def __init__(self,func,*args,**kwargs):
444 """Create a new job from a callable object.
445
446 Any positional arguments and keyword args given to this constructor
447 after the initial callable are passed directly to it."""
448
449 assert callable(func),'first argument must be callable'
450
451 if args is None:
452 args = []
453 if kwargs is None:
454 kwargs = {}
455
456 self.func = func
457 self.args = args
458 self.kwargs = kwargs
459 # The string form will only include the function passed, because
460 # generating string representations of the arguments is a potentially
461 # _very_ expensive operation (e.g. with large arrays).
462 self.strform = str(func)
463 self._init()
464
465 def call(self):
466 return self.func(*self.args,**self.kwargs)
467
468
469 if __name__=='__main__':
470
471 import time
472
473 def sleepfunc(interval=2,*a,**kw):
474 args = dict(interval=interval,
475 args=a,
476 kwargs=kw)
477 time.sleep(interval)
478 return args
479
480 def diefunc(interval=2,*a,**kw):
481 time.sleep(interval)
482 die
483
484 def printfunc(interval=1,reps=5):
485 for n in range(reps):
486 time.sleep(interval)
487 print 'In the background...'
488
489 jobs = BackgroundJobManager()
490 # first job will have # 0
491 jobs.new(sleepfunc,4)
492 jobs.new(sleepfunc,kw={'reps':2})
493 # This makes a job which will die
494 jobs.new(diefunc,1)
495 jobs.new('printfunc(1,3)')
496
497 # after a while, you can get the traceback of a dead job. Run the line
498 # below again interactively until it prints a traceback (check the status
499 # of the job):
500 print jobs[1].status
501 jobs[1].traceback()
502
503 # Run this line again until the printed result changes
504 print "The result of job #0 is:",jobs[0].result
@@ -0,0 +1,184 b''
1 # -*- coding: utf-8 -*-
2 """
3 A module to change reload() so that it acts recursively.
4 To enable it type:
5 >>> import __builtin__, deep_reload
6 >>> __builtin__.reload = deep_reload.reload
7 You can then disable it with:
8 >>> __builtin__.reload = deep_reload.original_reload
9
10 Alternatively, you can add a dreload builtin alongside normal reload with:
11 >>> __builtin__.dreload = deep_reload.reload
12
13 This code is almost entirely based on knee.py from the standard library.
14
15 $Id: deep_reload.py 410 2004-11-04 07:58:17Z fperez $"""
16
17 #*****************************************************************************
18 # Copyright (C) 2001 Nathaniel Gray <n8gray@caltech.edu>
19 #
20 # Distributed under the terms of the BSD License. The full license is in
21 # the file COPYING, distributed as part of this software.
22 #*****************************************************************************
23
24 from IPython import Release # do it explicitly so pydoc can see it - pydoc bug
25 __author__ = '%s <%s>' % Release.authors['Nathan']
26 __license__ = Release.license
27 __version__ = "0.5"
28 __date__ = "21 August 2001"
29
30 import sys, imp, __builtin__
31
32 # Replacement for __import__()
33 def deep_import_hook(name, globals=None, locals=None, fromlist=None):
34 parent = determine_parent(globals)
35 q, tail = find_head_package(parent, name)
36 m = load_tail(q, tail)
37 if not fromlist:
38 return q
39 if hasattr(m, "__path__"):
40 ensure_fromlist(m, fromlist)
41 return m
42
43 def determine_parent(globals):
44 if not globals or not globals.has_key("__name__"):
45 return None
46 pname = globals['__name__']
47 if globals.has_key("__path__"):
48 parent = sys.modules[pname]
49 assert globals is parent.__dict__
50 return parent
51 if '.' in pname:
52 i = pname.rfind('.')
53 pname = pname[:i]
54 parent = sys.modules[pname]
55 assert parent.__name__ == pname
56 return parent
57 return None
58
59 def find_head_package(parent, name):
60 # Import the first
61 if '.' in name:
62 # 'some.nested.package' -> head = 'some', tail = 'nested.package'
63 i = name.find('.')
64 head = name[:i]
65 tail = name[i+1:]
66 else:
67 # 'packagename' -> head = 'packagename', tail = ''
68 head = name
69 tail = ""
70 if parent:
71 # If this is a subpackage then qname = parent's name + head
72 qname = "%s.%s" % (parent.__name__, head)
73 else:
74 qname = head
75 q = import_module(head, qname, parent)
76 if q: return q, tail
77 if parent:
78 qname = head
79 parent = None
80 q = import_module(head, qname, parent)
81 if q: return q, tail
82 raise ImportError, "No module named " + qname
83
84 def load_tail(q, tail):
85 m = q
86 while tail:
87 i = tail.find('.')
88 if i < 0: i = len(tail)
89 head, tail = tail[:i], tail[i+1:]
90
91 # fperez: fix dotted.name reloading failures by changing:
92 #mname = "%s.%s" % (m.__name__, head)
93 # to:
94 mname = m.__name__
95 # This needs more testing!!! (I don't understand this module too well)
96
97 #print '** head,tail=|%s|->|%s|, mname=|%s|' % (head,tail,mname) # dbg
98 m = import_module(head, mname, m)
99 if not m:
100 raise ImportError, "No module named " + mname
101 return m
102
103 def ensure_fromlist(m, fromlist, recursive=0):
104 for sub in fromlist:
105 if sub == "*":
106 if not recursive:
107 try:
108 all = m.__all__
109 except AttributeError:
110 pass
111 else:
112 ensure_fromlist(m, all, 1)
113 continue
114 if sub != "*" and not hasattr(m, sub):
115 subname = "%s.%s" % (m.__name__, sub)
116 submod = import_module(sub, subname, m)
117 if not submod:
118 raise ImportError, "No module named " + subname
119
120 # Need to keep track of what we've already reloaded to prevent cyclic evil
121 found_now = {}
122
123 def import_module(partname, fqname, parent):
124 global found_now
125 if found_now.has_key(fqname):
126 try:
127 return sys.modules[fqname]
128 except KeyError:
129 pass
130
131 print 'Reloading', fqname #, sys.excepthook is sys.__excepthook__, \
132 #sys.displayhook is sys.__displayhook__
133
134 found_now[fqname] = 1
135 try:
136 fp, pathname, stuff = imp.find_module(partname,
137 parent and parent.__path__)
138 except ImportError:
139 return None
140
141 try:
142 m = imp.load_module(fqname, fp, pathname, stuff)
143 finally:
144 if fp: fp.close()
145
146 if parent:
147 setattr(parent, partname, m)
148
149 return m
150
151 def deep_reload_hook(module):
152 name = module.__name__
153 if '.' not in name:
154 return import_module(name, name, None)
155 i = name.rfind('.')
156 pname = name[:i]
157 parent = sys.modules[pname]
158 return import_module(name[i+1:], name, parent)
159
160 # Save the original hooks
161 original_reload = __builtin__.reload
162
163 # Replacement for reload()
164 def reload(module, exclude=['sys', '__builtin__', '__main__']):
165 """Recursively reload all modules used in the given module. Optionally
166 takes a list of modules to exclude from reloading. The default exclude
167 list contains sys, __main__, and __builtin__, to prevent, e.g., resetting
168 display, exception, and io hooks.
169 """
170 global found_now
171 for i in exclude:
172 found_now[i] = 1
173 original_import = __builtin__.__import__
174 __builtin__.__import__ = deep_import_hook
175 try:
176 ret = deep_reload_hook(module)
177 finally:
178 __builtin__.__import__ = original_import
179 found_now = {}
180 return ret
181
182 # Uncomment the following to automatically activate deep reloading whenever
183 # this module is imported
184 #__builtin__.reload = reload
This diff has been collapsed as it changes many lines, (1519 lines changed) Show them Hide them
@@ -0,0 +1,1519 b''
1 # -*- coding: utf-8 -*-
2 """
3 General purpose utilities.
4
5 This is a grab-bag of stuff I find useful in most programs I write. Some of
6 these things are also convenient when working at the command line.
7
8 $Id: genutils.py 543 2005-03-18 09:23:48Z fperez $"""
9
10 #*****************************************************************************
11 # Copyright (C) 2001-2004 Fernando Perez. <fperez@colorado.edu>
12 #
13 # Distributed under the terms of the BSD License. The full license is in
14 # the file COPYING, distributed as part of this software.
15 #*****************************************************************************
16
17 from IPython import Release
18 __author__ = '%s <%s>' % Release.authors['Fernando']
19 __license__ = Release.license
20
21 #****************************************************************************
22 # required modules
23 import __main__
24 import types,commands,time,sys,os,re,shutil
25 import tempfile
26 from IPython.Itpl import Itpl,itpl,printpl
27 from IPython import DPyGetOpt
28
29 #****************************************************************************
30 # Exceptions
31 class Error(Exception):
32 """Base class for exceptions in this module."""
33 pass
34
35 #----------------------------------------------------------------------------
36 class Stream:
37 """Simple class to hold the various I/O streams in Term"""
38
39 def __init__(self,stream,name):
40 self.stream = stream
41 self.name = name
42 try:
43 self.fileno = stream.fileno()
44 except AttributeError:
45 msg = ("Stream <%s> looks suspicious: it lacks a 'fileno' attribute."
46 % name)
47 print >> sys.stderr, 'WARNING:',msg
48 try:
49 self.mode = stream.mode
50 except AttributeError:
51 msg = ("Stream <%s> looks suspicious: it lacks a 'mode' attribute."
52 % name)
53 print >> sys.stderr, 'WARNING:',msg
54
55 class Term:
56 """ Term holds the file or file-like objects for handling I/O operations.
57
58 These are normally just sys.stdin, sys.stdout and sys.stderr but for
59 Windows they can can replaced to allow editing the strings before they are
60 displayed."""
61
62 # In the future, having IPython channel all its I/O operations through
63 # this class will make it easier to embed it into other environments which
64 # are not a normal terminal (such as a GUI-based shell)
65 in_s = Stream(sys.stdin,'cin')
66 out_s = Stream(sys.stdout,'cout')
67 err_s = Stream(sys.stderr,'cerr')
68
69 # Store the three streams in (err,out,in) order so that if we need to reopen
70 # them, the error channel is reopened first to provide info.
71 streams = [err_s,out_s,in_s]
72
73 # The class globals should be the actual 'bare' streams for normal I/O to work
74 cin = streams[2].stream
75 cout = streams[1].stream
76 cerr = streams[0].stream
77
78 def reopen_all(cls):
79 """Reopen all streams if necessary.
80
81 This should only be called if it is suspected that someting closed
82 accidentally one of the I/O streams."""
83
84 any_closed = 0
85
86 for sn in range(len(cls.streams)):
87 st = cls.streams[sn]
88 if st.stream.closed:
89 any_closed = 1
90 new_stream = os.fdopen(os.dup(st.fileno), st.mode,0)
91 cls.streams[sn] = Stream(new_stream,st.name)
92 print >> cls.streams[0].stream, \
93 '\nWARNING:\nStream Term.%s had to be reopened!' % st.name
94
95 # Rebuild the class globals
96 cls.cin = cls.streams[2].stream
97 cls.cout = cls.streams[1].stream
98 cls.cerr = cls.streams[0].stream
99
100 reopen_all = classmethod(reopen_all)
101
102 def set_stdout(cls,stream):
103 """Set the stream """
104 cls.cout = stream
105 set_stdout = classmethod(set_stdout)
106
107 def set_stderr(cls,stream):
108 cls.cerr = stream
109 set_stderr = classmethod(set_stderr)
110
111 # Windows-specific code to load Gary Bishop's readline and configure it
112 # automatically for the users
113 # Note: os.name on cygwin returns posix, so this should only pick up 'native'
114 # windows. Cygwin returns 'cygwin' for sys.platform.
115 if os.name == 'nt':
116 try:
117 import readline
118 except ImportError:
119 pass
120 else:
121 try:
122 _out = readline.GetOutputFile()
123 except AttributeError:
124 pass
125 else:
126 Term.set_stdout(_out)
127 Term.set_stderr(_out)
128 del _out
129
130 #****************************************************************************
131 # Generic warning/error printer, used by everything else
132 def warn(msg,level=2,exit_val=1):
133 """Standard warning printer. Gives formatting consistency.
134
135 Output is sent to Term.cerr (sys.stderr by default).
136
137 Options:
138
139 -level(2): allows finer control:
140 0 -> Do nothing, dummy function.
141 1 -> Print message.
142 2 -> Print 'WARNING:' + message. (Default level).
143 3 -> Print 'ERROR:' + message.
144 4 -> Print 'FATAL ERROR:' + message and trigger a sys.exit(exit_val).
145
146 -exit_val (1): exit value returned by sys.exit() for a level 4
147 warning. Ignored for all other levels."""
148
149 if level>0:
150 header = ['','','WARNING: ','ERROR: ','FATAL ERROR: ']
151 print >> Term.cerr, '%s%s' % (header[level],msg)
152 if level == 4:
153 print >> Term.cerr,'Exiting.\n'
154 sys.exit(exit_val)
155
156 def info(msg):
157 """Equivalent to warn(msg,level=1)."""
158
159 warn(msg,level=1)
160
161 def error(msg):
162 """Equivalent to warn(msg,level=3)."""
163
164 warn(msg,level=3)
165
166 def fatal(msg,exit_val=1):
167 """Equivalent to warn(msg,exit_val=exit_val,level=4)."""
168
169 warn(msg,exit_val=exit_val,level=4)
170
171 #----------------------------------------------------------------------------
172 StringTypes = types.StringTypes
173
174 # Basic timing functionality
175
176 # If possible (Unix), use the resource module instead of time.clock()
177 try:
178 import resource
179 def clock():
180 """clock() -> floating point number
181
182 Return the CPU time in seconds (user time only, system time is
183 ignored) since the start of the process. This is done via a call to
184 resource.getrusage, so it avoids the wraparound problems in
185 time.clock()."""
186
187 return resource.getrusage(resource.RUSAGE_SELF)[0]
188
189 def clock2():
190 """clock2() -> (t_user,t_system)
191
192 Similar to clock(), but return a tuple of user/system times."""
193 return resource.getrusage(resource.RUSAGE_SELF)[:2]
194
195 except ImportError:
196 clock = time.clock
197 def clock2():
198 """Under windows, system CPU time can't be measured.
199
200 This just returns clock() and zero."""
201 return time.clock(),0.0
202
203 def timings_out(reps,func,*args,**kw):
204 """timings_out(reps,func,*args,**kw) -> (t_total,t_per_call,output)
205
206 Execute a function reps times, return a tuple with the elapsed total
207 CPU time in seconds, the time per call and the function's output.
208
209 Under Unix, the return value is the sum of user+system time consumed by
210 the process, computed via the resource module. This prevents problems
211 related to the wraparound effect which the time.clock() function has.
212
213 Under Windows the return value is in wall clock seconds. See the
214 documentation for the time module for more details."""
215
216 reps = int(reps)
217 assert reps >=1, 'reps must be >= 1'
218 if reps==1:
219 start = clock()
220 out = func(*args,**kw)
221 tot_time = clock()-start
222 else:
223 rng = xrange(reps-1) # the last time is executed separately to store output
224 start = clock()
225 for dummy in rng: func(*args,**kw)
226 out = func(*args,**kw) # one last time
227 tot_time = clock()-start
228 av_time = tot_time / reps
229 return tot_time,av_time,out
230
231 def timings(reps,func,*args,**kw):
232 """timings(reps,func,*args,**kw) -> (t_total,t_per_call)
233
234 Execute a function reps times, return a tuple with the elapsed total CPU
235 time in seconds and the time per call. These are just the first two values
236 in timings_out()."""
237
238 return timings_out(reps,func,*args,**kw)[0:2]
239
240 def timing(func,*args,**kw):
241 """timing(func,*args,**kw) -> t_total
242
243 Execute a function once, return the elapsed total CPU time in
244 seconds. This is just the first value in timings_out()."""
245
246 return timings_out(1,func,*args,**kw)[0]
247
248 #****************************************************************************
249 # file and system
250
251 def system(cmd,verbose=0,debug=0,header=''):
252 """Execute a system command, return its exit status.
253
254 Options:
255
256 - verbose (0): print the command to be executed.
257
258 - debug (0): only print, do not actually execute.
259
260 - header (''): Header to print on screen prior to the executed command (it
261 is only prepended to the command, no newlines are added).
262
263 Note: a stateful version of this function is available through the
264 SystemExec class."""
265
266 stat = 0
267 if verbose or debug: print header+cmd
268 sys.stdout.flush()
269 if not debug: stat = os.system(cmd)
270 return stat
271
272 def shell(cmd,verbose=0,debug=0,header=''):
273 """Execute a command in the system shell, always return None.
274
275 Options:
276
277 - verbose (0): print the command to be executed.
278
279 - debug (0): only print, do not actually execute.
280
281 - header (''): Header to print on screen prior to the executed command (it
282 is only prepended to the command, no newlines are added).
283
284 Note: this is similar to genutils.system(), but it returns None so it can
285 be conveniently used in interactive loops without getting the return value
286 (typically 0) printed many times."""
287
288 stat = 0
289 if verbose or debug: print header+cmd
290 # flush stdout so we don't mangle python's buffering
291 sys.stdout.flush()
292 if not debug:
293 os.system(cmd)
294
295 def getoutput(cmd,verbose=0,debug=0,header='',split=0):
296 """Dummy substitute for perl's backquotes.
297
298 Executes a command and returns the output.
299
300 Accepts the same arguments as system(), plus:
301
302 - split(0): if true, the output is returned as a list split on newlines.
303
304 Note: a stateful version of this function is available through the
305 SystemExec class."""
306
307 if verbose or debug: print header+cmd
308 if not debug:
309 output = commands.getoutput(cmd)
310 if split:
311 return output.split('\n')
312 else:
313 return output
314
315 def getoutputerror(cmd,verbose=0,debug=0,header='',split=0):
316 """Return (standard output,standard error) of executing cmd in a shell.
317
318 Accepts the same arguments as system(), plus:
319
320 - split(0): if true, each of stdout/err is returned as a list split on
321 newlines.
322
323 Note: a stateful version of this function is available through the
324 SystemExec class."""
325
326 if verbose or debug: print header+cmd
327 if not cmd:
328 if split:
329 return [],[]
330 else:
331 return '',''
332 if not debug:
333 pin,pout,perr = os.popen3(cmd)
334 tout = pout.read().rstrip()
335 terr = perr.read().rstrip()
336 pin.close()
337 pout.close()
338 perr.close()
339 if split:
340 return tout.split('\n'),terr.split('\n')
341 else:
342 return tout,terr
343
344 # for compatibility with older naming conventions
345 xsys = system
346 bq = getoutput
347
348 class SystemExec:
349 """Access the system and getoutput functions through a stateful interface.
350
351 Note: here we refer to the system and getoutput functions from this
352 library, not the ones from the standard python library.
353
354 This class offers the system and getoutput functions as methods, but the
355 verbose, debug and header parameters can be set for the instance (at
356 creation time or later) so that they don't need to be specified on each
357 call.
358
359 For efficiency reasons, there's no way to override the parameters on a
360 per-call basis other than by setting instance attributes. If you need
361 local overrides, it's best to directly call system() or getoutput().
362
363 The following names are provided as alternate options:
364 - xsys: alias to system
365 - bq: alias to getoutput
366
367 An instance can then be created as:
368 >>> sysexec = SystemExec(verbose=1,debug=0,header='Calling: ')
369
370 And used as:
371 >>> sysexec.xsys('pwd')
372 >>> dirlist = sysexec.bq('ls -l')
373 """
374
375 def __init__(self,verbose=0,debug=0,header='',split=0):
376 """Specify the instance's values for verbose, debug and header."""
377 setattr_list(self,'verbose debug header split')
378
379 def system(self,cmd):
380 """Stateful interface to system(), with the same keyword parameters."""
381
382 system(cmd,self.verbose,self.debug,self.header)
383
384 def shell(self,cmd):
385 """Stateful interface to shell(), with the same keyword parameters."""
386
387 shell(cmd,self.verbose,self.debug,self.header)
388
389 xsys = system # alias
390
391 def getoutput(self,cmd):
392 """Stateful interface to getoutput()."""
393
394 return getoutput(cmd,self.verbose,self.debug,self.header,self.split)
395
396 def getoutputerror(self,cmd):
397 """Stateful interface to getoutputerror()."""
398
399 return getoutputerror(cmd,self.verbose,self.debug,self.header,self.split)
400
401 bq = getoutput # alias
402
403 #-----------------------------------------------------------------------------
404 def mutex_opts(dict,ex_op):
405 """Check for presence of mutually exclusive keys in a dict.
406
407 Call: mutex_opts(dict,[[op1a,op1b],[op2a,op2b]...]"""
408 for op1,op2 in ex_op:
409 if op1 in dict and op2 in dict:
410 raise ValueError,'\n*** ERROR in Arguments *** '\
411 'Options '+op1+' and '+op2+' are mutually exclusive.'
412
413 #-----------------------------------------------------------------------------
414 def filefind(fname,alt_dirs = None):
415 """Return the given filename either in the current directory, if it
416 exists, or in a specified list of directories.
417
418 ~ expansion is done on all file and directory names.
419
420 Upon an unsuccessful search, raise an IOError exception."""
421
422 if alt_dirs is None:
423 try:
424 alt_dirs = get_home_dir()
425 except HomeDirError:
426 alt_dirs = os.getcwd()
427 search = [fname] + list_strings(alt_dirs)
428 search = map(os.path.expanduser,search)
429 #print 'search list for',fname,'list:',search # dbg
430 fname = search[0]
431 if os.path.isfile(fname):
432 return fname
433 for direc in search[1:]:
434 testname = os.path.join(direc,fname)
435 #print 'testname',testname # dbg
436 if os.path.isfile(testname):
437 return testname
438 raise IOError,'File' + `fname` + \
439 ' not found in current or supplied directories:' + `alt_dirs`
440
441 #----------------------------------------------------------------------------
442 def target_outdated(target,deps):
443 """Determine whether a target is out of date.
444
445 target_outdated(target,deps) -> 1/0
446
447 deps: list of filenames which MUST exist.
448 target: single filename which may or may not exist.
449
450 If target doesn't exist or is older than any file listed in deps, return
451 true, otherwise return false.
452 """
453 try:
454 target_time = os.path.getmtime(target)
455 except os.error:
456 return 1
457 for dep in deps:
458 dep_time = os.path.getmtime(dep)
459 if dep_time > target_time:
460 #print "For target",target,"Dep failed:",dep # dbg
461 #print "times (dep,tar):",dep_time,target_time # dbg
462 return 1
463 return 0
464
465 #-----------------------------------------------------------------------------
466 def target_update(target,deps,cmd):
467 """Update a target with a given command given a list of dependencies.
468
469 target_update(target,deps,cmd) -> runs cmd if target is outdated.
470
471 This is just a wrapper around target_outdated() which calls the given
472 command if target is outdated."""
473
474 if target_outdated(target,deps):
475 xsys(cmd)
476
477 #----------------------------------------------------------------------------
478 def unquote_ends(istr):
479 """Remove a single pair of quotes from the endpoints of a string."""
480
481 if not istr:
482 return istr
483 if (istr[0]=="'" and istr[-1]=="'") or \
484 (istr[0]=='"' and istr[-1]=='"'):
485 return istr[1:-1]
486 else:
487 return istr
488
489 #----------------------------------------------------------------------------
490 def process_cmdline(argv,names=[],defaults={},usage=''):
491 """ Process command-line options and arguments.
492
493 Arguments:
494
495 - argv: list of arguments, typically sys.argv.
496
497 - names: list of option names. See DPyGetOpt docs for details on options
498 syntax.
499
500 - defaults: dict of default values.
501
502 - usage: optional usage notice to print if a wrong argument is passed.
503
504 Return a dict of options and a list of free arguments."""
505
506 getopt = DPyGetOpt.DPyGetOpt()
507 getopt.setIgnoreCase(0)
508 getopt.parseConfiguration(names)
509
510 try:
511 getopt.processArguments(argv)
512 except:
513 print usage
514 warn(`sys.exc_value`,level=4)
515
516 defaults.update(getopt.optionValues)
517 args = getopt.freeValues
518
519 return defaults,args
520
521 #----------------------------------------------------------------------------
522 def optstr2types(ostr):
523 """Convert a string of option names to a dict of type mappings.
524
525 optstr2types(str) -> {None:'string_opts',int:'int_opts',float:'float_opts'}
526
527 This is used to get the types of all the options in a string formatted
528 with the conventions of DPyGetOpt. The 'type' None is used for options
529 which are strings (they need no further conversion). This function's main
530 use is to get a typemap for use with read_dict().
531 """
532
533 typeconv = {None:'',int:'',float:''}
534 typemap = {'s':None,'i':int,'f':float}
535 opt_re = re.compile(r'([\w]*)([^:=]*:?=?)([sif]?)')
536
537 for w in ostr.split():
538 oname,alias,otype = opt_re.match(w).groups()
539 if otype == '' or alias == '!': # simple switches are integers too
540 otype = 'i'
541 typeconv[typemap[otype]] += oname + ' '
542 return typeconv
543
544 #----------------------------------------------------------------------------
545 def read_dict(filename,type_conv=None,**opt):
546
547 """Read a dictionary of key=value pairs from an input file, optionally
548 performing conversions on the resulting values.
549
550 read_dict(filename,type_conv,**opt) -> dict
551
552 Only one value per line is accepted, the format should be
553 # optional comments are ignored
554 key value\n
555
556 Args:
557
558 - type_conv: A dictionary specifying which keys need to be converted to
559 which types. By default all keys are read as strings. This dictionary
560 should have as its keys valid conversion functions for strings
561 (int,long,float,complex, or your own). The value for each key
562 (converter) should be a whitespace separated string containing the names
563 of all the entries in the file to be converted using that function. For
564 keys to be left alone, use None as the conversion function (only needed
565 with purge=1, see below).
566
567 - opt: dictionary with extra options as below (default in parens)
568
569 purge(0): if set to 1, all keys *not* listed in type_conv are purged out
570 of the dictionary to be returned. If purge is going to be used, the
571 set of keys to be left as strings also has to be explicitly specified
572 using the (non-existent) conversion function None.
573
574 fs(None): field separator. This is the key/value separator to be used
575 when parsing the file. The None default means any whitespace [behavior
576 of string.split()].
577
578 strip(0): if 1, strip string values of leading/trailinig whitespace.
579
580 warn(1): warning level if requested keys are not found in file.
581 - 0: silently ignore.
582 - 1: inform but proceed.
583 - 2: raise KeyError exception.
584
585 no_empty(0): if 1, remove keys with whitespace strings as a value.
586
587 unique([]): list of keys (or space separated string) which can't be
588 repeated. If one such key is found in the file, each new instance
589 overwrites the previous one. For keys not listed here, the behavior is
590 to make a list of all appearances.
591
592 Example:
593 If the input file test.ini has:
594 i 3
595 x 4.5
596 y 5.5
597 s hi ho
598 Then:
599
600 >>> type_conv={int:'i',float:'x',None:'s'}
601 >>> read_dict('test.ini')
602 {'i': '3', 's': 'hi ho', 'x': '4.5', 'y': '5.5'}
603 >>> read_dict('test.ini',type_conv)
604 {'i': 3, 's': 'hi ho', 'x': 4.5, 'y': '5.5'}
605 >>> read_dict('test.ini',type_conv,purge=1)
606 {'i': 3, 's': 'hi ho', 'x': 4.5}
607 """
608
609 # starting config
610 opt.setdefault('purge',0)
611 opt.setdefault('fs',None) # field sep defaults to any whitespace
612 opt.setdefault('strip',0)
613 opt.setdefault('warn',1)
614 opt.setdefault('no_empty',0)
615 opt.setdefault('unique','')
616 if type(opt['unique']) in StringTypes:
617 unique_keys = qw(opt['unique'])
618 elif type(opt['unique']) in (types.TupleType,types.ListType):
619 unique_keys = opt['unique']
620 else:
621 raise ValueError, 'Unique keys must be given as a string, List or Tuple'
622
623 dict = {}
624 # first read in table of values as strings
625 file = open(filename,'r')
626 for line in file.readlines():
627 line = line.strip()
628 if len(line) and line[0]=='#': continue
629 if len(line)>0:
630 lsplit = line.split(opt['fs'],1)
631 try:
632 key,val = lsplit
633 except ValueError:
634 key,val = lsplit[0],''
635 key = key.strip()
636 if opt['strip']: val = val.strip()
637 if val == "''" or val == '""': val = ''
638 if opt['no_empty'] and (val=='' or val.isspace()):
639 continue
640 # if a key is found more than once in the file, build a list
641 # unless it's in the 'unique' list. In that case, last found in file
642 # takes precedence. User beware.
643 try:
644 if dict[key] and key in unique_keys:
645 dict[key] = val
646 elif type(dict[key]) is types.ListType:
647 dict[key].append(val)
648 else:
649 dict[key] = [dict[key],val]
650 except KeyError:
651 dict[key] = val
652 # purge if requested
653 if opt['purge']:
654 accepted_keys = qwflat(type_conv.values())
655 for key in dict.keys():
656 if key in accepted_keys: continue
657 del(dict[key])
658 # now convert if requested
659 if type_conv==None: return dict
660 conversions = type_conv.keys()
661 try: conversions.remove(None)
662 except: pass
663 for convert in conversions:
664 for val in qw(type_conv[convert]):
665 try:
666 dict[val] = convert(dict[val])
667 except KeyError,e:
668 if opt['warn'] == 0:
669 pass
670 elif opt['warn'] == 1:
671 print >>sys.stderr, 'Warning: key',val,\
672 'not found in file',filename
673 elif opt['warn'] == 2:
674 raise KeyError,e
675 else:
676 raise ValueError,'Warning level must be 0,1 or 2'
677
678 return dict
679
680 #----------------------------------------------------------------------------
681 def flag_calls(func):
682 """Wrap a function to detect and flag when it gets called.
683
684 This is a decorator which takes a function and wraps it in a function with
685 a 'called' attribute. wrapper.called is initialized to False.
686
687 The wrapper.called attribute is set to False right before each call to the
688 wrapped function, so if the call fails it remains False. After the call
689 completes, wrapper.called is set to True and the output is returned.
690
691 Testing for truth in wrapper.called allows you to determine if a call to
692 func() was attempted and succeeded."""
693
694 def wrapper(*args,**kw):
695 wrapper.called = False
696 out = func(*args,**kw)
697 wrapper.called = True
698 return out
699
700 wrapper.called = False
701 wrapper.__doc__ = func.__doc__
702 return wrapper
703
704 #----------------------------------------------------------------------------
705 class HomeDirError(Error):
706 pass
707
708 def get_home_dir():
709 """Return the closest possible equivalent to a 'home' directory.
710
711 We first try $HOME. Absent that, on NT it's $HOMEDRIVE\$HOMEPATH.
712
713 Currently only Posix and NT are implemented, a HomeDirError exception is
714 raised for all other OSes. """ #'
715
716 try:
717 return os.environ['HOME']
718 except KeyError:
719 if os.name == 'posix':
720 raise HomeDirError,'undefined $HOME, IPython can not proceed.'
721 elif os.name == 'nt':
722 # For some strange reason, win9x returns 'nt' for os.name.
723 try:
724 return os.path.join(os.environ['HOMEDRIVE'],os.environ['HOMEPATH'])
725 except:
726 try:
727 # Use the registry to get the 'My Documents' folder.
728 import _winreg as wreg
729 key = wreg.OpenKey(wreg.HKEY_CURRENT_USER,
730 "Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders")
731 homedir = wreg.QueryValueEx(key,'Personal')[0]
732 key.Close()
733 return homedir
734 except:
735 return 'C:\\'
736 elif os.name == 'dos':
737 # Desperate, may do absurd things in classic MacOS. May work under DOS.
738 return 'C:\\'
739 else:
740 raise HomeDirError,'support for your operating system not implemented.'
741
742 #****************************************************************************
743 # strings and text
744
745 class LSString(str):
746 """String derivative with a special access attributes.
747
748 These are normal strings, but with the special attributes:
749
750 .l (or .list) : value as list (split on newlines).
751 .n (or .nlstr): original value (the string itself).
752 .s (or .spstr): value as whitespace-separated string.
753
754 Any values which require transformations are computed only once and
755 cached.
756
757 Such strings are very useful to efficiently interact with the shell, which
758 typically only understands whitespace-separated options for commands."""
759
760 def get_list(self):
761 try:
762 return self.__list
763 except AttributeError:
764 self.__list = self.split('\n')
765 return self.__list
766
767 l = list = property(get_list)
768
769 def get_spstr(self):
770 try:
771 return self.__spstr
772 except AttributeError:
773 self.__spstr = self.replace('\n',' ')
774 return self.__spstr
775
776 s = spstr = property(get_spstr)
777
778 def get_nlstr(self):
779 return self
780
781 n = nlstr = property(get_nlstr)
782
783 class SList(list):
784 """List derivative with a special access attributes.
785
786 These are normal lists, but with the special attributes:
787
788 .l (or .list) : value as list (the list itself).
789 .n (or .nlstr): value as a string, joined on newlines.
790 .s (or .spstr): value as a string, joined on spaces.
791
792 Any values which require transformations are computed only once and
793 cached."""
794
795 def get_list(self):
796 return self
797
798 l = list = property(get_list)
799
800 def get_spstr(self):
801 try:
802 return self.__spstr
803 except AttributeError:
804 self.__spstr = ' '.join(self)
805 return self.__spstr
806
807 s = spstr = property(get_spstr)
808
809 def get_nlstr(self):
810 try:
811 return self.__nlstr
812 except AttributeError:
813 self.__nlstr = '\n'.join(self)
814 return self.__nlstr
815
816 n = nlstr = property(get_nlstr)
817
818 def raw_input_multi(header='', ps1='==> ', ps2='..> ',terminate_str = '.'):
819 """Take multiple lines of input.
820
821 A list with each line of input as a separate element is returned when a
822 termination string is entered (defaults to a single '.'). Input can also
823 terminate via EOF (^D in Unix, ^Z-RET in Windows).
824
825 Lines of input which end in \\ are joined into single entries (and a
826 secondary continuation prompt is issued as long as the user terminates
827 lines with \\). This allows entering very long strings which are still
828 meant to be treated as single entities.
829 """
830
831 try:
832 if header:
833 header += '\n'
834 lines = [raw_input(header + ps1)]
835 except EOFError:
836 return []
837 terminate = [terminate_str]
838 try:
839 while lines[-1:] != terminate:
840 new_line = raw_input(ps1)
841 while new_line.endswith('\\'):
842 new_line = new_line[:-1] + raw_input(ps2)
843 lines.append(new_line)
844
845 return lines[:-1] # don't return the termination command
846 except EOFError:
847 print
848 return lines
849
850 #----------------------------------------------------------------------------
851 def raw_input_ext(prompt='', ps2='... '):
852 """Similar to raw_input(), but accepts extended lines if input ends with \\."""
853
854 line = raw_input(prompt)
855 while line.endswith('\\'):
856 line = line[:-1] + raw_input(ps2)
857 return line
858
859 #----------------------------------------------------------------------------
860 def ask_yes_no(prompt,default=None):
861 """Asks a question and returns an integer 1/0 (y/n) answer.
862
863 If default is given (one of 'y','n'), it is used if the user input is
864 empty. Otherwise the question is repeated until an answer is given.
865 If EOF occurs 20 times consecutively, the default answer is assumed,
866 or if there is no default, an exception is raised to prevent infinite
867 loops.
868
869 Valid answers are: y/yes/n/no (match is not case sensitive)."""
870
871 answers = {'y':1,'n':0,'yes':1,'no':0}
872 ans = None
873 eofs, max_eofs = 0, 20
874 while ans not in answers.keys():
875 try:
876 ans = raw_input(prompt+' ').lower()
877 if not ans: # response was an empty string
878 ans = default
879 eofs = 0
880 except (EOFError,KeyboardInterrupt):
881 eofs = eofs + 1
882 if eofs >= max_eofs:
883 if default in answers.keys():
884 ans = default
885 else:
886 raise
887
888 return answers[ans]
889
890 #----------------------------------------------------------------------------
891 class EvalDict:
892 """
893 Emulate a dict which evaluates its contents in the caller's frame.
894
895 Usage:
896 >>>number = 19
897 >>>text = "python"
898 >>>print "%(text.capitalize())s %(number/9.0).1f rules!" % EvalDict()
899 """
900
901 # This version is due to sismex01@hebmex.com on c.l.py, and is basically a
902 # modified (shorter) version of:
903 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66018 by
904 # Skip Montanaro (skip@pobox.com).
905
906 def __getitem__(self, name):
907 frame = sys._getframe(1)
908 return eval(name, frame.f_globals, frame.f_locals)
909
910 EvalString = EvalDict # for backwards compatibility
911 #----------------------------------------------------------------------------
912 def qw(words,flat=0,sep=None,maxsplit=-1):
913 """Similar to Perl's qw() operator, but with some more options.
914
915 qw(words,flat=0,sep=' ',maxsplit=-1) -> words.split(sep,maxsplit)
916
917 words can also be a list itself, and with flat=1, the output will be
918 recursively flattened. Examples:
919
920 >>> qw('1 2')
921 ['1', '2']
922 >>> qw(['a b','1 2',['m n','p q']])
923 [['a', 'b'], ['1', '2'], [['m', 'n'], ['p', 'q']]]
924 >>> qw(['a b','1 2',['m n','p q']],flat=1)
925 ['a', 'b', '1', '2', 'm', 'n', 'p', 'q'] """
926
927 if type(words) in StringTypes:
928 return [word.strip() for word in words.split(sep,maxsplit)
929 if word and not word.isspace() ]
930 if flat:
931 return flatten(map(qw,words,[1]*len(words)))
932 return map(qw,words)
933
934 #----------------------------------------------------------------------------
935 def qwflat(words,sep=None,maxsplit=-1):
936 """Calls qw(words) in flat mode. It's just a convenient shorthand."""
937 return qw(words,1,sep,maxsplit)
938
939 #-----------------------------------------------------------------------------
940 def list_strings(arg):
941 """Always return a list of strings, given a string or list of strings
942 as input."""
943
944 if type(arg) in StringTypes: return [arg]
945 else: return arg
946
947 #----------------------------------------------------------------------------
948 def grep(pat,list,case=1):
949 """Simple minded grep-like function.
950 grep(pat,list) returns occurrences of pat in list, None on failure.
951
952 It only does simple string matching, with no support for regexps. Use the
953 option case=0 for case-insensitive matching."""
954
955 # This is pretty crude. At least it should implement copying only references
956 # to the original data in case it's big. Now it copies the data for output.
957 out=[]
958 if case:
959 for term in list:
960 if term.find(pat)>-1: out.append(term)
961 else:
962 lpat=pat.lower()
963 for term in list:
964 if term.lower().find(lpat)>-1: out.append(term)
965
966 if len(out): return out
967 else: return None
968
969 #----------------------------------------------------------------------------
970 def dgrep(pat,*opts):
971 """Return grep() on dir()+dir(__builtins__).
972
973 A very common use of grep() when working interactively."""
974
975 return grep(pat,dir(__main__)+dir(__main__.__builtins__),*opts)
976
977 #----------------------------------------------------------------------------
978 def idgrep(pat):
979 """Case-insensitive dgrep()"""
980
981 return dgrep(pat,0)
982
983 #----------------------------------------------------------------------------
984 def igrep(pat,list):
985 """Synonym for case-insensitive grep."""
986
987 return grep(pat,list,case=0)
988
989 #----------------------------------------------------------------------------
990 def indent(str,nspaces=4,ntabs=0):
991 """Indent a string a given number of spaces or tabstops.
992
993 indent(str,nspaces=4,ntabs=0) -> indent str by ntabs+nspaces.
994 """
995 if str is None:
996 return
997 ind = '\t'*ntabs+' '*nspaces
998 outstr = '%s%s' % (ind,str.replace(os.linesep,os.linesep+ind))
999 if outstr.endswith(os.linesep+ind):
1000 return outstr[:-len(ind)]
1001 else:
1002 return outstr
1003
1004 #-----------------------------------------------------------------------------
1005 def native_line_ends(filename,backup=1):
1006 """Convert (in-place) a file to line-ends native to the current OS.
1007
1008 If the optional backup argument is given as false, no backup of the
1009 original file is left. """
1010
1011 backup_suffixes = {'posix':'~','dos':'.bak','nt':'.bak','mac':'.bak'}
1012
1013 bak_filename = filename + backup_suffixes[os.name]
1014
1015 original = open(filename).read()
1016 shutil.copy2(filename,bak_filename)
1017 try:
1018 new = open(filename,'wb')
1019 new.write(os.linesep.join(original.splitlines()))
1020 new.write(os.linesep) # ALWAYS put an eol at the end of the file
1021 new.close()
1022 except:
1023 os.rename(bak_filename,filename)
1024 if not backup:
1025 try:
1026 os.remove(bak_filename)
1027 except:
1028 pass
1029
1030 #----------------------------------------------------------------------------
1031 def get_pager_cmd(pager_cmd = None):
1032 """Return a pager command.
1033
1034 Makes some attempts at finding an OS-correct one."""
1035
1036 if os.name == 'posix':
1037 default_pager_cmd = 'less -r' # -r for color control sequences
1038 elif os.name in ['nt','dos']:
1039 default_pager_cmd = 'type'
1040
1041 if pager_cmd is None:
1042 try:
1043 pager_cmd = os.environ['PAGER']
1044 except:
1045 pager_cmd = default_pager_cmd
1046 return pager_cmd
1047
1048 #-----------------------------------------------------------------------------
1049 def get_pager_start(pager,start):
1050 """Return the string for paging files with an offset.
1051
1052 This is the '+N' argument which less and more (under Unix) accept.
1053 """
1054
1055 if pager in ['less','more']:
1056 if start:
1057 start_string = '+' + str(start)
1058 else:
1059 start_string = ''
1060 else:
1061 start_string = ''
1062 return start_string
1063
1064 #----------------------------------------------------------------------------
1065 def page_dumb(strng,start=0,screen_lines=25):
1066 """Very dumb 'pager' in Python, for when nothing else works.
1067
1068 Only moves forward, same interface as page(), except for pager_cmd and
1069 mode."""
1070
1071 out_ln = strng.splitlines()[start:]
1072 screens = chop(out_ln,screen_lines-1)
1073 if len(screens) == 1:
1074 print >>Term.cout, os.linesep.join(screens[0])
1075 else:
1076 for scr in screens[0:-1]:
1077 print >>Term.cout, os.linesep.join(scr)
1078 ans = raw_input('---Return to continue, q to quit--- ')
1079 if ans.lower().startswith('q'):
1080 return
1081 print >>Term.cout, os.linesep.join(screens[-1])
1082
1083 #----------------------------------------------------------------------------
1084 def page(strng,start=0,screen_lines=0,pager_cmd = None):
1085 """Print a string, piping through a pager after a certain length.
1086
1087 The screen_lines parameter specifies the number of *usable* lines of your
1088 terminal screen (total lines minus lines you need to reserve to show other
1089 information).
1090
1091 If you set screen_lines to a number <=0, page() will try to auto-determine
1092 your screen size and will only use up to (screen_size+screen_lines) for
1093 printing, paging after that. That is, if you want auto-detection but need
1094 to reserve the bottom 3 lines of the screen, use screen_lines = -3, and for
1095 auto-detection without any lines reserved simply use screen_lines = 0.
1096
1097 If a string won't fit in the allowed lines, it is sent through the
1098 specified pager command. If none given, look for PAGER in the environment,
1099 and ultimately default to less.
1100
1101 If no system pager works, the string is sent through a 'dumb pager'
1102 written in python, very simplistic.
1103 """
1104
1105 # Ugly kludge, but calling curses.initscr() flat out crashes in emacs
1106 TERM = os.environ.get('TERM','dumb')
1107 if TERM in ['dumb','emacs'] and os.name != 'nt':
1108 print strng
1109 return
1110 # chop off the topmost part of the string we don't want to see
1111 str_lines = strng.split(os.linesep)[start:]
1112 str_toprint = os.linesep.join(str_lines)
1113 num_newlines = len(str_lines)
1114 len_str = len(str_toprint)
1115
1116 # Dumb heuristics to guesstimate number of on-screen lines the string
1117 # takes. Very basic, but good enough for docstrings in reasonable
1118 # terminals. If someone later feels like refining it, it's not hard.
1119 numlines = max(num_newlines,int(len_str/80)+1)
1120
1121 screen_lines_def = 25 # default value if we can't auto-determine
1122
1123 # auto-determine screen size
1124 if screen_lines <= 0:
1125 if TERM=='xterm':
1126 try:
1127 import curses
1128 if hasattr(curses,'initscr'):
1129 use_curses = 1
1130 else:
1131 use_curses = 0
1132 except ImportError:
1133 use_curses = 0
1134 else:
1135 # curses causes problems on many terminals other than xterm.
1136 use_curses = 0
1137 if use_curses:
1138 scr = curses.initscr()
1139 screen_lines_real,screen_cols = scr.getmaxyx()
1140 curses.endwin()
1141 screen_lines += screen_lines_real
1142 #print '***Screen size:',screen_lines_real,'lines x',\
1143 #screen_cols,'columns.' # dbg
1144 else:
1145 screen_lines += screen_lines_def
1146
1147 #print 'numlines',numlines,'screenlines',screen_lines # dbg
1148 if numlines <= screen_lines :
1149 #print '*** normal print' # dbg
1150 print >>Term.cout, str_toprint
1151 else:
1152 # Try to open pager and default to internal one if that fails.
1153 # All failure modes are tagged as 'retval=1', to match the return
1154 # value of a failed system command. If any intermediate attempt
1155 # sets retval to 1, at the end we resort to our own page_dumb() pager.
1156 pager_cmd = get_pager_cmd(pager_cmd)
1157 pager_cmd += ' ' + get_pager_start(pager_cmd,start)
1158 if os.name == 'nt':
1159 if pager_cmd.startswith('type'):
1160 # The default WinXP 'type' command is failing on complex strings.
1161 retval = 1
1162 else:
1163 tmpname = tempfile.mktemp('.txt')
1164 tmpfile = file(tmpname,'wt')
1165 tmpfile.write(strng)
1166 tmpfile.close()
1167 cmd = "%s < %s" % (pager_cmd,tmpname)
1168 if os.system(cmd):
1169 retval = 1
1170 else:
1171 retval = None
1172 os.remove(tmpname)
1173 else:
1174 try:
1175 retval = None
1176 # if I use popen4, things hang. No idea why.
1177 #pager,shell_out = os.popen4(pager_cmd)
1178 pager = os.popen(pager_cmd,'w')
1179 pager.write(strng)
1180 pager.close()
1181 retval = pager.close() # success returns None
1182 except IOError,msg: # broken pipe when user quits
1183 if msg.args == (32,'Broken pipe'):
1184 retval = None
1185 else:
1186 retval = 1
1187 except OSError:
1188 # Other strange problems, sometimes seen in Win2k/cygwin
1189 retval = 1
1190 if retval is not None:
1191 page_dumb(strng,screen_lines=screen_lines)
1192
1193 #----------------------------------------------------------------------------
1194 def page_file(fname,start = 0, pager_cmd = None):
1195 """Page a file, using an optional pager command and starting line.
1196 """
1197
1198 pager_cmd = get_pager_cmd(pager_cmd)
1199 pager_cmd += ' ' + get_pager_start(pager_cmd,start)
1200
1201 try:
1202 if os.environ['TERM'] in ['emacs','dumb']:
1203 raise EnvironmentError
1204 xsys(pager_cmd + ' ' + fname)
1205 except:
1206 try:
1207 if start > 0:
1208 start -= 1
1209 page(open(fname).read(),start)
1210 except:
1211 print 'Unable to show file',`fname`
1212
1213 #----------------------------------------------------------------------------
1214 def snip_print(str,width = 75,print_full = 0,header = ''):
1215 """Print a string snipping the midsection to fit in width.
1216
1217 print_full: mode control:
1218 - 0: only snip long strings
1219 - 1: send to page() directly.
1220 - 2: snip long strings and ask for full length viewing with page()
1221 Return 1 if snipping was necessary, 0 otherwise."""
1222
1223 if print_full == 1:
1224 page(header+str)
1225 return 0
1226
1227 print header,
1228 if len(str) < width:
1229 print str
1230 snip = 0
1231 else:
1232 whalf = int((width -5)/2)
1233 print str[:whalf] + ' <...> ' + str[-whalf:]
1234 snip = 1
1235 if snip and print_full == 2:
1236 if raw_input(header+' Snipped. View (y/n)? [N]').lower() == 'y':
1237 page(str)
1238 return snip
1239
1240 #****************************************************************************
1241 # lists, dicts and structures
1242
1243 def belong(candidates,checklist):
1244 """Check whether a list of items appear in a given list of options.
1245
1246 Returns a list of 1 and 0, one for each candidate given."""
1247
1248 return [x in checklist for x in candidates]
1249
1250 #----------------------------------------------------------------------------
1251 def uniq_stable(elems):
1252 """uniq_stable(elems) -> list
1253
1254 Return from an iterable, a list of all the unique elements in the input,
1255 but maintaining the order in which they first appear.
1256
1257 A naive solution to this problem which just makes a dictionary with the
1258 elements as keys fails to respect the stability condition, since
1259 dictionaries are unsorted by nature.
1260
1261 Note: All elements in the input must be valid dictionary keys for this
1262 routine to work, as it internally uses a dictionary for efficiency
1263 reasons."""
1264
1265 unique = []
1266 unique_dict = {}
1267 for nn in elems:
1268 if nn not in unique_dict:
1269 unique.append(nn)
1270 unique_dict[nn] = None
1271 return unique
1272
1273 #----------------------------------------------------------------------------
1274 class NLprinter:
1275 """Print an arbitrarily nested list, indicating index numbers.
1276
1277 An instance of this class called nlprint is available and callable as a
1278 function.
1279
1280 nlprint(list,indent=' ',sep=': ') -> prints indenting each level by 'indent'
1281 and using 'sep' to separate the index from the value. """
1282
1283 def __init__(self):
1284 self.depth = 0
1285
1286 def __call__(self,lst,pos='',**kw):
1287 """Prints the nested list numbering levels."""
1288 kw.setdefault('indent',' ')
1289 kw.setdefault('sep',': ')
1290 kw.setdefault('start',0)
1291 kw.setdefault('stop',len(lst))
1292 # we need to remove start and stop from kw so they don't propagate
1293 # into a recursive call for a nested list.
1294 start = kw['start']; del kw['start']
1295 stop = kw['stop']; del kw['stop']
1296 if self.depth == 0 and 'header' in kw.keys():
1297 print kw['header']
1298
1299 for idx in range(start,stop):
1300 elem = lst[idx]
1301 if type(elem)==type([]):
1302 self.depth += 1
1303 self.__call__(elem,itpl('$pos$idx,'),**kw)
1304 self.depth -= 1
1305 else:
1306 printpl(kw['indent']*self.depth+'$pos$idx$kw["sep"]$elem')
1307
1308 nlprint = NLprinter()
1309 #----------------------------------------------------------------------------
1310 def all_belong(candidates,checklist):
1311 """Check whether a list of items ALL appear in a given list of options.
1312
1313 Returns a single 1 or 0 value."""
1314
1315 return 1-(0 in [x in checklist for x in candidates])
1316
1317 #----------------------------------------------------------------------------
1318 def sort_compare(lst1,lst2,inplace = 1):
1319 """Sort and compare two lists.
1320
1321 By default it does it in place, thus modifying the lists. Use inplace = 0
1322 to avoid that (at the cost of temporary copy creation)."""
1323 if not inplace:
1324 lst1 = lst1[:]
1325 lst2 = lst2[:]
1326 lst1.sort(); lst2.sort()
1327 return lst1 == lst2
1328
1329 #----------------------------------------------------------------------------
1330 def mkdict(**kwargs):
1331 """Return a dict from a keyword list.
1332
1333 It's just syntactic sugar for making ditcionary creation more convenient:
1334 # the standard way
1335 >>>data = { 'red' : 1, 'green' : 2, 'blue' : 3 }
1336 # a cleaner way
1337 >>>data = dict(red=1, green=2, blue=3)
1338
1339 If you need more than this, look at the Struct() class."""
1340
1341 return kwargs
1342
1343 #----------------------------------------------------------------------------
1344 def list2dict(lst):
1345 """Takes a list of (key,value) pairs and turns it into a dict."""
1346
1347 dic = {}
1348 for k,v in lst: dic[k] = v
1349 return dic
1350
1351 #----------------------------------------------------------------------------
1352 def list2dict2(lst,default=''):
1353 """Takes a list and turns it into a dict.
1354 Much slower than list2dict, but more versatile. This version can take
1355 lists with sublists of arbitrary length (including sclars)."""
1356
1357 dic = {}
1358 for elem in lst:
1359 if type(elem) in (types.ListType,types.TupleType):
1360 size = len(elem)
1361 if size == 0:
1362 pass
1363 elif size == 1:
1364 dic[elem] = default
1365 else:
1366 k,v = elem[0], elem[1:]
1367 if len(v) == 1: v = v[0]
1368 dic[k] = v
1369 else:
1370 dic[elem] = default
1371 return dic
1372
1373 #----------------------------------------------------------------------------
1374 def flatten(seq):
1375 """Flatten a list of lists (NOT recursive, only works for 2d lists)."""
1376
1377 # bug in python??? (YES. Fixed in 2.2, let's leave the kludgy fix in).
1378
1379 # if the x=0 isn't made, a *global* variable x is left over after calling
1380 # this function, with the value of the last element in the return
1381 # list. This does seem like a bug big time to me.
1382
1383 # the problem is fixed with the x=0, which seems to force the creation of
1384 # a local name
1385
1386 x = 0
1387 return [x for subseq in seq for x in subseq]
1388
1389 #----------------------------------------------------------------------------
1390 def get_slice(seq,start=0,stop=None,step=1):
1391 """Get a slice of a sequence with variable step. Specify start,stop,step."""
1392 if stop == None:
1393 stop = len(seq)
1394 item = lambda i: seq[i]
1395 return map(item,xrange(start,stop,step))
1396
1397 #----------------------------------------------------------------------------
1398 def chop(seq,size):
1399 """Chop a sequence into chunks of the given size."""
1400 chunk = lambda i: seq[i:i+size]
1401 return map(chunk,xrange(0,len(seq),size))
1402
1403 #----------------------------------------------------------------------------
1404 def with(object, **args):
1405 """Set multiple attributes for an object, similar to Pascal's with.
1406
1407 Example:
1408 with(jim,
1409 born = 1960,
1410 haircolour = 'Brown',
1411 eyecolour = 'Green')
1412
1413 Credit: Greg Ewing, in
1414 http://mail.python.org/pipermail/python-list/2001-May/040703.html"""
1415
1416 object.__dict__.update(args)
1417
1418 #----------------------------------------------------------------------------
1419 def setattr_list(obj,alist,nspace = None):
1420 """Set a list of attributes for an object taken from a namespace.
1421
1422 setattr_list(obj,alist,nspace) -> sets in obj all the attributes listed in
1423 alist with their values taken from nspace, which must be a dict (something
1424 like locals() will often do) If nspace isn't given, locals() of the
1425 *caller* is used, so in most cases you can omit it.
1426
1427 Note that alist can be given as a string, which will be automatically
1428 split into a list on whitespace. If given as a list, it must be a list of
1429 *strings* (the variable names themselves), not of variables."""
1430
1431 # this grabs the local variables from the *previous* call frame -- that is
1432 # the locals from the function that called setattr_list().
1433 # - snipped from weave.inline()
1434 if nspace is None:
1435 call_frame = sys._getframe().f_back
1436 nspace = call_frame.f_locals
1437
1438 if type(alist) in StringTypes:
1439 alist = alist.split()
1440 for attr in alist:
1441 val = eval(attr,nspace)
1442 setattr(obj,attr,val)
1443
1444 #----------------------------------------------------------------------------
1445 def getattr_list(obj,alist,*args):
1446 """getattr_list(obj,alist[, default]) -> attribute list.
1447
1448 Get a list of named attributes for an object. When a default argument is
1449 given, it is returned when the attribute doesn't exist; without it, an
1450 exception is raised in that case.
1451
1452 Note that alist can be given as a string, which will be automatically
1453 split into a list on whitespace. If given as a list, it must be a list of
1454 *strings* (the variable names themselves), not of variables."""
1455
1456 if type(alist) in StringTypes:
1457 alist = alist.split()
1458 if args:
1459 if len(args)==1:
1460 default = args[0]
1461 return map(lambda attr: getattr(obj,attr,default),alist)
1462 else:
1463 raise ValueError,'getattr_list() takes only one optional argument'
1464 else:
1465 return map(lambda attr: getattr(obj,attr),alist)
1466
1467 #----------------------------------------------------------------------------
1468 def map_method(method,object_list,*argseq,**kw):
1469 """map_method(method,object_list,*args,**kw) -> list
1470
1471 Return a list of the results of applying the methods to the items of the
1472 argument sequence(s). If more than one sequence is given, the method is
1473 called with an argument list consisting of the corresponding item of each
1474 sequence. All sequences must be of the same length.
1475
1476 Keyword arguments are passed verbatim to all objects called.
1477
1478 This is Python code, so it's not nearly as fast as the builtin map()."""
1479
1480 out_list = []
1481 idx = 0
1482 for object in object_list:
1483 try:
1484 handler = getattr(object, method)
1485 except AttributeError:
1486 out_list.append(None)
1487 else:
1488 if argseq:
1489 args = map(lambda lst:lst[idx],argseq)
1490 #print 'ob',object,'hand',handler,'ar',args # dbg
1491 out_list.append(handler(args,**kw))
1492 else:
1493 out_list.append(handler(**kw))
1494 idx += 1
1495 return out_list
1496
1497 #----------------------------------------------------------------------------
1498 # Proposed popitem() extension, written as a method
1499
1500 class NotGiven: pass
1501
1502 def popkey(dct,key,default=NotGiven):
1503 """Return dct[key] and delete dct[key].
1504
1505 If default is given, return it if dct[key] doesn't exist, otherwise raise
1506 KeyError. """
1507
1508 try:
1509 val = dct[key]
1510 except KeyError:
1511 if default is NotGiven:
1512 raise
1513 else:
1514 return default
1515 else:
1516 del dct[key]
1517 return val
1518 #*************************** end of file <genutils.py> **********************
1519
@@ -0,0 +1,72 b''
1 """hooks for IPython.
2
3 In Python, it is possible to overwrite any method of any object if you really
4 want to. But IPython exposes a few 'hooks', methods which are _designed_ to
5 be overwritten by users for customization purposes. This module defines the
6 default versions of all such hooks, which get used by IPython if not
7 overridden by the user.
8
9 hooks are simple functions, but they should be declared with 'self' as their
10 first argument, because when activated they are registered into IPython as
11 instance methods. The self argument will be the IPython running instance
12 itself, so hooks have full access to the entire IPython object.
13
14 If you wish to define a new hook and activate it, you need to put the
15 necessary code into a python file which can be either imported or execfile()'d
16 from within your ipythonrc configuration.
17
18 For example, suppose that you have a module called 'myiphooks' in your
19 PYTHONPATH, which contains the following definition:
20
21 import os
22 def calljed(self,filename, linenum):
23 "My editor hook calls the jed editor directly."
24 print "Calling my own editor, jed ..."
25 os.system('jed +%d %s' % (linenum,filename))
26
27 You can then execute the following line of code to make it the new IPython
28 editor hook, after having imported 'myiphooks':
29
30 ip_set_hook('editor',myiphooks.calljed)
31
32 The ip_set_hook function is put by IPython into the builtin namespace, so it
33 is always available from all running code.
34
35 $Id: hooks.py 535 2005-03-02 08:42:25Z fperez $"""
36
37 #*****************************************************************************
38 # Copyright (C) 2005 Fernando Perez. <fperez@colorado.edu>
39 #
40 # Distributed under the terms of the BSD License. The full license is in
41 # the file COPYING, distributed as part of this software.
42 #*****************************************************************************
43
44 from IPython import Release
45 __author__ = '%s <%s>' % Release.authors['Fernando']
46 __license__ = Release.license
47 __version__ = Release.version
48
49 import os
50
51 # List here all the default hooks. For now it's just the editor, but over
52 # time we'll move here all the public API for user-accessible things.
53 __all__ = ['editor']
54
55 def editor(self,filename, linenum):
56 """Open the default editor at the given filename and linenumber.
57
58 This is IPython's default editor hook, you can use it as an example to
59 write your own modified one. To set your own editor function as the
60 new editor hook, call ip_set_hook('editor',yourfunc)."""
61
62 # IPython configures a default editor at startup by reading $EDITOR from
63 # the environment, and falling back on vi (unix) or notepad (win32).
64 editor = self.rc.editor
65
66 # marker for at which line to open the file (for existing objects)
67 if linenum is None or editor=='notepad':
68 linemark = ''
69 else:
70 linemark = '+%d' % linenum
71 # Call the actual editor
72 os.system('%s %s %s' % (editor,linemark,filename))
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100755
NO CONTENT: new file 100755
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100755
NO CONTENT: new file 100755
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100755
NO CONTENT: new file 100755
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100755
NO CONTENT: new file 100755
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100755
NO CONTENT: new file 100755
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100755
NO CONTENT: new file 100755
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100755
NO CONTENT: new file 100755
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100755
NO CONTENT: new file 100755
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100755
NO CONTENT: new file 100755
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100755
NO CONTENT: new file 100755
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100755
NO CONTENT: new file 100755
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100755
NO CONTENT: new file 100755
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
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