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

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

@@ -1,116 +1,116 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Configuration loader
2 """Configuration loader
3
3
4 $Id: ConfigLoader.py 525 2005-02-19 10:53:12Z fperez $"""
4 $Id: ConfigLoader.py 958 2005-12-27 23:17:51Z fperez $"""
5
5
6 #*****************************************************************************
6 #*****************************************************************************
7 # Copyright (C) 2001-2004 Fernando Perez. <fperez@colorado.edu>
7 # Copyright (C) 2001-2004 Fernando Perez. <fperez@colorado.edu>
8 #
8 #
9 # Distributed under the terms of the BSD License. The full license is in
9 # Distributed under the terms of the BSD License. The full license is in
10 # the file COPYING, distributed as part of this software.
10 # the file COPYING, distributed as part of this software.
11 #*****************************************************************************
11 #*****************************************************************************
12
12
13 from IPython import Release
13 from IPython import Release
14 __author__ = '%s <%s>' % Release.authors['Fernando']
14 __author__ = '%s <%s>' % Release.authors['Fernando']
15 __license__ = Release.license
15 __license__ = Release.license
16
16
17 import exceptions
17 import os
18 import os
18 from pprint import pprint
19 from pprint import pprint
19 import exceptions
20
20
21 from IPython import ultraTB
21 from IPython import ultraTB
22 from IPython.Struct import Struct
22 from IPython.Struct import Struct
23 from IPython.genutils import *
23 from IPython.genutils import *
24
24
25 class ConfigLoaderError(exceptions.Exception):
25 class ConfigLoaderError(exceptions.Exception):
26 """Exception for ConfigLoader class."""
26 """Exception for ConfigLoader class."""
27
27
28 def __init__(self,args=None):
28 def __init__(self,args=None):
29 self.args = args
29 self.args = args
30
30
31 class ConfigLoader:
31 class ConfigLoader:
32
32
33 """Configuration file loader capable of handling recursive inclusions and
33 """Configuration file loader capable of handling recursive inclusions and
34 with parametrized conflict resolution for multiply found keys."""
34 with parametrized conflict resolution for multiply found keys."""
35
35
36 def __init__(self,conflict=None,field_sep=None,reclimit=15):
36 def __init__(self,conflict=None,field_sep=None,reclimit=15):
37
37
38 """The reclimit parameter controls the number of recursive
38 """The reclimit parameter controls the number of recursive
39 configuration file inclusions. This way we can stop early on (before
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
40 python's own recursion limit is hit) if there is a circular
41 inclusion.
41 inclusion.
42
42
43 - conflict: dictionary for conflict resolutions (see Struct.merge())
43 - conflict: dictionary for conflict resolutions (see Struct.merge())
44
44
45 """
45 """
46 self.conflict = conflict
46 self.conflict = conflict
47 self.field_sep = field_sep
47 self.field_sep = field_sep
48 self.reset(reclimit)
48 self.reset(reclimit)
49
49
50 def reset(self,reclimit=15):
50 def reset(self,reclimit=15):
51 self.reclimit = reclimit
51 self.reclimit = reclimit
52 self.recdepth = 0
52 self.recdepth = 0
53 self.included = []
53 self.included = []
54
54
55 def load(self,fname,convert=None,recurse_key='',incpath = '.',**kw):
55 def load(self,fname,convert=None,recurse_key='',incpath = '.',**kw):
56 """Load a configuration file, return the resulting Struct.
56 """Load a configuration file, return the resulting Struct.
57
57
58 Call: load_config(fname,convert=None,conflict=None,recurse_key='')
58 Call: load_config(fname,convert=None,conflict=None,recurse_key='')
59
59
60 - fname: file to load from.
60 - fname: file to load from.
61 - convert: dictionary of type conversions (see read_dict())
61 - convert: dictionary of type conversions (see read_dict())
62 - recurse_key: keyword in dictionary to trigger recursive file
62 - recurse_key: keyword in dictionary to trigger recursive file
63 inclusions.
63 inclusions.
64 """
64 """
65
65
66 if self.recdepth > self.reclimit:
66 if self.recdepth > self.reclimit:
67 raise ConfigLoaderError, 'maximum recursive inclusion of rcfiles '+\
67 raise ConfigLoaderError, 'maximum recursive inclusion of rcfiles '+\
68 'exceeded: ' + `self.recdepth` + \
68 'exceeded: ' + `self.recdepth` + \
69 '.\nMaybe you have a circular chain of inclusions?'
69 '.\nMaybe you have a circular chain of inclusions?'
70 self.recdepth += 1
70 self.recdepth += 1
71 fname = filefind(fname,incpath)
71 fname = filefind(fname,incpath)
72 data = Struct()
72 data = Struct()
73 # avoid including the same file more than once
73 # avoid including the same file more than once
74 if fname in self.included:
74 if fname in self.included:
75 return data
75 return data
76 Xinfo = ultraTB.AutoFormattedTB()
76 Xinfo = ultraTB.AutoFormattedTB()
77 if convert==None and recurse_key : convert = {qwflat:recurse_key}
77 if convert==None and recurse_key : convert = {qwflat:recurse_key}
78 # for production, change warn to 0:
78 # for production, change warn to 0:
79 data.merge(read_dict(fname,convert,fs=self.field_sep,strip=1,
79 data.merge(read_dict(fname,convert,fs=self.field_sep,strip=1,
80 warn=0,no_empty=0,**kw))
80 warn=0,no_empty=0,**kw))
81 # keep track of successfully loaded files
81 # keep track of successfully loaded files
82 self.included.append(fname)
82 self.included.append(fname)
83 if recurse_key in data.keys():
83 if recurse_key in data.keys():
84 for incfilename in data[recurse_key]:
84 for incfilename in data[recurse_key]:
85 found=0
85 found=0
86 try:
86 try:
87 incfile = filefind(incfilename,incpath)
87 incfile = filefind(incfilename,incpath)
88 except IOError:
88 except IOError:
89 if os.name in ['nt','dos']:
89 if os.name in ['nt','dos']:
90 try:
90 try:
91 # Try again with '.ini' extension
91 # Try again with '.ini' extension
92 incfilename += '.ini'
92 incfilename += '.ini'
93 incfile = filefind(incfilename,incpath)
93 incfile = filefind(incfilename,incpath)
94 except IOError:
94 except IOError:
95 found = 0
95 found = 0
96 else:
96 else:
97 found = 1
97 found = 1
98 else:
98 else:
99 found = 0
99 found = 0
100 else:
100 else:
101 found = 1
101 found = 1
102 if found:
102 if found:
103 try:
103 try:
104 data.merge(self.load(incfile,convert,recurse_key,
104 data.merge(self.load(incfile,convert,recurse_key,
105 incpath,**kw),
105 incpath,**kw),
106 self.conflict)
106 self.conflict)
107 except:
107 except:
108 Xinfo()
108 Xinfo()
109 warn('Problem loading included file: '+
109 warn('Problem loading included file: '+
110 `incfilename` + '. Ignoring it...')
110 `incfilename` + '. Ignoring it...')
111 else:
111 else:
112 warn('File `%s` not found. Included by %s' % (incfilename,fname))
112 warn('File `%s` not found. Included by %s' % (incfilename,fname))
113
113
114 return data
114 return data
115
115
116 # end ConfigLoader
116 # end ConfigLoader
@@ -1,110 +1,111 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """sys.excepthook for IPython itself, leaves a detailed report on disk.
2 """sys.excepthook for IPython itself, leaves a detailed report on disk.
3
3
4 $Id: CrashHandler.py 951 2005-12-25 00:57:24Z fperez $"""
4 $Id: CrashHandler.py 958 2005-12-27 23:17:51Z fperez $"""
5
5
6 #*****************************************************************************
6 #*****************************************************************************
7 # Copyright (C) 2001-2004 Fernando Perez. <fperez@colorado.edu>
7 # Copyright (C) 2001-2004 Fernando Perez. <fperez@colorado.edu>
8 #
8 #
9 # Distributed under the terms of the BSD License. The full license is in
9 # Distributed under the terms of the BSD License. The full license is in
10 # the file COPYING, distributed as part of this software.
10 # the file COPYING, distributed as part of this software.
11 #*****************************************************************************
11 #*****************************************************************************
12
12
13 from IPython import Release
13 from IPython import Release
14 __author__ = '%s <%s>' % Release.authors['Fernando']
14 __author__ = '%s <%s>' % Release.authors['Fernando']
15 __license__ = Release.license
15 __license__ = Release.license
16 __version__ = Release.version
16 __version__ = Release.version
17
17
18 #****************************************************************************
18 #****************************************************************************
19 # Required modules
19 # Required modules
20
20
21 # From the standard library
21 # From the standard library
22 import os,sys
22 import os
23 import sys
23 from pprint import pprint,pformat
24 from pprint import pprint,pformat
24
25
25 # Homebrewed
26 # Homebrewed
26 from IPython.Itpl import Itpl,itpl,printpl
27 from IPython.Itpl import Itpl,itpl,printpl
27 from IPython.ColorANSI import ColorScheme,ColorSchemeTable # too long names
28 from IPython.ColorANSI import ColorScheme,ColorSchemeTable # too long names
28 from IPython import ultraTB
29 from IPython import ultraTB
29 from IPython.genutils import *
30 from IPython.genutils import *
30
31
31 #****************************************************************************
32 #****************************************************************************
32 class CrashHandler:
33 class CrashHandler:
33 """sys.excepthook for IPython itself, leaves a detailed report on disk."""
34 """sys.excepthook for IPython itself, leaves a detailed report on disk."""
34
35
35 def __init__(self,IP):
36 def __init__(self,IP):
36 self.IP = IP # IPython instance
37 self.IP = IP # IPython instance
37 self.bug_contact = Release.authors['Fernando'][0]
38 self.bug_contact = Release.authors['Fernando'][0]
38 self.mailto = Release.authors['Fernando'][1]
39 self.mailto = Release.authors['Fernando'][1]
39
40
40 def __call__(self,etype, evalue, etb):
41 def __call__(self,etype, evalue, etb):
41
42
42 # Report tracebacks shouldn't use color in general (safer for users)
43 # Report tracebacks shouldn't use color in general (safer for users)
43 color_scheme = 'NoColor'
44 color_scheme = 'NoColor'
44
45
45 # Use this ONLY for developer debugging (keep commented out for release)
46 # Use this ONLY for developer debugging (keep commented out for release)
46 #color_scheme = 'Linux' # dbg
47 #color_scheme = 'Linux' # dbg
47
48
48 try:
49 try:
49 rptdir = self.IP.rc.ipythondir
50 rptdir = self.IP.rc.ipythondir
50 except:
51 except:
51 rptdir = os.getcwd()
52 rptdir = os.getcwd()
52 if not os.path.isdir(rptdir):
53 if not os.path.isdir(rptdir):
53 rptdir = os.getcwd()
54 rptdir = os.getcwd()
54 self.report_name = os.path.join(rptdir,'IPython_crash_report.txt')
55 self.report_name = os.path.join(rptdir,'IPython_crash_report.txt')
55 self.TBhandler = ultraTB.VerboseTB(color_scheme=color_scheme,long_header=1)
56 self.TBhandler = ultraTB.VerboseTB(color_scheme=color_scheme,long_header=1)
56 traceback = self.TBhandler.text(etype,evalue,etb,context=31)
57 traceback = self.TBhandler.text(etype,evalue,etb,context=31)
57
58
58 # print traceback to screen
59 # print traceback to screen
59 print >> sys.stderr, traceback
60 print >> sys.stderr, traceback
60
61
61 # and generate a complete report on disk
62 # and generate a complete report on disk
62 try:
63 try:
63 report = open(self.report_name,'w')
64 report = open(self.report_name,'w')
64 except:
65 except:
65 print >> sys.stderr, 'Could not create crash report on disk.'
66 print >> sys.stderr, 'Could not create crash report on disk.'
66 return
67 return
67
68
68 msg = itpl('\n'+'*'*70+'\n'
69 msg = itpl('\n'+'*'*70+'\n'
69 """
70 """
70 Oops, IPython crashed. We do our best to make it stable, but...
71 Oops, IPython crashed. We do our best to make it stable, but...
71
72
72 A crash report was automatically generated with the following information:
73 A crash report was automatically generated with the following information:
73 - A verbatim copy of the traceback above this text.
74 - A verbatim copy of the traceback above this text.
74 - A copy of your input history during this session.
75 - A copy of your input history during this session.
75 - Data on your current IPython configuration.
76 - Data on your current IPython configuration.
76
77
77 It was left in the file named:
78 It was left in the file named:
78 \t'$self.report_name'
79 \t'$self.report_name'
79 If you can email this file to the developers, the information in it will help
80 If you can email this file to the developers, the information in it will help
80 them in understanding and correcting the problem.
81 them in understanding and correcting the problem.
81
82
82 You can mail it to $self.bug_contact at $self.mailto
83 You can mail it to $self.bug_contact at $self.mailto
83 with the subject 'IPython Crash Report'.
84 with the subject 'IPython Crash Report'.
84
85
85 If you want to do it now, the following command will work (under Unix):
86 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 mail -s 'IPython Crash Report' $self.mailto < $self.report_name
87
88
88 To ensure accurate tracking of this issue, please file a report about it at:
89 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 http://www.scipy.net/roundup/ipython (IPython's online bug tracker).
90 """)
91 """)
91 print >> sys.stderr, msg
92 print >> sys.stderr, msg
92
93
93 sec_sep = '\n\n'+'*'*75+'\n\n'
94 sec_sep = '\n\n'+'*'*75+'\n\n'
94 report.write('*'*75+'\n\n'+'IPython post-mortem report\n\n')
95 report.write('*'*75+'\n\n'+'IPython post-mortem report\n\n')
95 report.write('IPython version: %s \n\n' % Release.version)
96 report.write('IPython version: %s \n\n' % Release.version)
96 report.write('SVN revision : %s \n\n' % Release.revision)
97 report.write('SVN revision : %s \n\n' % Release.revision)
97 report.write('Platform info : os.name -> %s, sys.platform -> %s' %
98 report.write('Platform info : os.name -> %s, sys.platform -> %s' %
98 (os.name,sys.platform) )
99 (os.name,sys.platform) )
99 report.write(sec_sep+'Current user configuration structure:\n\n')
100 report.write(sec_sep+'Current user configuration structure:\n\n')
100 report.write(pformat(self.IP.rc.dict()))
101 report.write(pformat(self.IP.rc.dict()))
101 report.write(sec_sep+'Crash traceback:\n\n' + traceback)
102 report.write(sec_sep+'Crash traceback:\n\n' + traceback)
102 try:
103 try:
103 report.write(sec_sep+"History of session input:")
104 report.write(sec_sep+"History of session input:")
104 for line in self.IP.user_ns['_ih']:
105 for line in self.IP.user_ns['_ih']:
105 report.write(line)
106 report.write(line)
106 report.write('\n*** Last line of input (may not be in above history):\n')
107 report.write('\n*** Last line of input (may not be in above history):\n')
107 report.write(self.IP._last_input_line+'\n')
108 report.write(self.IP._last_input_line+'\n')
108 except:
109 except:
109 pass
110 pass
110 report.close()
111 report.close()
@@ -1,671 +1,671 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """DPyGetOpt -- Demiurge Python GetOptions Module
2 """DPyGetOpt -- Demiurge Python GetOptions Module
3
3
4 $Id: DPyGetOpt.py 389 2004-10-09 07:59:30Z fperez $
4 $Id: DPyGetOpt.py 958 2005-12-27 23:17:51Z fperez $
5
5
6 This module is modeled after perl's Getopt::Long module-- which
6 This module is modeled after perl's Getopt::Long module-- which
7 is, in turn, modeled after GNU's extended getopt() function.
7 is, in turn, modeled after GNU's extended getopt() function.
8
8
9 Upon instantiation, the option specification should be a sequence
9 Upon instantiation, the option specification should be a sequence
10 (list) of option definitions.
10 (list) of option definitions.
11
11
12 Options that take no arguments should simply contain the name of
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
13 the option. If a ! is post-pended, the option can be negated by
14 prepending 'no'; ie 'debug!' specifies that -debug and -nodebug
14 prepending 'no'; ie 'debug!' specifies that -debug and -nodebug
15 should be accepted.
15 should be accepted.
16
16
17 Mandatory arguments to options are specified using a postpended
17 Mandatory arguments to options are specified using a postpended
18 '=' + a type specifier. '=s' specifies a mandatory string
18 '=' + a type specifier. '=s' specifies a mandatory string
19 argument, '=i' specifies a mandatory integer argument, and '=f'
19 argument, '=i' specifies a mandatory integer argument, and '=f'
20 specifies a mandatory real number. In all cases, the '=' can be
20 specifies a mandatory real number. In all cases, the '=' can be
21 substituted with ':' to specify that the argument is optional.
21 substituted with ':' to specify that the argument is optional.
22
22
23 Dashes '-' in option names are allowed.
23 Dashes '-' in option names are allowed.
24
24
25 If an option has the character '@' postpended (after the
25 If an option has the character '@' postpended (after the
26 argumentation specification), it can appear multiple times within
26 argumentation specification), it can appear multiple times within
27 each argument list that is processed. The results will be stored
27 each argument list that is processed. The results will be stored
28 in a list.
28 in a list.
29
29
30 The option name can actually be a list of names separated by '|'
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,
31 characters; ie-- 'foo|bar|baz=f@' specifies that all -foo, -bar,
32 and -baz options that appear on within the parsed argument list
32 and -baz options that appear on within the parsed argument list
33 must have a real number argument and that the accumulated list
33 must have a real number argument and that the accumulated list
34 of values will be available under the name 'foo'
34 of values will be available under the name 'foo'
35
35
36 $Id: DPyGetOpt.py 389 2004-10-09 07:59:30Z fperez $"""
36 $Id: DPyGetOpt.py 958 2005-12-27 23:17:51Z fperez $"""
37
37
38 #*****************************************************************************
38 #*****************************************************************************
39 #
39 #
40 # Copyright (c) 2001 Bill Bumgarner <bbum@friday.com>
40 # Copyright (c) 2001 Bill Bumgarner <bbum@friday.com>
41 #
41 #
42 #
42 #
43 # Published under the terms of the MIT license, hereby reproduced:
43 # Published under the terms of the MIT license, hereby reproduced:
44 #
44 #
45 # Permission is hereby granted, free of charge, to any person obtaining a copy
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
46 # of this software and associated documentation files (the "Software"), to
47 # deal in the Software without restriction, including without limitation the
47 # deal in the Software without restriction, including without limitation the
48 # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
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
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:
50 # furnished to do so, subject to the following conditions:
51 #
51 #
52 # The above copyright notice and this permission notice shall be included in
52 # The above copyright notice and this permission notice shall be included in
53 # all copies or substantial portions of the Software.
53 # all copies or substantial portions of the Software.
54 #
54 #
55 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
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,
56 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
57 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
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
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
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
60 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
61 # IN THE SOFTWARE.
61 # IN THE SOFTWARE.
62 #
62 #
63 #*****************************************************************************
63 #*****************************************************************************
64
64
65 __author__ = 'Bill Bumgarner <bbum@friday.com>'
65 __author__ = 'Bill Bumgarner <bbum@friday.com>'
66 __license__ = 'MIT'
66 __license__ = 'MIT'
67 __version__ = '1.2'
67 __version__ = '1.2'
68
68
69 # Modified to use re instead of regex and regsub modules.
69 # Modified to use re instead of regex and regsub modules.
70 # 2001/5/7, Jonathan Hogg <jonathan@onegoodidea.com>
70 # 2001/5/7, Jonathan Hogg <jonathan@onegoodidea.com>
71
71
72 import string
73 import re
72 import re
73 import string
74 import sys
74 import sys
75 import types
75 import types
76
76
77 arg_error = 'DPyGetOpt Argument Error'
77 arg_error = 'DPyGetOpt Argument Error'
78 spec_error = 'DPyGetOpt Specification Error'
78 spec_error = 'DPyGetOpt Specification Error'
79 term_error = 'DPyGetOpt Termination Error'
79 term_error = 'DPyGetOpt Termination Error'
80
80
81 specificationExpr = re.compile('(?P<required>.)(?P<type>.)(?P<multi>@?)')
81 specificationExpr = re.compile('(?P<required>.)(?P<type>.)(?P<multi>@?)')
82
82
83 ArgRequired = 'Requires an Argument'
83 ArgRequired = 'Requires an Argument'
84 ArgOptional = 'Argument Optional'
84 ArgOptional = 'Argument Optional'
85
85
86 # The types modules is not used for these identifiers because there
86 # The types modules is not used for these identifiers because there
87 # is no identifier for 'boolean' or 'generic'
87 # is no identifier for 'boolean' or 'generic'
88 StringArgType = 'String Argument Type'
88 StringArgType = 'String Argument Type'
89 IntegerArgType = 'Integer Argument Type'
89 IntegerArgType = 'Integer Argument Type'
90 RealArgType = 'Real Argument Type'
90 RealArgType = 'Real Argument Type'
91 BooleanArgType = 'Boolean Argument Type'
91 BooleanArgType = 'Boolean Argument Type'
92 GenericArgType = 'Generic Argument Type'
92 GenericArgType = 'Generic Argument Type'
93
93
94 # dictionary of conversion functions-- boolean and generic options
94 # dictionary of conversion functions-- boolean and generic options
95 # do not accept arguments and do not need conversion functions;
95 # do not accept arguments and do not need conversion functions;
96 # the identity function is used purely for convenience.
96 # the identity function is used purely for convenience.
97 ConversionFunctions = {
97 ConversionFunctions = {
98 StringArgType : lambda x: x,
98 StringArgType : lambda x: x,
99 IntegerArgType : string.atoi,
99 IntegerArgType : string.atoi,
100 RealArgType : string.atof,
100 RealArgType : string.atof,
101 BooleanArgType : lambda x: x,
101 BooleanArgType : lambda x: x,
102 GenericArgType : lambda x: x,
102 GenericArgType : lambda x: x,
103 }
103 }
104
104
105 class DPyGetOpt:
105 class DPyGetOpt:
106
106
107 def __init__(self, spec = None, terminators = ['--']):
107 def __init__(self, spec = None, terminators = ['--']):
108 """
108 """
109 Declare and intialize instance variables
109 Declare and intialize instance variables
110
110
111 Yes, declaration is not necessary... but one of the things
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
112 I sorely miss from C/Obj-C is the concept of having an
113 interface definition that clearly declares all instance
113 interface definition that clearly declares all instance
114 variables and methods without providing any implementation
114 variables and methods without providing any implementation
115 details. it is a useful reference!
115 details. it is a useful reference!
116
116
117 all instance variables are initialized to 0/Null/None of
117 all instance variables are initialized to 0/Null/None of
118 the appropriate type-- not even the default value...
118 the appropriate type-- not even the default value...
119 """
119 """
120
120
121 # sys.stderr.write(string.join(spec) + "\n")
121 # sys.stderr.write(string.join(spec) + "\n")
122
122
123 self.allowAbbreviations = 1 # boolean, 1 if abbreviations will
123 self.allowAbbreviations = 1 # boolean, 1 if abbreviations will
124 # be expanded
124 # be expanded
125 self.freeValues = [] # list, contains free values
125 self.freeValues = [] # list, contains free values
126 self.ignoreCase = 0 # boolean, YES if ignoring case
126 self.ignoreCase = 0 # boolean, YES if ignoring case
127 self.needsParse = 0 # boolean, YES if need to reparse parameter spec
127 self.needsParse = 0 # boolean, YES if need to reparse parameter spec
128 self.optionNames = {} # dict, all option names-- value is index of tuple
128 self.optionNames = {} # dict, all option names-- value is index of tuple
129 self.optionStartExpr = None # regexp defining the start of an option (ie; '-', '--')
129 self.optionStartExpr = None # regexp defining the start of an option (ie; '-', '--')
130 self.optionTuples = [] # list o' tuples containing defn of options AND aliases
130 self.optionTuples = [] # list o' tuples containing defn of options AND aliases
131 self.optionValues = {} # dict, option names (after alias expansion) -> option value(s)
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
132 self.orderMixed = 0 # boolean, YES if options can be mixed with args
133 self.posixCompliance = 0 # boolean, YES indicates posix like behaviour
133 self.posixCompliance = 0 # boolean, YES indicates posix like behaviour
134 self.spec = [] # list, raw specs (in case it must be reparsed)
134 self.spec = [] # list, raw specs (in case it must be reparsed)
135 self.terminators = terminators # list, strings that terminate argument processing
135 self.terminators = terminators # list, strings that terminate argument processing
136 self.termValues = [] # list, values after terminator
136 self.termValues = [] # list, values after terminator
137 self.terminator = None # full name of terminator that ended
137 self.terminator = None # full name of terminator that ended
138 # option processing
138 # option processing
139
139
140 # set up defaults
140 # set up defaults
141 self.setPosixCompliance()
141 self.setPosixCompliance()
142 self.setIgnoreCase()
142 self.setIgnoreCase()
143 self.setAllowAbbreviations()
143 self.setAllowAbbreviations()
144
144
145 # parse spec-- if present
145 # parse spec-- if present
146 if spec:
146 if spec:
147 self.parseConfiguration(spec)
147 self.parseConfiguration(spec)
148
148
149 def setPosixCompliance(self, aFlag = 0):
149 def setPosixCompliance(self, aFlag = 0):
150 """
150 """
151 Enables and disables posix compliance.
151 Enables and disables posix compliance.
152
152
153 When enabled, '+' can be used as an option prefix and free
153 When enabled, '+' can be used as an option prefix and free
154 values can be mixed with options.
154 values can be mixed with options.
155 """
155 """
156 self.posixCompliance = aFlag
156 self.posixCompliance = aFlag
157 self.needsParse = 1
157 self.needsParse = 1
158
158
159 if self.posixCompliance:
159 if self.posixCompliance:
160 self.optionStartExpr = re.compile('(--|-)(?P<option>[A-Za-z0-9_-]+)(?P<arg>=.*)?')
160 self.optionStartExpr = re.compile('(--|-)(?P<option>[A-Za-z0-9_-]+)(?P<arg>=.*)?')
161 self.orderMixed = 0
161 self.orderMixed = 0
162 else:
162 else:
163 self.optionStartExpr = re.compile('(--|-|\+)(?P<option>[A-Za-z0-9_-]+)(?P<arg>=.*)?')
163 self.optionStartExpr = re.compile('(--|-|\+)(?P<option>[A-Za-z0-9_-]+)(?P<arg>=.*)?')
164 self.orderMixed = 1
164 self.orderMixed = 1
165
165
166 def isPosixCompliant(self):
166 def isPosixCompliant(self):
167 """
167 """
168 Returns the value of the posix compliance flag.
168 Returns the value of the posix compliance flag.
169 """
169 """
170 return self.posixCompliance
170 return self.posixCompliance
171
171
172 def setIgnoreCase(self, aFlag = 1):
172 def setIgnoreCase(self, aFlag = 1):
173 """
173 """
174 Enables and disables ignoring case during option processing.
174 Enables and disables ignoring case during option processing.
175 """
175 """
176 self.needsParse = 1
176 self.needsParse = 1
177 self.ignoreCase = aFlag
177 self.ignoreCase = aFlag
178
178
179 def ignoreCase(self):
179 def ignoreCase(self):
180 """
180 """
181 Returns 1 if the option processor will ignore case when
181 Returns 1 if the option processor will ignore case when
182 processing options.
182 processing options.
183 """
183 """
184 return self.ignoreCase
184 return self.ignoreCase
185
185
186 def setAllowAbbreviations(self, aFlag = 1):
186 def setAllowAbbreviations(self, aFlag = 1):
187 """
187 """
188 Enables and disables the expansion of abbreviations during
188 Enables and disables the expansion of abbreviations during
189 option processing.
189 option processing.
190 """
190 """
191 self.allowAbbreviations = aFlag
191 self.allowAbbreviations = aFlag
192
192
193 def willAllowAbbreviations(self):
193 def willAllowAbbreviations(self):
194 """
194 """
195 Returns 1 if abbreviated options will be automatically
195 Returns 1 if abbreviated options will be automatically
196 expanded to the non-abbreviated form (instead of causing an
196 expanded to the non-abbreviated form (instead of causing an
197 unrecognized option error).
197 unrecognized option error).
198 """
198 """
199 return self.allowAbbreviations
199 return self.allowAbbreviations
200
200
201 def addTerminator(self, newTerm):
201 def addTerminator(self, newTerm):
202 """
202 """
203 Adds newTerm as terminator of option processing.
203 Adds newTerm as terminator of option processing.
204
204
205 Whenever the option processor encounters one of the terminators
205 Whenever the option processor encounters one of the terminators
206 during option processing, the processing of options terminates
206 during option processing, the processing of options terminates
207 immediately, all remaining options are stored in the termValues
207 immediately, all remaining options are stored in the termValues
208 instance variable and the full name of the terminator is stored
208 instance variable and the full name of the terminator is stored
209 in the terminator instance variable.
209 in the terminator instance variable.
210 """
210 """
211 self.terminators = self.terminators + [newTerm]
211 self.terminators = self.terminators + [newTerm]
212
212
213 def _addOption(self, oTuple):
213 def _addOption(self, oTuple):
214 """
214 """
215 Adds the option described by oTuple (name, (type, mode,
215 Adds the option described by oTuple (name, (type, mode,
216 default), alias) to optionTuples. Adds index keyed under name
216 default), alias) to optionTuples. Adds index keyed under name
217 to optionNames. Raises spec_error if name already in
217 to optionNames. Raises spec_error if name already in
218 optionNames
218 optionNames
219 """
219 """
220 (name, (type, mode, default, multi), realName) = oTuple
220 (name, (type, mode, default, multi), realName) = oTuple
221
221
222 # verify name and add to option names dictionary
222 # verify name and add to option names dictionary
223 if self.optionNames.has_key(name):
223 if self.optionNames.has_key(name):
224 if realName:
224 if realName:
225 raise spec_error, 'Alias \'' + name + '\' for \'' + realName + \
225 raise spec_error, 'Alias \'' + name + '\' for \'' + realName + \
226 '\' already used for another option or alias.'
226 '\' already used for another option or alias.'
227 else:
227 else:
228 raise spec_error, 'Option named \'' + name + \
228 raise spec_error, 'Option named \'' + name + \
229 '\' specified more than once. Specification: ' + option
229 '\' specified more than once. Specification: ' + option
230
230
231 # validated. add to optionNames
231 # validated. add to optionNames
232 self.optionNames[name] = self.tupleIndex
232 self.optionNames[name] = self.tupleIndex
233 self.tupleIndex = self.tupleIndex + 1
233 self.tupleIndex = self.tupleIndex + 1
234
234
235 # add to optionTuples
235 # add to optionTuples
236 self.optionTuples = self.optionTuples + [oTuple]
236 self.optionTuples = self.optionTuples + [oTuple]
237
237
238 # if type is boolean, add negation
238 # if type is boolean, add negation
239 if type == BooleanArgType:
239 if type == BooleanArgType:
240 alias = 'no' + name
240 alias = 'no' + name
241 specTuple = (type, mode, 0, multi)
241 specTuple = (type, mode, 0, multi)
242 oTuple = (alias, specTuple, name)
242 oTuple = (alias, specTuple, name)
243
243
244 # verify name and add to option names dictionary
244 # verify name and add to option names dictionary
245 if self.optionNames.has_key(alias):
245 if self.optionNames.has_key(alias):
246 if realName:
246 if realName:
247 raise spec_error, 'Negated alias \'' + name + '\' for \'' + realName + \
247 raise spec_error, 'Negated alias \'' + name + '\' for \'' + realName + \
248 '\' already used for another option or alias.'
248 '\' already used for another option or alias.'
249 else:
249 else:
250 raise spec_error, 'Negated option named \'' + name + \
250 raise spec_error, 'Negated option named \'' + name + \
251 '\' specified more than once. Specification: ' + option
251 '\' specified more than once. Specification: ' + option
252
252
253 # validated. add to optionNames
253 # validated. add to optionNames
254 self.optionNames[alias] = self.tupleIndex
254 self.optionNames[alias] = self.tupleIndex
255 self.tupleIndex = self.tupleIndex + 1
255 self.tupleIndex = self.tupleIndex + 1
256
256
257 # add to optionTuples
257 # add to optionTuples
258 self.optionTuples = self.optionTuples + [oTuple]
258 self.optionTuples = self.optionTuples + [oTuple]
259
259
260 def addOptionConfigurationTuple(self, oTuple):
260 def addOptionConfigurationTuple(self, oTuple):
261 (name, argSpec, realName) = oTuple
261 (name, argSpec, realName) = oTuple
262 if self.ignoreCase:
262 if self.ignoreCase:
263 name = string.lower(name)
263 name = string.lower(name)
264 if realName:
264 if realName:
265 realName = string.lower(realName)
265 realName = string.lower(realName)
266 else:
266 else:
267 realName = name
267 realName = name
268
268
269 oTuple = (name, argSpec, realName)
269 oTuple = (name, argSpec, realName)
270
270
271 # add option
271 # add option
272 self._addOption(oTuple)
272 self._addOption(oTuple)
273
273
274 def addOptionConfigurationTuples(self, oTuple):
274 def addOptionConfigurationTuples(self, oTuple):
275 if type(oTuple) is ListType:
275 if type(oTuple) is ListType:
276 for t in oTuple:
276 for t in oTuple:
277 self.addOptionConfigurationTuple(t)
277 self.addOptionConfigurationTuple(t)
278 else:
278 else:
279 self.addOptionConfigurationTuple(oTuple)
279 self.addOptionConfigurationTuple(oTuple)
280
280
281 def parseConfiguration(self, spec):
281 def parseConfiguration(self, spec):
282 # destroy previous stored information + store raw spec
282 # destroy previous stored information + store raw spec
283 self.spec = spec
283 self.spec = spec
284 self.optionTuples = []
284 self.optionTuples = []
285 self.optionNames = {}
285 self.optionNames = {}
286 self.tupleIndex = 0
286 self.tupleIndex = 0
287
287
288 tupleIndex = 0
288 tupleIndex = 0
289
289
290 # create some regex's for parsing each spec
290 # create some regex's for parsing each spec
291 splitExpr = \
291 splitExpr = \
292 re.compile('(?P<names>\w+[-A-Za-z0-9|]*)?(?P<spec>!|[=:][infs]@?)?')
292 re.compile('(?P<names>\w+[-A-Za-z0-9|]*)?(?P<spec>!|[=:][infs]@?)?')
293 for option in spec:
293 for option in spec:
294 # push to lower case (does not negatively affect
294 # push to lower case (does not negatively affect
295 # specification)
295 # specification)
296 if self.ignoreCase:
296 if self.ignoreCase:
297 option = string.lower(option)
297 option = string.lower(option)
298
298
299 # break into names, specification
299 # break into names, specification
300 match = splitExpr.match(option)
300 match = splitExpr.match(option)
301 if match is None:
301 if match is None:
302 raise spec_error, 'Invalid specification {' + option + '}'
302 raise spec_error, 'Invalid specification {' + option + '}'
303
303
304 names = match.group('names')
304 names = match.group('names')
305 specification = match.group('spec')
305 specification = match.group('spec')
306
306
307 # break name into name, aliases
307 # break name into name, aliases
308 nlist = string.split(names, '|')
308 nlist = string.split(names, '|')
309
309
310 # get name
310 # get name
311 name = nlist[0]
311 name = nlist[0]
312 aliases = nlist[1:]
312 aliases = nlist[1:]
313
313
314 # specificationExpr = regex.symcomp('\(<required>.\)\(<type>.\)\(<multi>@?\)')
314 # specificationExpr = regex.symcomp('\(<required>.\)\(<type>.\)\(<multi>@?\)')
315 if not specification:
315 if not specification:
316 #spec tuple is ('type', 'arg mode', 'default value', 'multiple')
316 #spec tuple is ('type', 'arg mode', 'default value', 'multiple')
317 argType = GenericArgType
317 argType = GenericArgType
318 argMode = None
318 argMode = None
319 argDefault = 1
319 argDefault = 1
320 argMultiple = 0
320 argMultiple = 0
321 elif specification == '!':
321 elif specification == '!':
322 argType = BooleanArgType
322 argType = BooleanArgType
323 argMode = None
323 argMode = None
324 argDefault = 1
324 argDefault = 1
325 argMultiple = 0
325 argMultiple = 0
326 else:
326 else:
327 # parse
327 # parse
328 match = specificationExpr.match(specification)
328 match = specificationExpr.match(specification)
329 if match is None:
329 if match is None:
330 # failed to parse, die
330 # failed to parse, die
331 raise spec_error, 'Invalid configuration for option \'' + option + '\''
331 raise spec_error, 'Invalid configuration for option \'' + option + '\''
332
332
333 # determine mode
333 # determine mode
334 required = match.group('required')
334 required = match.group('required')
335 if required == '=':
335 if required == '=':
336 argMode = ArgRequired
336 argMode = ArgRequired
337 elif required == ':':
337 elif required == ':':
338 argMode = ArgOptional
338 argMode = ArgOptional
339 else:
339 else:
340 raise spec_error, 'Unknown requirement configuration \'' + required + '\''
340 raise spec_error, 'Unknown requirement configuration \'' + required + '\''
341
341
342 # determine type
342 # determine type
343 type = match.group('type')
343 type = match.group('type')
344 if type == 's':
344 if type == 's':
345 argType = StringArgType
345 argType = StringArgType
346 argDefault = ''
346 argDefault = ''
347 elif type == 'i':
347 elif type == 'i':
348 argType = IntegerArgType
348 argType = IntegerArgType
349 argDefault = 1
349 argDefault = 1
350 elif type == 'f' or type == 'n':
350 elif type == 'f' or type == 'n':
351 argType = RealArgType
351 argType = RealArgType
352 argDefault = 1
352 argDefault = 1
353 else:
353 else:
354 raise spec_error, 'Unknown type specifier \'' + type + '\''
354 raise spec_error, 'Unknown type specifier \'' + type + '\''
355
355
356 # determine quantity
356 # determine quantity
357 if match.group('multi') == '@':
357 if match.group('multi') == '@':
358 argMultiple = 1
358 argMultiple = 1
359 else:
359 else:
360 argMultiple = 0
360 argMultiple = 0
361 ## end else (of not specification)
361 ## end else (of not specification)
362
362
363 # construct specification tuple
363 # construct specification tuple
364 specTuple = (argType, argMode, argDefault, argMultiple)
364 specTuple = (argType, argMode, argDefault, argMultiple)
365
365
366 # add the option-- option tuple is (name, specTuple, real name)
366 # add the option-- option tuple is (name, specTuple, real name)
367 oTuple = (name, specTuple, name)
367 oTuple = (name, specTuple, name)
368 self._addOption(oTuple)
368 self._addOption(oTuple)
369
369
370 for alias in aliases:
370 for alias in aliases:
371 # drop to all lower (if configured to do so)
371 # drop to all lower (if configured to do so)
372 if self.ignoreCase:
372 if self.ignoreCase:
373 alias = string.lower(alias)
373 alias = string.lower(alias)
374 # create configuration tuple
374 # create configuration tuple
375 oTuple = (alias, specTuple, name)
375 oTuple = (alias, specTuple, name)
376 # add
376 # add
377 self._addOption(oTuple)
377 self._addOption(oTuple)
378
378
379 # successfully parsed....
379 # successfully parsed....
380 self.needsParse = 0
380 self.needsParse = 0
381
381
382 def _getArgTuple(self, argName):
382 def _getArgTuple(self, argName):
383 """
383 """
384 Returns a list containing all the specification tuples that
384 Returns a list containing all the specification tuples that
385 match argName. If none match, None is returned. If one
385 match argName. If none match, None is returned. If one
386 matches, a list with one tuple is returned. If more than 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
387 match, a list containing all the tuples that matched is
388 returned.
388 returned.
389
389
390 In other words, this function does not pass judgement upon the
390 In other words, this function does not pass judgement upon the
391 validity of multiple matches.
391 validity of multiple matches.
392 """
392 """
393 # is it in the optionNames dict?
393 # is it in the optionNames dict?
394
394
395 try:
395 try:
396 # sys.stderr.write(argName + string.join(self.optionNames.keys()) + "\n")
396 # sys.stderr.write(argName + string.join(self.optionNames.keys()) + "\n")
397
397
398 # yes, get index
398 # yes, get index
399 tupleIndex = self.optionNames[argName]
399 tupleIndex = self.optionNames[argName]
400 # and return tuple as element of list
400 # and return tuple as element of list
401 return [self.optionTuples[tupleIndex]]
401 return [self.optionTuples[tupleIndex]]
402 except KeyError:
402 except KeyError:
403 # are abbreviations allowed?
403 # are abbreviations allowed?
404 if not self.allowAbbreviations:
404 if not self.allowAbbreviations:
405 # No! terefore, this cannot be valid argument-- nothing found
405 # No! terefore, this cannot be valid argument-- nothing found
406 return None
406 return None
407
407
408 # argName might be an abbreviation (and, abbreviations must
408 # argName might be an abbreviation (and, abbreviations must
409 # be allowed... or this would not have been reached!)
409 # be allowed... or this would not have been reached!)
410
410
411 # create regex for argName
411 # create regex for argName
412 argExpr = re.compile('^' + argName)
412 argExpr = re.compile('^' + argName)
413
413
414 tuples = filter(lambda x, argExpr=argExpr: argExpr.search(x[0]) is not None,
414 tuples = filter(lambda x, argExpr=argExpr: argExpr.search(x[0]) is not None,
415 self.optionTuples)
415 self.optionTuples)
416
416
417 if not len(tuples):
417 if not len(tuples):
418 return None
418 return None
419 else:
419 else:
420 return tuples
420 return tuples
421
421
422 def _isTerminator(self, optionName):
422 def _isTerminator(self, optionName):
423 """
423 """
424 Returns the full name of the terminator if optionName is a valid
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
425 terminator. If it is, sets self.terminator to the full name of
426 the terminator.
426 the terminator.
427
427
428 If more than one terminator matched, raises a term_error with a
428 If more than one terminator matched, raises a term_error with a
429 string describing the ambiguity.
429 string describing the ambiguity.
430 """
430 """
431
431
432 # sys.stderr.write(optionName + "\n")
432 # sys.stderr.write(optionName + "\n")
433 # sys.stderr.write(repr(self.terminators))
433 # sys.stderr.write(repr(self.terminators))
434
434
435 if optionName in self.terminators:
435 if optionName in self.terminators:
436 self.terminator = optionName
436 self.terminator = optionName
437 elif not self.allowAbbreviations:
437 elif not self.allowAbbreviations:
438 return None
438 return None
439
439
440 # regex thing in bogus
440 # regex thing in bogus
441 # termExpr = regex.compile('^' + optionName)
441 # termExpr = regex.compile('^' + optionName)
442
442
443 terms = filter(lambda x, on=optionName: string.find(x,on) == 0, self.terminators)
443 terms = filter(lambda x, on=optionName: string.find(x,on) == 0, self.terminators)
444
444
445 if not len(terms):
445 if not len(terms):
446 return None
446 return None
447 elif len(terms) > 1:
447 elif len(terms) > 1:
448 raise term_error, 'Ambiguous terminator \'' + optionName + \
448 raise term_error, 'Ambiguous terminator \'' + optionName + \
449 '\' matches ' + repr(terms)
449 '\' matches ' + repr(terms)
450
450
451 self.terminator = terms[0]
451 self.terminator = terms[0]
452 return self.terminator
452 return self.terminator
453
453
454 def processArguments(self, args = None):
454 def processArguments(self, args = None):
455 """
455 """
456 Processes args, a list of arguments (including options).
456 Processes args, a list of arguments (including options).
457
457
458 If args is the same as sys.argv, automatically trims the first
458 If args is the same as sys.argv, automatically trims the first
459 argument (the executable name/path).
459 argument (the executable name/path).
460
460
461 If an exception is not raised, the argument list was parsed
461 If an exception is not raised, the argument list was parsed
462 correctly.
462 correctly.
463
463
464 Upon successful completion, the freeValues instance variable
464 Upon successful completion, the freeValues instance variable
465 will contain all the arguments that were not associated with an
465 will contain all the arguments that were not associated with an
466 option in the order they were encountered. optionValues is a
466 option in the order they were encountered. optionValues is a
467 dictionary containing the value of each option-- the method
467 dictionary containing the value of each option-- the method
468 valueForOption() can be used to query this dictionary.
468 valueForOption() can be used to query this dictionary.
469 terminator will contain the argument encountered that terminated
469 terminator will contain the argument encountered that terminated
470 option processing (or None, if a terminator was never
470 option processing (or None, if a terminator was never
471 encountered) and termValues will contain all of the options that
471 encountered) and termValues will contain all of the options that
472 appeared after the Terminator (or an empty list).
472 appeared after the Terminator (or an empty list).
473 """
473 """
474
474
475 if hasattr(sys, "argv") and args == sys.argv:
475 if hasattr(sys, "argv") and args == sys.argv:
476 args = sys.argv[1:]
476 args = sys.argv[1:]
477
477
478 max = len(args) # maximum index + 1
478 max = len(args) # maximum index + 1
479 self.freeValues = [] # array to hold return values
479 self.freeValues = [] # array to hold return values
480 self.optionValues= {}
480 self.optionValues= {}
481 index = 0 # initial index
481 index = 0 # initial index
482 self.terminator = None
482 self.terminator = None
483 self.termValues = []
483 self.termValues = []
484
484
485 while index < max:
485 while index < max:
486 # obtain argument
486 # obtain argument
487 arg = args[index]
487 arg = args[index]
488 # increment index -- REMEMBER; it is NOW incremented
488 # increment index -- REMEMBER; it is NOW incremented
489 index = index + 1
489 index = index + 1
490
490
491 # terminate immediately if option terminator encountered
491 # terminate immediately if option terminator encountered
492 if self._isTerminator(arg):
492 if self._isTerminator(arg):
493 self.freeValues = self.freeValues + args[index:]
493 self.freeValues = self.freeValues + args[index:]
494 self.termValues = args[index:]
494 self.termValues = args[index:]
495 return
495 return
496
496
497 # is this possibly an option?
497 # is this possibly an option?
498 match = self.optionStartExpr.match(arg)
498 match = self.optionStartExpr.match(arg)
499 if match is None:
499 if match is None:
500 # not an option-- add to freeValues
500 # not an option-- add to freeValues
501 self.freeValues = self.freeValues + [arg]
501 self.freeValues = self.freeValues + [arg]
502 if not self.orderMixed:
502 if not self.orderMixed:
503 # mixing not allowed; add rest of args as freeValues
503 # mixing not allowed; add rest of args as freeValues
504 self.freeValues = self.freeValues + args[index:]
504 self.freeValues = self.freeValues + args[index:]
505 # return to caller
505 # return to caller
506 return
506 return
507 else:
507 else:
508 continue
508 continue
509
509
510 # grab name
510 # grab name
511 optName = match.group('option')
511 optName = match.group('option')
512
512
513 # obtain next argument-- index has already been incremented
513 # obtain next argument-- index has already been incremented
514 nextArg = match.group('arg')
514 nextArg = match.group('arg')
515 if nextArg:
515 if nextArg:
516 nextArg = nextArg[1:]
516 nextArg = nextArg[1:]
517 index = index - 1 # put it back
517 index = index - 1 # put it back
518 else:
518 else:
519 try:
519 try:
520 nextArg = args[index]
520 nextArg = args[index]
521 except:
521 except:
522 nextArg = None
522 nextArg = None
523
523
524 # transpose to lower case, if necessary
524 # transpose to lower case, if necessary
525 if self.ignoreCase:
525 if self.ignoreCase:
526 optName = string.lower(optName)
526 optName = string.lower(optName)
527
527
528 # obtain defining tuple
528 # obtain defining tuple
529 tuples = self._getArgTuple(optName)
529 tuples = self._getArgTuple(optName)
530
530
531 if tuples == None:
531 if tuples == None:
532 raise arg_error, 'Illegal option \'' + arg + '\''
532 raise arg_error, 'Illegal option \'' + arg + '\''
533 elif len(tuples) > 1:
533 elif len(tuples) > 1:
534 raise arg_error, 'Ambiguous option \'' + arg + '\'; matches ' + \
534 raise arg_error, 'Ambiguous option \'' + arg + '\'; matches ' + \
535 repr(map(lambda x: x[0], tuples))
535 repr(map(lambda x: x[0], tuples))
536 else:
536 else:
537 config = tuples[0]
537 config = tuples[0]
538
538
539 # config is now set to the configuration tuple for the
539 # config is now set to the configuration tuple for the
540 # argument
540 # argument
541 (fullName, spec, realName) = config
541 (fullName, spec, realName) = config
542 (optType, optMode, optDefault, optMultiple) = spec
542 (optType, optMode, optDefault, optMultiple) = spec
543
543
544 # if opt mode required, but nextArg is none, raise an error
544 # if opt mode required, but nextArg is none, raise an error
545 if (optMode == ArgRequired):
545 if (optMode == ArgRequired):
546 if (not nextArg) or self._isTerminator(nextArg):
546 if (not nextArg) or self._isTerminator(nextArg):
547 # print nextArg
547 # print nextArg
548 raise arg_error, 'Option \'' + arg + \
548 raise arg_error, 'Option \'' + arg + \
549 '\' requires an argument of type ' + optType
549 '\' requires an argument of type ' + optType
550
550
551 if (not optMode == None) and nextArg and (not self._isTerminator(nextArg)):
551 if (not optMode == None) and nextArg and (not self._isTerminator(nextArg)):
552 # nextArg defined, option configured to possibly consume arg
552 # nextArg defined, option configured to possibly consume arg
553 try:
553 try:
554 # grab conversion function-- the try is more for internal diagnostics
554 # grab conversion function-- the try is more for internal diagnostics
555 func = ConversionFunctions[optType]
555 func = ConversionFunctions[optType]
556 try:
556 try:
557 optionValue = func(nextArg)
557 optionValue = func(nextArg)
558 index = index + 1
558 index = index + 1
559 except:
559 except:
560 # only raise conversion error if REQUIRED to consume argument
560 # only raise conversion error if REQUIRED to consume argument
561 if optMode == ArgRequired:
561 if optMode == ArgRequired:
562 raise arg_error, 'Invalid argument to option \'' + arg + \
562 raise arg_error, 'Invalid argument to option \'' + arg + \
563 '\'; should be \'' + optType + '\''
563 '\'; should be \'' + optType + '\''
564 else:
564 else:
565 optionValue = optDefault
565 optionValue = optDefault
566 except arg_error:
566 except arg_error:
567 raise arg_error, sys.exc_value
567 raise arg_error, sys.exc_value
568 except:
568 except:
569 raise arg_error, '(' + arg + \
569 raise arg_error, '(' + arg + \
570 ') Conversion function for \'' + optType + '\' not found.'
570 ') Conversion function for \'' + optType + '\' not found.'
571 else:
571 else:
572 optionValue = optDefault
572 optionValue = optDefault
573
573
574 # add value to options dictionary
574 # add value to options dictionary
575 if optMultiple:
575 if optMultiple:
576 # can be multiple values
576 # can be multiple values
577 try:
577 try:
578 # try to append element
578 # try to append element
579 self.optionValues[realName] = self.optionValues[realName] + [optionValue]
579 self.optionValues[realName] = self.optionValues[realName] + [optionValue]
580 except:
580 except:
581 # failed-- must not exist; add it
581 # failed-- must not exist; add it
582 self.optionValues[realName] = [optionValue]
582 self.optionValues[realName] = [optionValue]
583 else:
583 else:
584 # only one value per
584 # only one value per
585 if self.isPosixCompliant and self.optionValues.has_key(realName):
585 if self.isPosixCompliant and self.optionValues.has_key(realName):
586 raise arg_error, 'Argument \'' + arg + '\' occurs multiple times.'
586 raise arg_error, 'Argument \'' + arg + '\' occurs multiple times.'
587
587
588 self.optionValues[realName] = optionValue
588 self.optionValues[realName] = optionValue
589
589
590 def valueForOption(self, optionName, defaultValue = None):
590 def valueForOption(self, optionName, defaultValue = None):
591 """
591 """
592 Return the value associated with optionName. If optionName was
592 Return the value associated with optionName. If optionName was
593 not encountered during parsing of the arguments, returns the
593 not encountered during parsing of the arguments, returns the
594 defaultValue (which defaults to None).
594 defaultValue (which defaults to None).
595 """
595 """
596 try:
596 try:
597 optionValue = self.optionValues[optionName]
597 optionValue = self.optionValues[optionName]
598 except:
598 except:
599 optionValue = defaultValue
599 optionValue = defaultValue
600
600
601 return optionValue
601 return optionValue
602
602
603 ##
603 ##
604 ## test/example section
604 ## test/example section
605 ##
605 ##
606 test_error = 'Test Run Amok!'
606 test_error = 'Test Run Amok!'
607 def _test():
607 def _test():
608 """
608 """
609 A relatively complete test suite.
609 A relatively complete test suite.
610 """
610 """
611 try:
611 try:
612 DPyGetOpt(['foo', 'bar=s', 'foo'])
612 DPyGetOpt(['foo', 'bar=s', 'foo'])
613 except:
613 except:
614 print 'EXCEPTION (should be \'foo\' already used..): ' + sys.exc_value
614 print 'EXCEPTION (should be \'foo\' already used..): ' + sys.exc_value
615
615
616 try:
616 try:
617 DPyGetOpt(['foo|bar|apple=s@', 'baz|apple!'])
617 DPyGetOpt(['foo|bar|apple=s@', 'baz|apple!'])
618 except:
618 except:
619 print 'EXCEPTION (should be duplicate alias/name error): ' + sys.exc_value
619 print 'EXCEPTION (should be duplicate alias/name error): ' + sys.exc_value
620
620
621 x = DPyGetOpt(['apple|atlas=i@', 'application|executable=f@'])
621 x = DPyGetOpt(['apple|atlas=i@', 'application|executable=f@'])
622 try:
622 try:
623 x.processArguments(['-app', '29.3'])
623 x.processArguments(['-app', '29.3'])
624 except:
624 except:
625 print 'EXCEPTION (should be ambiguous argument): ' + sys.exc_value
625 print 'EXCEPTION (should be ambiguous argument): ' + sys.exc_value
626
626
627 x = DPyGetOpt(['foo'], ['antigravity', 'antithesis'])
627 x = DPyGetOpt(['foo'], ['antigravity', 'antithesis'])
628 try:
628 try:
629 x.processArguments(['-foo', 'anti'])
629 x.processArguments(['-foo', 'anti'])
630 except:
630 except:
631 print 'EXCEPTION (should be ambiguous terminator): ' + sys.exc_value
631 print 'EXCEPTION (should be ambiguous terminator): ' + sys.exc_value
632
632
633 profile = ['plain-option',
633 profile = ['plain-option',
634 'boolean-option!',
634 'boolean-option!',
635 'list-of-integers=i@',
635 'list-of-integers=i@',
636 'list-real-option|list-real-alias|list-real-pseudonym=f@',
636 'list-real-option|list-real-alias|list-real-pseudonym=f@',
637 'optional-string-option:s',
637 'optional-string-option:s',
638 'abbreviated-string-list=s@']
638 'abbreviated-string-list=s@']
639
639
640 terminators = ['terminator']
640 terminators = ['terminator']
641
641
642 args = ['-plain-option',
642 args = ['-plain-option',
643 '+noboolean-option',
643 '+noboolean-option',
644 '--list-of-integers', '1',
644 '--list-of-integers', '1',
645 '+list-of-integers', '2',
645 '+list-of-integers', '2',
646 '-list-of-integers', '3',
646 '-list-of-integers', '3',
647 'freeargone',
647 'freeargone',
648 '-list-real-option', '1.1',
648 '-list-real-option', '1.1',
649 '+list-real-alias', '1.2',
649 '+list-real-alias', '1.2',
650 '--list-real-pseudonym', '1.3',
650 '--list-real-pseudonym', '1.3',
651 'freeargtwo',
651 'freeargtwo',
652 '-abbreviated-string-list', 'String1',
652 '-abbreviated-string-list', 'String1',
653 '--abbreviated-s', 'String2',
653 '--abbreviated-s', 'String2',
654 '-abbrev', 'String3',
654 '-abbrev', 'String3',
655 '-a', 'String4',
655 '-a', 'String4',
656 '-optional-string-option',
656 '-optional-string-option',
657 'term',
657 'term',
658 'next option should look like an invalid arg',
658 'next option should look like an invalid arg',
659 '-a']
659 '-a']
660
660
661
661
662 print 'Using profile: ' + repr(profile)
662 print 'Using profile: ' + repr(profile)
663 print 'With terminator: ' + repr(terminators)
663 print 'With terminator: ' + repr(terminators)
664 print 'Processing arguments: ' + repr(args)
664 print 'Processing arguments: ' + repr(args)
665
665
666 go = DPyGetOpt(profile, terminators)
666 go = DPyGetOpt(profile, terminators)
667 go.processArguments(args)
667 go.processArguments(args)
668
668
669 print 'Options (and values): ' + repr(go.optionValues)
669 print 'Options (and values): ' + repr(go.optionValues)
670 print 'free args: ' + repr(go.freeValues)
670 print 'free args: ' + repr(go.freeValues)
671 print 'term args: ' + repr(go.termValues)
671 print 'term args: ' + repr(go.termValues)
@@ -1,264 +1,270 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 Pdb debugger class.
3 Pdb debugger class.
4
4
5 Modified from the standard pdb.Pdb class to avoid including readline, so that
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
6 the command line completion of other programs which include this isn't
7 damaged.
7 damaged.
8
8
9 In the future, this class will be expanded with improvements over the standard
9 In the future, this class will be expanded with improvements over the standard
10 pdb.
10 pdb.
11
11
12 The code in this file is mainly lifted out of cmd.py in Python 2.2, with minor
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
13 changes. Licensing should therefore be under the standard Python terms. For
14 details on the PSF (Python Software Foundation) standard license, see:
14 details on the PSF (Python Software Foundation) standard license, see:
15
15
16 http://www.python.org/2.2.3/license.html
16 http://www.python.org/2.2.3/license.html
17
17
18 $Id: Debugger.py 951 2005-12-25 00:57:24Z fperez $"""
18 $Id: Debugger.py 958 2005-12-27 23:17:51Z fperez $"""
19
19
20 from IPython import Release
20 from IPython import Release
21 __author__ = '%s <%s>' % Release.authors['Fernando']
21 __author__ = '%s <%s>' % Release.authors['Fernando']
22 __license__ = 'Python'
22 __license__ = 'Python'
23
23
24 import pdb,bdb,cmd,os,sys,linecache
24 import bdb
25 import cmd
26 import linecache
27 import os
28 import pdb
29 import sys
30
25 from IPython import PyColorize, ColorANSI
31 from IPython import PyColorize, ColorANSI
26 from IPython.genutils import Term
32 from IPython.genutils import Term
27 from IPython.excolors import ExceptionColors
33 from IPython.excolors import ExceptionColors
28
34
29 def _file_lines(fname):
35 def _file_lines(fname):
30 """Return the contents of a named file as a list of lines.
36 """Return the contents of a named file as a list of lines.
31
37
32 This function never raises an IOError exception: if the file can't be
38 This function never raises an IOError exception: if the file can't be
33 read, it simply returns an empty list."""
39 read, it simply returns an empty list."""
34
40
35 try:
41 try:
36 outfile = open(fname)
42 outfile = open(fname)
37 except IOError:
43 except IOError:
38 return []
44 return []
39 else:
45 else:
40 out = outfile.readlines()
46 out = outfile.readlines()
41 outfile.close()
47 outfile.close()
42 return out
48 return out
43
49
44
50
45 class Pdb(pdb.Pdb):
51 class Pdb(pdb.Pdb):
46 """Modified Pdb class, does not load readline."""
52 """Modified Pdb class, does not load readline."""
47 def __init__(self,color_scheme='NoColor'):
53 def __init__(self,color_scheme='NoColor'):
48 bdb.Bdb.__init__(self)
54 bdb.Bdb.__init__(self)
49 cmd.Cmd.__init__(self,completekey=None) # don't load readline
55 cmd.Cmd.__init__(self,completekey=None) # don't load readline
50 self.prompt = 'ipdb> ' # The default prompt is '(Pdb)'
56 self.prompt = 'ipdb> ' # The default prompt is '(Pdb)'
51 self.aliases = {}
57 self.aliases = {}
52
58
53 # Read $HOME/.pdbrc and ./.pdbrc
59 # Read $HOME/.pdbrc and ./.pdbrc
54 try:
60 try:
55 self.rcLines = _file_lines(os.path.join(os.environ['HOME'],
61 self.rcLines = _file_lines(os.path.join(os.environ['HOME'],
56 ".pdbrc"))
62 ".pdbrc"))
57 except KeyError:
63 except KeyError:
58 self.rcLines = []
64 self.rcLines = []
59 self.rcLines.extend(_file_lines(".pdbrc"))
65 self.rcLines.extend(_file_lines(".pdbrc"))
60
66
61 # Create color table: we copy the default one from the traceback
67 # Create color table: we copy the default one from the traceback
62 # module and add a few attributes needed for debugging
68 # module and add a few attributes needed for debugging
63 self.color_scheme_table = ExceptionColors.copy()
69 self.color_scheme_table = ExceptionColors.copy()
64
70
65 # shorthands
71 # shorthands
66 C = ColorANSI.TermColors
72 C = ColorANSI.TermColors
67 cst = self.color_scheme_table
73 cst = self.color_scheme_table
68
74
69 cst['NoColor'].colors.breakpoint_enabled = C.NoColor
75 cst['NoColor'].colors.breakpoint_enabled = C.NoColor
70 cst['NoColor'].colors.breakpoint_disabled = C.NoColor
76 cst['NoColor'].colors.breakpoint_disabled = C.NoColor
71
77
72 cst['Linux'].colors.breakpoint_enabled = C.LightRed
78 cst['Linux'].colors.breakpoint_enabled = C.LightRed
73 cst['Linux'].colors.breakpoint_disabled = C.Red
79 cst['Linux'].colors.breakpoint_disabled = C.Red
74
80
75 cst['LightBG'].colors.breakpoint_enabled = C.LightRed
81 cst['LightBG'].colors.breakpoint_enabled = C.LightRed
76 cst['LightBG'].colors.breakpoint_disabled = C.Red
82 cst['LightBG'].colors.breakpoint_disabled = C.Red
77
83
78 self.set_colors(color_scheme)
84 self.set_colors(color_scheme)
79
85
80 def set_colors(self, scheme):
86 def set_colors(self, scheme):
81 """Shorthand access to the color table scheme selector method."""
87 """Shorthand access to the color table scheme selector method."""
82 self.color_scheme_table.set_active_scheme(scheme)
88 self.color_scheme_table.set_active_scheme(scheme)
83
89
84
90
85 def interaction(self, frame, traceback):
91 def interaction(self, frame, traceback):
86 __IPYTHON__.set_completer_frame(frame)
92 __IPYTHON__.set_completer_frame(frame)
87 pdb.Pdb.interaction(self, frame, traceback)
93 pdb.Pdb.interaction(self, frame, traceback)
88
94
89
95
90 def do_up(self, arg):
96 def do_up(self, arg):
91 pdb.Pdb.do_up(self, arg)
97 pdb.Pdb.do_up(self, arg)
92 __IPYTHON__.set_completer_frame(self.curframe)
98 __IPYTHON__.set_completer_frame(self.curframe)
93 do_u = do_up
99 do_u = do_up
94
100
95
101
96 def do_down(self, arg):
102 def do_down(self, arg):
97 pdb.Pdb.do_down(self, arg)
103 pdb.Pdb.do_down(self, arg)
98 __IPYTHON__.set_completer_frame(self.curframe)
104 __IPYTHON__.set_completer_frame(self.curframe)
99 do_d = do_down
105 do_d = do_down
100
106
101
107
102 def postloop(self):
108 def postloop(self):
103 __IPYTHON__.set_completer_frame(None)
109 __IPYTHON__.set_completer_frame(None)
104
110
105
111
106 def print_stack_trace(self):
112 def print_stack_trace(self):
107 try:
113 try:
108 for frame_lineno in self.stack:
114 for frame_lineno in self.stack:
109 self.print_stack_entry(frame_lineno, context = 5)
115 self.print_stack_entry(frame_lineno, context = 5)
110 except KeyboardInterrupt:
116 except KeyboardInterrupt:
111 pass
117 pass
112
118
113
119
114 def print_stack_entry(self,frame_lineno,prompt_prefix='\n-> ',
120 def print_stack_entry(self,frame_lineno,prompt_prefix='\n-> ',
115 context = 3):
121 context = 3):
116 frame, lineno = frame_lineno
122 frame, lineno = frame_lineno
117 print >>Term.cout, self.format_stack_entry(frame_lineno, '', context)
123 print >>Term.cout, self.format_stack_entry(frame_lineno, '', context)
118
124
119
125
120 def format_stack_entry(self, frame_lineno, lprefix=': ', context = 3):
126 def format_stack_entry(self, frame_lineno, lprefix=': ', context = 3):
121 import linecache, repr
127 import linecache, repr
122
128
123 ret = ""
129 ret = ""
124
130
125 Colors = self.color_scheme_table.active_colors
131 Colors = self.color_scheme_table.active_colors
126 ColorsNormal = Colors.Normal
132 ColorsNormal = Colors.Normal
127 tpl_link = '%s%%s%s' % (Colors.filenameEm, ColorsNormal)
133 tpl_link = '%s%%s%s' % (Colors.filenameEm, ColorsNormal)
128 tpl_call = 'in %s%%s%s%%s%s' % (Colors.vName, Colors.valEm, ColorsNormal)
134 tpl_call = 'in %s%%s%s%%s%s' % (Colors.vName, Colors.valEm, ColorsNormal)
129 tpl_line = '%%s%s%%s %s%%s' % (Colors.lineno, ColorsNormal)
135 tpl_line = '%%s%s%%s %s%%s' % (Colors.lineno, ColorsNormal)
130 tpl_line_em = '%%s%s%%s %s%%s%s' % (Colors.linenoEm, Colors.line,
136 tpl_line_em = '%%s%s%%s %s%%s%s' % (Colors.linenoEm, Colors.line,
131 ColorsNormal)
137 ColorsNormal)
132
138
133 frame, lineno = frame_lineno
139 frame, lineno = frame_lineno
134
140
135 return_value = ''
141 return_value = ''
136 if '__return__' in frame.f_locals:
142 if '__return__' in frame.f_locals:
137 rv = frame.f_locals['__return__']
143 rv = frame.f_locals['__return__']
138 #return_value += '->'
144 #return_value += '->'
139 return_value += repr.repr(rv) + '\n'
145 return_value += repr.repr(rv) + '\n'
140 ret += return_value
146 ret += return_value
141
147
142 #s = filename + '(' + `lineno` + ')'
148 #s = filename + '(' + `lineno` + ')'
143 filename = self.canonic(frame.f_code.co_filename)
149 filename = self.canonic(frame.f_code.co_filename)
144 link = tpl_link % filename
150 link = tpl_link % filename
145
151
146 if frame.f_code.co_name:
152 if frame.f_code.co_name:
147 func = frame.f_code.co_name
153 func = frame.f_code.co_name
148 else:
154 else:
149 func = "<lambda>"
155 func = "<lambda>"
150
156
151 call = ''
157 call = ''
152 if func != '?':
158 if func != '?':
153 if '__args__' in frame.f_locals:
159 if '__args__' in frame.f_locals:
154 args = repr.repr(frame.f_locals['__args__'])
160 args = repr.repr(frame.f_locals['__args__'])
155 else:
161 else:
156 args = '()'
162 args = '()'
157 call = tpl_call % (func, args)
163 call = tpl_call % (func, args)
158
164
159 level = '%s %s\n' % (link, call)
165 level = '%s %s\n' % (link, call)
160 ret += level
166 ret += level
161
167
162 start = lineno - 1 - context//2
168 start = lineno - 1 - context//2
163 lines = linecache.getlines(filename)
169 lines = linecache.getlines(filename)
164 start = max(start, 0)
170 start = max(start, 0)
165 start = min(start, len(lines) - context)
171 start = min(start, len(lines) - context)
166 lines = lines[start : start + context]
172 lines = lines[start : start + context]
167
173
168 for i in range(len(lines)):
174 for i in range(len(lines)):
169 line = lines[i]
175 line = lines[i]
170 if start + 1 + i == lineno:
176 if start + 1 + i == lineno:
171 ret += self.__format_line(tpl_line_em, filename, start + 1 + i, line, arrow = True)
177 ret += self.__format_line(tpl_line_em, filename, start + 1 + i, line, arrow = True)
172 else:
178 else:
173 ret += self.__format_line(tpl_line, filename, start + 1 + i, line, arrow = False)
179 ret += self.__format_line(tpl_line, filename, start + 1 + i, line, arrow = False)
174
180
175 return ret
181 return ret
176
182
177
183
178 def __format_line(self, tpl_line, filename, lineno, line, arrow = False):
184 def __format_line(self, tpl_line, filename, lineno, line, arrow = False):
179 bp_mark = ""
185 bp_mark = ""
180 bp_mark_color = ""
186 bp_mark_color = ""
181
187
182 bp = None
188 bp = None
183 if lineno in self.get_file_breaks(filename):
189 if lineno in self.get_file_breaks(filename):
184 bps = self.get_breaks(filename, lineno)
190 bps = self.get_breaks(filename, lineno)
185 bp = bps[-1]
191 bp = bps[-1]
186
192
187 if bp:
193 if bp:
188 Colors = self.color_scheme_table.active_colors
194 Colors = self.color_scheme_table.active_colors
189 bp_mark = str(bp.number)
195 bp_mark = str(bp.number)
190 bp_mark_color = Colors.breakpoint_enabled
196 bp_mark_color = Colors.breakpoint_enabled
191 if not bp.enabled:
197 if not bp.enabled:
192 bp_mark_color = Colors.breakpoint_disabled
198 bp_mark_color = Colors.breakpoint_disabled
193
199
194 numbers_width = 7
200 numbers_width = 7
195 if arrow:
201 if arrow:
196 # This is the line with the error
202 # This is the line with the error
197 pad = numbers_width - len(str(lineno)) - len(bp_mark)
203 pad = numbers_width - len(str(lineno)) - len(bp_mark)
198 if pad >= 3:
204 if pad >= 3:
199 marker = '-'*(pad-3) + '-> '
205 marker = '-'*(pad-3) + '-> '
200 elif pad == 2:
206 elif pad == 2:
201 marker = '> '
207 marker = '> '
202 elif pad == 1:
208 elif pad == 1:
203 marker = '>'
209 marker = '>'
204 else:
210 else:
205 marker = ''
211 marker = ''
206 num = '%s%s' % (marker, str(lineno))
212 num = '%s%s' % (marker, str(lineno))
207 line = tpl_line % (bp_mark_color + bp_mark, num, line)
213 line = tpl_line % (bp_mark_color + bp_mark, num, line)
208 else:
214 else:
209 num = '%*s' % (numbers_width - len(bp_mark), str(lineno))
215 num = '%*s' % (numbers_width - len(bp_mark), str(lineno))
210 line = tpl_line % (bp_mark_color + bp_mark, num, line)
216 line = tpl_line % (bp_mark_color + bp_mark, num, line)
211
217
212 return line
218 return line
213
219
214
220
215 def do_list(self, arg):
221 def do_list(self, arg):
216 self.lastcmd = 'list'
222 self.lastcmd = 'list'
217 last = None
223 last = None
218 if arg:
224 if arg:
219 try:
225 try:
220 x = eval(arg, {}, {})
226 x = eval(arg, {}, {})
221 if type(x) == type(()):
227 if type(x) == type(()):
222 first, last = x
228 first, last = x
223 first = int(first)
229 first = int(first)
224 last = int(last)
230 last = int(last)
225 if last < first:
231 if last < first:
226 # Assume it's a count
232 # Assume it's a count
227 last = first + last
233 last = first + last
228 else:
234 else:
229 first = max(1, int(x) - 5)
235 first = max(1, int(x) - 5)
230 except:
236 except:
231 print '*** Error in argument:', `arg`
237 print '*** Error in argument:', `arg`
232 return
238 return
233 elif self.lineno is None:
239 elif self.lineno is None:
234 first = max(1, self.curframe.f_lineno - 5)
240 first = max(1, self.curframe.f_lineno - 5)
235 else:
241 else:
236 first = self.lineno + 1
242 first = self.lineno + 1
237 if last is None:
243 if last is None:
238 last = first + 10
244 last = first + 10
239 filename = self.curframe.f_code.co_filename
245 filename = self.curframe.f_code.co_filename
240 try:
246 try:
241 Colors = self.color_scheme_table.active_colors
247 Colors = self.color_scheme_table.active_colors
242 ColorsNormal = Colors.Normal
248 ColorsNormal = Colors.Normal
243 tpl_line = '%%s%s%%s %s%%s' % (Colors.lineno, ColorsNormal)
249 tpl_line = '%%s%s%%s %s%%s' % (Colors.lineno, ColorsNormal)
244 tpl_line_em = '%%s%s%%s %s%%s%s' % (Colors.linenoEm, Colors.line, ColorsNormal)
250 tpl_line_em = '%%s%s%%s %s%%s%s' % (Colors.linenoEm, Colors.line, ColorsNormal)
245 src = []
251 src = []
246 for lineno in range(first, last+1):
252 for lineno in range(first, last+1):
247 line = linecache.getline(filename, lineno)
253 line = linecache.getline(filename, lineno)
248 if not line:
254 if not line:
249 break
255 break
250
256
251 if lineno == self.curframe.f_lineno:
257 if lineno == self.curframe.f_lineno:
252 line = self.__format_line(tpl_line_em, filename, lineno, line, arrow = True)
258 line = self.__format_line(tpl_line_em, filename, lineno, line, arrow = True)
253 else:
259 else:
254 line = self.__format_line(tpl_line, filename, lineno, line, arrow = False)
260 line = self.__format_line(tpl_line, filename, lineno, line, arrow = False)
255
261
256 src.append(line)
262 src.append(line)
257 self.lineno = lineno
263 self.lineno = lineno
258
264
259 print >>Term.cout, ''.join(src)
265 print >>Term.cout, ''.join(src)
260
266
261 except KeyboardInterrupt:
267 except KeyboardInterrupt:
262 pass
268 pass
263
269
264 do_l = do_list
270 do_l = do_list
@@ -1,655 +1,660 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Improved replacement for the Gnuplot.Gnuplot class.
2 """Improved replacement for the Gnuplot.Gnuplot class.
3
3
4 This module imports Gnuplot and replaces some of its functionality with
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
5 improved versions. They add better handling of arrays for plotting and more
6 convenient PostScript generation, plus some fixes for hardcopy().
6 convenient PostScript generation, plus some fixes for hardcopy().
7
7
8 It also adds a convenient plot2 method for plotting dictionaries and
8 It also adds a convenient plot2 method for plotting dictionaries and
9 lists/tuples of arrays.
9 lists/tuples of arrays.
10
10
11 This module is meant to be used as a drop-in replacement to the original
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:
12 Gnuplot, so it should be safe to do:
13
13
14 import IPython.Gnuplot2 as Gnuplot
14 import IPython.Gnuplot2 as Gnuplot
15
15
16 $Id: Gnuplot2.py 392 2004-10-09 22:01:51Z fperez $"""
16 $Id: Gnuplot2.py 958 2005-12-27 23:17:51Z fperez $"""
17
17
18 import string,os,time,types
19 import cStringIO
18 import cStringIO
19 import os
20 import string
20 import sys
21 import sys
21 import tempfile
22 import tempfile
22 import Numeric
23 import time
24 import types
25
23 import Gnuplot as Gnuplot_ori
26 import Gnuplot as Gnuplot_ori
27 import Numeric
28
24 from IPython.genutils import popkey,xsys
29 from IPython.genutils import popkey,xsys
25
30
26 # needed by hardcopy():
31 # needed by hardcopy():
27 gp = Gnuplot_ori.gp
32 gp = Gnuplot_ori.gp
28
33
29 # Patch for Gnuplot.py 1.6 compatibility.
34 # Patch for Gnuplot.py 1.6 compatibility.
30 # Thanks to Hayden Callow <h.callow@elec.canterbury.ac.nz>
35 # Thanks to Hayden Callow <h.callow@elec.canterbury.ac.nz>
31 try:
36 try:
32 OptionException = Gnuplot_ori.PlotItems.OptionException
37 OptionException = Gnuplot_ori.PlotItems.OptionException
33 except AttributeError:
38 except AttributeError:
34 OptionException = Gnuplot_ori.Errors.OptionError
39 OptionException = Gnuplot_ori.Errors.OptionError
35
40
36 # exhibit a similar interface to Gnuplot so it can be somewhat drop-in
41 # exhibit a similar interface to Gnuplot so it can be somewhat drop-in
37 Data = Gnuplot_ori.Data
42 Data = Gnuplot_ori.Data
38 Func = Gnuplot_ori.Func
43 Func = Gnuplot_ori.Func
39 GridData = Gnuplot_ori.GridData
44 GridData = Gnuplot_ori.GridData
40 PlotItem = Gnuplot_ori.PlotItem
45 PlotItem = Gnuplot_ori.PlotItem
41 PlotItems = Gnuplot_ori.PlotItems
46 PlotItems = Gnuplot_ori.PlotItems
42
47
43 # Modify some of Gnuplot's functions with improved versions (or bugfixed, in
48 # 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
49 # hardcopy's case). In order to preserve the docstrings at runtime, I've
45 # copied them from the original code.
50 # copied them from the original code.
46
51
47 # After some significant changes in v 1.7 of Gnuplot.py, we need to do a bit
52 # After some significant changes in v 1.7 of Gnuplot.py, we need to do a bit
48 # of version checking.
53 # of version checking.
49
54
50 if Gnuplot_ori.__version__ <= '1.6':
55 if Gnuplot_ori.__version__ <= '1.6':
51 _BaseFileItem = PlotItems.File
56 _BaseFileItem = PlotItems.File
52 _BaseTempFileItem = PlotItems.TempFile
57 _BaseTempFileItem = PlotItems.TempFile
53
58
54 # Fix the File class to add the 'index' option for Gnuplot versions < 1.7
59 # Fix the File class to add the 'index' option for Gnuplot versions < 1.7
55 class File(_BaseFileItem):
60 class File(_BaseFileItem):
56
61
57 _option_list = _BaseFileItem._option_list.copy()
62 _option_list = _BaseFileItem._option_list.copy()
58 _option_list.update({
63 _option_list.update({
59 'index' : lambda self, index: self.set_option_index(index),
64 'index' : lambda self, index: self.set_option_index(index),
60 })
65 })
61
66
62 # A new initializer is needed b/c we want to add a modified
67 # A new initializer is needed b/c we want to add a modified
63 # _option_sequence list which includes 'index' in the right place.
68 # _option_sequence list which includes 'index' in the right place.
64 def __init__(self,*args,**kw):
69 def __init__(self,*args,**kw):
65 self._option_sequence = ['binary', 'index', 'using', 'smooth', 'axes',
70 self._option_sequence = ['binary', 'index', 'using', 'smooth', 'axes',
66 'title', 'with']
71 'title', 'with']
67
72
68 _BaseFileItem.__init__(self,*args,**kw)
73 _BaseFileItem.__init__(self,*args,**kw)
69
74
70 # Let's fix the constructor docstring
75 # Let's fix the constructor docstring
71 __newdoc = \
76 __newdoc = \
72 """Additional Keyword arguments added by IPython:
77 """Additional Keyword arguments added by IPython:
73
78
74 'index=<int>' -- similar to the `index` keyword in Gnuplot.
79 'index=<int>' -- similar to the `index` keyword in Gnuplot.
75 This allows only some of the datasets in a file to be
80 This allows only some of the datasets in a file to be
76 plotted. Datasets within a file are assumed to be separated
81 plotted. Datasets within a file are assumed to be separated
77 by _pairs_ of blank lines, and the first one is numbered as
82 by _pairs_ of blank lines, and the first one is numbered as
78 0 (similar to C/Python usage)."""
83 0 (similar to C/Python usage)."""
79 __init__.__doc__ = PlotItems.File.__init__.__doc__ + __newdoc
84 __init__.__doc__ = PlotItems.File.__init__.__doc__ + __newdoc
80
85
81 def set_option_index(self, index):
86 def set_option_index(self, index):
82 if index is None:
87 if index is None:
83 self.clear_option('index')
88 self.clear_option('index')
84 elif type(index) in [type(''), type(1)]:
89 elif type(index) in [type(''), type(1)]:
85 self._options['index'] = (index, 'index %s' % index)
90 self._options['index'] = (index, 'index %s' % index)
86 elif type(index) is type(()):
91 elif type(index) is type(()):
87 self._options['index'] = (index,'index %s' %
92 self._options['index'] = (index,'index %s' %
88 string.join(map(repr, index), ':'))
93 string.join(map(repr, index), ':'))
89 else:
94 else:
90 raise OptionException('index=%s' % (index,))
95 raise OptionException('index=%s' % (index,))
91
96
92 # We need a FileClass with a different name from 'File', which is a
97 # 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
98 # factory function in 1.7, so that our String class can subclass FileClass
94 # in any version.
99 # in any version.
95 _FileClass = File
100 _FileClass = File
96
101
97 else: # Gnuplot.py version 1.7 and greater
102 else: # Gnuplot.py version 1.7 and greater
98 _FileClass = _BaseFileItem = PlotItems._FileItem
103 _FileClass = _BaseFileItem = PlotItems._FileItem
99 _BaseTempFileItem = PlotItems._TempFileItem
104 _BaseTempFileItem = PlotItems._TempFileItem
100 File = PlotItems.File
105 File = PlotItems.File
101
106
102 # Now, we can add our generic code which is version independent
107 # Now, we can add our generic code which is version independent
103
108
104 # First some useful utilities
109 # First some useful utilities
105 def eps_fix_bbox(fname):
110 def eps_fix_bbox(fname):
106 """Fix the bounding box of an eps file by running ps2eps on it.
111 """Fix the bounding box of an eps file by running ps2eps on it.
107
112
108 If its name ends in .eps, the original file is removed.
113 If its name ends in .eps, the original file is removed.
109
114
110 This is particularly useful for plots made by Gnuplot with square aspect
115 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
116 ratio: there is a bug in Gnuplot which makes it generate a bounding box
112 which is far wider than the actual plot.
117 which is far wider than the actual plot.
113
118
114 This function assumes that ps2eps is installed in your system."""
119 This function assumes that ps2eps is installed in your system."""
115
120
116 # note: ps2ps and eps2eps do NOT work, ONLY ps2eps works correctly. The
121 # note: ps2ps and eps2eps do NOT work, ONLY ps2eps works correctly. The
117 # others make output with bitmapped fonts, which looks horrible.
122 # others make output with bitmapped fonts, which looks horrible.
118 print 'Fixing eps file: <%s>' % fname
123 print 'Fixing eps file: <%s>' % fname
119 xsys('ps2eps -f -q -l %s' % fname)
124 xsys('ps2eps -f -q -l %s' % fname)
120 if fname.endswith('.eps'):
125 if fname.endswith('.eps'):
121 os.rename(fname+'.eps',fname)
126 os.rename(fname+'.eps',fname)
122
127
123 def is_list1d(x,containers = [types.ListType,types.TupleType]):
128 def is_list1d(x,containers = [types.ListType,types.TupleType]):
124 """Returns true if x appears to be a 1d list/tuple/array.
129 """Returns true if x appears to be a 1d list/tuple/array.
125
130
126 The heuristics are: identify Numeric arrays, or lists/tuples whose first
131 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
132 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
133 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
134 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.
135 will produce an error. But it should work well in most cases.
131 """
136 """
132 x_type = type(x)
137 x_type = type(x)
133
138
134 return x_type == Numeric.ArrayType and len(x.shape)==1 or \
139 return x_type == Numeric.ArrayType and len(x.shape)==1 or \
135 (x_type in containers and
140 (x_type in containers and
136 type(x[0]) not in containers + [Numeric.ArrayType])
141 type(x[0]) not in containers + [Numeric.ArrayType])
137
142
138 def zip_items(items,titles=None):
143 def zip_items(items,titles=None):
139 """zip together neighboring 1-d arrays, and zip standalone ones
144 """zip together neighboring 1-d arrays, and zip standalone ones
140 with their index. Leave other plot items alone."""
145 with their index. Leave other plot items alone."""
141
146
142 class StandaloneItem(Exception): pass
147 class StandaloneItem(Exception): pass
143
148
144 def get_titles(titles):
149 def get_titles(titles):
145 """Return the next title and the input titles array.
150 """Return the next title and the input titles array.
146
151
147 The input array may be changed to None when no titles are left to
152 The input array may be changed to None when no titles are left to
148 prevent extra unnecessary calls to this function."""
153 prevent extra unnecessary calls to this function."""
149
154
150 try:
155 try:
151 title = titles[tit_ct[0]] # tit_ct[0] is in zip_items'scope
156 title = titles[tit_ct[0]] # tit_ct[0] is in zip_items'scope
152 except IndexError:
157 except IndexError:
153 titles = None # so we don't enter again
158 titles = None # so we don't enter again
154 title = None
159 title = None
155 else:
160 else:
156 tit_ct[0] += 1
161 tit_ct[0] += 1
157 return title,titles
162 return title,titles
158
163
159 new_items = []
164 new_items = []
160
165
161 if titles:
166 if titles:
162 # Initialize counter. It was put in a list as a hack to allow the
167 # 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.
168 # nested get_titles to modify it without raising a NameError.
164 tit_ct = [0]
169 tit_ct = [0]
165
170
166 n = 0 # this loop needs to be done by hand
171 n = 0 # this loop needs to be done by hand
167 while n < len(items):
172 while n < len(items):
168 item = items[n]
173 item = items[n]
169 try:
174 try:
170 if is_list1d(item):
175 if is_list1d(item):
171 if n==len(items)-1: # last in list
176 if n==len(items)-1: # last in list
172 raise StandaloneItem
177 raise StandaloneItem
173 else: # check the next item and zip together if needed
178 else: # check the next item and zip together if needed
174 next_item = items[n+1]
179 next_item = items[n+1]
175 if next_item is None:
180 if next_item is None:
176 n += 1
181 n += 1
177 raise StandaloneItem
182 raise StandaloneItem
178 elif is_list1d(next_item):
183 elif is_list1d(next_item):
179 # this would be best done with an iterator
184 # this would be best done with an iterator
180 if titles:
185 if titles:
181 title,titles = get_titles(titles)
186 title,titles = get_titles(titles)
182 else:
187 else:
183 title = None
188 title = None
184 new_items.append(Data(zip(item,next_item),
189 new_items.append(Data(zip(item,next_item),
185 title=title))
190 title=title))
186 n += 1 # avoid double-inclusion of next item
191 n += 1 # avoid double-inclusion of next item
187 else: # can't zip with next, zip with own index list
192 else: # can't zip with next, zip with own index list
188 raise StandaloneItem
193 raise StandaloneItem
189 else: # not 1-d array
194 else: # not 1-d array
190 new_items.append(item)
195 new_items.append(item)
191 except StandaloneItem:
196 except StandaloneItem:
192 if titles:
197 if titles:
193 title,titles = get_titles(titles)
198 title,titles = get_titles(titles)
194 else:
199 else:
195 title = None
200 title = None
196 new_items.append(Data(zip(range(len(item)),item),title=title))
201 new_items.append(Data(zip(range(len(item)),item),title=title))
197 except AttributeError:
202 except AttributeError:
198 new_items.append(item)
203 new_items.append(item)
199 n+=1
204 n+=1
200
205
201 return new_items
206 return new_items
202
207
203 # And some classes with enhanced functionality.
208 # And some classes with enhanced functionality.
204 class String(_FileClass):
209 class String(_FileClass):
205 """Make a PlotItem from data in a string with the same format as a File.
210 """Make a PlotItem from data in a string with the same format as a File.
206
211
207 This allows writing data directly inside python scripts using the exact
212 This allows writing data directly inside python scripts using the exact
208 same format and manipulation options which would be used for external
213 same format and manipulation options which would be used for external
209 files."""
214 files."""
210
215
211 def __init__(self, data_str, **keyw):
216 def __init__(self, data_str, **keyw):
212 """Construct a String object.
217 """Construct a String object.
213
218
214 <data_str> is a string formatted exactly like a valid Gnuplot data
219 <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.
220 file would be. All options from the File constructor are valid here.
216
221
217 Warning: when used for interactive plotting in scripts which exit
222 Warning: when used for interactive plotting in scripts which exit
218 immediately, you may get an error because the temporary file used to
223 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
224 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
225 it. You can work around this problem by putting a raw_input() call at
221 the end of the script.
226 the end of the script.
222
227
223 This problem does not appear when generating PostScript output, only
228 This problem does not appear when generating PostScript output, only
224 with Gnuplot windows."""
229 with Gnuplot windows."""
225
230
226 self.tmpfile = _BaseTempFileItem()
231 self.tmpfile = _BaseTempFileItem()
227 tmpfile = file(self.tmpfile.filename,'w')
232 tmpfile = file(self.tmpfile.filename,'w')
228 tmpfile.write(data_str)
233 tmpfile.write(data_str)
229 _BaseFileItem.__init__(self,self.tmpfile,**keyw)
234 _BaseFileItem.__init__(self,self.tmpfile,**keyw)
230
235
231
236
232 class Gnuplot(Gnuplot_ori.Gnuplot):
237 class Gnuplot(Gnuplot_ori.Gnuplot):
233 """Improved Gnuplot class.
238 """Improved Gnuplot class.
234
239
235 Enhancements: better plot,replot and hardcopy methods. New methods for
240 Enhancements: better plot,replot and hardcopy methods. New methods for
236 quick range setting.
241 quick range setting.
237 """
242 """
238
243
239 def xrange(self,min='*',max='*'):
244 def xrange(self,min='*',max='*'):
240 """Set xrange. If min/max is omitted, it is set to '*' (auto).
245 """Set xrange. If min/max is omitted, it is set to '*' (auto).
241
246
242 Note that this is different from the regular Gnuplot behavior, where
247 Note that this is different from the regular Gnuplot behavior, where
243 an unspecified limit means no change. Here any unspecified limit is
248 an unspecified limit means no change. Here any unspecified limit is
244 set to autoscaling, allowing these functions to be used for full
249 set to autoscaling, allowing these functions to be used for full
245 autoscaling when called with no arguments.
250 autoscaling when called with no arguments.
246
251
247 To preserve one limit's current value while changing the other, an
252 To preserve one limit's current value while changing the other, an
248 explicit '' argument must be given as the limit to be kept.
253 explicit '' argument must be given as the limit to be kept.
249
254
250 Similar functions exist for [y{2}z{2}rtuv]range."""
255 Similar functions exist for [y{2}z{2}rtuv]range."""
251
256
252 self('set xrange [%s:%s]' % (min,max))
257 self('set xrange [%s:%s]' % (min,max))
253
258
254 def yrange(self,min='*',max='*'):
259 def yrange(self,min='*',max='*'):
255 self('set yrange [%s:%s]' % (min,max))
260 self('set yrange [%s:%s]' % (min,max))
256
261
257 def zrange(self,min='*',max='*'):
262 def zrange(self,min='*',max='*'):
258 self('set zrange [%s:%s]' % (min,max))
263 self('set zrange [%s:%s]' % (min,max))
259
264
260 def x2range(self,min='*',max='*'):
265 def x2range(self,min='*',max='*'):
261 self('set xrange [%s:%s]' % (min,max))
266 self('set xrange [%s:%s]' % (min,max))
262
267
263 def y2range(self,min='*',max='*'):
268 def y2range(self,min='*',max='*'):
264 self('set yrange [%s:%s]' % (min,max))
269 self('set yrange [%s:%s]' % (min,max))
265
270
266 def z2range(self,min='*',max='*'):
271 def z2range(self,min='*',max='*'):
267 self('set zrange [%s:%s]' % (min,max))
272 self('set zrange [%s:%s]' % (min,max))
268
273
269 def rrange(self,min='*',max='*'):
274 def rrange(self,min='*',max='*'):
270 self('set rrange [%s:%s]' % (min,max))
275 self('set rrange [%s:%s]' % (min,max))
271
276
272 def trange(self,min='*',max='*'):
277 def trange(self,min='*',max='*'):
273 self('set trange [%s:%s]' % (min,max))
278 self('set trange [%s:%s]' % (min,max))
274
279
275 def urange(self,min='*',max='*'):
280 def urange(self,min='*',max='*'):
276 self('set urange [%s:%s]' % (min,max))
281 self('set urange [%s:%s]' % (min,max))
277
282
278 def vrange(self,min='*',max='*'):
283 def vrange(self,min='*',max='*'):
279 self('set vrange [%s:%s]' % (min,max))
284 self('set vrange [%s:%s]' % (min,max))
280
285
281 def set_ps(self,option):
286 def set_ps(self,option):
282 """Set an option for the PostScript terminal and reset default term."""
287 """Set an option for the PostScript terminal and reset default term."""
283
288
284 self('set terminal postscript %s ' % option)
289 self('set terminal postscript %s ' % option)
285 self('set terminal %s' % gp.GnuplotOpts.default_term)
290 self('set terminal %s' % gp.GnuplotOpts.default_term)
286
291
287 def __plot_ps(self, plot_method,*items, **keyw):
292 def __plot_ps(self, plot_method,*items, **keyw):
288 """Wrapper for plot/splot/replot, with processing of hardcopy options.
293 """Wrapper for plot/splot/replot, with processing of hardcopy options.
289
294
290 For internal use only."""
295 For internal use only."""
291
296
292 # Filter out PostScript options which will crash the normal plot/replot
297 # Filter out PostScript options which will crash the normal plot/replot
293 psargs = {'filename':None,
298 psargs = {'filename':None,
294 'mode':None,
299 'mode':None,
295 'eps':None,
300 'eps':None,
296 'enhanced':None,
301 'enhanced':None,
297 'color':None,
302 'color':None,
298 'solid':None,
303 'solid':None,
299 'duplexing':None,
304 'duplexing':None,
300 'fontname':None,
305 'fontname':None,
301 'fontsize':None,
306 'fontsize':None,
302 'debug':0 }
307 'debug':0 }
303
308
304 for k in psargs.keys():
309 for k in psargs.keys():
305 if keyw.has_key(k):
310 if keyw.has_key(k):
306 psargs[k] = keyw[k]
311 psargs[k] = keyw[k]
307 del keyw[k]
312 del keyw[k]
308
313
309 # Filter out other options the original plot doesn't know
314 # Filter out other options the original plot doesn't know
310 hardcopy = popkey(keyw,'hardcopy',psargs['filename'] is not None)
315 hardcopy = popkey(keyw,'hardcopy',psargs['filename'] is not None)
311 titles = popkey(keyw,'titles',0)
316 titles = popkey(keyw,'titles',0)
312
317
313 # the filename keyword should control hardcopy generation, this is an
318 # the filename keyword should control hardcopy generation, this is an
314 # override switch only which needs to be explicitly set to zero
319 # override switch only which needs to be explicitly set to zero
315 if hardcopy:
320 if hardcopy:
316 if psargs['filename'] is None:
321 if psargs['filename'] is None:
317 raise ValueError, \
322 raise ValueError, \
318 'If you request hardcopy, you must give a filename.'
323 'If you request hardcopy, you must give a filename.'
319
324
320 # set null output so nothing goes to screen. hardcopy() restores output
325 # set null output so nothing goes to screen. hardcopy() restores output
321 self('set term dumb')
326 self('set term dumb')
322 # I don't know how to prevent screen output in Windows
327 # I don't know how to prevent screen output in Windows
323 if os.name == 'posix':
328 if os.name == 'posix':
324 self('set output "/dev/null"')
329 self('set output "/dev/null"')
325
330
326 new_items = zip_items(items,titles)
331 new_items = zip_items(items,titles)
327 # plot_method is either plot or replot from the original Gnuplot class:
332 # plot_method is either plot or replot from the original Gnuplot class:
328 plot_method(self,*new_items,**keyw)
333 plot_method(self,*new_items,**keyw)
329
334
330 # Do hardcopy if requested
335 # Do hardcopy if requested
331 if hardcopy:
336 if hardcopy:
332 if psargs['filename'].endswith('.eps'):
337 if psargs['filename'].endswith('.eps'):
333 psargs['eps'] = 1
338 psargs['eps'] = 1
334 self.hardcopy(**psargs)
339 self.hardcopy(**psargs)
335
340
336 def plot(self, *items, **keyw):
341 def plot(self, *items, **keyw):
337 """Draw a new plot.
342 """Draw a new plot.
338
343
339 Clear the current plot and create a new 2-d plot containing
344 Clear the current plot and create a new 2-d plot containing
340 the specified items. Each arguments should be of the
345 the specified items. Each arguments should be of the
341 following types:
346 following types:
342
347
343 'PlotItem' (e.g., 'Data', 'File', 'Func') -- This is the most
348 'PlotItem' (e.g., 'Data', 'File', 'Func') -- This is the most
344 flexible way to call plot because the PlotItems can
349 flexible way to call plot because the PlotItems can
345 contain suboptions. Moreover, PlotItems can be saved to
350 contain suboptions. Moreover, PlotItems can be saved to
346 variables so that their lifetime is longer than one plot
351 variables so that their lifetime is longer than one plot
347 command; thus they can be replotted with minimal overhead.
352 command; thus they can be replotted with minimal overhead.
348
353
349 'string' (e.g., 'sin(x)') -- The string is interpreted as
354 'string' (e.g., 'sin(x)') -- The string is interpreted as
350 'Func(string)' (a function that is computed by gnuplot).
355 'Func(string)' (a function that is computed by gnuplot).
351
356
352 Anything else -- The object, which should be convertible to an
357 Anything else -- The object, which should be convertible to an
353 array, is passed to the 'Data' constructor, and thus
358 array, is passed to the 'Data' constructor, and thus
354 plotted as data. If the conversion fails, an exception is
359 plotted as data. If the conversion fails, an exception is
355 raised.
360 raised.
356
361
357
362
358 This is a modified version of plot(). Compared to the original in
363 This is a modified version of plot(). Compared to the original in
359 Gnuplot.py, this version has several enhancements, listed below.
364 Gnuplot.py, this version has several enhancements, listed below.
360
365
361
366
362 Modifications to the input arguments
367 Modifications to the input arguments
363 ------------------------------------
368 ------------------------------------
364
369
365 (1-d array means Numeric array, list or tuple):
370 (1-d array means Numeric array, list or tuple):
366
371
367 (i) Any 1-d array which is NOT followed by another 1-d array, is
372 (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
373 automatically zipped with range(len(array_1d)). Typing g.plot(y) will
369 plot y against its indices.
374 plot y against its indices.
370
375
371 (ii) If two 1-d arrays are contiguous in the argument list, they are
376 (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
377 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.
378 g.plot(x1,y1,x2,y2) plots y1 vs. x1 and y2 vs. x2.
374
379
375 (iii) Any 1-d array which is followed by None is automatically zipped
380 (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)
381 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
382 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
383 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)
384 since y2 is unpaired it is automatically zipped to its indices by (i)
380
385
381 (iv) Any other arguments which don't match these cases are left alone and
386 (iv) Any other arguments which don't match these cases are left alone and
382 passed to the code below.
387 passed to the code below.
383
388
384 For lists or tuples, the heuristics used to determine whether they are
389 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
390 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
391 if it is not a list or tuple itself, it is assumed that the whole
387 object is one-dimensional.
392 object is one-dimensional.
388
393
389 An additional optional keyword 'titles' has been added: it must be a
394 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
395 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
396 are NOT PlotItem objects (since those objects carry their own labels
392 within).
397 within).
393
398
394
399
395 PostScript generation
400 PostScript generation
396 ---------------------
401 ---------------------
397
402
398 This version of plot() also handles automatically the production of
403 This version of plot() also handles automatically the production of
399 PostScript output. The main options are (given as keyword arguments):
404 PostScript output. The main options are (given as keyword arguments):
400
405
401 - filename: a string, typically ending in .eps. If given, the plot is
406 - filename: a string, typically ending in .eps. If given, the plot is
402 sent to this file in PostScript format.
407 sent to this file in PostScript format.
403
408
404 - hardcopy: this can be set to 0 to override 'filename'. It does not
409 - 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
410 need to be given to produce PostScript, its purpose is to allow
406 switching PostScript output off globally in scripts without having to
411 switching PostScript output off globally in scripts without having to
407 manually change 'filename' values in multiple calls.
412 manually change 'filename' values in multiple calls.
408
413
409 All other keywords accepted by Gnuplot.hardcopy() are transparently
414 All other keywords accepted by Gnuplot.hardcopy() are transparently
410 passed, and safely ignored if output is sent to the screen instead of
415 passed, and safely ignored if output is sent to the screen instead of
411 PostScript.
416 PostScript.
412
417
413 For example:
418 For example:
414
419
415 In [1]: x=frange(0,2*pi,npts=100)
420 In [1]: x=frange(0,2*pi,npts=100)
416
421
417 Generate a plot in file 'sin.eps':
422 Generate a plot in file 'sin.eps':
418
423
419 In [2]: plot(x,sin(x),filename = 'sin.eps')
424 In [2]: plot(x,sin(x),filename = 'sin.eps')
420
425
421 Plot to screen instead, without having to change the filename:
426 Plot to screen instead, without having to change the filename:
422
427
423 In [3]: plot(x,sin(x),filename = 'sin.eps',hardcopy=0)
428 In [3]: plot(x,sin(x),filename = 'sin.eps',hardcopy=0)
424
429
425 Pass the 'color=0' option to hardcopy for monochrome output:
430 Pass the 'color=0' option to hardcopy for monochrome output:
426
431
427 In [4]: plot(x,sin(x),filename = 'sin.eps',color=0)
432 In [4]: plot(x,sin(x),filename = 'sin.eps',color=0)
428
433
429 PostScript generation through plot() is useful mainly for scripting
434 PostScript generation through plot() is useful mainly for scripting
430 uses where you are not interested in interactive plotting. For
435 uses where you are not interested in interactive plotting. For
431 interactive use, the hardcopy() function is typically more convenient:
436 interactive use, the hardcopy() function is typically more convenient:
432
437
433 In [5]: plot(x,sin(x))
438 In [5]: plot(x,sin(x))
434
439
435 In [6]: hardcopy('sin.eps') """
440 In [6]: hardcopy('sin.eps') """
436
441
437 self.__plot_ps(Gnuplot_ori.Gnuplot.plot,*items,**keyw)
442 self.__plot_ps(Gnuplot_ori.Gnuplot.plot,*items,**keyw)
438
443
439 def plot2(self,arg,**kw):
444 def plot2(self,arg,**kw):
440 """Plot the entries of a dictionary or a list/tuple of arrays.
445 """Plot the entries of a dictionary or a list/tuple of arrays.
441
446
442 This simple utility calls plot() with a list of Gnuplot.Data objects
447 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
448 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
449 in it if it is a tuple or list. Each item gets labeled with the key/index
445 in the Gnuplot legend.
450 in the Gnuplot legend.
446
451
447 Each item is plotted by zipping it with a list of its indices.
452 Each item is plotted by zipping it with a list of its indices.
448
453
449 Any keywords are passed directly to plot()."""
454 Any keywords are passed directly to plot()."""
450
455
451 if hasattr(arg,'keys'):
456 if hasattr(arg,'keys'):
452 keys = arg.keys()
457 keys = arg.keys()
453 keys.sort()
458 keys.sort()
454 else:
459 else:
455 keys = range(len(arg))
460 keys = range(len(arg))
456
461
457 pitems = [Data(zip(range(len(arg[k])),arg[k]),title=`k`) for k in keys]
462 pitems = [Data(zip(range(len(arg[k])),arg[k]),title=`k`) for k in keys]
458 self.plot(*pitems,**kw)
463 self.plot(*pitems,**kw)
459
464
460 def splot(self, *items, **keyw):
465 def splot(self, *items, **keyw):
461 """Draw a new three-dimensional plot.
466 """Draw a new three-dimensional plot.
462
467
463 Clear the current plot and create a new 3-d plot containing
468 Clear the current plot and create a new 3-d plot containing
464 the specified items. Arguments can be of the following types:
469 the specified items. Arguments can be of the following types:
465
470
466 'PlotItem' (e.g., 'Data', 'File', 'Func', 'GridData' ) -- This
471 'PlotItem' (e.g., 'Data', 'File', 'Func', 'GridData' ) -- This
467 is the most flexible way to call plot because the
472 is the most flexible way to call plot because the
468 PlotItems can contain suboptions. Moreover, PlotItems can
473 PlotItems can contain suboptions. Moreover, PlotItems can
469 be saved to variables so that their lifetime is longer
474 be saved to variables so that their lifetime is longer
470 than one plot command--thus they can be replotted with
475 than one plot command--thus they can be replotted with
471 minimal overhead.
476 minimal overhead.
472
477
473 'string' (e.g., 'sin(x*y)') -- The string is interpreted as a
478 'string' (e.g., 'sin(x*y)') -- The string is interpreted as a
474 'Func()' (a function that is computed by gnuplot).
479 'Func()' (a function that is computed by gnuplot).
475
480
476 Anything else -- The object is converted to a Data() item, and
481 Anything else -- The object is converted to a Data() item, and
477 thus plotted as data. Note that each data point should
482 thus plotted as data. Note that each data point should
478 normally have at least three values associated with it
483 normally have at least three values associated with it
479 (i.e., x, y, and z). If the conversion fails, an
484 (i.e., x, y, and z). If the conversion fails, an
480 exception is raised.
485 exception is raised.
481
486
482 This is a modified version of splot(). Compared to the original in
487 This is a modified version of splot(). Compared to the original in
483 Gnuplot.py, this version has several enhancements, listed in the
488 Gnuplot.py, this version has several enhancements, listed in the
484 plot() documentation.
489 plot() documentation.
485 """
490 """
486
491
487 self.__plot_ps(Gnuplot_ori.Gnuplot.splot,*items,**keyw)
492 self.__plot_ps(Gnuplot_ori.Gnuplot.splot,*items,**keyw)
488
493
489 def replot(self, *items, **keyw):
494 def replot(self, *items, **keyw):
490 """Replot the data, possibly adding new 'PlotItem's.
495 """Replot the data, possibly adding new 'PlotItem's.
491
496
492 Replot the existing graph, using the items in the current
497 Replot the existing graph, using the items in the current
493 itemlist. If arguments are specified, they are interpreted as
498 itemlist. If arguments are specified, they are interpreted as
494 additional items to be plotted alongside the existing items on
499 additional items to be plotted alongside the existing items on
495 the same graph. See 'plot' for details.
500 the same graph. See 'plot' for details.
496
501
497 If you want to replot to a postscript file, you MUST give the
502 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
503 'filename' keyword argument in each call to replot. The Gnuplot python
499 interface has no way of knowing that your previous call to
504 interface has no way of knowing that your previous call to
500 Gnuplot.plot() was meant for PostScript output."""
505 Gnuplot.plot() was meant for PostScript output."""
501
506
502 self.__plot_ps(Gnuplot_ori.Gnuplot.replot,*items,**keyw)
507 self.__plot_ps(Gnuplot_ori.Gnuplot.replot,*items,**keyw)
503
508
504 # The original hardcopy has a bug. See fix at the end. The rest of the code
509 # 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
510 # was lifted verbatim from the original, so that people using IPython get the
506 # benefits without having to manually patch Gnuplot.py
511 # benefits without having to manually patch Gnuplot.py
507 def hardcopy(self, filename=None,
512 def hardcopy(self, filename=None,
508 mode=None,
513 mode=None,
509 eps=None,
514 eps=None,
510 enhanced=None,
515 enhanced=None,
511 color=None,
516 color=None,
512 solid=None,
517 solid=None,
513 duplexing=None,
518 duplexing=None,
514 fontname=None,
519 fontname=None,
515 fontsize=None,
520 fontsize=None,
516 debug = 0,
521 debug = 0,
517 ):
522 ):
518 """Create a hardcopy of the current plot.
523 """Create a hardcopy of the current plot.
519
524
520 Create a postscript hardcopy of the current plot to the
525 Create a postscript hardcopy of the current plot to the
521 default printer (if configured) or to the specified filename.
526 default printer (if configured) or to the specified filename.
522
527
523 Note that gnuplot remembers the postscript suboptions across
528 Note that gnuplot remembers the postscript suboptions across
524 terminal changes. Therefore if you set, for example, color=1
529 terminal changes. Therefore if you set, for example, color=1
525 for one hardcopy then the next hardcopy will also be color
530 for one hardcopy then the next hardcopy will also be color
526 unless you explicitly choose color=0. Alternately you can
531 unless you explicitly choose color=0. Alternately you can
527 force all of the options to their defaults by setting
532 force all of the options to their defaults by setting
528 mode='default'. I consider this to be a bug in gnuplot.
533 mode='default'. I consider this to be a bug in gnuplot.
529
534
530 Keyword arguments:
535 Keyword arguments:
531
536
532 'filename=<string>' -- if a filename is specified, save the
537 'filename=<string>' -- if a filename is specified, save the
533 output in that file; otherwise print it immediately
538 output in that file; otherwise print it immediately
534 using the 'default_lpr' configuration option. If the
539 using the 'default_lpr' configuration option. If the
535 filename ends in '.eps', EPS mode is automatically
540 filename ends in '.eps', EPS mode is automatically
536 selected (like manually specifying eps=1 or mode='eps').
541 selected (like manually specifying eps=1 or mode='eps').
537
542
538 'mode=<string>' -- set the postscript submode ('landscape',
543 'mode=<string>' -- set the postscript submode ('landscape',
539 'portrait', 'eps', or 'default'). The default is
544 'portrait', 'eps', or 'default'). The default is
540 to leave this option unspecified.
545 to leave this option unspecified.
541
546
542 'eps=<bool>' -- shorthand for 'mode="eps"'; asks gnuplot to
547 'eps=<bool>' -- shorthand for 'mode="eps"'; asks gnuplot to
543 generate encapsulated postscript.
548 generate encapsulated postscript.
544
549
545 'enhanced=<bool>' -- if set (the default), then generate
550 'enhanced=<bool>' -- if set (the default), then generate
546 enhanced postscript, which allows extra features like
551 enhanced postscript, which allows extra features like
547 font-switching, superscripts, and subscripts in axis
552 font-switching, superscripts, and subscripts in axis
548 labels. (Some old gnuplot versions do not support
553 labels. (Some old gnuplot versions do not support
549 enhanced postscript; if this is the case set
554 enhanced postscript; if this is the case set
550 gp.GnuplotOpts.prefer_enhanced_postscript=None.)
555 gp.GnuplotOpts.prefer_enhanced_postscript=None.)
551
556
552 'color=<bool>' -- if set, create a plot with color. Default
557 'color=<bool>' -- if set, create a plot with color. Default
553 is to leave this option unchanged.
558 is to leave this option unchanged.
554
559
555 'solid=<bool>' -- if set, force lines to be solid (i.e., not
560 'solid=<bool>' -- if set, force lines to be solid (i.e., not
556 dashed).
561 dashed).
557
562
558 'duplexing=<string>' -- set duplexing option ('defaultplex',
563 'duplexing=<string>' -- set duplexing option ('defaultplex',
559 'simplex', or 'duplex'). Only request double-sided
564 'simplex', or 'duplex'). Only request double-sided
560 printing if your printer can handle it. Actually this
565 printing if your printer can handle it. Actually this
561 option is probably meaningless since hardcopy() can only
566 option is probably meaningless since hardcopy() can only
562 print a single plot at a time.
567 print a single plot at a time.
563
568
564 'fontname=<string>' -- set the default font to <string>,
569 'fontname=<string>' -- set the default font to <string>,
565 which must be a valid postscript font. The default is
570 which must be a valid postscript font. The default is
566 to leave this option unspecified.
571 to leave this option unspecified.
567
572
568 'fontsize=<double>' -- set the default font size, in
573 'fontsize=<double>' -- set the default font size, in
569 postscript points.
574 postscript points.
570
575
571 'debug=<bool>' -- print extra debugging information (useful if
576 'debug=<bool>' -- print extra debugging information (useful if
572 your PostScript files are misteriously not being created).
577 your PostScript files are misteriously not being created).
573 """
578 """
574
579
575 if filename is None:
580 if filename is None:
576 assert gp.GnuplotOpts.default_lpr is not None, \
581 assert gp.GnuplotOpts.default_lpr is not None, \
577 OptionException('default_lpr is not set, so you can only '
582 OptionException('default_lpr is not set, so you can only '
578 'print to a file.')
583 'print to a file.')
579 filename = gp.GnuplotOpts.default_lpr
584 filename = gp.GnuplotOpts.default_lpr
580 lpr_output = 1
585 lpr_output = 1
581 else:
586 else:
582 if filename.endswith('.eps'):
587 if filename.endswith('.eps'):
583 eps = 1
588 eps = 1
584 lpr_output = 0
589 lpr_output = 0
585
590
586 # Be careful processing the options. If the user didn't
591 # Be careful processing the options. If the user didn't
587 # request an option explicitly, do not specify it on the 'set
592 # request an option explicitly, do not specify it on the 'set
588 # terminal' line (don't even specify the default value for the
593 # terminal' line (don't even specify the default value for the
589 # option). This is to avoid confusing older versions of
594 # option). This is to avoid confusing older versions of
590 # gnuplot that do not support all of these options. The
595 # gnuplot that do not support all of these options. The
591 # exception is 'enhanced', which is just too useful to have to
596 # exception is 'enhanced', which is just too useful to have to
592 # specify each time!
597 # specify each time!
593
598
594 setterm = ['set', 'terminal', 'postscript']
599 setterm = ['set', 'terminal', 'postscript']
595 if eps:
600 if eps:
596 assert mode is None or mode=='eps', \
601 assert mode is None or mode=='eps', \
597 OptionException('eps option and mode are incompatible')
602 OptionException('eps option and mode are incompatible')
598 setterm.append('eps')
603 setterm.append('eps')
599 else:
604 else:
600 if mode is not None:
605 if mode is not None:
601 assert mode in ['landscape', 'portrait', 'eps', 'default'], \
606 assert mode in ['landscape', 'portrait', 'eps', 'default'], \
602 OptionException('illegal mode "%s"' % mode)
607 OptionException('illegal mode "%s"' % mode)
603 setterm.append(mode)
608 setterm.append(mode)
604 if enhanced is None:
609 if enhanced is None:
605 enhanced = gp.GnuplotOpts.prefer_enhanced_postscript
610 enhanced = gp.GnuplotOpts.prefer_enhanced_postscript
606 if enhanced is not None:
611 if enhanced is not None:
607 if enhanced: setterm.append('enhanced')
612 if enhanced: setterm.append('enhanced')
608 else: setterm.append('noenhanced')
613 else: setterm.append('noenhanced')
609 if color is not None:
614 if color is not None:
610 if color: setterm.append('color')
615 if color: setterm.append('color')
611 else: setterm.append('monochrome')
616 else: setterm.append('monochrome')
612 if solid is not None:
617 if solid is not None:
613 if solid: setterm.append('solid')
618 if solid: setterm.append('solid')
614 else: setterm.append('dashed')
619 else: setterm.append('dashed')
615 if duplexing is not None:
620 if duplexing is not None:
616 assert duplexing in ['defaultplex', 'simplex', 'duplex'], \
621 assert duplexing in ['defaultplex', 'simplex', 'duplex'], \
617 OptionException('illegal duplexing mode "%s"' % duplexing)
622 OptionException('illegal duplexing mode "%s"' % duplexing)
618 setterm.append(duplexing)
623 setterm.append(duplexing)
619 if fontname is not None:
624 if fontname is not None:
620 setterm.append('"%s"' % fontname)
625 setterm.append('"%s"' % fontname)
621 if fontsize is not None:
626 if fontsize is not None:
622 setterm.append('%s' % fontsize)
627 setterm.append('%s' % fontsize)
623
628
624 self(string.join(setterm))
629 self(string.join(setterm))
625 self.set_string('output', filename)
630 self.set_string('output', filename)
626 # replot the current figure (to the printer):
631 # replot the current figure (to the printer):
627 self.refresh()
632 self.refresh()
628
633
629 # fperez. Ugly kludge: often for some reason the file is NOT created
634 # 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!
635 # and we must reissue the creation commands. I have no idea why!
631 if not lpr_output:
636 if not lpr_output:
632 #print 'Hardcopy <%s>' % filename # dbg
637 #print 'Hardcopy <%s>' % filename # dbg
633 maxtries = 20
638 maxtries = 20
634 delay = 0.1 # delay (in seconds) between print attempts
639 delay = 0.1 # delay (in seconds) between print attempts
635 for i in range(maxtries):
640 for i in range(maxtries):
636 time.sleep(0.05) # safety, very small delay
641 time.sleep(0.05) # safety, very small delay
637 if os.path.isfile(filename):
642 if os.path.isfile(filename):
638 if debug:
643 if debug:
639 print 'Hardcopy to file <%s> success at attempt #%s.' \
644 print 'Hardcopy to file <%s> success at attempt #%s.' \
640 % (filename,i+1)
645 % (filename,i+1)
641 break
646 break
642 time.sleep(delay)
647 time.sleep(delay)
643 # try again, issue all commands just in case
648 # try again, issue all commands just in case
644 self(string.join(setterm))
649 self(string.join(setterm))
645 self.set_string('output', filename)
650 self.set_string('output', filename)
646 self.refresh()
651 self.refresh()
647 if not os.path.isfile(filename):
652 if not os.path.isfile(filename):
648 print >> sys.stderr,'ERROR: Tried %s times and failed to '\
653 print >> sys.stderr,'ERROR: Tried %s times and failed to '\
649 'create hardcopy file `%s`' % (maxtries,filename)
654 'create hardcopy file `%s`' % (maxtries,filename)
650
655
651 # reset the terminal to its `default' setting:
656 # reset the terminal to its `default' setting:
652 self('set terminal %s' % gp.GnuplotOpts.default_term)
657 self('set terminal %s' % gp.GnuplotOpts.default_term)
653 self.set_string('output')
658 self.set_string('output')
654
659
655 #********************** End of file <Gnuplot2.py> ************************
660 #********************** End of file <Gnuplot2.py> ************************
@@ -1,277 +1,278 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """String interpolation for Python (by Ka-Ping Yee, 14 Feb 2000).
2 """String interpolation for Python (by Ka-Ping Yee, 14 Feb 2000).
3
3
4 This module lets you quickly and conveniently interpolate values into
4 This module lets you quickly and conveniently interpolate values into
5 strings (in the flavour of Perl or Tcl, but with less extraneous
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,
6 punctuation). You get a bit more power than in the other languages,
7 because this module allows subscripting, slicing, function calls,
7 because this module allows subscripting, slicing, function calls,
8 attribute lookup, or arbitrary expressions. Variables and expressions
8 attribute lookup, or arbitrary expressions. Variables and expressions
9 are evaluated in the namespace of the caller.
9 are evaluated in the namespace of the caller.
10
10
11 The itpl() function returns the result of interpolating a string, and
11 The itpl() function returns the result of interpolating a string, and
12 printpl() prints out an interpolated string. Here are some examples:
12 printpl() prints out an interpolated string. Here are some examples:
13
13
14 from Itpl import printpl
14 from Itpl import printpl
15 printpl("Here is a $string.")
15 printpl("Here is a $string.")
16 printpl("Here is a $module.member.")
16 printpl("Here is a $module.member.")
17 printpl("Here is an $object.member.")
17 printpl("Here is an $object.member.")
18 printpl("Here is a $functioncall(with, arguments).")
18 printpl("Here is a $functioncall(with, arguments).")
19 printpl("Here is an ${arbitrary + expression}.")
19 printpl("Here is an ${arbitrary + expression}.")
20 printpl("Here is an $array[3] member.")
20 printpl("Here is an $array[3] member.")
21 printpl("Here is a $dictionary['member'].")
21 printpl("Here is a $dictionary['member'].")
22
22
23 The filter() function filters a file object so that output through it
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
24 is interpolated. This lets you produce the illusion that Python knows
25 how to do interpolation:
25 how to do interpolation:
26
26
27 import Itpl
27 import Itpl
28 sys.stdout = Itpl.filter()
28 sys.stdout = Itpl.filter()
29 f = "fancy"
29 f = "fancy"
30 print "Isn't this $f?"
30 print "Isn't this $f?"
31 print "Standard output has been replaced with a $sys.stdout object."
31 print "Standard output has been replaced with a $sys.stdout object."
32 sys.stdout = Itpl.unfilter()
32 sys.stdout = Itpl.unfilter()
33 print "Okay, back $to $normal."
33 print "Okay, back $to $normal."
34
34
35 Under the hood, the Itpl class represents a string that knows how to
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
36 interpolate values. An instance of the class parses the string once
37 upon initialization; the evaluation and substitution can then be done
37 upon initialization; the evaluation and substitution can then be done
38 each time the instance is evaluated with str(instance). For example:
38 each time the instance is evaluated with str(instance). For example:
39
39
40 from Itpl import Itpl
40 from Itpl import Itpl
41 s = Itpl("Here is $foo.")
41 s = Itpl("Here is $foo.")
42 foo = 5
42 foo = 5
43 print str(s)
43 print str(s)
44 foo = "bar"
44 foo = "bar"
45 print str(s)
45 print str(s)
46
46
47 $Id: Itpl.py 638 2005-07-18 03:01:41Z fperez $
47 $Id: Itpl.py 958 2005-12-27 23:17:51Z fperez $
48 """ # ' -> close an open quote for stupid emacs
48 """ # ' -> close an open quote for stupid emacs
49
49
50 #*****************************************************************************
50 #*****************************************************************************
51 #
51 #
52 # Copyright (c) 2001 Ka-Ping Yee <ping@lfw.org>
52 # Copyright (c) 2001 Ka-Ping Yee <ping@lfw.org>
53 #
53 #
54 #
54 #
55 # Published under the terms of the MIT license, hereby reproduced:
55 # Published under the terms of the MIT license, hereby reproduced:
56 #
56 #
57 # Permission is hereby granted, free of charge, to any person obtaining a copy
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
58 # of this software and associated documentation files (the "Software"), to
59 # deal in the Software without restriction, including without limitation the
59 # deal in the Software without restriction, including without limitation the
60 # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
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
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:
62 # furnished to do so, subject to the following conditions:
63 #
63 #
64 # The above copyright notice and this permission notice shall be included in
64 # The above copyright notice and this permission notice shall be included in
65 # all copies or substantial portions of the Software.
65 # all copies or substantial portions of the Software.
66 #
66 #
67 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
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,
68 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
69 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
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
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
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
72 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
73 # IN THE SOFTWARE.
73 # IN THE SOFTWARE.
74 #
74 #
75 #*****************************************************************************
75 #*****************************************************************************
76
76
77 __author__ = 'Ka-Ping Yee <ping@lfw.org>'
77 __author__ = 'Ka-Ping Yee <ping@lfw.org>'
78 __license__ = 'MIT'
78 __license__ = 'MIT'
79
79
80 import sys, string
80 import string
81 from types import StringType
81 import sys
82 from tokenize import tokenprog
82 from tokenize import tokenprog
83 from types import StringType
83
84
84 class ItplError(ValueError):
85 class ItplError(ValueError):
85 def __init__(self, text, pos):
86 def __init__(self, text, pos):
86 self.text = text
87 self.text = text
87 self.pos = pos
88 self.pos = pos
88 def __str__(self):
89 def __str__(self):
89 return "unfinished expression in %s at char %d" % (
90 return "unfinished expression in %s at char %d" % (
90 repr(self.text), self.pos)
91 repr(self.text), self.pos)
91
92
92 def matchorfail(text, pos):
93 def matchorfail(text, pos):
93 match = tokenprog.match(text, pos)
94 match = tokenprog.match(text, pos)
94 if match is None:
95 if match is None:
95 raise ItplError(text, pos)
96 raise ItplError(text, pos)
96 return match, match.end()
97 return match, match.end()
97
98
98 class Itpl:
99 class Itpl:
99 """Class representing a string with interpolation abilities.
100 """Class representing a string with interpolation abilities.
100
101
101 Upon creation, an instance works out what parts of the format
102 Upon creation, an instance works out what parts of the format
102 string are literal and what parts need to be evaluated. The
103 string are literal and what parts need to be evaluated. The
103 evaluation and substitution happens in the namespace of the
104 evaluation and substitution happens in the namespace of the
104 caller when str(instance) is called."""
105 caller when str(instance) is called."""
105
106
106 def __init__(self, format,codec='utf_8',encoding_errors='backslashreplace'):
107 def __init__(self, format,codec='utf_8',encoding_errors='backslashreplace'):
107 """The single mandatory argument to this constructor is a format
108 """The single mandatory argument to this constructor is a format
108 string.
109 string.
109
110
110 The format string is parsed according to the following rules:
111 The format string is parsed according to the following rules:
111
112
112 1. A dollar sign and a name, possibly followed by any of:
113 1. A dollar sign and a name, possibly followed by any of:
113 - an open-paren, and anything up to the matching paren
114 - an open-paren, and anything up to the matching paren
114 - an open-bracket, and anything up to the matching bracket
115 - an open-bracket, and anything up to the matching bracket
115 - a period and a name
116 - a period and a name
116 any number of times, is evaluated as a Python expression.
117 any number of times, is evaluated as a Python expression.
117
118
118 2. A dollar sign immediately followed by an open-brace, and
119 2. A dollar sign immediately followed by an open-brace, and
119 anything up to the matching close-brace, is evaluated as
120 anything up to the matching close-brace, is evaluated as
120 a Python expression.
121 a Python expression.
121
122
122 3. Outside of the expressions described in the above two rules,
123 3. Outside of the expressions described in the above two rules,
123 two dollar signs in a row give you one literal dollar sign.
124 two dollar signs in a row give you one literal dollar sign.
124
125
125 Optional arguments:
126 Optional arguments:
126
127
127 - codec('utf_8'): a string containing the name of a valid Python
128 - codec('utf_8'): a string containing the name of a valid Python
128 codec.
129 codec.
129
130
130 - encoding_errors('backslashreplace'): a string with a valid error handling
131 - encoding_errors('backslashreplace'): a string with a valid error handling
131 policy. See the codecs module documentation for details.
132 policy. See the codecs module documentation for details.
132
133
133 These are used to encode the format string if a call to str() fails on
134 These are used to encode the format string if a call to str() fails on
134 the expanded result."""
135 the expanded result."""
135
136
136 if not isinstance(format,basestring):
137 if not isinstance(format,basestring):
137 raise TypeError, "needs string initializer"
138 raise TypeError, "needs string initializer"
138 self.format = format
139 self.format = format
139 self.codec = codec
140 self.codec = codec
140 self.encoding_errors = encoding_errors
141 self.encoding_errors = encoding_errors
141
142
142 namechars = "abcdefghijklmnopqrstuvwxyz" \
143 namechars = "abcdefghijklmnopqrstuvwxyz" \
143 "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
144 "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
144 chunks = []
145 chunks = []
145 pos = 0
146 pos = 0
146
147
147 while 1:
148 while 1:
148 dollar = string.find(format, "$", pos)
149 dollar = string.find(format, "$", pos)
149 if dollar < 0: break
150 if dollar < 0: break
150 nextchar = format[dollar+1]
151 nextchar = format[dollar+1]
151
152
152 if nextchar == "{":
153 if nextchar == "{":
153 chunks.append((0, format[pos:dollar]))
154 chunks.append((0, format[pos:dollar]))
154 pos, level = dollar+2, 1
155 pos, level = dollar+2, 1
155 while level:
156 while level:
156 match, pos = matchorfail(format, pos)
157 match, pos = matchorfail(format, pos)
157 tstart, tend = match.regs[3]
158 tstart, tend = match.regs[3]
158 token = format[tstart:tend]
159 token = format[tstart:tend]
159 if token == "{": level = level+1
160 if token == "{": level = level+1
160 elif token == "}": level = level-1
161 elif token == "}": level = level-1
161 chunks.append((1, format[dollar+2:pos-1]))
162 chunks.append((1, format[dollar+2:pos-1]))
162
163
163 elif nextchar in namechars:
164 elif nextchar in namechars:
164 chunks.append((0, format[pos:dollar]))
165 chunks.append((0, format[pos:dollar]))
165 match, pos = matchorfail(format, dollar+1)
166 match, pos = matchorfail(format, dollar+1)
166 while pos < len(format):
167 while pos < len(format):
167 if format[pos] == "." and \
168 if format[pos] == "." and \
168 pos+1 < len(format) and format[pos+1] in namechars:
169 pos+1 < len(format) and format[pos+1] in namechars:
169 match, pos = matchorfail(format, pos+1)
170 match, pos = matchorfail(format, pos+1)
170 elif format[pos] in "([":
171 elif format[pos] in "([":
171 pos, level = pos+1, 1
172 pos, level = pos+1, 1
172 while level:
173 while level:
173 match, pos = matchorfail(format, pos)
174 match, pos = matchorfail(format, pos)
174 tstart, tend = match.regs[3]
175 tstart, tend = match.regs[3]
175 token = format[tstart:tend]
176 token = format[tstart:tend]
176 if token[0] in "([": level = level+1
177 if token[0] in "([": level = level+1
177 elif token[0] in ")]": level = level-1
178 elif token[0] in ")]": level = level-1
178 else: break
179 else: break
179 chunks.append((1, format[dollar+1:pos]))
180 chunks.append((1, format[dollar+1:pos]))
180
181
181 else:
182 else:
182 chunks.append((0, format[pos:dollar+1]))
183 chunks.append((0, format[pos:dollar+1]))
183 pos = dollar + 1 + (nextchar == "$")
184 pos = dollar + 1 + (nextchar == "$")
184
185
185 if pos < len(format): chunks.append((0, format[pos:]))
186 if pos < len(format): chunks.append((0, format[pos:]))
186 self.chunks = chunks
187 self.chunks = chunks
187
188
188 def __repr__(self):
189 def __repr__(self):
189 return "<Itpl %s >" % repr(self.format)
190 return "<Itpl %s >" % repr(self.format)
190
191
191 def _str(self,glob,loc):
192 def _str(self,glob,loc):
192 """Evaluate to a string in the given globals/locals.
193 """Evaluate to a string in the given globals/locals.
193
194
194 The final output is built by calling str(), but if this fails, the
195 The final output is built by calling str(), but if this fails, the
195 result is encoded with the instance's codec and error handling policy,
196 result is encoded with the instance's codec and error handling policy,
196 via a call to out.encode(self.codec,self.encoding_errors)"""
197 via a call to out.encode(self.codec,self.encoding_errors)"""
197 result = []
198 result = []
198 app = result.append
199 app = result.append
199 for live, chunk in self.chunks:
200 for live, chunk in self.chunks:
200 if live: app(str(eval(chunk,glob,loc)))
201 if live: app(str(eval(chunk,glob,loc)))
201 else: app(chunk)
202 else: app(chunk)
202 out = ''.join(result)
203 out = ''.join(result)
203 try:
204 try:
204 return str(out)
205 return str(out)
205 except UnicodeError:
206 except UnicodeError:
206 return out.encode(self.codec,self.encoding_errors)
207 return out.encode(self.codec,self.encoding_errors)
207
208
208 def __str__(self):
209 def __str__(self):
209 """Evaluate and substitute the appropriate parts of the string."""
210 """Evaluate and substitute the appropriate parts of the string."""
210
211
211 # We need to skip enough frames to get to the actual caller outside of
212 # We need to skip enough frames to get to the actual caller outside of
212 # Itpl.
213 # Itpl.
213 frame = sys._getframe(1)
214 frame = sys._getframe(1)
214 while frame.f_globals["__name__"] == __name__: frame = frame.f_back
215 while frame.f_globals["__name__"] == __name__: frame = frame.f_back
215 loc, glob = frame.f_locals, frame.f_globals
216 loc, glob = frame.f_locals, frame.f_globals
216
217
217 return self._str(glob,loc)
218 return self._str(glob,loc)
218
219
219 class ItplNS(Itpl):
220 class ItplNS(Itpl):
220 """Class representing a string with interpolation abilities.
221 """Class representing a string with interpolation abilities.
221
222
222 This inherits from Itpl, but at creation time a namespace is provided
223 This inherits from Itpl, but at creation time a namespace is provided
223 where the evaluation will occur. The interpolation becomes a bit more
224 where the evaluation will occur. The interpolation becomes a bit more
224 efficient, as no traceback needs to be extracte. It also allows the
225 efficient, as no traceback needs to be extracte. It also allows the
225 caller to supply a different namespace for the interpolation to occur than
226 caller to supply a different namespace for the interpolation to occur than
226 its own."""
227 its own."""
227
228
228 def __init__(self, format,globals,locals=None,
229 def __init__(self, format,globals,locals=None,
229 codec='utf_8',encoding_errors='backslashreplace'):
230 codec='utf_8',encoding_errors='backslashreplace'):
230 """ItplNS(format,globals[,locals]) -> interpolating string instance.
231 """ItplNS(format,globals[,locals]) -> interpolating string instance.
231
232
232 This constructor, besides a format string, takes a globals dictionary
233 This constructor, besides a format string, takes a globals dictionary
233 and optionally a locals (which defaults to globals if not provided).
234 and optionally a locals (which defaults to globals if not provided).
234
235
235 For further details, see the Itpl constructor."""
236 For further details, see the Itpl constructor."""
236
237
237 if locals is None:
238 if locals is None:
238 locals = globals
239 locals = globals
239 self.globals = globals
240 self.globals = globals
240 self.locals = locals
241 self.locals = locals
241 Itpl.__init__(self,format,codec,encoding_errors)
242 Itpl.__init__(self,format,codec,encoding_errors)
242
243
243 def __str__(self):
244 def __str__(self):
244 """Evaluate and substitute the appropriate parts of the string."""
245 """Evaluate and substitute the appropriate parts of the string."""
245 return self._str(self.globals,self.locals)
246 return self._str(self.globals,self.locals)
246
247
247 def __repr__(self):
248 def __repr__(self):
248 return "<ItplNS %s >" % repr(self.format)
249 return "<ItplNS %s >" % repr(self.format)
249
250
250 # utilities for fast printing
251 # utilities for fast printing
251 def itpl(text): return str(Itpl(text))
252 def itpl(text): return str(Itpl(text))
252 def printpl(text): print itpl(text)
253 def printpl(text): print itpl(text)
253 # versions with namespace
254 # versions with namespace
254 def itplns(text,globals,locals=None): return str(ItplNS(text,globals,locals))
255 def itplns(text,globals,locals=None): return str(ItplNS(text,globals,locals))
255 def printplns(text,globals,locals=None): print itplns(text,globals,locals)
256 def printplns(text,globals,locals=None): print itplns(text,globals,locals)
256
257
257 class ItplFile:
258 class ItplFile:
258 """A file object that filters each write() through an interpolator."""
259 """A file object that filters each write() through an interpolator."""
259 def __init__(self, file): self.file = file
260 def __init__(self, file): self.file = file
260 def __repr__(self): return "<interpolated " + repr(self.file) + ">"
261 def __repr__(self): return "<interpolated " + repr(self.file) + ">"
261 def __getattr__(self, attr): return getattr(self.file, attr)
262 def __getattr__(self, attr): return getattr(self.file, attr)
262 def write(self, text): self.file.write(str(Itpl(text)))
263 def write(self, text): self.file.write(str(Itpl(text)))
263
264
264 def filter(file=sys.stdout):
265 def filter(file=sys.stdout):
265 """Return an ItplFile that filters writes to the given file object.
266 """Return an ItplFile that filters writes to the given file object.
266
267
267 'file = filter(file)' replaces 'file' with a filtered object that
268 'file = filter(file)' replaces 'file' with a filtered object that
268 has a write() method. When called with no argument, this creates
269 has a write() method. When called with no argument, this creates
269 a filter to sys.stdout."""
270 a filter to sys.stdout."""
270 return ItplFile(file)
271 return ItplFile(file)
271
272
272 def unfilter(ifile=None):
273 def unfilter(ifile=None):
273 """Return the original file that corresponds to the given ItplFile.
274 """Return the original file that corresponds to the given ItplFile.
274
275
275 'file = unfilter(file)' undoes the effect of 'file = filter(file)'.
276 'file = unfilter(file)' undoes the effect of 'file = filter(file)'.
276 'sys.stdout = unfilter()' undoes the effect of 'sys.stdout = filter()'."""
277 'sys.stdout = unfilter()' undoes the effect of 'sys.stdout = filter()'."""
277 return ifile and ifile.file or sys.stdout.file
278 return ifile and ifile.file or sys.stdout.file
@@ -1,185 +1,187 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 Logger class for IPython's logging facilities.
3 Logger class for IPython's logging facilities.
4
4
5 $Id: Logger.py 430 2004-11-30 08:52:05Z fperez $
5 $Id: Logger.py 958 2005-12-27 23:17:51Z fperez $
6 """
6 """
7
7
8 #*****************************************************************************
8 #*****************************************************************************
9 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de> and
9 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de> and
10 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
10 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
11 #
11 #
12 # Distributed under the terms of the BSD License. The full license is in
12 # Distributed under the terms of the BSD License. The full license is in
13 # the file COPYING, distributed as part of this software.
13 # the file COPYING, distributed as part of this software.
14 #*****************************************************************************
14 #*****************************************************************************
15
15
16 #****************************************************************************
16 #****************************************************************************
17 # Modules and globals
17 # Modules and globals
18
18
19 from IPython import Release
19 from IPython import Release
20 __author__ = '%s <%s>\n%s <%s>' % \
20 __author__ = '%s <%s>\n%s <%s>' % \
21 ( Release.authors['Janko'] + Release.authors['Fernando'] )
21 ( Release.authors['Janko'] + Release.authors['Fernando'] )
22 __license__ = Release.license
22 __license__ = Release.license
23
23
24 # Python standard modules
24 # Python standard modules
25 import os,sys,glob
25 import glob
26 import os
27 import sys
26
28
27 # Homebrewed
29 # Homebrewed
28 from IPython.genutils import *
30 from IPython.genutils import *
29
31
30 #****************************************************************************
32 #****************************************************************************
31 # FIXME: The logger class shouldn't be a mixin, it throws too many things into
33 # 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
34 # the InteractiveShell namespace. Rather make it a standalone tool, and create
33 # a Logger instance in InteractiveShell that uses it. Doing this will require
35 # 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
36 # tracking down a *lot* of nasty uses of the Logger attributes in
35 # InteractiveShell, but will clean up things quite a bit.
37 # InteractiveShell, but will clean up things quite a bit.
36
38
37 class Logger:
39 class Logger:
38 """A Logfile Mixin class with different policies for file creation"""
40 """A Logfile Mixin class with different policies for file creation"""
39
41
40 # FIXME: once this isn't a mixin, log_ns should just be 'namespace', since the
42 # FIXME: once this isn't a mixin, log_ns should just be 'namespace', since the
41 # names won't collide anymore.
43 # names won't collide anymore.
42 def __init__(self,log_ns):
44 def __init__(self,log_ns):
43 self._i00,self._i,self._ii,self._iii = '','','',''
45 self._i00,self._i,self._ii,self._iii = '','','',''
44 self.do_full_cache = 0 # FIXME. There's also a do_full.. in OutputCache
46 self.do_full_cache = 0 # FIXME. There's also a do_full.. in OutputCache
45 self.log_ns = log_ns
47 self.log_ns = log_ns
46 # defaults
48 # defaults
47 self.LOGMODE = 'backup'
49 self.LOGMODE = 'backup'
48 self.defname = 'logfile'
50 self.defname = 'logfile'
49
51
50 def create_log(self,header='',fname='',defname='.Logger.log'):
52 def create_log(self,header='',fname='',defname='.Logger.log'):
51 """Generate a new log-file with a default header"""
53 """Generate a new log-file with a default header"""
52 if fname:
54 if fname:
53 self.LOG = fname
55 self.LOG = fname
54
56
55 if self.LOG:
57 if self.LOG:
56 self.logfname = self.LOG
58 self.logfname = self.LOG
57 else:
59 else:
58 self.logfname = defname
60 self.logfname = defname
59
61
60 if self.LOGMODE == 'over':
62 if self.LOGMODE == 'over':
61 if os.path.isfile(self.logfname):
63 if os.path.isfile(self.logfname):
62 os.remove(self.logfname)
64 os.remove(self.logfname)
63 self.logfile = open(self.logfname,'w')
65 self.logfile = open(self.logfname,'w')
64 if self.LOGMODE == 'backup':
66 if self.LOGMODE == 'backup':
65 if os.path.isfile(self.logfname):
67 if os.path.isfile(self.logfname):
66 backup_logname = self.logfname+'~'
68 backup_logname = self.logfname+'~'
67 # Manually remove any old backup, since os.rename may fail
69 # Manually remove any old backup, since os.rename may fail
68 # under Windows.
70 # under Windows.
69 if os.path.isfile(backup_logname):
71 if os.path.isfile(backup_logname):
70 os.remove(backup_logname)
72 os.remove(backup_logname)
71 os.rename(self.logfname,backup_logname)
73 os.rename(self.logfname,backup_logname)
72 self.logfile = open(self.logfname,'w')
74 self.logfile = open(self.logfname,'w')
73 elif self.LOGMODE == 'global':
75 elif self.LOGMODE == 'global':
74 self.logfname = os.path.join(self.home_dir, self.defname)
76 self.logfname = os.path.join(self.home_dir, self.defname)
75 self.logfile = open(self.logfname, 'a')
77 self.logfile = open(self.logfname, 'a')
76 self.LOG = self.logfname
78 self.LOG = self.logfname
77 elif self.LOGMODE == 'rotate':
79 elif self.LOGMODE == 'rotate':
78 if os.path.isfile(self.logfname):
80 if os.path.isfile(self.logfname):
79 if os.path.isfile(self.logfname+'.001~'):
81 if os.path.isfile(self.logfname+'.001~'):
80 old = glob.glob(self.logfname+'.*~')
82 old = glob.glob(self.logfname+'.*~')
81 old.sort()
83 old.sort()
82 old.reverse()
84 old.reverse()
83 for f in old:
85 for f in old:
84 root, ext = os.path.splitext(f)
86 root, ext = os.path.splitext(f)
85 num = int(ext[1:-1])+1
87 num = int(ext[1:-1])+1
86 os.rename(f, root+'.'+`num`.zfill(3)+'~')
88 os.rename(f, root+'.'+`num`.zfill(3)+'~')
87 os.rename(self.logfname, self.logfname+'.001~')
89 os.rename(self.logfname, self.logfname+'.001~')
88 self.logfile = open(self.logfname,'w')
90 self.logfile = open(self.logfname,'w')
89 elif self.LOGMODE == 'append':
91 elif self.LOGMODE == 'append':
90 self.logfile = open(self.logfname,'a')
92 self.logfile = open(self.logfname,'a')
91
93
92 if self.LOGMODE != 'append':
94 if self.LOGMODE != 'append':
93 self.logfile.write(header)
95 self.logfile.write(header)
94 self.logfile.flush()
96 self.logfile.flush()
95
97
96 def logstart(self, header='',parameter_s = ''):
98 def logstart(self, header='',parameter_s = ''):
97 if not hasattr(self, 'LOG'):
99 if not hasattr(self, 'LOG'):
98 logfname = self.LOG or parameter_s or './'+self.defname
100 logfname = self.LOG or parameter_s or './'+self.defname
99 self.create_log(header,logfname)
101 self.create_log(header,logfname)
100 elif parameter_s and hasattr(self,'logfname') and \
102 elif parameter_s and hasattr(self,'logfname') and \
101 parameter_s != self.logfname:
103 parameter_s != self.logfname:
102 self.close_log()
104 self.close_log()
103 self.create_log(header,parameter_s)
105 self.create_log(header,parameter_s)
104
106
105 self._dolog = 1
107 self._dolog = 1
106
108
107 def switch_log(self,val):
109 def switch_log(self,val):
108 """Switch logging on/off. val should be ONLY 0 or 1."""
110 """Switch logging on/off. val should be ONLY 0 or 1."""
109
111
110 if not val in [0,1]:
112 if not val in [0,1]:
111 raise ValueError, \
113 raise ValueError, \
112 'Call switch_log ONLY with 0 or 1 as argument, not with:',val
114 'Call switch_log ONLY with 0 or 1 as argument, not with:',val
113
115
114 label = {0:'OFF',1:'ON'}
116 label = {0:'OFF',1:'ON'}
115
117
116 try:
118 try:
117 _ = self.logfile
119 _ = self.logfile
118 except AttributeError:
120 except AttributeError:
119 print """
121 print """
120 Logging hasn't been started yet (use %logstart for that).
122 Logging hasn't been started yet (use %logstart for that).
121
123
122 %logon/%logoff are for temporarily starting and stopping logging for a logfile
124 %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
125 which already exists. But you must first start the logging process with
124 %logstart (optionally giving a logfile name)."""
126 %logstart (optionally giving a logfile name)."""
125
127
126 else:
128 else:
127 if self._dolog == val:
129 if self._dolog == val:
128 print 'Logging is already',label[val]
130 print 'Logging is already',label[val]
129 else:
131 else:
130 print 'Switching logging',label[val]
132 print 'Switching logging',label[val]
131 self._dolog = 1 - self._dolog
133 self._dolog = 1 - self._dolog
132
134
133 def logstate(self):
135 def logstate(self):
134 """Print a status message about the logger."""
136 """Print a status message about the logger."""
135 try:
137 try:
136 logfile = self.logfname
138 logfile = self.logfname
137 except:
139 except:
138 print 'Logging has not been activated.'
140 print 'Logging has not been activated.'
139 else:
141 else:
140 state = self._dolog and 'active' or 'temporarily suspended'
142 state = self._dolog and 'active' or 'temporarily suspended'
141 print """
143 print """
142 File:\t%s
144 File:\t%s
143 Mode:\t%s
145 Mode:\t%s
144 State:\t%s """ % (logfile,self.LOGMODE,state)
146 State:\t%s """ % (logfile,self.LOGMODE,state)
145
147
146
148
147 def log(self, line,continuation=None):
149 def log(self, line,continuation=None):
148 """Write the line to a log and create input cache variables _i*."""
150 """Write the line to a log and create input cache variables _i*."""
149
151
150 # update the auto _i tables
152 # update the auto _i tables
151 #print '***logging line',line # dbg
153 #print '***logging line',line # dbg
152 #print '***cache_count', self.outputcache.prompt_count # dbg
154 #print '***cache_count', self.outputcache.prompt_count # dbg
153 input_hist = self.log_ns['_ih']
155 input_hist = self.log_ns['_ih']
154 if not continuation and line:
156 if not continuation and line:
155 self._iii = self._ii
157 self._iii = self._ii
156 self._ii = self._i
158 self._ii = self._i
157 self._i = self._i00
159 self._i = self._i00
158 # put back the final \n of every input line
160 # put back the final \n of every input line
159 self._i00 = line+'\n'
161 self._i00 = line+'\n'
160 #print 'Logging input:<%s>' % line # dbg
162 #print 'Logging input:<%s>' % line # dbg
161 input_hist.append(self._i00)
163 input_hist.append(self._i00)
162
164
163 # hackish access to top-level namespace to create _i1,_i2... dynamically
165 # hackish access to top-level namespace to create _i1,_i2... dynamically
164 to_main = {'_i':self._i,'_ii':self._ii,'_iii':self._iii}
166 to_main = {'_i':self._i,'_ii':self._ii,'_iii':self._iii}
165 if self.do_full_cache:
167 if self.do_full_cache:
166 in_num = self.outputcache.prompt_count
168 in_num = self.outputcache.prompt_count
167 # add blank lines if the input cache fell out of sync. This can happen
169 # 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.
170 # for embedded instances which get killed via C-D and then get resumed.
169 while in_num >= len(input_hist):
171 while in_num >= len(input_hist):
170 input_hist.append('\n')
172 input_hist.append('\n')
171 new_i = '_i%s' % in_num
173 new_i = '_i%s' % in_num
172 if continuation:
174 if continuation:
173 self._i00 = '%s%s\n' % (self.log_ns[new_i],line)
175 self._i00 = '%s%s\n' % (self.log_ns[new_i],line)
174 input_hist[in_num] = self._i00
176 input_hist[in_num] = self._i00
175 to_main[new_i] = self._i00
177 to_main[new_i] = self._i00
176 self.log_ns.update(to_main)
178 self.log_ns.update(to_main)
177
179
178 if self._dolog and line:
180 if self._dolog and line:
179 self.logfile.write(line+'\n')
181 self.logfile.write(line+'\n')
180 self.logfile.flush()
182 self.logfile.flush()
181
183
182 def close_log(self):
184 def close_log(self):
183 if hasattr(self, 'logfile'):
185 if hasattr(self, 'logfile'):
184 self.logfile.close()
186 self.logfile.close()
185 self.logfname = ''
187 self.logfname = ''
@@ -1,2573 +1,2579 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Magic functions for InteractiveShell.
2 """Magic functions for InteractiveShell.
3
3
4 $Id: Magic.py 951 2005-12-25 00:57:24Z fperez $"""
4 $Id: Magic.py 958 2005-12-27 23:17:51Z fperez $"""
5
5
6 #*****************************************************************************
6 #*****************************************************************************
7 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de> and
7 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de> and
8 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
8 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
9 #
9 #
10 # Distributed under the terms of the BSD License. The full license is in
10 # Distributed under the terms of the BSD License. The full license is in
11 # the file COPYING, distributed as part of this software.
11 # the file COPYING, distributed as part of this software.
12 #*****************************************************************************
12 #*****************************************************************************
13
13
14 #****************************************************************************
14 #****************************************************************************
15 # Modules and globals
15 # Modules and globals
16
16
17 from IPython import Release
17 from IPython import Release
18 __author__ = '%s <%s>\n%s <%s>' % \
18 __author__ = '%s <%s>\n%s <%s>' % \
19 ( Release.authors['Janko'] + Release.authors['Fernando'] )
19 ( Release.authors['Janko'] + Release.authors['Fernando'] )
20 __license__ = Release.license
20 __license__ = Release.license
21
21
22 # Python standard modules
22 # Python standard modules
23 import __builtin__
23 import __builtin__
24 import os,sys,inspect,pydoc,re,tempfile,pdb,bdb,time
24 import bdb
25 import Debugger
25 import inspect
26 import os
27 import pdb
28 import pydoc
29 import sys
30 import re
31 import tempfile
32 import time
33 from cStringIO import StringIO
26 from getopt import getopt
34 from getopt import getopt
27 from pprint import pprint, pformat
35 from pprint import pprint, pformat
28 from cStringIO import StringIO
29
36
30 # profile isn't bundled by default in Debian for license reasons
37 # profile isn't bundled by default in Debian for license reasons
31 try:
38 try:
32 import profile,pstats
39 import profile,pstats
33 except ImportError:
40 except ImportError:
34 profile = pstats = None
41 profile = pstats = None
35
42
36 # Homebrewed
43 # Homebrewed
37 from IPython.Struct import Struct
44 from IPython import Debugger, OInspect, wildcard
38 from IPython.Itpl import Itpl, itpl, printpl,itplns
39 from IPython.FakeModule import FakeModule
45 from IPython.FakeModule import FakeModule
46 from IPython.Itpl import Itpl, itpl, printpl,itplns
40 from IPython.PyColorize import Parser
47 from IPython.PyColorize import Parser
41 from IPython import OInspect
48 from IPython.Struct import Struct
42 from IPython import wildcard
43 from IPython.genutils import *
49 from IPython.genutils import *
44
50
45 # Globals to be set later by Magic constructor
51 # Globals to be set later by Magic constructor
46 MAGIC_PREFIX = ''
52 MAGIC_PREFIX = ''
47 MAGIC_ESCAPE = ''
53 MAGIC_ESCAPE = ''
48
54
49 #***************************************************************************
55 #***************************************************************************
50 # Utility functions
56 # Utility functions
51 def magic2python(cmd):
57 def magic2python(cmd):
52 """Convert a command string of magic syntax to valid Python code."""
58 """Convert a command string of magic syntax to valid Python code."""
53
59
54 if cmd.startswith('#'+MAGIC_ESCAPE) or \
60 if cmd.startswith('#'+MAGIC_ESCAPE) or \
55 cmd.startswith(MAGIC_ESCAPE):
61 cmd.startswith(MAGIC_ESCAPE):
56 if cmd[0]=='#':
62 if cmd[0]=='#':
57 cmd = cmd[1:]
63 cmd = cmd[1:]
58 # we need to return the proper line end later
64 # we need to return the proper line end later
59 if cmd[-1] == '\n':
65 if cmd[-1] == '\n':
60 endl = '\n'
66 endl = '\n'
61 else:
67 else:
62 endl = ''
68 endl = ''
63 try:
69 try:
64 func,args = cmd[1:].split(' ',1)
70 func,args = cmd[1:].split(' ',1)
65 except:
71 except:
66 func,args = cmd[1:].rstrip(),''
72 func,args = cmd[1:].rstrip(),''
67 args = args.replace('"','\\"').replace("'","\\'").rstrip()
73 args = args.replace('"','\\"').replace("'","\\'").rstrip()
68 return '%s%s ("%s")%s' % (MAGIC_PREFIX,func,args,endl)
74 return '%s%s ("%s")%s' % (MAGIC_PREFIX,func,args,endl)
69 else:
75 else:
70 return cmd
76 return cmd
71
77
72 def on_off(tag):
78 def on_off(tag):
73 """Return an ON/OFF string for a 1/0 input. Simple utility function."""
79 """Return an ON/OFF string for a 1/0 input. Simple utility function."""
74 return ['OFF','ON'][tag]
80 return ['OFF','ON'][tag]
75
81
76
82
77 #****************************************************************************
83 #****************************************************************************
78 # Utility classes
84 # Utility classes
79 class Macro:
85 class Macro:
80 """Simple class to store the value of macros as strings.
86 """Simple class to store the value of macros as strings.
81
87
82 This allows us to later exec them by checking when something is an
88 This allows us to later exec them by checking when something is an
83 instance of this class."""
89 instance of this class."""
84
90
85 def __init__(self,cmds):
91 def __init__(self,cmds):
86 """Build a macro from a list of commands."""
92 """Build a macro from a list of commands."""
87
93
88 # Since the list may include multi-line entries, first make sure that
94 # Since the list may include multi-line entries, first make sure that
89 # they've been all broken up before passing it to magic2python
95 # they've been all broken up before passing it to magic2python
90 cmdlist = map(magic2python,''.join(cmds).split('\n'))
96 cmdlist = map(magic2python,''.join(cmds).split('\n'))
91 self.value = '\n'.join(cmdlist)
97 self.value = '\n'.join(cmdlist)
92
98
93 def __str__(self):
99 def __str__(self):
94 return self.value
100 return self.value
95
101
96 #***************************************************************************
102 #***************************************************************************
97 # Main class implementing Magic functionality
103 # Main class implementing Magic functionality
98 class Magic:
104 class Magic:
99 """Magic functions for InteractiveShell.
105 """Magic functions for InteractiveShell.
100
106
101 Shell functions which can be reached as %function_name. All magic
107 Shell functions which can be reached as %function_name. All magic
102 functions should accept a string, which they can parse for their own
108 functions should accept a string, which they can parse for their own
103 needs. This can make some functions easier to type, eg `%cd ../`
109 needs. This can make some functions easier to type, eg `%cd ../`
104 vs. `%cd("../")`
110 vs. `%cd("../")`
105
111
106 ALL definitions MUST begin with the prefix magic_. The user won't need it
112 ALL definitions MUST begin with the prefix magic_. The user won't need it
107 at the command line, but it is is needed in the definition. """
113 at the command line, but it is is needed in the definition. """
108
114
109 # class globals
115 # class globals
110 auto_status = ['Automagic is OFF, % prefix IS needed for magic functions.',
116 auto_status = ['Automagic is OFF, % prefix IS needed for magic functions.',
111 'Automagic is ON, % prefix NOT needed for magic functions.']
117 'Automagic is ON, % prefix NOT needed for magic functions.']
112
118
113 #......................................................................
119 #......................................................................
114 # some utility functions
120 # some utility functions
115
121
116 def __init__(self,shell):
122 def __init__(self,shell):
117 # XXX This is hackish, clean up later to avoid these messy globals
123 # XXX This is hackish, clean up later to avoid these messy globals
118 global MAGIC_PREFIX, MAGIC_ESCAPE
124 global MAGIC_PREFIX, MAGIC_ESCAPE
119
125
120 self.options_table = {}
126 self.options_table = {}
121 MAGIC_PREFIX = shell.name+'.magic_'
127 MAGIC_PREFIX = shell.name+'.magic_'
122 MAGIC_ESCAPE = shell.ESC_MAGIC
128 MAGIC_ESCAPE = shell.ESC_MAGIC
123 if profile is None:
129 if profile is None:
124 self.magic_prun = self.profile_missing_notice
130 self.magic_prun = self.profile_missing_notice
125
131
126 def profile_missing_notice(self, *args, **kwargs):
132 def profile_missing_notice(self, *args, **kwargs):
127 error("""\
133 error("""\
128 The profile module could not be found. If you are a Debian user,
134 The profile module could not be found. If you are a Debian user,
129 it has been removed from the standard Debian package because of its non-free
135 it has been removed from the standard Debian package because of its non-free
130 license. To use profiling, please install"python2.3-profiler" from non-free.""")
136 license. To use profiling, please install"python2.3-profiler" from non-free.""")
131
137
132 def default_option(self,fn,optstr):
138 def default_option(self,fn,optstr):
133 """Make an entry in the options_table for fn, with value optstr"""
139 """Make an entry in the options_table for fn, with value optstr"""
134
140
135 if fn not in self.lsmagic():
141 if fn not in self.lsmagic():
136 error("%s is not a magic function" % fn)
142 error("%s is not a magic function" % fn)
137 self.options_table[fn] = optstr
143 self.options_table[fn] = optstr
138
144
139 def lsmagic(self):
145 def lsmagic(self):
140 """Return a list of currently available magic functions.
146 """Return a list of currently available magic functions.
141
147
142 Gives a list of the bare names after mangling (['ls','cd', ...], not
148 Gives a list of the bare names after mangling (['ls','cd', ...], not
143 ['magic_ls','magic_cd',...]"""
149 ['magic_ls','magic_cd',...]"""
144
150
145 # FIXME. This needs a cleanup, in the way the magics list is built.
151 # FIXME. This needs a cleanup, in the way the magics list is built.
146
152
147 # magics in class definition
153 # magics in class definition
148 class_magic = lambda fn: fn.startswith('magic_') and \
154 class_magic = lambda fn: fn.startswith('magic_') and \
149 callable(Magic.__dict__[fn])
155 callable(Magic.__dict__[fn])
150 # in instance namespace (run-time user additions)
156 # in instance namespace (run-time user additions)
151 inst_magic = lambda fn: fn.startswith('magic_') and \
157 inst_magic = lambda fn: fn.startswith('magic_') and \
152 callable(self.__dict__[fn])
158 callable(self.__dict__[fn])
153 # and bound magics by user (so they can access self):
159 # and bound magics by user (so they can access self):
154 inst_bound_magic = lambda fn: fn.startswith('magic_') and \
160 inst_bound_magic = lambda fn: fn.startswith('magic_') and \
155 callable(self.__class__.__dict__[fn])
161 callable(self.__class__.__dict__[fn])
156 magics = filter(class_magic,Magic.__dict__.keys()) + \
162 magics = filter(class_magic,Magic.__dict__.keys()) + \
157 filter(inst_magic,self.__dict__.keys()) + \
163 filter(inst_magic,self.__dict__.keys()) + \
158 filter(inst_bound_magic,self.__class__.__dict__.keys())
164 filter(inst_bound_magic,self.__class__.__dict__.keys())
159 out = []
165 out = []
160 for fn in magics:
166 for fn in magics:
161 out.append(fn.replace('magic_','',1))
167 out.append(fn.replace('magic_','',1))
162 out.sort()
168 out.sort()
163 return out
169 return out
164
170
165 def set_shell(self,shell):
171 def set_shell(self,shell):
166 self.shell = shell
172 self.shell = shell
167 self.alias_table = shell.alias_table
173 self.alias_table = shell.alias_table
168
174
169 def extract_input_slices(self,slices):
175 def extract_input_slices(self,slices):
170 """Return as a string a set of input history slices.
176 """Return as a string a set of input history slices.
171
177
172 The set of slices is given as a list of strings (like ['1','4:8','9'],
178 The set of slices is given as a list of strings (like ['1','4:8','9'],
173 since this function is for use by magic functions which get their
179 since this function is for use by magic functions which get their
174 arguments as strings."""
180 arguments as strings."""
175
181
176 cmds = []
182 cmds = []
177 for chunk in slices:
183 for chunk in slices:
178 if ':' in chunk:
184 if ':' in chunk:
179 ini,fin = map(int,chunk.split(':'))
185 ini,fin = map(int,chunk.split(':'))
180 else:
186 else:
181 ini = int(chunk)
187 ini = int(chunk)
182 fin = ini+1
188 fin = ini+1
183 cmds.append(self.shell.input_hist[ini:fin])
189 cmds.append(self.shell.input_hist[ini:fin])
184 return cmds
190 return cmds
185
191
186 def _ofind(self,oname):
192 def _ofind(self,oname):
187 """Find an object in the available namespaces.
193 """Find an object in the available namespaces.
188
194
189 self._ofind(oname) -> dict with keys: found,obj,ospace,ismagic
195 self._ofind(oname) -> dict with keys: found,obj,ospace,ismagic
190
196
191 Has special code to detect magic functions.
197 Has special code to detect magic functions.
192 """
198 """
193
199
194 oname = oname.strip()
200 oname = oname.strip()
195
201
196 # Namespaces to search in:
202 # Namespaces to search in:
197 user_ns = self.shell.user_ns
203 user_ns = self.shell.user_ns
198 internal_ns = self.shell.internal_ns
204 internal_ns = self.shell.internal_ns
199 builtin_ns = __builtin__.__dict__
205 builtin_ns = __builtin__.__dict__
200 alias_ns = self.shell.alias_table
206 alias_ns = self.shell.alias_table
201
207
202 # Put them in a list. The order is important so that we find things in
208 # Put them in a list. The order is important so that we find things in
203 # the same order that Python finds them.
209 # the same order that Python finds them.
204 namespaces = [ ('Interactive',user_ns),
210 namespaces = [ ('Interactive',user_ns),
205 ('IPython internal',internal_ns),
211 ('IPython internal',internal_ns),
206 ('Python builtin',builtin_ns),
212 ('Python builtin',builtin_ns),
207 ('Alias',alias_ns),
213 ('Alias',alias_ns),
208 ]
214 ]
209
215
210 # initialize results to 'null'
216 # initialize results to 'null'
211 found = 0; obj = None; ospace = None; ds = None;
217 found = 0; obj = None; ospace = None; ds = None;
212 ismagic = 0; isalias = 0
218 ismagic = 0; isalias = 0
213
219
214 # Look for the given name by splitting it in parts. If the head is
220 # Look for the given name by splitting it in parts. If the head is
215 # found, then we look for all the remaining parts as members, and only
221 # found, then we look for all the remaining parts as members, and only
216 # declare success if we can find them all.
222 # declare success if we can find them all.
217 oname_parts = oname.split('.')
223 oname_parts = oname.split('.')
218 oname_head, oname_rest = oname_parts[0],oname_parts[1:]
224 oname_head, oname_rest = oname_parts[0],oname_parts[1:]
219 for nsname,ns in namespaces:
225 for nsname,ns in namespaces:
220 try:
226 try:
221 obj = ns[oname_head]
227 obj = ns[oname_head]
222 except KeyError:
228 except KeyError:
223 continue
229 continue
224 else:
230 else:
225 for part in oname_rest:
231 for part in oname_rest:
226 try:
232 try:
227 obj = getattr(obj,part)
233 obj = getattr(obj,part)
228 except:
234 except:
229 # Blanket except b/c some badly implemented objects
235 # Blanket except b/c some badly implemented objects
230 # allow __getattr__ to raise exceptions other than
236 # allow __getattr__ to raise exceptions other than
231 # AttributeError, which then crashes IPython.
237 # AttributeError, which then crashes IPython.
232 break
238 break
233 else:
239 else:
234 # If we finish the for loop (no break), we got all members
240 # If we finish the for loop (no break), we got all members
235 found = 1
241 found = 1
236 ospace = nsname
242 ospace = nsname
237 if ns == alias_ns:
243 if ns == alias_ns:
238 isalias = 1
244 isalias = 1
239 break # namespace loop
245 break # namespace loop
240
246
241 # Try to see if it's magic
247 # Try to see if it's magic
242 if not found:
248 if not found:
243 if oname.startswith(self.shell.ESC_MAGIC):
249 if oname.startswith(self.shell.ESC_MAGIC):
244 oname = oname[1:]
250 oname = oname[1:]
245 obj = getattr(self,'magic_'+oname,None)
251 obj = getattr(self,'magic_'+oname,None)
246 if obj is not None:
252 if obj is not None:
247 found = 1
253 found = 1
248 ospace = 'IPython internal'
254 ospace = 'IPython internal'
249 ismagic = 1
255 ismagic = 1
250
256
251 # Last try: special-case some literals like '', [], {}, etc:
257 # Last try: special-case some literals like '', [], {}, etc:
252 if not found and oname_head in ["''",'""','[]','{}','()']:
258 if not found and oname_head in ["''",'""','[]','{}','()']:
253 obj = eval(oname_head)
259 obj = eval(oname_head)
254 found = 1
260 found = 1
255 ospace = 'Interactive'
261 ospace = 'Interactive'
256
262
257 return {'found':found, 'obj':obj, 'namespace':ospace,
263 return {'found':found, 'obj':obj, 'namespace':ospace,
258 'ismagic':ismagic, 'isalias':isalias}
264 'ismagic':ismagic, 'isalias':isalias}
259
265
260 def arg_err(self,func):
266 def arg_err(self,func):
261 """Print docstring if incorrect arguments were passed"""
267 """Print docstring if incorrect arguments were passed"""
262 print 'Error in arguments:'
268 print 'Error in arguments:'
263 print OInspect.getdoc(func)
269 print OInspect.getdoc(func)
264
270
265
271
266 def format_latex(self,str):
272 def format_latex(self,str):
267 """Format a string for latex inclusion."""
273 """Format a string for latex inclusion."""
268
274
269 # Characters that need to be escaped for latex:
275 # Characters that need to be escaped for latex:
270 escape_re = re.compile(r'(%|_|\$)',re.MULTILINE)
276 escape_re = re.compile(r'(%|_|\$)',re.MULTILINE)
271 # Magic command names as headers:
277 # Magic command names as headers:
272 cmd_name_re = re.compile(r'^(%s.*?):' % self.shell.ESC_MAGIC,
278 cmd_name_re = re.compile(r'^(%s.*?):' % self.shell.ESC_MAGIC,
273 re.MULTILINE)
279 re.MULTILINE)
274 # Magic commands
280 # Magic commands
275 cmd_re = re.compile(r'(?P<cmd>%s.+?\b)(?!\}\}:)' % self.shell.ESC_MAGIC,
281 cmd_re = re.compile(r'(?P<cmd>%s.+?\b)(?!\}\}:)' % self.shell.ESC_MAGIC,
276 re.MULTILINE)
282 re.MULTILINE)
277 # Paragraph continue
283 # Paragraph continue
278 par_re = re.compile(r'\\$',re.MULTILINE)
284 par_re = re.compile(r'\\$',re.MULTILINE)
279
285
280 str = cmd_name_re.sub(r'\n\\texttt{\\textsl{\\large \1}}:',str)
286 str = cmd_name_re.sub(r'\n\\texttt{\\textsl{\\large \1}}:',str)
281 str = cmd_re.sub(r'\\texttt{\g<cmd>}',str)
287 str = cmd_re.sub(r'\\texttt{\g<cmd>}',str)
282 str = par_re.sub(r'\\\\',str)
288 str = par_re.sub(r'\\\\',str)
283 str = escape_re.sub(r'\\\1',str)
289 str = escape_re.sub(r'\\\1',str)
284 return str
290 return str
285
291
286 def format_screen(self,str):
292 def format_screen(self,str):
287 """Format a string for screen printing.
293 """Format a string for screen printing.
288
294
289 This removes some latex-type format codes."""
295 This removes some latex-type format codes."""
290 # Paragraph continue
296 # Paragraph continue
291 par_re = re.compile(r'\\$',re.MULTILINE)
297 par_re = re.compile(r'\\$',re.MULTILINE)
292 str = par_re.sub('',str)
298 str = par_re.sub('',str)
293 return str
299 return str
294
300
295 def parse_options(self,arg_str,opt_str,*long_opts,**kw):
301 def parse_options(self,arg_str,opt_str,*long_opts,**kw):
296 """Parse options passed to an argument string.
302 """Parse options passed to an argument string.
297
303
298 The interface is similar to that of getopt(), but it returns back a
304 The interface is similar to that of getopt(), but it returns back a
299 Struct with the options as keys and the stripped argument string still
305 Struct with the options as keys and the stripped argument string still
300 as a string.
306 as a string.
301
307
302 arg_str is quoted as a true sys.argv vector by using shlex.split.
308 arg_str is quoted as a true sys.argv vector by using shlex.split.
303 This allows us to easily expand variables, glob files, quote
309 This allows us to easily expand variables, glob files, quote
304 arguments, etc.
310 arguments, etc.
305
311
306 Options:
312 Options:
307 -mode: default 'string'. If given as 'list', the argument string is
313 -mode: default 'string'. If given as 'list', the argument string is
308 returned as a list (split on whitespace) instead of a string.
314 returned as a list (split on whitespace) instead of a string.
309
315
310 -list_all: put all option values in lists. Normally only options
316 -list_all: put all option values in lists. Normally only options
311 appearing more than once are put in a list."""
317 appearing more than once are put in a list."""
312
318
313 # inject default options at the beginning of the input line
319 # inject default options at the beginning of the input line
314 caller = sys._getframe(1).f_code.co_name.replace('magic_','')
320 caller = sys._getframe(1).f_code.co_name.replace('magic_','')
315 arg_str = '%s %s' % (self.options_table.get(caller,''),arg_str)
321 arg_str = '%s %s' % (self.options_table.get(caller,''),arg_str)
316
322
317 mode = kw.get('mode','string')
323 mode = kw.get('mode','string')
318 if mode not in ['string','list']:
324 if mode not in ['string','list']:
319 raise ValueError,'incorrect mode given: %s' % mode
325 raise ValueError,'incorrect mode given: %s' % mode
320 # Get options
326 # Get options
321 list_all = kw.get('list_all',0)
327 list_all = kw.get('list_all',0)
322
328
323 # Check if we have more than one argument to warrant extra processing:
329 # Check if we have more than one argument to warrant extra processing:
324 odict = {} # Dictionary with options
330 odict = {} # Dictionary with options
325 args = arg_str.split()
331 args = arg_str.split()
326 if len(args) >= 1:
332 if len(args) >= 1:
327 # If the list of inputs only has 0 or 1 thing in it, there's no
333 # If the list of inputs only has 0 or 1 thing in it, there's no
328 # need to look for options
334 # need to look for options
329 argv = shlex_split(arg_str)
335 argv = shlex_split(arg_str)
330 # Do regular option processing
336 # Do regular option processing
331 opts,args = getopt(argv,opt_str,*long_opts)
337 opts,args = getopt(argv,opt_str,*long_opts)
332 for o,a in opts:
338 for o,a in opts:
333 if o.startswith('--'):
339 if o.startswith('--'):
334 o = o[2:]
340 o = o[2:]
335 else:
341 else:
336 o = o[1:]
342 o = o[1:]
337 try:
343 try:
338 odict[o].append(a)
344 odict[o].append(a)
339 except AttributeError:
345 except AttributeError:
340 odict[o] = [odict[o],a]
346 odict[o] = [odict[o],a]
341 except KeyError:
347 except KeyError:
342 if list_all:
348 if list_all:
343 odict[o] = [a]
349 odict[o] = [a]
344 else:
350 else:
345 odict[o] = a
351 odict[o] = a
346
352
347 # Prepare opts,args for return
353 # Prepare opts,args for return
348 opts = Struct(odict)
354 opts = Struct(odict)
349 if mode == 'string':
355 if mode == 'string':
350 args = ' '.join(args)
356 args = ' '.join(args)
351
357
352 return opts,args
358 return opts,args
353
359
354 #......................................................................
360 #......................................................................
355 # And now the actual magic functions
361 # And now the actual magic functions
356
362
357 # Functions for IPython shell work (vars,funcs, config, etc)
363 # Functions for IPython shell work (vars,funcs, config, etc)
358 def magic_lsmagic(self, parameter_s = ''):
364 def magic_lsmagic(self, parameter_s = ''):
359 """List currently available magic functions."""
365 """List currently available magic functions."""
360 mesc = self.shell.ESC_MAGIC
366 mesc = self.shell.ESC_MAGIC
361 print 'Available magic functions:\n'+mesc+\
367 print 'Available magic functions:\n'+mesc+\
362 (' '+mesc).join(self.lsmagic())
368 (' '+mesc).join(self.lsmagic())
363 print '\n' + Magic.auto_status[self.shell.rc.automagic]
369 print '\n' + Magic.auto_status[self.shell.rc.automagic]
364 return None
370 return None
365
371
366 def magic_magic(self, parameter_s = ''):
372 def magic_magic(self, parameter_s = ''):
367 """Print information about the magic function system."""
373 """Print information about the magic function system."""
368
374
369 mode = ''
375 mode = ''
370 try:
376 try:
371 if parameter_s.split()[0] == '-latex':
377 if parameter_s.split()[0] == '-latex':
372 mode = 'latex'
378 mode = 'latex'
373 except:
379 except:
374 pass
380 pass
375
381
376 magic_docs = []
382 magic_docs = []
377 for fname in self.lsmagic():
383 for fname in self.lsmagic():
378 mname = 'magic_' + fname
384 mname = 'magic_' + fname
379 for space in (Magic,self,self.__class__):
385 for space in (Magic,self,self.__class__):
380 try:
386 try:
381 fn = space.__dict__[mname]
387 fn = space.__dict__[mname]
382 except KeyError:
388 except KeyError:
383 pass
389 pass
384 else:
390 else:
385 break
391 break
386 magic_docs.append('%s%s:\n\t%s\n' %(self.shell.ESC_MAGIC,
392 magic_docs.append('%s%s:\n\t%s\n' %(self.shell.ESC_MAGIC,
387 fname,fn.__doc__))
393 fname,fn.__doc__))
388 magic_docs = ''.join(magic_docs)
394 magic_docs = ''.join(magic_docs)
389
395
390 if mode == 'latex':
396 if mode == 'latex':
391 print self.format_latex(magic_docs)
397 print self.format_latex(magic_docs)
392 return
398 return
393 else:
399 else:
394 magic_docs = self.format_screen(magic_docs)
400 magic_docs = self.format_screen(magic_docs)
395
401
396 outmsg = """
402 outmsg = """
397 IPython's 'magic' functions
403 IPython's 'magic' functions
398 ===========================
404 ===========================
399
405
400 The magic function system provides a series of functions which allow you to
406 The magic function system provides a series of functions which allow you to
401 control the behavior of IPython itself, plus a lot of system-type
407 control the behavior of IPython itself, plus a lot of system-type
402 features. All these functions are prefixed with a % character, but parameters
408 features. All these functions are prefixed with a % character, but parameters
403 are given without parentheses or quotes.
409 are given without parentheses or quotes.
404
410
405 NOTE: If you have 'automagic' enabled (via the command line option or with the
411 NOTE: If you have 'automagic' enabled (via the command line option or with the
406 %automagic function), you don't need to type in the % explicitly. By default,
412 %automagic function), you don't need to type in the % explicitly. By default,
407 IPython ships with automagic on, so you should only rarely need the % escape.
413 IPython ships with automagic on, so you should only rarely need the % escape.
408
414
409 Example: typing '%cd mydir' (without the quotes) changes you working directory
415 Example: typing '%cd mydir' (without the quotes) changes you working directory
410 to 'mydir', if it exists.
416 to 'mydir', if it exists.
411
417
412 You can define your own magic functions to extend the system. See the supplied
418 You can define your own magic functions to extend the system. See the supplied
413 ipythonrc and example-magic.py files for details (in your ipython
419 ipythonrc and example-magic.py files for details (in your ipython
414 configuration directory, typically $HOME/.ipython/).
420 configuration directory, typically $HOME/.ipython/).
415
421
416 You can also define your own aliased names for magic functions. In your
422 You can also define your own aliased names for magic functions. In your
417 ipythonrc file, placing a line like:
423 ipythonrc file, placing a line like:
418
424
419 execute __IPYTHON__.magic_pf = __IPYTHON__.magic_profile
425 execute __IPYTHON__.magic_pf = __IPYTHON__.magic_profile
420
426
421 will define %pf as a new name for %profile.
427 will define %pf as a new name for %profile.
422
428
423 You can also call magics in code using the ipmagic() function, which IPython
429 You can also call magics in code using the ipmagic() function, which IPython
424 automatically adds to the builtin namespace. Type 'ipmagic?' for details.
430 automatically adds to the builtin namespace. Type 'ipmagic?' for details.
425
431
426 For a list of the available magic functions, use %lsmagic. For a description
432 For a list of the available magic functions, use %lsmagic. For a description
427 of any of them, type %magic_name?, e.g. '%cd?'.
433 of any of them, type %magic_name?, e.g. '%cd?'.
428
434
429 Currently the magic system has the following functions:\n"""
435 Currently the magic system has the following functions:\n"""
430
436
431 mesc = self.shell.ESC_MAGIC
437 mesc = self.shell.ESC_MAGIC
432 outmsg = ("%s\n%s\n\nSummary of magic functions (from %slsmagic):"
438 outmsg = ("%s\n%s\n\nSummary of magic functions (from %slsmagic):"
433 "\n\n%s%s\n\n%s" % (outmsg,
439 "\n\n%s%s\n\n%s" % (outmsg,
434 magic_docs,mesc,mesc,
440 magic_docs,mesc,mesc,
435 (' '+mesc).join(self.lsmagic()),
441 (' '+mesc).join(self.lsmagic()),
436 Magic.auto_status[self.shell.rc.automagic] ) )
442 Magic.auto_status[self.shell.rc.automagic] ) )
437
443
438 page(outmsg,screen_lines=self.shell.rc.screen_length)
444 page(outmsg,screen_lines=self.shell.rc.screen_length)
439
445
440 def magic_automagic(self, parameter_s = ''):
446 def magic_automagic(self, parameter_s = ''):
441 """Make magic functions callable without having to type the initial %.
447 """Make magic functions callable without having to type the initial %.
442
448
443 Toggles on/off (when off, you must call it as %automagic, of
449 Toggles on/off (when off, you must call it as %automagic, of
444 course). Note that magic functions have lowest priority, so if there's
450 course). Note that magic functions have lowest priority, so if there's
445 a variable whose name collides with that of a magic fn, automagic
451 a variable whose name collides with that of a magic fn, automagic
446 won't work for that function (you get the variable instead). However,
452 won't work for that function (you get the variable instead). However,
447 if you delete the variable (del var), the previously shadowed magic
453 if you delete the variable (del var), the previously shadowed magic
448 function becomes visible to automagic again."""
454 function becomes visible to automagic again."""
449
455
450 rc = self.shell.rc
456 rc = self.shell.rc
451 rc.automagic = not rc.automagic
457 rc.automagic = not rc.automagic
452 print '\n' + Magic.auto_status[rc.automagic]
458 print '\n' + Magic.auto_status[rc.automagic]
453
459
454 def magic_autocall(self, parameter_s = ''):
460 def magic_autocall(self, parameter_s = ''):
455 """Make functions callable without having to type parentheses.
461 """Make functions callable without having to type parentheses.
456
462
457 This toggles the autocall command line option on and off."""
463 This toggles the autocall command line option on and off."""
458
464
459 rc = self.shell.rc
465 rc = self.shell.rc
460 rc.autocall = not rc.autocall
466 rc.autocall = not rc.autocall
461 print "Automatic calling is:",['OFF','ON'][rc.autocall]
467 print "Automatic calling is:",['OFF','ON'][rc.autocall]
462
468
463 def magic_autoindent(self, parameter_s = ''):
469 def magic_autoindent(self, parameter_s = ''):
464 """Toggle autoindent on/off (if available)."""
470 """Toggle autoindent on/off (if available)."""
465
471
466 self.shell.set_autoindent()
472 self.shell.set_autoindent()
467 print "Automatic indentation is:",['OFF','ON'][self.shell.autoindent]
473 print "Automatic indentation is:",['OFF','ON'][self.shell.autoindent]
468
474
469 def magic_system_verbose(self, parameter_s = ''):
475 def magic_system_verbose(self, parameter_s = ''):
470 """Toggle verbose printing of system calls on/off."""
476 """Toggle verbose printing of system calls on/off."""
471
477
472 self.shell.rc_set_toggle('system_verbose')
478 self.shell.rc_set_toggle('system_verbose')
473 print "System verbose printing is:",\
479 print "System verbose printing is:",\
474 ['OFF','ON'][self.shell.rc.system_verbose]
480 ['OFF','ON'][self.shell.rc.system_verbose]
475
481
476 def magic_history(self, parameter_s = ''):
482 def magic_history(self, parameter_s = ''):
477 """Print input history (_i<n> variables), with most recent last.
483 """Print input history (_i<n> variables), with most recent last.
478
484
479 %history [-n] -> print at most 40 inputs (some may be multi-line)\\
485 %history [-n] -> print at most 40 inputs (some may be multi-line)\\
480 %history [-n] n -> print at most n inputs\\
486 %history [-n] n -> print at most n inputs\\
481 %history [-n] n1 n2 -> print inputs between n1 and n2 (n2 not included)\\
487 %history [-n] n1 n2 -> print inputs between n1 and n2 (n2 not included)\\
482
488
483 Each input's number <n> is shown, and is accessible as the
489 Each input's number <n> is shown, and is accessible as the
484 automatically generated variable _i<n>. Multi-line statements are
490 automatically generated variable _i<n>. Multi-line statements are
485 printed starting at a new line for easy copy/paste.
491 printed starting at a new line for easy copy/paste.
486
492
487 If option -n is used, input numbers are not printed. This is useful if
493 If option -n is used, input numbers are not printed. This is useful if
488 you want to get a printout of many lines which can be directly pasted
494 you want to get a printout of many lines which can be directly pasted
489 into a text editor.
495 into a text editor.
490
496
491 This feature is only available if numbered prompts are in use."""
497 This feature is only available if numbered prompts are in use."""
492
498
493 if not self.do_full_cache:
499 if not self.do_full_cache:
494 print 'This feature is only available if numbered prompts are in use.'
500 print 'This feature is only available if numbered prompts are in use.'
495 return
501 return
496 opts,args = self.parse_options(parameter_s,'n',mode='list')
502 opts,args = self.parse_options(parameter_s,'n',mode='list')
497
503
498 default_length = 40
504 default_length = 40
499 if len(args) == 0:
505 if len(args) == 0:
500 final = self.outputcache.prompt_count
506 final = self.outputcache.prompt_count
501 init = max(1,final-default_length)
507 init = max(1,final-default_length)
502 elif len(args) == 1:
508 elif len(args) == 1:
503 final = self.outputcache.prompt_count
509 final = self.outputcache.prompt_count
504 init = max(1,final-int(args[0]))
510 init = max(1,final-int(args[0]))
505 elif len(args) == 2:
511 elif len(args) == 2:
506 init,final = map(int,args)
512 init,final = map(int,args)
507 else:
513 else:
508 warn('%hist takes 0, 1 or 2 arguments separated by spaces.')
514 warn('%hist takes 0, 1 or 2 arguments separated by spaces.')
509 print self.magic_hist.__doc__
515 print self.magic_hist.__doc__
510 return
516 return
511 width = len(str(final))
517 width = len(str(final))
512 line_sep = ['','\n']
518 line_sep = ['','\n']
513 input_hist = self.shell.input_hist
519 input_hist = self.shell.input_hist
514 print_nums = not opts.has_key('n')
520 print_nums = not opts.has_key('n')
515 for in_num in range(init,final):
521 for in_num in range(init,final):
516 inline = input_hist[in_num]
522 inline = input_hist[in_num]
517 multiline = inline.count('\n') > 1
523 multiline = inline.count('\n') > 1
518 if print_nums:
524 if print_nums:
519 print str(in_num).ljust(width)+':'+ line_sep[multiline],
525 print str(in_num).ljust(width)+':'+ line_sep[multiline],
520 if inline.startswith('#'+self.shell.ESC_MAGIC) or \
526 if inline.startswith('#'+self.shell.ESC_MAGIC) or \
521 inline.startswith('#!'):
527 inline.startswith('#!'):
522 print inline[1:],
528 print inline[1:],
523 else:
529 else:
524 print inline,
530 print inline,
525
531
526 def magic_hist(self, parameter_s=''):
532 def magic_hist(self, parameter_s=''):
527 """Alternate name for %history."""
533 """Alternate name for %history."""
528 return self.magic_history(parameter_s)
534 return self.magic_history(parameter_s)
529
535
530 def magic_p(self, parameter_s=''):
536 def magic_p(self, parameter_s=''):
531 """Just a short alias for Python's 'print'."""
537 """Just a short alias for Python's 'print'."""
532 exec 'print ' + parameter_s in self.shell.user_ns
538 exec 'print ' + parameter_s in self.shell.user_ns
533
539
534 def magic_r(self, parameter_s=''):
540 def magic_r(self, parameter_s=''):
535 """Repeat previous input.
541 """Repeat previous input.
536
542
537 If given an argument, repeats the previous command which starts with
543 If given an argument, repeats the previous command which starts with
538 the same string, otherwise it just repeats the previous input.
544 the same string, otherwise it just repeats the previous input.
539
545
540 Shell escaped commands (with ! as first character) are not recognized
546 Shell escaped commands (with ! as first character) are not recognized
541 by this system, only pure python code and magic commands.
547 by this system, only pure python code and magic commands.
542 """
548 """
543
549
544 start = parameter_s.strip()
550 start = parameter_s.strip()
545 esc_magic = self.shell.ESC_MAGIC
551 esc_magic = self.shell.ESC_MAGIC
546 # Identify magic commands even if automagic is on (which means
552 # Identify magic commands even if automagic is on (which means
547 # the in-memory version is different from that typed by the user).
553 # the in-memory version is different from that typed by the user).
548 if self.shell.rc.automagic:
554 if self.shell.rc.automagic:
549 start_magic = esc_magic+start
555 start_magic = esc_magic+start
550 else:
556 else:
551 start_magic = start
557 start_magic = start
552 # Look through the input history in reverse
558 # Look through the input history in reverse
553 for n in range(len(self.shell.input_hist)-2,0,-1):
559 for n in range(len(self.shell.input_hist)-2,0,-1):
554 input = self.shell.input_hist[n]
560 input = self.shell.input_hist[n]
555 # skip plain 'r' lines so we don't recurse to infinity
561 # skip plain 'r' lines so we don't recurse to infinity
556 if input != 'ipmagic("r")\n' and \
562 if input != 'ipmagic("r")\n' and \
557 (input.startswith(start) or input.startswith(start_magic)):
563 (input.startswith(start) or input.startswith(start_magic)):
558 #print 'match',`input` # dbg
564 #print 'match',`input` # dbg
559 if input.startswith(esc_magic):
565 if input.startswith(esc_magic):
560 input = magic2python(input)
566 input = magic2python(input)
561 #print 'modified',`input` # dbg
567 #print 'modified',`input` # dbg
562 print 'Executing:',input,
568 print 'Executing:',input,
563 exec input in self.shell.user_ns
569 exec input in self.shell.user_ns
564 return
570 return
565 print 'No previous input matching `%s` found.' % start
571 print 'No previous input matching `%s` found.' % start
566
572
567 def magic_page(self, parameter_s=''):
573 def magic_page(self, parameter_s=''):
568 """Pretty print the object and display it through a pager.
574 """Pretty print the object and display it through a pager.
569
575
570 If no parameter is given, use _ (last output)."""
576 If no parameter is given, use _ (last output)."""
571 # After a function contributed by Olivier Aubert, slightly modified.
577 # After a function contributed by Olivier Aubert, slightly modified.
572
578
573 oname = parameter_s and parameter_s or '_'
579 oname = parameter_s and parameter_s or '_'
574 info = self._ofind(oname)
580 info = self._ofind(oname)
575 if info['found']:
581 if info['found']:
576 page(pformat(info['obj']))
582 page(pformat(info['obj']))
577 else:
583 else:
578 print 'Object `%s` not found' % oname
584 print 'Object `%s` not found' % oname
579
585
580 def magic_profile(self, parameter_s=''):
586 def magic_profile(self, parameter_s=''):
581 """Print your currently active IPyhton profile."""
587 """Print your currently active IPyhton profile."""
582 if self.shell.rc.profile:
588 if self.shell.rc.profile:
583 printpl('Current IPython profile: $self.shell.rc.profile.')
589 printpl('Current IPython profile: $self.shell.rc.profile.')
584 else:
590 else:
585 print 'No profile active.'
591 print 'No profile active.'
586
592
587 def _inspect(self,meth,oname,**kw):
593 def _inspect(self,meth,oname,**kw):
588 """Generic interface to the inspector system.
594 """Generic interface to the inspector system.
589
595
590 This function is meant to be called by pdef, pdoc & friends."""
596 This function is meant to be called by pdef, pdoc & friends."""
591
597
592 oname = oname.strip()
598 oname = oname.strip()
593 info = Struct(self._ofind(oname))
599 info = Struct(self._ofind(oname))
594 if info.found:
600 if info.found:
595 pmethod = getattr(self.shell.inspector,meth)
601 pmethod = getattr(self.shell.inspector,meth)
596 formatter = info.ismagic and self.format_screen or None
602 formatter = info.ismagic and self.format_screen or None
597 if meth == 'pdoc':
603 if meth == 'pdoc':
598 pmethod(info.obj,oname,formatter)
604 pmethod(info.obj,oname,formatter)
599 elif meth == 'pinfo':
605 elif meth == 'pinfo':
600 pmethod(info.obj,oname,formatter,info,**kw)
606 pmethod(info.obj,oname,formatter,info,**kw)
601 else:
607 else:
602 pmethod(info.obj,oname)
608 pmethod(info.obj,oname)
603 else:
609 else:
604 print 'Object `%s` not found.' % oname
610 print 'Object `%s` not found.' % oname
605 return 'not found' # so callers can take other action
611 return 'not found' # so callers can take other action
606
612
607 def magic_pdef(self, parameter_s=''):
613 def magic_pdef(self, parameter_s=''):
608 """Print the definition header for any callable object.
614 """Print the definition header for any callable object.
609
615
610 If the object is a class, print the constructor information."""
616 If the object is a class, print the constructor information."""
611 self._inspect('pdef',parameter_s)
617 self._inspect('pdef',parameter_s)
612
618
613 def magic_pdoc(self, parameter_s=''):
619 def magic_pdoc(self, parameter_s=''):
614 """Print the docstring for an object.
620 """Print the docstring for an object.
615
621
616 If the given object is a class, it will print both the class and the
622 If the given object is a class, it will print both the class and the
617 constructor docstrings."""
623 constructor docstrings."""
618 self._inspect('pdoc',parameter_s)
624 self._inspect('pdoc',parameter_s)
619
625
620 def magic_psource(self, parameter_s=''):
626 def magic_psource(self, parameter_s=''):
621 """Print (or run through pager) the source code for an object."""
627 """Print (or run through pager) the source code for an object."""
622 self._inspect('psource',parameter_s)
628 self._inspect('psource',parameter_s)
623
629
624 def magic_pfile(self, parameter_s=''):
630 def magic_pfile(self, parameter_s=''):
625 """Print (or run through pager) the file where an object is defined.
631 """Print (or run through pager) the file where an object is defined.
626
632
627 The file opens at the line where the object definition begins. IPython
633 The file opens at the line where the object definition begins. IPython
628 will honor the environment variable PAGER if set, and otherwise will
634 will honor the environment variable PAGER if set, and otherwise will
629 do its best to print the file in a convenient form.
635 do its best to print the file in a convenient form.
630
636
631 If the given argument is not an object currently defined, IPython will
637 If the given argument is not an object currently defined, IPython will
632 try to interpret it as a filename (automatically adding a .py extension
638 try to interpret it as a filename (automatically adding a .py extension
633 if needed). You can thus use %pfile as a syntax highlighting code
639 if needed). You can thus use %pfile as a syntax highlighting code
634 viewer."""
640 viewer."""
635
641
636 # first interpret argument as an object name
642 # first interpret argument as an object name
637 out = self._inspect('pfile',parameter_s)
643 out = self._inspect('pfile',parameter_s)
638 # if not, try the input as a filename
644 # if not, try the input as a filename
639 if out == 'not found':
645 if out == 'not found':
640 try:
646 try:
641 filename = get_py_filename(parameter_s)
647 filename = get_py_filename(parameter_s)
642 except IOError,msg:
648 except IOError,msg:
643 print msg
649 print msg
644 return
650 return
645 page(self.shell.inspector.format(file(filename).read()))
651 page(self.shell.inspector.format(file(filename).read()))
646
652
647 def magic_pinfo(self, parameter_s=''):
653 def magic_pinfo(self, parameter_s=''):
648 """Provide detailed information about an object.
654 """Provide detailed information about an object.
649
655
650 '%pinfo object' is just a synonym for object? or ?object."""
656 '%pinfo object' is just a synonym for object? or ?object."""
651
657
652 #print 'pinfo par: <%s>' % parameter_s # dbg
658 #print 'pinfo par: <%s>' % parameter_s # dbg
653
659
654 # detail_level: 0 -> obj? , 1 -> obj??
660 # detail_level: 0 -> obj? , 1 -> obj??
655 detail_level = 0
661 detail_level = 0
656 # We need to detect if we got called as 'pinfo pinfo foo', which can
662 # We need to detect if we got called as 'pinfo pinfo foo', which can
657 # happen if the user types 'pinfo foo?' at the cmd line.
663 # happen if the user types 'pinfo foo?' at the cmd line.
658 pinfo,qmark1,oname,qmark2 = \
664 pinfo,qmark1,oname,qmark2 = \
659 re.match('(pinfo )?(\?*)(.*?)(\??$)',parameter_s).groups()
665 re.match('(pinfo )?(\?*)(.*?)(\??$)',parameter_s).groups()
660 if pinfo or qmark1 or qmark2:
666 if pinfo or qmark1 or qmark2:
661 detail_level = 1
667 detail_level = 1
662 if "*" in oname:
668 if "*" in oname:
663 self.magic_psearch(oname)
669 self.magic_psearch(oname)
664 else:
670 else:
665 self._inspect('pinfo',oname,detail_level=detail_level)
671 self._inspect('pinfo',oname,detail_level=detail_level)
666
672
667 def magic_psearch(self, parameter_s=''):
673 def magic_psearch(self, parameter_s=''):
668 """Search for object in namespaces by wildcard.
674 """Search for object in namespaces by wildcard.
669
675
670 %psearch [options] PATTERN [OBJECT TYPE]
676 %psearch [options] PATTERN [OBJECT TYPE]
671
677
672 Note: ? can be used as a synonym for %psearch, at the beginning or at
678 Note: ? can be used as a synonym for %psearch, at the beginning or at
673 the end: both a*? and ?a* are equivalent to '%psearch a*'. Still, the
679 the end: both a*? and ?a* are equivalent to '%psearch a*'. Still, the
674 rest of the command line must be unchanged (options come first), so
680 rest of the command line must be unchanged (options come first), so
675 for example the following forms are equivalent
681 for example the following forms are equivalent
676
682
677 %psearch -i a* function
683 %psearch -i a* function
678 -i a* function?
684 -i a* function?
679 ?-i a* function
685 ?-i a* function
680
686
681 Arguments:
687 Arguments:
682
688
683 PATTERN
689 PATTERN
684
690
685 where PATTERN is a string containing * as a wildcard similar to its
691 where PATTERN is a string containing * as a wildcard similar to its
686 use in a shell. The pattern is matched in all namespaces on the
692 use in a shell. The pattern is matched in all namespaces on the
687 search path. By default objects starting with a single _ are not
693 search path. By default objects starting with a single _ are not
688 matched, many IPython generated objects have a single
694 matched, many IPython generated objects have a single
689 underscore. The default is case insensitive matching. Matching is
695 underscore. The default is case insensitive matching. Matching is
690 also done on the attributes of objects and not only on the objects
696 also done on the attributes of objects and not only on the objects
691 in a module.
697 in a module.
692
698
693 [OBJECT TYPE]
699 [OBJECT TYPE]
694
700
695 Is the name of a python type from the types module. The name is
701 Is the name of a python type from the types module. The name is
696 given in lowercase without the ending type, ex. StringType is
702 given in lowercase without the ending type, ex. StringType is
697 written string. By adding a type here only objects matching the
703 written string. By adding a type here only objects matching the
698 given type are matched. Using all here makes the pattern match all
704 given type are matched. Using all here makes the pattern match all
699 types (this is the default).
705 types (this is the default).
700
706
701 Options:
707 Options:
702
708
703 -a: makes the pattern match even objects whose names start with a
709 -a: makes the pattern match even objects whose names start with a
704 single underscore. These names are normally ommitted from the
710 single underscore. These names are normally ommitted from the
705 search.
711 search.
706
712
707 -i/-c: make the pattern case insensitive/sensitive. If neither of
713 -i/-c: make the pattern case insensitive/sensitive. If neither of
708 these options is given, the default is read from your ipythonrc
714 these options is given, the default is read from your ipythonrc
709 file. The option name which sets this value is
715 file. The option name which sets this value is
710 'wildcards_case_sensitive'. If this option is not specified in your
716 'wildcards_case_sensitive'. If this option is not specified in your
711 ipythonrc file, IPython's internal default is to do a case sensitive
717 ipythonrc file, IPython's internal default is to do a case sensitive
712 search.
718 search.
713
719
714 -e/-s NAMESPACE: exclude/search a given namespace. The pattern you
720 -e/-s NAMESPACE: exclude/search a given namespace. The pattern you
715 specifiy can be searched in any of the following namespaces:
721 specifiy can be searched in any of the following namespaces:
716 'builtin', 'user', 'user_global','internal', 'alias', where
722 'builtin', 'user', 'user_global','internal', 'alias', where
717 'builtin' and 'user' are the search defaults. Note that you should
723 'builtin' and 'user' are the search defaults. Note that you should
718 not use quotes when specifying namespaces.
724 not use quotes when specifying namespaces.
719
725
720 'Builtin' contains the python module builtin, 'user' contains all
726 'Builtin' contains the python module builtin, 'user' contains all
721 user data, 'alias' only contain the shell aliases and no python
727 user data, 'alias' only contain the shell aliases and no python
722 objects, 'internal' contains objects used by IPython. The
728 objects, 'internal' contains objects used by IPython. The
723 'user_global' namespace is only used by embedded IPython instances,
729 'user_global' namespace is only used by embedded IPython instances,
724 and it contains module-level globals. You can add namespaces to the
730 and it contains module-level globals. You can add namespaces to the
725 search with -s or exclude them with -e (these options can be given
731 search with -s or exclude them with -e (these options can be given
726 more than once).
732 more than once).
727
733
728 Examples:
734 Examples:
729
735
730 %psearch a* -> objects beginning with an a
736 %psearch a* -> objects beginning with an a
731 %psearch -e builtin a* -> objects NOT in the builtin space starting in a
737 %psearch -e builtin a* -> objects NOT in the builtin space starting in a
732 %psearch a* function -> all functions beginning with an a
738 %psearch a* function -> all functions beginning with an a
733 %psearch re.e* -> objects beginning with an e in module re
739 %psearch re.e* -> objects beginning with an e in module re
734 %psearch r*.e* -> objects that start with e in modules starting in r
740 %psearch r*.e* -> objects that start with e in modules starting in r
735 %psearch r*.* string -> all strings in modules beginning with r
741 %psearch r*.* string -> all strings in modules beginning with r
736
742
737 Case sensitve search:
743 Case sensitve search:
738
744
739 %psearch -c a* list all object beginning with lower case a
745 %psearch -c a* list all object beginning with lower case a
740
746
741 Show objects beginning with a single _:
747 Show objects beginning with a single _:
742
748
743 %psearch -a _* list objects beginning with a single underscore"""
749 %psearch -a _* list objects beginning with a single underscore"""
744
750
745 # default namespaces to be searched
751 # default namespaces to be searched
746 def_search = ['user','builtin']
752 def_search = ['user','builtin']
747
753
748 # Process options/args
754 # Process options/args
749 opts,args = self.parse_options(parameter_s,'cias:e:',list_all=True)
755 opts,args = self.parse_options(parameter_s,'cias:e:',list_all=True)
750 opt = opts.get
756 opt = opts.get
751 shell = self.shell
757 shell = self.shell
752 psearch = shell.inspector.psearch
758 psearch = shell.inspector.psearch
753
759
754 # select case options
760 # select case options
755 if opts.has_key('i'):
761 if opts.has_key('i'):
756 ignore_case = True
762 ignore_case = True
757 elif opts.has_key('c'):
763 elif opts.has_key('c'):
758 ignore_case = False
764 ignore_case = False
759 else:
765 else:
760 ignore_case = not shell.rc.wildcards_case_sensitive
766 ignore_case = not shell.rc.wildcards_case_sensitive
761
767
762 # Build list of namespaces to search from user options
768 # Build list of namespaces to search from user options
763 def_search.extend(opt('s',[]))
769 def_search.extend(opt('s',[]))
764 ns_exclude = ns_exclude=opt('e',[])
770 ns_exclude = ns_exclude=opt('e',[])
765 ns_search = [nm for nm in def_search if nm not in ns_exclude]
771 ns_search = [nm for nm in def_search if nm not in ns_exclude]
766
772
767 # Call the actual search
773 # Call the actual search
768 try:
774 try:
769 psearch(args,shell.ns_table,ns_search,
775 psearch(args,shell.ns_table,ns_search,
770 show_all=opt('a'),ignore_case=ignore_case)
776 show_all=opt('a'),ignore_case=ignore_case)
771 except:
777 except:
772 shell.showtraceback()
778 shell.showtraceback()
773
779
774 def magic_who_ls(self, parameter_s=''):
780 def magic_who_ls(self, parameter_s=''):
775 """Return a sorted list of all interactive variables.
781 """Return a sorted list of all interactive variables.
776
782
777 If arguments are given, only variables of types matching these
783 If arguments are given, only variables of types matching these
778 arguments are returned."""
784 arguments are returned."""
779
785
780 user_ns = self.shell.user_ns
786 user_ns = self.shell.user_ns
781 out = []
787 out = []
782 typelist = parameter_s.split()
788 typelist = parameter_s.split()
783 for i in self.shell.user_ns.keys():
789 for i in self.shell.user_ns.keys():
784 if not (i.startswith('_') or i.startswith('_i')) \
790 if not (i.startswith('_') or i.startswith('_i')) \
785 and not (self.internal_ns.has_key(i) or
791 and not (self.internal_ns.has_key(i) or
786 self.user_config_ns.has_key(i)):
792 self.user_config_ns.has_key(i)):
787 if typelist:
793 if typelist:
788 if type(user_ns[i]).__name__ in typelist:
794 if type(user_ns[i]).__name__ in typelist:
789 out.append(i)
795 out.append(i)
790 else:
796 else:
791 out.append(i)
797 out.append(i)
792 out.sort()
798 out.sort()
793 return out
799 return out
794
800
795 def magic_who(self, parameter_s=''):
801 def magic_who(self, parameter_s=''):
796 """Print all interactive variables, with some minimal formatting.
802 """Print all interactive variables, with some minimal formatting.
797
803
798 If any arguments are given, only variables whose type matches one of
804 If any arguments are given, only variables whose type matches one of
799 these are printed. For example:
805 these are printed. For example:
800
806
801 %who function str
807 %who function str
802
808
803 will only list functions and strings, excluding all other types of
809 will only list functions and strings, excluding all other types of
804 variables. To find the proper type names, simply use type(var) at a
810 variables. To find the proper type names, simply use type(var) at a
805 command line to see how python prints type names. For example:
811 command line to see how python prints type names. For example:
806
812
807 In [1]: type('hello')\\
813 In [1]: type('hello')\\
808 Out[1]: <type 'str'>
814 Out[1]: <type 'str'>
809
815
810 indicates that the type name for strings is 'str'.
816 indicates that the type name for strings is 'str'.
811
817
812 %who always excludes executed names loaded through your configuration
818 %who always excludes executed names loaded through your configuration
813 file and things which are internal to IPython.
819 file and things which are internal to IPython.
814
820
815 This is deliberate, as typically you may load many modules and the
821 This is deliberate, as typically you may load many modules and the
816 purpose of %who is to show you only what you've manually defined."""
822 purpose of %who is to show you only what you've manually defined."""
817
823
818 varlist = self.magic_who_ls(parameter_s)
824 varlist = self.magic_who_ls(parameter_s)
819 if not varlist:
825 if not varlist:
820 print 'Interactive namespace is empty.'
826 print 'Interactive namespace is empty.'
821 return
827 return
822
828
823 # if we have variables, move on...
829 # if we have variables, move on...
824
830
825 # stupid flushing problem: when prompts have no separators, stdout is
831 # stupid flushing problem: when prompts have no separators, stdout is
826 # getting lost. I'm starting to think this is a python bug. I'm having
832 # getting lost. I'm starting to think this is a python bug. I'm having
827 # to force a flush with a print because even a sys.stdout.flush
833 # to force a flush with a print because even a sys.stdout.flush
828 # doesn't seem to do anything!
834 # doesn't seem to do anything!
829
835
830 count = 0
836 count = 0
831 for i in varlist:
837 for i in varlist:
832 print i+'\t',
838 print i+'\t',
833 count += 1
839 count += 1
834 if count > 8:
840 if count > 8:
835 count = 0
841 count = 0
836 print
842 print
837 sys.stdout.flush() # FIXME. Why the hell isn't this flushing???
843 sys.stdout.flush() # FIXME. Why the hell isn't this flushing???
838
844
839 print # well, this does force a flush at the expense of an extra \n
845 print # well, this does force a flush at the expense of an extra \n
840
846
841 def magic_whos(self, parameter_s=''):
847 def magic_whos(self, parameter_s=''):
842 """Like %who, but gives some extra information about each variable.
848 """Like %who, but gives some extra information about each variable.
843
849
844 The same type filtering of %who can be applied here.
850 The same type filtering of %who can be applied here.
845
851
846 For all variables, the type is printed. Additionally it prints:
852 For all variables, the type is printed. Additionally it prints:
847
853
848 - For {},[],(): their length.
854 - For {},[],(): their length.
849
855
850 - For Numeric arrays, a summary with shape, number of elements,
856 - For Numeric arrays, a summary with shape, number of elements,
851 typecode and size in memory.
857 typecode and size in memory.
852
858
853 - Everything else: a string representation, snipping their middle if
859 - Everything else: a string representation, snipping their middle if
854 too long."""
860 too long."""
855
861
856 varnames = self.magic_who_ls(parameter_s)
862 varnames = self.magic_who_ls(parameter_s)
857 if not varnames:
863 if not varnames:
858 print 'Interactive namespace is empty.'
864 print 'Interactive namespace is empty.'
859 return
865 return
860
866
861 # if we have variables, move on...
867 # if we have variables, move on...
862
868
863 # for these types, show len() instead of data:
869 # for these types, show len() instead of data:
864 seq_types = [types.DictType,types.ListType,types.TupleType]
870 seq_types = [types.DictType,types.ListType,types.TupleType]
865
871
866 # for Numeric arrays, display summary info
872 # for Numeric arrays, display summary info
867 try:
873 try:
868 import Numeric
874 import Numeric
869 except ImportError:
875 except ImportError:
870 array_type = None
876 array_type = None
871 else:
877 else:
872 array_type = Numeric.ArrayType.__name__
878 array_type = Numeric.ArrayType.__name__
873
879
874 # Find all variable names and types so we can figure out column sizes
880 # Find all variable names and types so we can figure out column sizes
875 get_vars = lambda i: self.shell.user_ns[i]
881 get_vars = lambda i: self.shell.user_ns[i]
876 type_name = lambda v: type(v).__name__
882 type_name = lambda v: type(v).__name__
877 varlist = map(get_vars,varnames)
883 varlist = map(get_vars,varnames)
878 typelist = map(type_name,varlist)
884 typelist = map(type_name,varlist)
879 # column labels and # of spaces as separator
885 # column labels and # of spaces as separator
880 varlabel = 'Variable'
886 varlabel = 'Variable'
881 typelabel = 'Type'
887 typelabel = 'Type'
882 datalabel = 'Data/Info'
888 datalabel = 'Data/Info'
883 colsep = 3
889 colsep = 3
884 # variable format strings
890 # variable format strings
885 vformat = "$vname.ljust(varwidth)$vtype.ljust(typewidth)"
891 vformat = "$vname.ljust(varwidth)$vtype.ljust(typewidth)"
886 vfmt_short = '$vstr[:25]<...>$vstr[-25:]'
892 vfmt_short = '$vstr[:25]<...>$vstr[-25:]'
887 aformat = "%s: %s elems, type `%s`, %s bytes"
893 aformat = "%s: %s elems, type `%s`, %s bytes"
888 # find the size of the columns to format the output nicely
894 # find the size of the columns to format the output nicely
889 varwidth = max(max(map(len,varnames)), len(varlabel)) + colsep
895 varwidth = max(max(map(len,varnames)), len(varlabel)) + colsep
890 typewidth = max(max(map(len,typelist)), len(typelabel)) + colsep
896 typewidth = max(max(map(len,typelist)), len(typelabel)) + colsep
891 # table header
897 # table header
892 print varlabel.ljust(varwidth) + typelabel.ljust(typewidth) + \
898 print varlabel.ljust(varwidth) + typelabel.ljust(typewidth) + \
893 ' '+datalabel+'\n' + '-'*(varwidth+typewidth+len(datalabel)+1)
899 ' '+datalabel+'\n' + '-'*(varwidth+typewidth+len(datalabel)+1)
894 # and the table itself
900 # and the table itself
895 kb = 1024
901 kb = 1024
896 Mb = 1048576 # kb**2
902 Mb = 1048576 # kb**2
897 for vname,var,vtype in zip(varnames,varlist,typelist):
903 for vname,var,vtype in zip(varnames,varlist,typelist):
898 print itpl(vformat),
904 print itpl(vformat),
899 if vtype in seq_types:
905 if vtype in seq_types:
900 print len(var)
906 print len(var)
901 elif vtype==array_type:
907 elif vtype==array_type:
902 vshape = str(var.shape).replace(',','').replace(' ','x')[1:-1]
908 vshape = str(var.shape).replace(',','').replace(' ','x')[1:-1]
903 vsize = Numeric.size(var)
909 vsize = Numeric.size(var)
904 vbytes = vsize*var.itemsize()
910 vbytes = vsize*var.itemsize()
905 if vbytes < 100000:
911 if vbytes < 100000:
906 print aformat % (vshape,vsize,var.typecode(),vbytes)
912 print aformat % (vshape,vsize,var.typecode(),vbytes)
907 else:
913 else:
908 print aformat % (vshape,vsize,var.typecode(),vbytes),
914 print aformat % (vshape,vsize,var.typecode(),vbytes),
909 if vbytes < Mb:
915 if vbytes < Mb:
910 print '(%s kb)' % (vbytes/kb,)
916 print '(%s kb)' % (vbytes/kb,)
911 else:
917 else:
912 print '(%s Mb)' % (vbytes/Mb,)
918 print '(%s Mb)' % (vbytes/Mb,)
913 else:
919 else:
914 vstr = str(var)
920 vstr = str(var)
915 if len(vstr) < 50:
921 if len(vstr) < 50:
916 print vstr
922 print vstr
917 else:
923 else:
918 printpl(vfmt_short)
924 printpl(vfmt_short)
919
925
920 def magic_reset(self, parameter_s=''):
926 def magic_reset(self, parameter_s=''):
921 """Resets the namespace by removing all names defined by the user.
927 """Resets the namespace by removing all names defined by the user.
922
928
923 Input/Output history are left around in case you need them."""
929 Input/Output history are left around in case you need them."""
924
930
925 ans = raw_input(
931 ans = raw_input(
926 "Once deleted, variables cannot be recovered. Proceed (y/n)? ")
932 "Once deleted, variables cannot be recovered. Proceed (y/n)? ")
927 if not ans.lower() == 'y':
933 if not ans.lower() == 'y':
928 print 'Nothing done.'
934 print 'Nothing done.'
929 return
935 return
930 user_ns = self.shell.user_ns
936 user_ns = self.shell.user_ns
931 for i in self.magic_who_ls():
937 for i in self.magic_who_ls():
932 del(user_ns[i])
938 del(user_ns[i])
933
939
934 def magic_config(self,parameter_s=''):
940 def magic_config(self,parameter_s=''):
935 """Show IPython's internal configuration."""
941 """Show IPython's internal configuration."""
936
942
937 page('Current configuration structure:\n'+
943 page('Current configuration structure:\n'+
938 pformat(self.shell.rc.dict()))
944 pformat(self.shell.rc.dict()))
939
945
940 def magic_logstart(self,parameter_s=''):
946 def magic_logstart(self,parameter_s=''):
941 """Start logging anywhere in a session.
947 """Start logging anywhere in a session.
942
948
943 %logstart [log_name [log_mode]]
949 %logstart [log_name [log_mode]]
944
950
945 If no name is given, it defaults to a file named 'ipython.log' in your
951 If no name is given, it defaults to a file named 'ipython.log' in your
946 current directory, in 'rotate' mode (see below).
952 current directory, in 'rotate' mode (see below).
947
953
948 '%logstart name' saves to file 'name' in 'backup' mode. It saves your
954 '%logstart name' saves to file 'name' in 'backup' mode. It saves your
949 history up to that point and then continues logging.
955 history up to that point and then continues logging.
950
956
951 %logstart takes a second optional parameter: logging mode. This can be one
957 %logstart takes a second optional parameter: logging mode. This can be one
952 of (note that the modes are given unquoted):\\
958 of (note that the modes are given unquoted):\\
953 over: overwrite existing log.\\
959 over: overwrite existing log.\\
954 backup: rename (if exists) to name~ and start name.\\
960 backup: rename (if exists) to name~ and start name.\\
955 append: well, that says it.\\
961 append: well, that says it.\\
956 rotate: create rotating logs name.1~, name.2~, etc.
962 rotate: create rotating logs name.1~, name.2~, etc.
957 """
963 """
958
964
959 #FIXME. This function should all be moved to the Logger class.
965 #FIXME. This function should all be moved to the Logger class.
960
966
961 valid_modes = qw('over backup append rotate')
967 valid_modes = qw('over backup append rotate')
962 if self.LOG:
968 if self.LOG:
963 print 'Logging is already in place. Logfile:',self.LOG
969 print 'Logging is already in place. Logfile:',self.LOG
964 return
970 return
965
971
966 par = parameter_s.strip()
972 par = parameter_s.strip()
967 if not par:
973 if not par:
968 logname = self.LOGDEF
974 logname = self.LOGDEF
969 logmode = 'rotate' # use rotate for the auto-generated logs
975 logmode = 'rotate' # use rotate for the auto-generated logs
970 else:
976 else:
971 try:
977 try:
972 logname,logmode = par.split()
978 logname,logmode = par.split()
973 except:
979 except:
974 try:
980 try:
975 logname = par
981 logname = par
976 logmode = 'backup'
982 logmode = 'backup'
977 except:
983 except:
978 warn('Usage: %log [log_name [log_mode]]')
984 warn('Usage: %log [log_name [log_mode]]')
979 return
985 return
980 if not logmode in valid_modes:
986 if not logmode in valid_modes:
981 warn('Logging NOT activated.\n'
987 warn('Logging NOT activated.\n'
982 'Usage: %log [log_name [log_mode]]\n'
988 'Usage: %log [log_name [log_mode]]\n'
983 'Valid modes: '+str(valid_modes))
989 'Valid modes: '+str(valid_modes))
984 return
990 return
985
991
986 # If we made it this far, I think we're ok:
992 # If we made it this far, I think we're ok:
987 print 'Activating auto-logging.'
993 print 'Activating auto-logging.'
988 print 'Current session state plus future input saved to:',logname
994 print 'Current session state plus future input saved to:',logname
989 print 'Logging mode: ',logmode
995 print 'Logging mode: ',logmode
990 # put logname into rc struct as if it had been called on the command line,
996 # put logname into rc struct as if it had been called on the command line,
991 # so it ends up saved in the log header
997 # so it ends up saved in the log header
992 # Save it in case we need to restore it...
998 # Save it in case we need to restore it...
993 old_logfile = self.shell.rc.opts.get('logfile','')
999 old_logfile = self.shell.rc.opts.get('logfile','')
994 logname = os.path.expanduser(logname)
1000 logname = os.path.expanduser(logname)
995 self.shell.rc.opts.logfile = logname
1001 self.shell.rc.opts.logfile = logname
996 self.LOGMODE = logmode # FIXME: this should be set through a function.
1002 self.LOGMODE = logmode # FIXME: this should be set through a function.
997 try:
1003 try:
998 header = str(self.LOGHEAD)
1004 header = str(self.LOGHEAD)
999 self.create_log(header,logname)
1005 self.create_log(header,logname)
1000 self.logstart(header,logname)
1006 self.logstart(header,logname)
1001 except:
1007 except:
1002 self.LOG = '' # we are NOT logging, something went wrong
1008 self.LOG = '' # we are NOT logging, something went wrong
1003 self.shell.rc.opts.logfile = old_logfile
1009 self.shell.rc.opts.logfile = old_logfile
1004 warn("Couldn't start log: "+str(sys.exc_info()[1]))
1010 warn("Couldn't start log: "+str(sys.exc_info()[1]))
1005 else: # log input history up to this point
1011 else: # log input history up to this point
1006 self.logfile.write(self.shell.user_ns['_ih'][1:])
1012 self.logfile.write(self.shell.user_ns['_ih'][1:])
1007 self.logfile.flush()
1013 self.logfile.flush()
1008
1014
1009 def magic_logoff(self,parameter_s=''):
1015 def magic_logoff(self,parameter_s=''):
1010 """Temporarily stop logging.
1016 """Temporarily stop logging.
1011
1017
1012 You must have previously started logging."""
1018 You must have previously started logging."""
1013 self.switch_log(0)
1019 self.switch_log(0)
1014
1020
1015 def magic_logon(self,parameter_s=''):
1021 def magic_logon(self,parameter_s=''):
1016 """Restart logging.
1022 """Restart logging.
1017
1023
1018 This function is for restarting logging which you've temporarily
1024 This function is for restarting logging which you've temporarily
1019 stopped with %logoff. For starting logging for the first time, you
1025 stopped with %logoff. For starting logging for the first time, you
1020 must use the %logstart function, which allows you to specify an
1026 must use the %logstart function, which allows you to specify an
1021 optional log filename."""
1027 optional log filename."""
1022
1028
1023 self.switch_log(1)
1029 self.switch_log(1)
1024
1030
1025 def magic_logstate(self,parameter_s=''):
1031 def magic_logstate(self,parameter_s=''):
1026 """Print the status of the logging system."""
1032 """Print the status of the logging system."""
1027
1033
1028 self.logstate()
1034 self.logstate()
1029
1035
1030 def magic_pdb(self, parameter_s=''):
1036 def magic_pdb(self, parameter_s=''):
1031 """Control the calling of the pdb interactive debugger.
1037 """Control the calling of the pdb interactive debugger.
1032
1038
1033 Call as '%pdb on', '%pdb 1', '%pdb off' or '%pdb 0'. If called without
1039 Call as '%pdb on', '%pdb 1', '%pdb off' or '%pdb 0'. If called without
1034 argument it works as a toggle.
1040 argument it works as a toggle.
1035
1041
1036 When an exception is triggered, IPython can optionally call the
1042 When an exception is triggered, IPython can optionally call the
1037 interactive pdb debugger after the traceback printout. %pdb toggles
1043 interactive pdb debugger after the traceback printout. %pdb toggles
1038 this feature on and off."""
1044 this feature on and off."""
1039
1045
1040 par = parameter_s.strip().lower()
1046 par = parameter_s.strip().lower()
1041
1047
1042 if par:
1048 if par:
1043 try:
1049 try:
1044 pdb = {'off':0,'0':0,'on':1,'1':1}[par]
1050 pdb = {'off':0,'0':0,'on':1,'1':1}[par]
1045 except KeyError:
1051 except KeyError:
1046 print 'Incorrect argument. Use on/1, off/0 or nothing for a toggle.'
1052 print 'Incorrect argument. Use on/1, off/0 or nothing for a toggle.'
1047 return
1053 return
1048 else:
1054 else:
1049 self.shell.InteractiveTB.call_pdb = pdb
1055 self.shell.InteractiveTB.call_pdb = pdb
1050 else:
1056 else:
1051 self.shell.InteractiveTB.call_pdb = 1 - self.shell.InteractiveTB.call_pdb
1057 self.shell.InteractiveTB.call_pdb = 1 - self.shell.InteractiveTB.call_pdb
1052 print 'Automatic pdb calling has been turned',\
1058 print 'Automatic pdb calling has been turned',\
1053 on_off(self.shell.InteractiveTB.call_pdb)
1059 on_off(self.shell.InteractiveTB.call_pdb)
1054
1060
1055
1061
1056 def magic_prun(self, parameter_s ='',user_mode=1,
1062 def magic_prun(self, parameter_s ='',user_mode=1,
1057 opts=None,arg_lst=None,prog_ns=None):
1063 opts=None,arg_lst=None,prog_ns=None):
1058
1064
1059 """Run a statement through the python code profiler.
1065 """Run a statement through the python code profiler.
1060
1066
1061 Usage:\\
1067 Usage:\\
1062 %prun [options] statement
1068 %prun [options] statement
1063
1069
1064 The given statement (which doesn't require quote marks) is run via the
1070 The given statement (which doesn't require quote marks) is run via the
1065 python profiler in a manner similar to the profile.run() function.
1071 python profiler in a manner similar to the profile.run() function.
1066 Namespaces are internally managed to work correctly; profile.run
1072 Namespaces are internally managed to work correctly; profile.run
1067 cannot be used in IPython because it makes certain assumptions about
1073 cannot be used in IPython because it makes certain assumptions about
1068 namespaces which do not hold under IPython.
1074 namespaces which do not hold under IPython.
1069
1075
1070 Options:
1076 Options:
1071
1077
1072 -l <limit>: you can place restrictions on what or how much of the
1078 -l <limit>: you can place restrictions on what or how much of the
1073 profile gets printed. The limit value can be:
1079 profile gets printed. The limit value can be:
1074
1080
1075 * A string: only information for function names containing this string
1081 * A string: only information for function names containing this string
1076 is printed.
1082 is printed.
1077
1083
1078 * An integer: only these many lines are printed.
1084 * An integer: only these many lines are printed.
1079
1085
1080 * A float (between 0 and 1): this fraction of the report is printed
1086 * A float (between 0 and 1): this fraction of the report is printed
1081 (for example, use a limit of 0.4 to see the topmost 40% only).
1087 (for example, use a limit of 0.4 to see the topmost 40% only).
1082
1088
1083 You can combine several limits with repeated use of the option. For
1089 You can combine several limits with repeated use of the option. For
1084 example, '-l __init__ -l 5' will print only the topmost 5 lines of
1090 example, '-l __init__ -l 5' will print only the topmost 5 lines of
1085 information about class constructors.
1091 information about class constructors.
1086
1092
1087 -r: return the pstats.Stats object generated by the profiling. This
1093 -r: return the pstats.Stats object generated by the profiling. This
1088 object has all the information about the profile in it, and you can
1094 object has all the information about the profile in it, and you can
1089 later use it for further analysis or in other functions.
1095 later use it for further analysis or in other functions.
1090
1096
1091 Since magic functions have a particular form of calling which prevents
1097 Since magic functions have a particular form of calling which prevents
1092 you from writing something like:\\
1098 you from writing something like:\\
1093 In [1]: p = %prun -r print 4 # invalid!\\
1099 In [1]: p = %prun -r print 4 # invalid!\\
1094 you must instead use IPython's automatic variables to assign this:\\
1100 you must instead use IPython's automatic variables to assign this:\\
1095 In [1]: %prun -r print 4 \\
1101 In [1]: %prun -r print 4 \\
1096 Out[1]: <pstats.Stats instance at 0x8222cec>\\
1102 Out[1]: <pstats.Stats instance at 0x8222cec>\\
1097 In [2]: stats = _
1103 In [2]: stats = _
1098
1104
1099 If you really need to assign this value via an explicit function call,
1105 If you really need to assign this value via an explicit function call,
1100 you can always tap directly into the true name of the magic function
1106 you can always tap directly into the true name of the magic function
1101 by using the ipmagic function (which IPython automatically adds to the
1107 by using the ipmagic function (which IPython automatically adds to the
1102 builtins):\\
1108 builtins):\\
1103 In [3]: stats = ipmagic('prun','-r print 4')
1109 In [3]: stats = ipmagic('prun','-r print 4')
1104
1110
1105 You can type ipmagic? for more details on ipmagic.
1111 You can type ipmagic? for more details on ipmagic.
1106
1112
1107 -s <key>: sort profile by given key. You can provide more than one key
1113 -s <key>: sort profile by given key. You can provide more than one key
1108 by using the option several times: '-s key1 -s key2 -s key3...'. The
1114 by using the option several times: '-s key1 -s key2 -s key3...'. The
1109 default sorting key is 'time'.
1115 default sorting key is 'time'.
1110
1116
1111 The following is copied verbatim from the profile documentation
1117 The following is copied verbatim from the profile documentation
1112 referenced below:
1118 referenced below:
1113
1119
1114 When more than one key is provided, additional keys are used as
1120 When more than one key is provided, additional keys are used as
1115 secondary criteria when the there is equality in all keys selected
1121 secondary criteria when the there is equality in all keys selected
1116 before them.
1122 before them.
1117
1123
1118 Abbreviations can be used for any key names, as long as the
1124 Abbreviations can be used for any key names, as long as the
1119 abbreviation is unambiguous. The following are the keys currently
1125 abbreviation is unambiguous. The following are the keys currently
1120 defined:
1126 defined:
1121
1127
1122 Valid Arg Meaning\\
1128 Valid Arg Meaning\\
1123 "calls" call count\\
1129 "calls" call count\\
1124 "cumulative" cumulative time\\
1130 "cumulative" cumulative time\\
1125 "file" file name\\
1131 "file" file name\\
1126 "module" file name\\
1132 "module" file name\\
1127 "pcalls" primitive call count\\
1133 "pcalls" primitive call count\\
1128 "line" line number\\
1134 "line" line number\\
1129 "name" function name\\
1135 "name" function name\\
1130 "nfl" name/file/line\\
1136 "nfl" name/file/line\\
1131 "stdname" standard name\\
1137 "stdname" standard name\\
1132 "time" internal time
1138 "time" internal time
1133
1139
1134 Note that all sorts on statistics are in descending order (placing
1140 Note that all sorts on statistics are in descending order (placing
1135 most time consuming items first), where as name, file, and line number
1141 most time consuming items first), where as name, file, and line number
1136 searches are in ascending order (i.e., alphabetical). The subtle
1142 searches are in ascending order (i.e., alphabetical). The subtle
1137 distinction between "nfl" and "stdname" is that the standard name is a
1143 distinction between "nfl" and "stdname" is that the standard name is a
1138 sort of the name as printed, which means that the embedded line
1144 sort of the name as printed, which means that the embedded line
1139 numbers get compared in an odd way. For example, lines 3, 20, and 40
1145 numbers get compared in an odd way. For example, lines 3, 20, and 40
1140 would (if the file names were the same) appear in the string order
1146 would (if the file names were the same) appear in the string order
1141 "20" "3" and "40". In contrast, "nfl" does a numeric compare of the
1147 "20" "3" and "40". In contrast, "nfl" does a numeric compare of the
1142 line numbers. In fact, sort_stats("nfl") is the same as
1148 line numbers. In fact, sort_stats("nfl") is the same as
1143 sort_stats("name", "file", "line").
1149 sort_stats("name", "file", "line").
1144
1150
1145 -T <filename>: save profile results as shown on screen to a text
1151 -T <filename>: save profile results as shown on screen to a text
1146 file. The profile is still shown on screen.
1152 file. The profile is still shown on screen.
1147
1153
1148 -D <filename>: save (via dump_stats) profile statistics to given
1154 -D <filename>: save (via dump_stats) profile statistics to given
1149 filename. This data is in a format understod by the pstats module, and
1155 filename. This data is in a format understod by the pstats module, and
1150 is generated by a call to the dump_stats() method of profile
1156 is generated by a call to the dump_stats() method of profile
1151 objects. The profile is still shown on screen.
1157 objects. The profile is still shown on screen.
1152
1158
1153 If you want to run complete programs under the profiler's control, use
1159 If you want to run complete programs under the profiler's control, use
1154 '%run -p [prof_opts] filename.py [args to program]' where prof_opts
1160 '%run -p [prof_opts] filename.py [args to program]' where prof_opts
1155 contains profiler specific options as described here.
1161 contains profiler specific options as described here.
1156
1162
1157 You can read the complete documentation for the profile module with:\\
1163 You can read the complete documentation for the profile module with:\\
1158 In [1]: import profile; profile.help() """
1164 In [1]: import profile; profile.help() """
1159
1165
1160 opts_def = Struct(D=[''],l=[],s=['time'],T=[''])
1166 opts_def = Struct(D=[''],l=[],s=['time'],T=[''])
1161 # protect user quote marks
1167 # protect user quote marks
1162 parameter_s = parameter_s.replace('"',r'\"').replace("'",r"\'")
1168 parameter_s = parameter_s.replace('"',r'\"').replace("'",r"\'")
1163
1169
1164 if user_mode: # regular user call
1170 if user_mode: # regular user call
1165 opts,arg_str = self.parse_options(parameter_s,'D:l:rs:T:',
1171 opts,arg_str = self.parse_options(parameter_s,'D:l:rs:T:',
1166 list_all=1)
1172 list_all=1)
1167 namespace = self.shell.user_ns
1173 namespace = self.shell.user_ns
1168 else: # called to run a program by %run -p
1174 else: # called to run a program by %run -p
1169 try:
1175 try:
1170 filename = get_py_filename(arg_lst[0])
1176 filename = get_py_filename(arg_lst[0])
1171 except IOError,msg:
1177 except IOError,msg:
1172 error(msg)
1178 error(msg)
1173 return
1179 return
1174
1180
1175 arg_str = 'execfile(filename,prog_ns)'
1181 arg_str = 'execfile(filename,prog_ns)'
1176 namespace = locals()
1182 namespace = locals()
1177
1183
1178 opts.merge(opts_def)
1184 opts.merge(opts_def)
1179
1185
1180 prof = profile.Profile()
1186 prof = profile.Profile()
1181 try:
1187 try:
1182 prof = prof.runctx(arg_str,namespace,namespace)
1188 prof = prof.runctx(arg_str,namespace,namespace)
1183 sys_exit = ''
1189 sys_exit = ''
1184 except SystemExit:
1190 except SystemExit:
1185 sys_exit = """*** SystemExit exception caught in code being profiled."""
1191 sys_exit = """*** SystemExit exception caught in code being profiled."""
1186
1192
1187 stats = pstats.Stats(prof).strip_dirs().sort_stats(*opts.s)
1193 stats = pstats.Stats(prof).strip_dirs().sort_stats(*opts.s)
1188
1194
1189 lims = opts.l
1195 lims = opts.l
1190 if lims:
1196 if lims:
1191 lims = [] # rebuild lims with ints/floats/strings
1197 lims = [] # rebuild lims with ints/floats/strings
1192 for lim in opts.l:
1198 for lim in opts.l:
1193 try:
1199 try:
1194 lims.append(int(lim))
1200 lims.append(int(lim))
1195 except ValueError:
1201 except ValueError:
1196 try:
1202 try:
1197 lims.append(float(lim))
1203 lims.append(float(lim))
1198 except ValueError:
1204 except ValueError:
1199 lims.append(lim)
1205 lims.append(lim)
1200
1206
1201 # trap output
1207 # trap output
1202 sys_stdout = sys.stdout
1208 sys_stdout = sys.stdout
1203 stdout_trap = StringIO()
1209 stdout_trap = StringIO()
1204 try:
1210 try:
1205 sys.stdout = stdout_trap
1211 sys.stdout = stdout_trap
1206 stats.print_stats(*lims)
1212 stats.print_stats(*lims)
1207 finally:
1213 finally:
1208 sys.stdout = sys_stdout
1214 sys.stdout = sys_stdout
1209 output = stdout_trap.getvalue()
1215 output = stdout_trap.getvalue()
1210 output = output.rstrip()
1216 output = output.rstrip()
1211
1217
1212 page(output,screen_lines=self.shell.rc.screen_length)
1218 page(output,screen_lines=self.shell.rc.screen_length)
1213 print sys_exit,
1219 print sys_exit,
1214
1220
1215 dump_file = opts.D[0]
1221 dump_file = opts.D[0]
1216 text_file = opts.T[0]
1222 text_file = opts.T[0]
1217 if dump_file:
1223 if dump_file:
1218 prof.dump_stats(dump_file)
1224 prof.dump_stats(dump_file)
1219 print '\n*** Profile stats marshalled to file',\
1225 print '\n*** Profile stats marshalled to file',\
1220 `dump_file`+'.',sys_exit
1226 `dump_file`+'.',sys_exit
1221 if text_file:
1227 if text_file:
1222 file(text_file,'w').write(output)
1228 file(text_file,'w').write(output)
1223 print '\n*** Profile printout saved to text file',\
1229 print '\n*** Profile printout saved to text file',\
1224 `text_file`+'.',sys_exit
1230 `text_file`+'.',sys_exit
1225
1231
1226 if opts.has_key('r'):
1232 if opts.has_key('r'):
1227 return stats
1233 return stats
1228 else:
1234 else:
1229 return None
1235 return None
1230
1236
1231 def magic_run(self, parameter_s ='',runner=None):
1237 def magic_run(self, parameter_s ='',runner=None):
1232 """Run the named file inside IPython as a program.
1238 """Run the named file inside IPython as a program.
1233
1239
1234 Usage:\\
1240 Usage:\\
1235 %run [-n -i -t [-N<N>] -d [-b<N>] -p [profile options]] file [args]
1241 %run [-n -i -t [-N<N>] -d [-b<N>] -p [profile options]] file [args]
1236
1242
1237 Parameters after the filename are passed as command-line arguments to
1243 Parameters after the filename are passed as command-line arguments to
1238 the program (put in sys.argv). Then, control returns to IPython's
1244 the program (put in sys.argv). Then, control returns to IPython's
1239 prompt.
1245 prompt.
1240
1246
1241 This is similar to running at a system prompt:\\
1247 This is similar to running at a system prompt:\\
1242 $ python file args\\
1248 $ python file args\\
1243 but with the advantage of giving you IPython's tracebacks, and of
1249 but with the advantage of giving you IPython's tracebacks, and of
1244 loading all variables into your interactive namespace for further use
1250 loading all variables into your interactive namespace for further use
1245 (unless -p is used, see below).
1251 (unless -p is used, see below).
1246
1252
1247 The file is executed in a namespace initially consisting only of
1253 The file is executed in a namespace initially consisting only of
1248 __name__=='__main__' and sys.argv constructed as indicated. It thus
1254 __name__=='__main__' and sys.argv constructed as indicated. It thus
1249 sees its environment as if it were being run as a stand-alone
1255 sees its environment as if it were being run as a stand-alone
1250 program. But after execution, the IPython interactive namespace gets
1256 program. But after execution, the IPython interactive namespace gets
1251 updated with all variables defined in the program (except for __name__
1257 updated with all variables defined in the program (except for __name__
1252 and sys.argv). This allows for very convenient loading of code for
1258 and sys.argv). This allows for very convenient loading of code for
1253 interactive work, while giving each program a 'clean sheet' to run in.
1259 interactive work, while giving each program a 'clean sheet' to run in.
1254
1260
1255 Options:
1261 Options:
1256
1262
1257 -n: __name__ is NOT set to '__main__', but to the running file's name
1263 -n: __name__ is NOT set to '__main__', but to the running file's name
1258 without extension (as python does under import). This allows running
1264 without extension (as python does under import). This allows running
1259 scripts and reloading the definitions in them without calling code
1265 scripts and reloading the definitions in them without calling code
1260 protected by an ' if __name__ == "__main__" ' clause.
1266 protected by an ' if __name__ == "__main__" ' clause.
1261
1267
1262 -i: run the file in IPython's namespace instead of an empty one. This
1268 -i: run the file in IPython's namespace instead of an empty one. This
1263 is useful if you are experimenting with code written in a text editor
1269 is useful if you are experimenting with code written in a text editor
1264 which depends on variables defined interactively.
1270 which depends on variables defined interactively.
1265
1271
1266 -e: ignore sys.exit() calls or SystemExit exceptions in the script
1272 -e: ignore sys.exit() calls or SystemExit exceptions in the script
1267 being run. This is particularly useful if IPython is being used to
1273 being run. This is particularly useful if IPython is being used to
1268 run unittests, which always exit with a sys.exit() call. In such
1274 run unittests, which always exit with a sys.exit() call. In such
1269 cases you are interested in the output of the test results, not in
1275 cases you are interested in the output of the test results, not in
1270 seeing a traceback of the unittest module.
1276 seeing a traceback of the unittest module.
1271
1277
1272 -t: print timing information at the end of the run. IPython will give
1278 -t: print timing information at the end of the run. IPython will give
1273 you an estimated CPU time consumption for your script, which under
1279 you an estimated CPU time consumption for your script, which under
1274 Unix uses the resource module to avoid the wraparound problems of
1280 Unix uses the resource module to avoid the wraparound problems of
1275 time.clock(). Under Unix, an estimate of time spent on system tasks
1281 time.clock(). Under Unix, an estimate of time spent on system tasks
1276 is also given (for Windows platforms this is reported as 0.0).
1282 is also given (for Windows platforms this is reported as 0.0).
1277
1283
1278 If -t is given, an additional -N<N> option can be given, where <N>
1284 If -t is given, an additional -N<N> option can be given, where <N>
1279 must be an integer indicating how many times you want the script to
1285 must be an integer indicating how many times you want the script to
1280 run. The final timing report will include total and per run results.
1286 run. The final timing report will include total and per run results.
1281
1287
1282 For example (testing the script uniq_stable.py):
1288 For example (testing the script uniq_stable.py):
1283
1289
1284 In [1]: run -t uniq_stable
1290 In [1]: run -t uniq_stable
1285
1291
1286 IPython CPU timings (estimated):\\
1292 IPython CPU timings (estimated):\\
1287 User : 0.19597 s.\\
1293 User : 0.19597 s.\\
1288 System: 0.0 s.\\
1294 System: 0.0 s.\\
1289
1295
1290 In [2]: run -t -N5 uniq_stable
1296 In [2]: run -t -N5 uniq_stable
1291
1297
1292 IPython CPU timings (estimated):\\
1298 IPython CPU timings (estimated):\\
1293 Total runs performed: 5\\
1299 Total runs performed: 5\\
1294 Times : Total Per run\\
1300 Times : Total Per run\\
1295 User : 0.910862 s, 0.1821724 s.\\
1301 User : 0.910862 s, 0.1821724 s.\\
1296 System: 0.0 s, 0.0 s.
1302 System: 0.0 s, 0.0 s.
1297
1303
1298 -d: run your program under the control of pdb, the Python debugger.
1304 -d: run your program under the control of pdb, the Python debugger.
1299 This allows you to execute your program step by step, watch variables,
1305 This allows you to execute your program step by step, watch variables,
1300 etc. Internally, what IPython does is similar to calling:
1306 etc. Internally, what IPython does is similar to calling:
1301
1307
1302 pdb.run('execfile("YOURFILENAME")')
1308 pdb.run('execfile("YOURFILENAME")')
1303
1309
1304 with a breakpoint set on line 1 of your file. You can change the line
1310 with a breakpoint set on line 1 of your file. You can change the line
1305 number for this automatic breakpoint to be <N> by using the -bN option
1311 number for this automatic breakpoint to be <N> by using the -bN option
1306 (where N must be an integer). For example:
1312 (where N must be an integer). For example:
1307
1313
1308 %run -d -b40 myscript
1314 %run -d -b40 myscript
1309
1315
1310 will set the first breakpoint at line 40 in myscript.py. Note that
1316 will set the first breakpoint at line 40 in myscript.py. Note that
1311 the first breakpoint must be set on a line which actually does
1317 the first breakpoint must be set on a line which actually does
1312 something (not a comment or docstring) for it to stop execution.
1318 something (not a comment or docstring) for it to stop execution.
1313
1319
1314 When the pdb debugger starts, you will see a (Pdb) prompt. You must
1320 When the pdb debugger starts, you will see a (Pdb) prompt. You must
1315 first enter 'c' (without qoutes) to start execution up to the first
1321 first enter 'c' (without qoutes) to start execution up to the first
1316 breakpoint.
1322 breakpoint.
1317
1323
1318 Entering 'help' gives information about the use of the debugger. You
1324 Entering 'help' gives information about the use of the debugger. You
1319 can easily see pdb's full documentation with "import pdb;pdb.help()"
1325 can easily see pdb's full documentation with "import pdb;pdb.help()"
1320 at a prompt.
1326 at a prompt.
1321
1327
1322 -p: run program under the control of the Python profiler module (which
1328 -p: run program under the control of the Python profiler module (which
1323 prints a detailed report of execution times, function calls, etc).
1329 prints a detailed report of execution times, function calls, etc).
1324
1330
1325 You can pass other options after -p which affect the behavior of the
1331 You can pass other options after -p which affect the behavior of the
1326 profiler itself. See the docs for %prun for details.
1332 profiler itself. See the docs for %prun for details.
1327
1333
1328 In this mode, the program's variables do NOT propagate back to the
1334 In this mode, the program's variables do NOT propagate back to the
1329 IPython interactive namespace (because they remain in the namespace
1335 IPython interactive namespace (because they remain in the namespace
1330 where the profiler executes them).
1336 where the profiler executes them).
1331
1337
1332 Internally this triggers a call to %prun, see its documentation for
1338 Internally this triggers a call to %prun, see its documentation for
1333 details on the options available specifically for profiling."""
1339 details on the options available specifically for profiling."""
1334
1340
1335 # get arguments and set sys.argv for program to be run.
1341 # get arguments and set sys.argv for program to be run.
1336 opts,arg_lst = self.parse_options(parameter_s,'nidtN:b:pD:l:rs:T:e',
1342 opts,arg_lst = self.parse_options(parameter_s,'nidtN:b:pD:l:rs:T:e',
1337 mode='list',list_all=1)
1343 mode='list',list_all=1)
1338
1344
1339 try:
1345 try:
1340 filename = get_py_filename(arg_lst[0])
1346 filename = get_py_filename(arg_lst[0])
1341 except IndexError:
1347 except IndexError:
1342 warn('you must provide at least a filename.')
1348 warn('you must provide at least a filename.')
1343 print '\n%run:\n',OInspect.getdoc(self.magic_run)
1349 print '\n%run:\n',OInspect.getdoc(self.magic_run)
1344 return
1350 return
1345 except IOError,msg:
1351 except IOError,msg:
1346 error(msg)
1352 error(msg)
1347 return
1353 return
1348
1354
1349 # Control the response to exit() calls made by the script being run
1355 # Control the response to exit() calls made by the script being run
1350 exit_ignore = opts.has_key('e')
1356 exit_ignore = opts.has_key('e')
1351
1357
1352 # Make sure that the running script gets a proper sys.argv as if it
1358 # Make sure that the running script gets a proper sys.argv as if it
1353 # were run from a system shell.
1359 # were run from a system shell.
1354 save_argv = sys.argv # save it for later restoring
1360 save_argv = sys.argv # save it for later restoring
1355 sys.argv = [filename]+ arg_lst[1:] # put in the proper filename
1361 sys.argv = [filename]+ arg_lst[1:] # put in the proper filename
1356
1362
1357 if opts.has_key('i'):
1363 if opts.has_key('i'):
1358 prog_ns = self.shell.user_ns
1364 prog_ns = self.shell.user_ns
1359 __name__save = self.shell.user_ns['__name__']
1365 __name__save = self.shell.user_ns['__name__']
1360 prog_ns['__name__'] = '__main__'
1366 prog_ns['__name__'] = '__main__'
1361 else:
1367 else:
1362 if opts.has_key('n'):
1368 if opts.has_key('n'):
1363 name = os.path.splitext(os.path.basename(filename))[0]
1369 name = os.path.splitext(os.path.basename(filename))[0]
1364 else:
1370 else:
1365 name = '__main__'
1371 name = '__main__'
1366 prog_ns = {'__name__':name}
1372 prog_ns = {'__name__':name}
1367
1373
1368 # pickle fix. See iplib for an explanation
1374 # pickle fix. See iplib for an explanation
1369 sys.modules[prog_ns['__name__']] = FakeModule(prog_ns)
1375 sys.modules[prog_ns['__name__']] = FakeModule(prog_ns)
1370
1376
1371 stats = None
1377 stats = None
1372 try:
1378 try:
1373 if opts.has_key('p'):
1379 if opts.has_key('p'):
1374 stats = self.magic_prun('',0,opts,arg_lst,prog_ns)
1380 stats = self.magic_prun('',0,opts,arg_lst,prog_ns)
1375 else:
1381 else:
1376 if opts.has_key('d'):
1382 if opts.has_key('d'):
1377 deb = Debugger.Pdb(self.shell.rc.colors)
1383 deb = Debugger.Pdb(self.shell.rc.colors)
1378 # reset Breakpoint state, which is moronically kept
1384 # reset Breakpoint state, which is moronically kept
1379 # in a class
1385 # in a class
1380 bdb.Breakpoint.next = 1
1386 bdb.Breakpoint.next = 1
1381 bdb.Breakpoint.bplist = {}
1387 bdb.Breakpoint.bplist = {}
1382 bdb.Breakpoint.bpbynumber = [None]
1388 bdb.Breakpoint.bpbynumber = [None]
1383 # Set an initial breakpoint to stop execution
1389 # Set an initial breakpoint to stop execution
1384 maxtries = 10
1390 maxtries = 10
1385 bp = int(opts.get('b',[1])[0])
1391 bp = int(opts.get('b',[1])[0])
1386 checkline = deb.checkline(filename,bp)
1392 checkline = deb.checkline(filename,bp)
1387 if not checkline:
1393 if not checkline:
1388 for bp in range(bp+1,bp+maxtries+1):
1394 for bp in range(bp+1,bp+maxtries+1):
1389 if deb.checkline(filename,bp):
1395 if deb.checkline(filename,bp):
1390 break
1396 break
1391 else:
1397 else:
1392 msg = ("\nI failed to find a valid line to set "
1398 msg = ("\nI failed to find a valid line to set "
1393 "a breakpoint\n"
1399 "a breakpoint\n"
1394 "after trying up to line: %s.\n"
1400 "after trying up to line: %s.\n"
1395 "Please set a valid breakpoint manually "
1401 "Please set a valid breakpoint manually "
1396 "with the -b option." % bp)
1402 "with the -b option." % bp)
1397 error(msg)
1403 error(msg)
1398 return
1404 return
1399 # if we find a good linenumber, set the breakpoint
1405 # if we find a good linenumber, set the breakpoint
1400 deb.do_break('%s:%s' % (filename,bp))
1406 deb.do_break('%s:%s' % (filename,bp))
1401 # Start file run
1407 # Start file run
1402 print "NOTE: Enter 'c' at the",
1408 print "NOTE: Enter 'c' at the",
1403 print "ipdb> prompt to start your script."
1409 print "ipdb> prompt to start your script."
1404 try:
1410 try:
1405 deb.run('execfile("%s")' % filename,prog_ns)
1411 deb.run('execfile("%s")' % filename,prog_ns)
1406 except:
1412 except:
1407 etype, value, tb = sys.exc_info()
1413 etype, value, tb = sys.exc_info()
1408 # Skip three frames in the traceback: the %run one,
1414 # Skip three frames in the traceback: the %run one,
1409 # one inside bdb.py, and the command-line typed by the
1415 # one inside bdb.py, and the command-line typed by the
1410 # user (run by exec in pdb itself).
1416 # user (run by exec in pdb itself).
1411 self.shell.InteractiveTB(etype,value,tb,tb_offset=3)
1417 self.shell.InteractiveTB(etype,value,tb,tb_offset=3)
1412 else:
1418 else:
1413 if runner is None:
1419 if runner is None:
1414 runner = self.shell.safe_execfile
1420 runner = self.shell.safe_execfile
1415 if opts.has_key('t'):
1421 if opts.has_key('t'):
1416 try:
1422 try:
1417 nruns = int(opts['N'][0])
1423 nruns = int(opts['N'][0])
1418 if nruns < 1:
1424 if nruns < 1:
1419 error('Number of runs must be >=1')
1425 error('Number of runs must be >=1')
1420 return
1426 return
1421 except (KeyError):
1427 except (KeyError):
1422 nruns = 1
1428 nruns = 1
1423 if nruns == 1:
1429 if nruns == 1:
1424 t0 = clock2()
1430 t0 = clock2()
1425 runner(filename,prog_ns,prog_ns,exit_ignore=exit_ignore)
1431 runner(filename,prog_ns,prog_ns,exit_ignore=exit_ignore)
1426 t1 = clock2()
1432 t1 = clock2()
1427 t_usr = t1[0]-t0[0]
1433 t_usr = t1[0]-t0[0]
1428 t_sys = t1[1]-t1[1]
1434 t_sys = t1[1]-t1[1]
1429 print "\nIPython CPU timings (estimated):"
1435 print "\nIPython CPU timings (estimated):"
1430 print " User : %10s s." % t_usr
1436 print " User : %10s s." % t_usr
1431 print " System: %10s s." % t_sys
1437 print " System: %10s s." % t_sys
1432 else:
1438 else:
1433 runs = range(nruns)
1439 runs = range(nruns)
1434 t0 = clock2()
1440 t0 = clock2()
1435 for nr in runs:
1441 for nr in runs:
1436 runner(filename,prog_ns,prog_ns,exit_ignore=exit_ignore)
1442 runner(filename,prog_ns,prog_ns,exit_ignore=exit_ignore)
1437 t1 = clock2()
1443 t1 = clock2()
1438 t_usr = t1[0]-t0[0]
1444 t_usr = t1[0]-t0[0]
1439 t_sys = t1[1]-t1[1]
1445 t_sys = t1[1]-t1[1]
1440 print "\nIPython CPU timings (estimated):"
1446 print "\nIPython CPU timings (estimated):"
1441 print "Total runs performed:",nruns
1447 print "Total runs performed:",nruns
1442 print " Times : %10s %10s" % ('Total','Per run')
1448 print " Times : %10s %10s" % ('Total','Per run')
1443 print " User : %10s s, %10s s." % (t_usr,t_usr/nruns)
1449 print " User : %10s s, %10s s." % (t_usr,t_usr/nruns)
1444 print " System: %10s s, %10s s." % (t_sys,t_sys/nruns)
1450 print " System: %10s s, %10s s." % (t_sys,t_sys/nruns)
1445
1451
1446 else:
1452 else:
1447 runner(filename,prog_ns,prog_ns,exit_ignore=exit_ignore)
1453 runner(filename,prog_ns,prog_ns,exit_ignore=exit_ignore)
1448 if opts.has_key('i'):
1454 if opts.has_key('i'):
1449 self.shell.user_ns['__name__'] = __name__save
1455 self.shell.user_ns['__name__'] = __name__save
1450 else:
1456 else:
1451 # update IPython interactive namespace
1457 # update IPython interactive namespace
1452 del prog_ns['__name__']
1458 del prog_ns['__name__']
1453 self.shell.user_ns.update(prog_ns)
1459 self.shell.user_ns.update(prog_ns)
1454 finally:
1460 finally:
1455 sys.argv = save_argv
1461 sys.argv = save_argv
1456 return stats
1462 return stats
1457
1463
1458 def magic_runlog(self, parameter_s =''):
1464 def magic_runlog(self, parameter_s =''):
1459 """Run files as logs.
1465 """Run files as logs.
1460
1466
1461 Usage:\\
1467 Usage:\\
1462 %runlog file1 file2 ...
1468 %runlog file1 file2 ...
1463
1469
1464 Run the named files (treating them as log files) in sequence inside
1470 Run the named files (treating them as log files) in sequence inside
1465 the interpreter, and return to the prompt. This is much slower than
1471 the interpreter, and return to the prompt. This is much slower than
1466 %run because each line is executed in a try/except block, but it
1472 %run because each line is executed in a try/except block, but it
1467 allows running files with syntax errors in them.
1473 allows running files with syntax errors in them.
1468
1474
1469 Normally IPython will guess when a file is one of its own logfiles, so
1475 Normally IPython will guess when a file is one of its own logfiles, so
1470 you can typically use %run even for logs. This shorthand allows you to
1476 you can typically use %run even for logs. This shorthand allows you to
1471 force any file to be treated as a log file."""
1477 force any file to be treated as a log file."""
1472
1478
1473 for f in parameter_s.split():
1479 for f in parameter_s.split():
1474 self.shell.safe_execfile(f,self.shell.user_ns,
1480 self.shell.safe_execfile(f,self.shell.user_ns,
1475 self.shell.user_ns,islog=1)
1481 self.shell.user_ns,islog=1)
1476
1482
1477 def magic_time(self,parameter_s = ''):
1483 def magic_time(self,parameter_s = ''):
1478 """Time execution of a Python statement or expression.
1484 """Time execution of a Python statement or expression.
1479
1485
1480 The CPU and wall clock times are printed, and the value of the
1486 The CPU and wall clock times are printed, and the value of the
1481 expression (if any) is returned. Note that under Win32, system time
1487 expression (if any) is returned. Note that under Win32, system time
1482 is always reported as 0, since it can not be measured.
1488 is always reported as 0, since it can not be measured.
1483
1489
1484 This function provides very basic timing functionality. In Python
1490 This function provides very basic timing functionality. In Python
1485 2.3, the timeit module offers more control and sophistication, but for
1491 2.3, the timeit module offers more control and sophistication, but for
1486 now IPython supports Python 2.2, so we can not rely on timeit being
1492 now IPython supports Python 2.2, so we can not rely on timeit being
1487 present.
1493 present.
1488
1494
1489 Some examples:
1495 Some examples:
1490
1496
1491 In [1]: time 2**128
1497 In [1]: time 2**128
1492 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1498 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1493 Wall time: 0.00
1499 Wall time: 0.00
1494 Out[1]: 340282366920938463463374607431768211456L
1500 Out[1]: 340282366920938463463374607431768211456L
1495
1501
1496 In [2]: n = 1000000
1502 In [2]: n = 1000000
1497
1503
1498 In [3]: time sum(range(n))
1504 In [3]: time sum(range(n))
1499 CPU times: user 1.20 s, sys: 0.05 s, total: 1.25 s
1505 CPU times: user 1.20 s, sys: 0.05 s, total: 1.25 s
1500 Wall time: 1.37
1506 Wall time: 1.37
1501 Out[3]: 499999500000L
1507 Out[3]: 499999500000L
1502
1508
1503 In [4]: time print 'hello world'
1509 In [4]: time print 'hello world'
1504 hello world
1510 hello world
1505 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1511 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1506 Wall time: 0.00
1512 Wall time: 0.00
1507 """
1513 """
1508
1514
1509 # fail immediately if the given expression can't be compiled
1515 # fail immediately if the given expression can't be compiled
1510 try:
1516 try:
1511 mode = 'eval'
1517 mode = 'eval'
1512 code = compile(parameter_s,'<timed eval>',mode)
1518 code = compile(parameter_s,'<timed eval>',mode)
1513 except SyntaxError:
1519 except SyntaxError:
1514 mode = 'exec'
1520 mode = 'exec'
1515 code = compile(parameter_s,'<timed exec>',mode)
1521 code = compile(parameter_s,'<timed exec>',mode)
1516 # skew measurement as little as possible
1522 # skew measurement as little as possible
1517 glob = self.shell.user_ns
1523 glob = self.shell.user_ns
1518 clk = clock2
1524 clk = clock2
1519 wtime = time.time
1525 wtime = time.time
1520 # time execution
1526 # time execution
1521 wall_st = wtime()
1527 wall_st = wtime()
1522 if mode=='eval':
1528 if mode=='eval':
1523 st = clk()
1529 st = clk()
1524 out = eval(code,glob)
1530 out = eval(code,glob)
1525 end = clk()
1531 end = clk()
1526 else:
1532 else:
1527 st = clk()
1533 st = clk()
1528 exec code in glob
1534 exec code in glob
1529 end = clk()
1535 end = clk()
1530 out = None
1536 out = None
1531 wall_end = wtime()
1537 wall_end = wtime()
1532 # Compute actual times and report
1538 # Compute actual times and report
1533 wall_time = wall_end-wall_st
1539 wall_time = wall_end-wall_st
1534 cpu_user = end[0]-st[0]
1540 cpu_user = end[0]-st[0]
1535 cpu_sys = end[1]-st[1]
1541 cpu_sys = end[1]-st[1]
1536 cpu_tot = cpu_user+cpu_sys
1542 cpu_tot = cpu_user+cpu_sys
1537 print "CPU times: user %.2f s, sys: %.2f s, total: %.2f s" % \
1543 print "CPU times: user %.2f s, sys: %.2f s, total: %.2f s" % \
1538 (cpu_user,cpu_sys,cpu_tot)
1544 (cpu_user,cpu_sys,cpu_tot)
1539 print "Wall time: %.2f" % wall_time
1545 print "Wall time: %.2f" % wall_time
1540 return out
1546 return out
1541
1547
1542 def magic_macro(self,parameter_s = ''):
1548 def magic_macro(self,parameter_s = ''):
1543 """Define a set of input lines as a macro for future re-execution.
1549 """Define a set of input lines as a macro for future re-execution.
1544
1550
1545 Usage:\\
1551 Usage:\\
1546 %macro name n1:n2 n3:n4 ... n5 .. n6 ...
1552 %macro name n1:n2 n3:n4 ... n5 .. n6 ...
1547
1553
1548 This will define a global variable called `name` which is a string
1554 This will define a global variable called `name` which is a string
1549 made of joining the slices and lines you specify (n1,n2,... numbers
1555 made of joining the slices and lines you specify (n1,n2,... numbers
1550 above) from your input history into a single string. This variable
1556 above) from your input history into a single string. This variable
1551 acts like an automatic function which re-executes those lines as if
1557 acts like an automatic function which re-executes those lines as if
1552 you had typed them. You just type 'name' at the prompt and the code
1558 you had typed them. You just type 'name' at the prompt and the code
1553 executes.
1559 executes.
1554
1560
1555 Note that the slices use the standard Python slicing notation (5:8
1561 Note that the slices use the standard Python slicing notation (5:8
1556 means include lines numbered 5,6,7).
1562 means include lines numbered 5,6,7).
1557
1563
1558 For example, if your history contains (%hist prints it):
1564 For example, if your history contains (%hist prints it):
1559
1565
1560 44: x=1\\
1566 44: x=1\\
1561 45: y=3\\
1567 45: y=3\\
1562 46: z=x+y\\
1568 46: z=x+y\\
1563 47: print x\\
1569 47: print x\\
1564 48: a=5\\
1570 48: a=5\\
1565 49: print 'x',x,'y',y\\
1571 49: print 'x',x,'y',y\\
1566
1572
1567 you can create a macro with lines 44 through 47 (included) and line 49
1573 you can create a macro with lines 44 through 47 (included) and line 49
1568 called my_macro with:
1574 called my_macro with:
1569
1575
1570 In [51]: %macro my_macro 44:48 49
1576 In [51]: %macro my_macro 44:48 49
1571
1577
1572 Now, typing `my_macro` (without quotes) will re-execute all this code
1578 Now, typing `my_macro` (without quotes) will re-execute all this code
1573 in one pass.
1579 in one pass.
1574
1580
1575 You don't need to give the line-numbers in order, and any given line
1581 You don't need to give the line-numbers in order, and any given line
1576 number can appear multiple times. You can assemble macros with any
1582 number can appear multiple times. You can assemble macros with any
1577 lines from your input history in any order.
1583 lines from your input history in any order.
1578
1584
1579 The macro is a simple object which holds its value in an attribute,
1585 The macro is a simple object which holds its value in an attribute,
1580 but IPython's display system checks for macros and executes them as
1586 but IPython's display system checks for macros and executes them as
1581 code instead of printing them when you type their name.
1587 code instead of printing them when you type their name.
1582
1588
1583 You can view a macro's contents by explicitly printing it with:
1589 You can view a macro's contents by explicitly printing it with:
1584
1590
1585 'print macro_name'.
1591 'print macro_name'.
1586
1592
1587 For one-off cases which DON'T contain magic function calls in them you
1593 For one-off cases which DON'T contain magic function calls in them you
1588 can obtain similar results by explicitly executing slices from your
1594 can obtain similar results by explicitly executing slices from your
1589 input history with:
1595 input history with:
1590
1596
1591 In [60]: exec In[44:48]+In[49]"""
1597 In [60]: exec In[44:48]+In[49]"""
1592
1598
1593 args = parameter_s.split()
1599 args = parameter_s.split()
1594 name,ranges = args[0], args[1:]
1600 name,ranges = args[0], args[1:]
1595 #print 'rng',ranges # dbg
1601 #print 'rng',ranges # dbg
1596 cmds = self.extract_input_slices(ranges)
1602 cmds = self.extract_input_slices(ranges)
1597 macro = Macro(cmds)
1603 macro = Macro(cmds)
1598 self.shell.user_ns.update({name:macro})
1604 self.shell.user_ns.update({name:macro})
1599 print 'Macro `%s` created. To execute, type its name (without quotes).' % name
1605 print 'Macro `%s` created. To execute, type its name (without quotes).' % name
1600 print 'Macro contents:'
1606 print 'Macro contents:'
1601 print str(macro).rstrip(),
1607 print str(macro).rstrip(),
1602
1608
1603 def magic_save(self,parameter_s = ''):
1609 def magic_save(self,parameter_s = ''):
1604 """Save a set of lines to a given filename.
1610 """Save a set of lines to a given filename.
1605
1611
1606 Usage:\\
1612 Usage:\\
1607 %save filename n1:n2 n3:n4 ... n5 .. n6 ...
1613 %save filename n1:n2 n3:n4 ... n5 .. n6 ...
1608
1614
1609 This function uses the same syntax as %macro for line extraction, but
1615 This function uses the same syntax as %macro for line extraction, but
1610 instead of creating a macro it saves the resulting string to the
1616 instead of creating a macro it saves the resulting string to the
1611 filename you specify.
1617 filename you specify.
1612
1618
1613 It adds a '.py' extension to the file if you don't do so yourself, and
1619 It adds a '.py' extension to the file if you don't do so yourself, and
1614 it asks for confirmation before overwriting existing files."""
1620 it asks for confirmation before overwriting existing files."""
1615
1621
1616 args = parameter_s.split()
1622 args = parameter_s.split()
1617 fname,ranges = args[0], args[1:]
1623 fname,ranges = args[0], args[1:]
1618 if not fname.endswith('.py'):
1624 if not fname.endswith('.py'):
1619 fname += '.py'
1625 fname += '.py'
1620 if os.path.isfile(fname):
1626 if os.path.isfile(fname):
1621 ans = raw_input('File `%s` exists. Overwrite (y/[N])? ' % fname)
1627 ans = raw_input('File `%s` exists. Overwrite (y/[N])? ' % fname)
1622 if ans.lower() not in ['y','yes']:
1628 if ans.lower() not in ['y','yes']:
1623 print 'Operation cancelled.'
1629 print 'Operation cancelled.'
1624 return
1630 return
1625 cmds = ''.join(self.extract_input_slices(ranges))
1631 cmds = ''.join(self.extract_input_slices(ranges))
1626 f = file(fname,'w')
1632 f = file(fname,'w')
1627 f.write(cmds)
1633 f.write(cmds)
1628 f.close()
1634 f.close()
1629 print 'The following commands were written to file `%s`:' % fname
1635 print 'The following commands were written to file `%s`:' % fname
1630 print cmds
1636 print cmds
1631
1637
1632 def magic_ed(self,parameter_s = ''):
1638 def magic_ed(self,parameter_s = ''):
1633 """Alias to %edit."""
1639 """Alias to %edit."""
1634 return self.magic_edit(parameter_s)
1640 return self.magic_edit(parameter_s)
1635
1641
1636 def magic_edit(self,parameter_s = '',last_call=['','']):
1642 def magic_edit(self,parameter_s = '',last_call=['','']):
1637 """Bring up an editor and execute the resulting code.
1643 """Bring up an editor and execute the resulting code.
1638
1644
1639 Usage:
1645 Usage:
1640 %edit [options] [args]
1646 %edit [options] [args]
1641
1647
1642 %edit runs IPython's editor hook. The default version of this hook is
1648 %edit runs IPython's editor hook. The default version of this hook is
1643 set to call the __IPYTHON__.rc.editor command. This is read from your
1649 set to call the __IPYTHON__.rc.editor command. This is read from your
1644 environment variable $EDITOR. If this isn't found, it will default to
1650 environment variable $EDITOR. If this isn't found, it will default to
1645 vi under Linux/Unix and to notepad under Windows. See the end of this
1651 vi under Linux/Unix and to notepad under Windows. See the end of this
1646 docstring for how to change the editor hook.
1652 docstring for how to change the editor hook.
1647
1653
1648 You can also set the value of this editor via the command line option
1654 You can also set the value of this editor via the command line option
1649 '-editor' or in your ipythonrc file. This is useful if you wish to use
1655 '-editor' or in your ipythonrc file. This is useful if you wish to use
1650 specifically for IPython an editor different from your typical default
1656 specifically for IPython an editor different from your typical default
1651 (and for Windows users who typically don't set environment variables).
1657 (and for Windows users who typically don't set environment variables).
1652
1658
1653 This command allows you to conveniently edit multi-line code right in
1659 This command allows you to conveniently edit multi-line code right in
1654 your IPython session.
1660 your IPython session.
1655
1661
1656 If called without arguments, %edit opens up an empty editor with a
1662 If called without arguments, %edit opens up an empty editor with a
1657 temporary file and will execute the contents of this file when you
1663 temporary file and will execute the contents of this file when you
1658 close it (don't forget to save it!).
1664 close it (don't forget to save it!).
1659
1665
1660 Options:
1666 Options:
1661
1667
1662 -p: this will call the editor with the same data as the previous time
1668 -p: this will call the editor with the same data as the previous time
1663 it was used, regardless of how long ago (in your current session) it
1669 it was used, regardless of how long ago (in your current session) it
1664 was.
1670 was.
1665
1671
1666 -x: do not execute the edited code immediately upon exit. This is
1672 -x: do not execute the edited code immediately upon exit. This is
1667 mainly useful if you are editing programs which need to be called with
1673 mainly useful if you are editing programs which need to be called with
1668 command line arguments, which you can then do using %run.
1674 command line arguments, which you can then do using %run.
1669
1675
1670 Arguments:
1676 Arguments:
1671
1677
1672 If arguments are given, the following possibilites exist:
1678 If arguments are given, the following possibilites exist:
1673
1679
1674 - The arguments are numbers or pairs of colon-separated numbers (like
1680 - The arguments are numbers or pairs of colon-separated numbers (like
1675 1 4:8 9). These are interpreted as lines of previous input to be
1681 1 4:8 9). These are interpreted as lines of previous input to be
1676 loaded into the editor. The syntax is the same of the %macro command.
1682 loaded into the editor. The syntax is the same of the %macro command.
1677
1683
1678 - If the argument doesn't start with a number, it is evaluated as a
1684 - If the argument doesn't start with a number, it is evaluated as a
1679 variable and its contents loaded into the editor. You can thus edit
1685 variable and its contents loaded into the editor. You can thus edit
1680 any string which contains python code (including the result of
1686 any string which contains python code (including the result of
1681 previous edits).
1687 previous edits).
1682
1688
1683 - If the argument is the name of an object (other than a string),
1689 - If the argument is the name of an object (other than a string),
1684 IPython will try to locate the file where it was defined and open the
1690 IPython will try to locate the file where it was defined and open the
1685 editor at the point where it is defined. You can use `%edit function`
1691 editor at the point where it is defined. You can use `%edit function`
1686 to load an editor exactly at the point where 'function' is defined,
1692 to load an editor exactly at the point where 'function' is defined,
1687 edit it and have the file be executed automatically.
1693 edit it and have the file be executed automatically.
1688
1694
1689 Note: opening at an exact line is only supported under Unix, and some
1695 Note: opening at an exact line is only supported under Unix, and some
1690 editors (like kedit and gedit up to Gnome 2.8) do not understand the
1696 editors (like kedit and gedit up to Gnome 2.8) do not understand the
1691 '+NUMBER' parameter necessary for this feature. Good editors like
1697 '+NUMBER' parameter necessary for this feature. Good editors like
1692 (X)Emacs, vi, jed, pico and joe all do.
1698 (X)Emacs, vi, jed, pico and joe all do.
1693
1699
1694 - If the argument is not found as a variable, IPython will look for a
1700 - If the argument is not found as a variable, IPython will look for a
1695 file with that name (adding .py if necessary) and load it into the
1701 file with that name (adding .py if necessary) and load it into the
1696 editor. It will execute its contents with execfile() when you exit,
1702 editor. It will execute its contents with execfile() when you exit,
1697 loading any code in the file into your interactive namespace.
1703 loading any code in the file into your interactive namespace.
1698
1704
1699 After executing your code, %edit will return as output the code you
1705 After executing your code, %edit will return as output the code you
1700 typed in the editor (except when it was an existing file). This way
1706 typed in the editor (except when it was an existing file). This way
1701 you can reload the code in further invocations of %edit as a variable,
1707 you can reload the code in further invocations of %edit as a variable,
1702 via _<NUMBER> or Out[<NUMBER>], where <NUMBER> is the prompt number of
1708 via _<NUMBER> or Out[<NUMBER>], where <NUMBER> is the prompt number of
1703 the output.
1709 the output.
1704
1710
1705 Note that %edit is also available through the alias %ed.
1711 Note that %edit is also available through the alias %ed.
1706
1712
1707 This is an example of creating a simple function inside the editor and
1713 This is an example of creating a simple function inside the editor and
1708 then modifying it. First, start up the editor:
1714 then modifying it. First, start up the editor:
1709
1715
1710 In [1]: ed\\
1716 In [1]: ed\\
1711 Editing... done. Executing edited code...\\
1717 Editing... done. Executing edited code...\\
1712 Out[1]: 'def foo():\\n print "foo() was defined in an editing session"\\n'
1718 Out[1]: 'def foo():\\n print "foo() was defined in an editing session"\\n'
1713
1719
1714 We can then call the function foo():
1720 We can then call the function foo():
1715
1721
1716 In [2]: foo()\\
1722 In [2]: foo()\\
1717 foo() was defined in an editing session
1723 foo() was defined in an editing session
1718
1724
1719 Now we edit foo. IPython automatically loads the editor with the
1725 Now we edit foo. IPython automatically loads the editor with the
1720 (temporary) file where foo() was previously defined:
1726 (temporary) file where foo() was previously defined:
1721
1727
1722 In [3]: ed foo\\
1728 In [3]: ed foo\\
1723 Editing... done. Executing edited code...
1729 Editing... done. Executing edited code...
1724
1730
1725 And if we call foo() again we get the modified version:
1731 And if we call foo() again we get the modified version:
1726
1732
1727 In [4]: foo()\\
1733 In [4]: foo()\\
1728 foo() has now been changed!
1734 foo() has now been changed!
1729
1735
1730 Here is an example of how to edit a code snippet successive
1736 Here is an example of how to edit a code snippet successive
1731 times. First we call the editor:
1737 times. First we call the editor:
1732
1738
1733 In [8]: ed\\
1739 In [8]: ed\\
1734 Editing... done. Executing edited code...\\
1740 Editing... done. Executing edited code...\\
1735 hello\\
1741 hello\\
1736 Out[8]: "print 'hello'\\n"
1742 Out[8]: "print 'hello'\\n"
1737
1743
1738 Now we call it again with the previous output (stored in _):
1744 Now we call it again with the previous output (stored in _):
1739
1745
1740 In [9]: ed _\\
1746 In [9]: ed _\\
1741 Editing... done. Executing edited code...\\
1747 Editing... done. Executing edited code...\\
1742 hello world\\
1748 hello world\\
1743 Out[9]: "print 'hello world'\\n"
1749 Out[9]: "print 'hello world'\\n"
1744
1750
1745 Now we call it with the output #8 (stored in _8, also as Out[8]):
1751 Now we call it with the output #8 (stored in _8, also as Out[8]):
1746
1752
1747 In [10]: ed _8\\
1753 In [10]: ed _8\\
1748 Editing... done. Executing edited code...\\
1754 Editing... done. Executing edited code...\\
1749 hello again\\
1755 hello again\\
1750 Out[10]: "print 'hello again'\\n"
1756 Out[10]: "print 'hello again'\\n"
1751
1757
1752
1758
1753 Changing the default editor hook:
1759 Changing the default editor hook:
1754
1760
1755 If you wish to write your own editor hook, you can put it in a
1761 If you wish to write your own editor hook, you can put it in a
1756 configuration file which you load at startup time. The default hook
1762 configuration file which you load at startup time. The default hook
1757 is defined in the IPython.hooks module, and you can use that as a
1763 is defined in the IPython.hooks module, and you can use that as a
1758 starting example for further modifications. That file also has
1764 starting example for further modifications. That file also has
1759 general instructions on how to set a new hook for use once you've
1765 general instructions on how to set a new hook for use once you've
1760 defined it."""
1766 defined it."""
1761
1767
1762 # FIXME: This function has become a convoluted mess. It needs a
1768 # FIXME: This function has become a convoluted mess. It needs a
1763 # ground-up rewrite with clean, simple logic.
1769 # ground-up rewrite with clean, simple logic.
1764
1770
1765 def make_filename(arg):
1771 def make_filename(arg):
1766 "Make a filename from the given args"
1772 "Make a filename from the given args"
1767 try:
1773 try:
1768 filename = get_py_filename(arg)
1774 filename = get_py_filename(arg)
1769 except IOError:
1775 except IOError:
1770 if args.endswith('.py'):
1776 if args.endswith('.py'):
1771 filename = arg
1777 filename = arg
1772 else:
1778 else:
1773 filename = None
1779 filename = None
1774 return filename
1780 return filename
1775
1781
1776 # custom exceptions
1782 # custom exceptions
1777 class DataIsObject(Exception): pass
1783 class DataIsObject(Exception): pass
1778
1784
1779 opts,args = self.parse_options(parameter_s,'px')
1785 opts,args = self.parse_options(parameter_s,'px')
1780
1786
1781 # Default line number value
1787 # Default line number value
1782 lineno = None
1788 lineno = None
1783 if opts.has_key('p'):
1789 if opts.has_key('p'):
1784 args = '_%s' % last_call[0]
1790 args = '_%s' % last_call[0]
1785 if not self.shell.user_ns.has_key(args):
1791 if not self.shell.user_ns.has_key(args):
1786 args = last_call[1]
1792 args = last_call[1]
1787
1793
1788 # use last_call to remember the state of the previous call, but don't
1794 # use last_call to remember the state of the previous call, but don't
1789 # let it be clobbered by successive '-p' calls.
1795 # let it be clobbered by successive '-p' calls.
1790 try:
1796 try:
1791 last_call[0] = self.shell.outputcache.prompt_count
1797 last_call[0] = self.shell.outputcache.prompt_count
1792 if not opts.has_key('p'):
1798 if not opts.has_key('p'):
1793 last_call[1] = parameter_s
1799 last_call[1] = parameter_s
1794 except:
1800 except:
1795 pass
1801 pass
1796
1802
1797 # by default this is done with temp files, except when the given
1803 # by default this is done with temp files, except when the given
1798 # arg is a filename
1804 # arg is a filename
1799 use_temp = 1
1805 use_temp = 1
1800
1806
1801 if re.match(r'\d',args):
1807 if re.match(r'\d',args):
1802 # Mode where user specifies ranges of lines, like in %macro.
1808 # Mode where user specifies ranges of lines, like in %macro.
1803 # This means that you can't edit files whose names begin with
1809 # This means that you can't edit files whose names begin with
1804 # numbers this way. Tough.
1810 # numbers this way. Tough.
1805 ranges = args.split()
1811 ranges = args.split()
1806 data = ''.join(self.extract_input_slices(ranges))
1812 data = ''.join(self.extract_input_slices(ranges))
1807 elif args.endswith('.py'):
1813 elif args.endswith('.py'):
1808 filename = make_filename(args)
1814 filename = make_filename(args)
1809 data = ''
1815 data = ''
1810 use_temp = 0
1816 use_temp = 0
1811 elif args:
1817 elif args:
1812 try:
1818 try:
1813 # Load the parameter given as a variable. If not a string,
1819 # Load the parameter given as a variable. If not a string,
1814 # process it as an object instead (below)
1820 # process it as an object instead (below)
1815
1821
1816 #print '*** args',args,'type',type(args) # dbg
1822 #print '*** args',args,'type',type(args) # dbg
1817 data = eval(args,self.shell.user_ns)
1823 data = eval(args,self.shell.user_ns)
1818 if not type(data) in StringTypes:
1824 if not type(data) in StringTypes:
1819 raise DataIsObject
1825 raise DataIsObject
1820 except (NameError,SyntaxError):
1826 except (NameError,SyntaxError):
1821 # given argument is not a variable, try as a filename
1827 # given argument is not a variable, try as a filename
1822 filename = make_filename(args)
1828 filename = make_filename(args)
1823 if filename is None:
1829 if filename is None:
1824 warn("Argument given (%s) can't be found as a variable "
1830 warn("Argument given (%s) can't be found as a variable "
1825 "or as a filename." % args)
1831 "or as a filename." % args)
1826 return
1832 return
1827 data = ''
1833 data = ''
1828 use_temp = 0
1834 use_temp = 0
1829 except DataIsObject:
1835 except DataIsObject:
1830 # For objects, try to edit the file where they are defined
1836 # For objects, try to edit the file where they are defined
1831 try:
1837 try:
1832 filename = inspect.getabsfile(data)
1838 filename = inspect.getabsfile(data)
1833 datafile = 1
1839 datafile = 1
1834 except TypeError:
1840 except TypeError:
1835 filename = make_filename(args)
1841 filename = make_filename(args)
1836 datafile = 1
1842 datafile = 1
1837 warn('Could not find file where `%s` is defined.\n'
1843 warn('Could not find file where `%s` is defined.\n'
1838 'Opening a file named `%s`' % (args,filename))
1844 'Opening a file named `%s`' % (args,filename))
1839 # Now, make sure we can actually read the source (if it was in
1845 # Now, make sure we can actually read the source (if it was in
1840 # a temp file it's gone by now).
1846 # a temp file it's gone by now).
1841 if datafile:
1847 if datafile:
1842 try:
1848 try:
1843 lineno = inspect.getsourcelines(data)[1]
1849 lineno = inspect.getsourcelines(data)[1]
1844 except IOError:
1850 except IOError:
1845 filename = make_filename(args)
1851 filename = make_filename(args)
1846 if filename is None:
1852 if filename is None:
1847 warn('The file `%s` where `%s` was defined cannot '
1853 warn('The file `%s` where `%s` was defined cannot '
1848 'be read.' % (filename,data))
1854 'be read.' % (filename,data))
1849 return
1855 return
1850 use_temp = 0
1856 use_temp = 0
1851 else:
1857 else:
1852 data = ''
1858 data = ''
1853
1859
1854 if use_temp:
1860 if use_temp:
1855 filename = tempfile.mktemp('.py')
1861 filename = tempfile.mktemp('.py')
1856 self.shell.tempfiles.append(filename)
1862 self.shell.tempfiles.append(filename)
1857
1863
1858 if data and use_temp:
1864 if data and use_temp:
1859 tmp_file = open(filename,'w')
1865 tmp_file = open(filename,'w')
1860 tmp_file.write(data)
1866 tmp_file.write(data)
1861 tmp_file.close()
1867 tmp_file.close()
1862
1868
1863 # do actual editing here
1869 # do actual editing here
1864 print 'Editing...',
1870 print 'Editing...',
1865 sys.stdout.flush()
1871 sys.stdout.flush()
1866 self.shell.hooks.editor(filename,lineno)
1872 self.shell.hooks.editor(filename,lineno)
1867 if opts.has_key('x'): # -x prevents actual execution
1873 if opts.has_key('x'): # -x prevents actual execution
1868 print
1874 print
1869 else:
1875 else:
1870 print 'done. Executing edited code...'
1876 print 'done. Executing edited code...'
1871 try:
1877 try:
1872 execfile(filename,self.shell.user_ns)
1878 execfile(filename,self.shell.user_ns)
1873 except IOError,msg:
1879 except IOError,msg:
1874 if msg.filename == filename:
1880 if msg.filename == filename:
1875 warn('File not found. Did you forget to save?')
1881 warn('File not found. Did you forget to save?')
1876 return
1882 return
1877 else:
1883 else:
1878 self.shell.showtraceback()
1884 self.shell.showtraceback()
1879 except:
1885 except:
1880 self.shell.showtraceback()
1886 self.shell.showtraceback()
1881 if use_temp:
1887 if use_temp:
1882 contents = open(filename).read()
1888 contents = open(filename).read()
1883 return contents
1889 return contents
1884
1890
1885 def magic_xmode(self,parameter_s = ''):
1891 def magic_xmode(self,parameter_s = ''):
1886 """Switch modes for the exception handlers.
1892 """Switch modes for the exception handlers.
1887
1893
1888 Valid modes: Plain, Context and Verbose.
1894 Valid modes: Plain, Context and Verbose.
1889
1895
1890 If called without arguments, acts as a toggle."""
1896 If called without arguments, acts as a toggle."""
1891
1897
1892 new_mode = parameter_s.strip().capitalize()
1898 new_mode = parameter_s.strip().capitalize()
1893 try:
1899 try:
1894 self.InteractiveTB.set_mode(mode = new_mode)
1900 self.InteractiveTB.set_mode(mode = new_mode)
1895 print 'Exception reporting mode:',self.InteractiveTB.mode
1901 print 'Exception reporting mode:',self.InteractiveTB.mode
1896 except:
1902 except:
1897 warn('Error changing exception modes.\n' + str(sys.exc_info()[1]))
1903 warn('Error changing exception modes.\n' + str(sys.exc_info()[1]))
1898
1904
1899 def magic_colors(self,parameter_s = ''):
1905 def magic_colors(self,parameter_s = ''):
1900 """Switch color scheme for prompts, info system and exception handlers.
1906 """Switch color scheme for prompts, info system and exception handlers.
1901
1907
1902 Currently implemented schemes: NoColor, Linux, LightBG.
1908 Currently implemented schemes: NoColor, Linux, LightBG.
1903
1909
1904 Color scheme names are not case-sensitive."""
1910 Color scheme names are not case-sensitive."""
1905
1911
1906 new_scheme = parameter_s.strip()
1912 new_scheme = parameter_s.strip()
1907 if not new_scheme:
1913 if not new_scheme:
1908 print 'You must specify a color scheme.'
1914 print 'You must specify a color scheme.'
1909 return
1915 return
1910 # Under Windows, check for Gary Bishop's readline, which is necessary
1916 # Under Windows, check for Gary Bishop's readline, which is necessary
1911 # for ANSI coloring
1917 # for ANSI coloring
1912 if os.name in ['nt','dos']:
1918 if os.name in ['nt','dos']:
1913 try:
1919 try:
1914 import readline
1920 import readline
1915 except ImportError:
1921 except ImportError:
1916 has_readline = 0
1922 has_readline = 0
1917 else:
1923 else:
1918 try:
1924 try:
1919 readline.GetOutputFile()
1925 readline.GetOutputFile()
1920 except AttributeError:
1926 except AttributeError:
1921 has_readline = 0
1927 has_readline = 0
1922 else:
1928 else:
1923 has_readline = 1
1929 has_readline = 1
1924 if not has_readline:
1930 if not has_readline:
1925 msg = """\
1931 msg = """\
1926 Proper color support under MS Windows requires Gary Bishop's readline library.
1932 Proper color support under MS Windows requires Gary Bishop's readline library.
1927 You can find it at:
1933 You can find it at:
1928 http://sourceforge.net/projects/uncpythontools
1934 http://sourceforge.net/projects/uncpythontools
1929 Gary's readline needs the ctypes module, from:
1935 Gary's readline needs the ctypes module, from:
1930 http://starship.python.net/crew/theller/ctypes
1936 http://starship.python.net/crew/theller/ctypes
1931
1937
1932 Defaulting color scheme to 'NoColor'"""
1938 Defaulting color scheme to 'NoColor'"""
1933 new_scheme = 'NoColor'
1939 new_scheme = 'NoColor'
1934 warn(msg)
1940 warn(msg)
1935
1941
1936 # Set prompt colors
1942 # Set prompt colors
1937 try:
1943 try:
1938 self.shell.outputcache.set_colors(new_scheme)
1944 self.shell.outputcache.set_colors(new_scheme)
1939 except:
1945 except:
1940 warn('Error changing prompt color schemes.\n'
1946 warn('Error changing prompt color schemes.\n'
1941 + str(sys.exc_info()[1]))
1947 + str(sys.exc_info()[1]))
1942 else:
1948 else:
1943 self.shell.rc.colors = \
1949 self.shell.rc.colors = \
1944 self.shell.outputcache.color_table.active_scheme_name
1950 self.shell.outputcache.color_table.active_scheme_name
1945 # Set exception colors
1951 # Set exception colors
1946 try:
1952 try:
1947 self.shell.InteractiveTB.set_colors(scheme = new_scheme)
1953 self.shell.InteractiveTB.set_colors(scheme = new_scheme)
1948 self.shell.SyntaxTB.set_colors(scheme = new_scheme)
1954 self.shell.SyntaxTB.set_colors(scheme = new_scheme)
1949 except:
1955 except:
1950 warn('Error changing exception color schemes.\n'
1956 warn('Error changing exception color schemes.\n'
1951 + str(sys.exc_info()[1]))
1957 + str(sys.exc_info()[1]))
1952 # Set info (for 'object?') colors
1958 # Set info (for 'object?') colors
1953 if self.shell.rc.color_info:
1959 if self.shell.rc.color_info:
1954 try:
1960 try:
1955 self.shell.inspector.set_active_scheme(new_scheme)
1961 self.shell.inspector.set_active_scheme(new_scheme)
1956 except:
1962 except:
1957 warn('Error changing object inspector color schemes.\n'
1963 warn('Error changing object inspector color schemes.\n'
1958 + str(sys.exc_info()[1]))
1964 + str(sys.exc_info()[1]))
1959 else:
1965 else:
1960 self.shell.inspector.set_active_scheme('NoColor')
1966 self.shell.inspector.set_active_scheme('NoColor')
1961
1967
1962 def magic_color_info(self,parameter_s = ''):
1968 def magic_color_info(self,parameter_s = ''):
1963 """Toggle color_info.
1969 """Toggle color_info.
1964
1970
1965 The color_info configuration parameter controls whether colors are
1971 The color_info configuration parameter controls whether colors are
1966 used for displaying object details (by things like %psource, %pfile or
1972 used for displaying object details (by things like %psource, %pfile or
1967 the '?' system). This function toggles this value with each call.
1973 the '?' system). This function toggles this value with each call.
1968
1974
1969 Note that unless you have a fairly recent pager (less works better
1975 Note that unless you have a fairly recent pager (less works better
1970 than more) in your system, using colored object information displays
1976 than more) in your system, using colored object information displays
1971 will not work properly. Test it and see."""
1977 will not work properly. Test it and see."""
1972
1978
1973 self.shell.rc.color_info = 1 - self.shell.rc.color_info
1979 self.shell.rc.color_info = 1 - self.shell.rc.color_info
1974 self.magic_colors(self.shell.rc.colors)
1980 self.magic_colors(self.shell.rc.colors)
1975 print 'Object introspection functions have now coloring:',
1981 print 'Object introspection functions have now coloring:',
1976 print ['OFF','ON'][self.shell.rc.color_info]
1982 print ['OFF','ON'][self.shell.rc.color_info]
1977
1983
1978 def magic_Pprint(self, parameter_s=''):
1984 def magic_Pprint(self, parameter_s=''):
1979 """Toggle pretty printing on/off."""
1985 """Toggle pretty printing on/off."""
1980
1986
1981 self.shell.outputcache.Pprint = 1 - self.shell.outputcache.Pprint
1987 self.shell.outputcache.Pprint = 1 - self.shell.outputcache.Pprint
1982 print 'Pretty printing has been turned', \
1988 print 'Pretty printing has been turned', \
1983 ['OFF','ON'][self.shell.outputcache.Pprint]
1989 ['OFF','ON'][self.shell.outputcache.Pprint]
1984
1990
1985 def magic_Exit(self, parameter_s=''):
1991 def magic_Exit(self, parameter_s=''):
1986 """Exit IPython without confirmation."""
1992 """Exit IPython without confirmation."""
1987
1993
1988 self.shell.exit_now = True
1994 self.shell.exit_now = True
1989
1995
1990 def magic_Quit(self, parameter_s=''):
1996 def magic_Quit(self, parameter_s=''):
1991 """Exit IPython without confirmation (like %Exit)."""
1997 """Exit IPython without confirmation (like %Exit)."""
1992
1998
1993 self.shell.exit_now = True
1999 self.shell.exit_now = True
1994
2000
1995 #......................................................................
2001 #......................................................................
1996 # Functions to implement unix shell-type things
2002 # Functions to implement unix shell-type things
1997
2003
1998 def magic_alias(self, parameter_s = ''):
2004 def magic_alias(self, parameter_s = ''):
1999 """Define an alias for a system command.
2005 """Define an alias for a system command.
2000
2006
2001 '%alias alias_name cmd' defines 'alias_name' as an alias for 'cmd'
2007 '%alias alias_name cmd' defines 'alias_name' as an alias for 'cmd'
2002
2008
2003 Then, typing 'alias_name params' will execute the system command 'cmd
2009 Then, typing 'alias_name params' will execute the system command 'cmd
2004 params' (from your underlying operating system).
2010 params' (from your underlying operating system).
2005
2011
2006 Aliases have lower precedence than magic functions and Python normal
2012 Aliases have lower precedence than magic functions and Python normal
2007 variables, so if 'foo' is both a Python variable and an alias, the
2013 variables, so if 'foo' is both a Python variable and an alias, the
2008 alias can not be executed until 'del foo' removes the Python variable.
2014 alias can not be executed until 'del foo' removes the Python variable.
2009
2015
2010 You can use the %l specifier in an alias definition to represent the
2016 You can use the %l specifier in an alias definition to represent the
2011 whole line when the alias is called. For example:
2017 whole line when the alias is called. For example:
2012
2018
2013 In [2]: alias all echo "Input in brackets: <%l>"\\
2019 In [2]: alias all echo "Input in brackets: <%l>"\\
2014 In [3]: all hello world\\
2020 In [3]: all hello world\\
2015 Input in brackets: <hello world>
2021 Input in brackets: <hello world>
2016
2022
2017 You can also define aliases with parameters using %s specifiers (one
2023 You can also define aliases with parameters using %s specifiers (one
2018 per parameter):
2024 per parameter):
2019
2025
2020 In [1]: alias parts echo first %s second %s\\
2026 In [1]: alias parts echo first %s second %s\\
2021 In [2]: %parts A B\\
2027 In [2]: %parts A B\\
2022 first A second B\\
2028 first A second B\\
2023 In [3]: %parts A\\
2029 In [3]: %parts A\\
2024 Incorrect number of arguments: 2 expected.\\
2030 Incorrect number of arguments: 2 expected.\\
2025 parts is an alias to: 'echo first %s second %s'
2031 parts is an alias to: 'echo first %s second %s'
2026
2032
2027 Note that %l and %s are mutually exclusive. You can only use one or
2033 Note that %l and %s are mutually exclusive. You can only use one or
2028 the other in your aliases.
2034 the other in your aliases.
2029
2035
2030 Aliases expand Python variables just like system calls using ! or !!
2036 Aliases expand Python variables just like system calls using ! or !!
2031 do: all expressions prefixed with '$' get expanded. For details of
2037 do: all expressions prefixed with '$' get expanded. For details of
2032 the semantic rules, see PEP-215:
2038 the semantic rules, see PEP-215:
2033 http://www.python.org/peps/pep-0215.html. This is the library used by
2039 http://www.python.org/peps/pep-0215.html. This is the library used by
2034 IPython for variable expansion. If you want to access a true shell
2040 IPython for variable expansion. If you want to access a true shell
2035 variable, an extra $ is necessary to prevent its expansion by IPython:
2041 variable, an extra $ is necessary to prevent its expansion by IPython:
2036
2042
2037 In [6]: alias show echo\\
2043 In [6]: alias show echo\\
2038 In [7]: PATH='A Python string'\\
2044 In [7]: PATH='A Python string'\\
2039 In [8]: show $PATH\\
2045 In [8]: show $PATH\\
2040 A Python string\\
2046 A Python string\\
2041 In [9]: show $$PATH\\
2047 In [9]: show $$PATH\\
2042 /usr/local/lf9560/bin:/usr/local/intel/compiler70/ia32/bin:...
2048 /usr/local/lf9560/bin:/usr/local/intel/compiler70/ia32/bin:...
2043
2049
2044 You can use the alias facility to acess all of $PATH. See the %rehash
2050 You can use the alias facility to acess all of $PATH. See the %rehash
2045 and %rehashx functions, which automatically create aliases for the
2051 and %rehashx functions, which automatically create aliases for the
2046 contents of your $PATH.
2052 contents of your $PATH.
2047
2053
2048 If called with no parameters, %alias prints the current alias table."""
2054 If called with no parameters, %alias prints the current alias table."""
2049
2055
2050 par = parameter_s.strip()
2056 par = parameter_s.strip()
2051 if not par:
2057 if not par:
2052 if self.shell.rc.automagic:
2058 if self.shell.rc.automagic:
2053 prechar = ''
2059 prechar = ''
2054 else:
2060 else:
2055 prechar = self.shell.ESC_MAGIC
2061 prechar = self.shell.ESC_MAGIC
2056 print 'Alias\t\tSystem Command\n'+'-'*30
2062 print 'Alias\t\tSystem Command\n'+'-'*30
2057 atab = self.shell.alias_table
2063 atab = self.shell.alias_table
2058 aliases = atab.keys()
2064 aliases = atab.keys()
2059 aliases.sort()
2065 aliases.sort()
2060 for alias in aliases:
2066 for alias in aliases:
2061 print prechar+alias+'\t\t'+atab[alias][1]
2067 print prechar+alias+'\t\t'+atab[alias][1]
2062 print '-'*30+'\nTotal number of aliases:',len(aliases)
2068 print '-'*30+'\nTotal number of aliases:',len(aliases)
2063 return
2069 return
2064 try:
2070 try:
2065 alias,cmd = par.split(None,1)
2071 alias,cmd = par.split(None,1)
2066 except:
2072 except:
2067 print OInspect.getdoc(self.magic_alias)
2073 print OInspect.getdoc(self.magic_alias)
2068 else:
2074 else:
2069 nargs = cmd.count('%s')
2075 nargs = cmd.count('%s')
2070 if nargs>0 and cmd.find('%l')>=0:
2076 if nargs>0 and cmd.find('%l')>=0:
2071 error('The %s and %l specifiers are mutually exclusive '
2077 error('The %s and %l specifiers are mutually exclusive '
2072 'in alias definitions.')
2078 'in alias definitions.')
2073 else: # all looks OK
2079 else: # all looks OK
2074 self.shell.alias_table[alias] = (nargs,cmd)
2080 self.shell.alias_table[alias] = (nargs,cmd)
2075 self.shell.alias_table_validate(verbose=1)
2081 self.shell.alias_table_validate(verbose=1)
2076 # end magic_alias
2082 # end magic_alias
2077
2083
2078 def magic_unalias(self, parameter_s = ''):
2084 def magic_unalias(self, parameter_s = ''):
2079 """Remove an alias"""
2085 """Remove an alias"""
2080
2086
2081 aname = parameter_s.strip()
2087 aname = parameter_s.strip()
2082 if aname in self.shell.alias_table:
2088 if aname in self.shell.alias_table:
2083 del self.shell.alias_table[aname]
2089 del self.shell.alias_table[aname]
2084
2090
2085 def magic_rehash(self, parameter_s = ''):
2091 def magic_rehash(self, parameter_s = ''):
2086 """Update the alias table with all entries in $PATH.
2092 """Update the alias table with all entries in $PATH.
2087
2093
2088 This version does no checks on execute permissions or whether the
2094 This version does no checks on execute permissions or whether the
2089 contents of $PATH are truly files (instead of directories or something
2095 contents of $PATH are truly files (instead of directories or something
2090 else). For such a safer (but slower) version, use %rehashx."""
2096 else). For such a safer (but slower) version, use %rehashx."""
2091
2097
2092 # This function (and rehashx) manipulate the alias_table directly
2098 # This function (and rehashx) manipulate the alias_table directly
2093 # rather than calling magic_alias, for speed reasons. A rehash on a
2099 # rather than calling magic_alias, for speed reasons. A rehash on a
2094 # typical Linux box involves several thousand entries, so efficiency
2100 # typical Linux box involves several thousand entries, so efficiency
2095 # here is a top concern.
2101 # here is a top concern.
2096
2102
2097 path = filter(os.path.isdir,os.environ['PATH'].split(os.pathsep))
2103 path = filter(os.path.isdir,os.environ['PATH'].split(os.pathsep))
2098 alias_table = self.shell.alias_table
2104 alias_table = self.shell.alias_table
2099 for pdir in path:
2105 for pdir in path:
2100 for ff in os.listdir(pdir):
2106 for ff in os.listdir(pdir):
2101 # each entry in the alias table must be (N,name), where
2107 # each entry in the alias table must be (N,name), where
2102 # N is the number of positional arguments of the alias.
2108 # N is the number of positional arguments of the alias.
2103 alias_table[ff] = (0,ff)
2109 alias_table[ff] = (0,ff)
2104 # Make sure the alias table doesn't contain keywords or builtins
2110 # Make sure the alias table doesn't contain keywords or builtins
2105 self.shell.alias_table_validate()
2111 self.shell.alias_table_validate()
2106 # Call again init_auto_alias() so we get 'rm -i' and other modified
2112 # Call again init_auto_alias() so we get 'rm -i' and other modified
2107 # aliases since %rehash will probably clobber them
2113 # aliases since %rehash will probably clobber them
2108 self.shell.init_auto_alias()
2114 self.shell.init_auto_alias()
2109
2115
2110 def magic_rehashx(self, parameter_s = ''):
2116 def magic_rehashx(self, parameter_s = ''):
2111 """Update the alias table with all executable files in $PATH.
2117 """Update the alias table with all executable files in $PATH.
2112
2118
2113 This version explicitly checks that every entry in $PATH is a file
2119 This version explicitly checks that every entry in $PATH is a file
2114 with execute access (os.X_OK), so it is much slower than %rehash.
2120 with execute access (os.X_OK), so it is much slower than %rehash.
2115
2121
2116 Under Windows, it checks executability as a match agains a
2122 Under Windows, it checks executability as a match agains a
2117 '|'-separated string of extensions, stored in the IPython config
2123 '|'-separated string of extensions, stored in the IPython config
2118 variable win_exec_ext. This defaults to 'exe|com|bat'. """
2124 variable win_exec_ext. This defaults to 'exe|com|bat'. """
2119
2125
2120 path = filter(os.path.isdir,os.environ['PATH'].split(os.pathsep))
2126 path = filter(os.path.isdir,os.environ['PATH'].split(os.pathsep))
2121 alias_table = self.shell.alias_table
2127 alias_table = self.shell.alias_table
2122
2128
2123 if os.name == 'posix':
2129 if os.name == 'posix':
2124 isexec = lambda fname:os.path.isfile(fname) and \
2130 isexec = lambda fname:os.path.isfile(fname) and \
2125 os.access(fname,os.X_OK)
2131 os.access(fname,os.X_OK)
2126 else:
2132 else:
2127
2133
2128 try:
2134 try:
2129 winext = os.environ['pathext'].replace(';','|').replace('.','')
2135 winext = os.environ['pathext'].replace(';','|').replace('.','')
2130 except KeyError:
2136 except KeyError:
2131 winext = 'exe|com|bat'
2137 winext = 'exe|com|bat'
2132
2138
2133 execre = re.compile(r'(.*)\.(%s)$' % winext,re.IGNORECASE)
2139 execre = re.compile(r'(.*)\.(%s)$' % winext,re.IGNORECASE)
2134 isexec = lambda fname:os.path.isfile(fname) and execre.match(fname)
2140 isexec = lambda fname:os.path.isfile(fname) and execre.match(fname)
2135 savedir = os.getcwd()
2141 savedir = os.getcwd()
2136 try:
2142 try:
2137 # write the whole loop for posix/Windows so we don't have an if in
2143 # write the whole loop for posix/Windows so we don't have an if in
2138 # the innermost part
2144 # the innermost part
2139 if os.name == 'posix':
2145 if os.name == 'posix':
2140 for pdir in path:
2146 for pdir in path:
2141 os.chdir(pdir)
2147 os.chdir(pdir)
2142 for ff in os.listdir(pdir):
2148 for ff in os.listdir(pdir):
2143 if isexec(ff):
2149 if isexec(ff):
2144 # each entry in the alias table must be (N,name),
2150 # each entry in the alias table must be (N,name),
2145 # where N is the number of positional arguments of the
2151 # where N is the number of positional arguments of the
2146 # alias.
2152 # alias.
2147 alias_table[ff] = (0,ff)
2153 alias_table[ff] = (0,ff)
2148 else:
2154 else:
2149 for pdir in path:
2155 for pdir in path:
2150 os.chdir(pdir)
2156 os.chdir(pdir)
2151 for ff in os.listdir(pdir):
2157 for ff in os.listdir(pdir):
2152 if isexec(ff):
2158 if isexec(ff):
2153 alias_table[execre.sub(r'\1',ff)] = (0,ff)
2159 alias_table[execre.sub(r'\1',ff)] = (0,ff)
2154 # Make sure the alias table doesn't contain keywords or builtins
2160 # Make sure the alias table doesn't contain keywords or builtins
2155 self.shell.alias_table_validate()
2161 self.shell.alias_table_validate()
2156 # Call again init_auto_alias() so we get 'rm -i' and other
2162 # Call again init_auto_alias() so we get 'rm -i' and other
2157 # modified aliases since %rehashx will probably clobber them
2163 # modified aliases since %rehashx will probably clobber them
2158 self.shell.init_auto_alias()
2164 self.shell.init_auto_alias()
2159 finally:
2165 finally:
2160 os.chdir(savedir)
2166 os.chdir(savedir)
2161
2167
2162 def magic_pwd(self, parameter_s = ''):
2168 def magic_pwd(self, parameter_s = ''):
2163 """Return the current working directory path."""
2169 """Return the current working directory path."""
2164 return os.getcwd()
2170 return os.getcwd()
2165
2171
2166 def magic_cd(self, parameter_s=''):
2172 def magic_cd(self, parameter_s=''):
2167 """Change the current working directory.
2173 """Change the current working directory.
2168
2174
2169 This command automatically maintains an internal list of directories
2175 This command automatically maintains an internal list of directories
2170 you visit during your IPython session, in the variable _dh. The
2176 you visit during your IPython session, in the variable _dh. The
2171 command %dhist shows this history nicely formatted.
2177 command %dhist shows this history nicely formatted.
2172
2178
2173 Usage:
2179 Usage:
2174
2180
2175 cd 'dir': changes to directory 'dir'.
2181 cd 'dir': changes to directory 'dir'.
2176
2182
2177 cd -: changes to the last visited directory.
2183 cd -: changes to the last visited directory.
2178
2184
2179 cd -<n>: changes to the n-th directory in the directory history.
2185 cd -<n>: changes to the n-th directory in the directory history.
2180
2186
2181 cd -b <bookmark_name>: jump to a bookmark set by %bookmark
2187 cd -b <bookmark_name>: jump to a bookmark set by %bookmark
2182 (note: cd <bookmark_name> is enough if there is no
2188 (note: cd <bookmark_name> is enough if there is no
2183 directory <bookmark_name>, but a bookmark with the name exists.)
2189 directory <bookmark_name>, but a bookmark with the name exists.)
2184
2190
2185 Options:
2191 Options:
2186
2192
2187 -q: quiet. Do not print the working directory after the cd command is
2193 -q: quiet. Do not print the working directory after the cd command is
2188 executed. By default IPython's cd command does print this directory,
2194 executed. By default IPython's cd command does print this directory,
2189 since the default prompts do not display path information.
2195 since the default prompts do not display path information.
2190
2196
2191 Note that !cd doesn't work for this purpose because the shell where
2197 Note that !cd doesn't work for this purpose because the shell where
2192 !command runs is immediately discarded after executing 'command'."""
2198 !command runs is immediately discarded after executing 'command'."""
2193
2199
2194 parameter_s = parameter_s.strip()
2200 parameter_s = parameter_s.strip()
2195 bkms = self.shell.persist.get("bookmarks",{})
2201 bkms = self.shell.persist.get("bookmarks",{})
2196
2202
2197 numcd = re.match(r'(-)(\d+)$',parameter_s)
2203 numcd = re.match(r'(-)(\d+)$',parameter_s)
2198 # jump in directory history by number
2204 # jump in directory history by number
2199 if numcd:
2205 if numcd:
2200 nn = int(numcd.group(2))
2206 nn = int(numcd.group(2))
2201 try:
2207 try:
2202 ps = self.shell.user_ns['_dh'][nn]
2208 ps = self.shell.user_ns['_dh'][nn]
2203 except IndexError:
2209 except IndexError:
2204 print 'The requested directory does not exist in history.'
2210 print 'The requested directory does not exist in history.'
2205 return
2211 return
2206 else:
2212 else:
2207 opts = {}
2213 opts = {}
2208 else:
2214 else:
2209 opts,ps = self.parse_options(parameter_s,'qb',mode='string')
2215 opts,ps = self.parse_options(parameter_s,'qb',mode='string')
2210 # jump to previous
2216 # jump to previous
2211 if ps == '-':
2217 if ps == '-':
2212 try:
2218 try:
2213 ps = self.shell.user_ns['_dh'][-2]
2219 ps = self.shell.user_ns['_dh'][-2]
2214 except IndexError:
2220 except IndexError:
2215 print 'No previous directory to change to.'
2221 print 'No previous directory to change to.'
2216 return
2222 return
2217 # jump to bookmark
2223 # jump to bookmark
2218 elif opts.has_key('b') or (bkms.has_key(ps) and not os.path.isdir(ps)):
2224 elif opts.has_key('b') or (bkms.has_key(ps) and not os.path.isdir(ps)):
2219 if bkms.has_key(ps):
2225 if bkms.has_key(ps):
2220 target = bkms[ps]
2226 target = bkms[ps]
2221 print '(bookmark:%s) -> %s' % (ps,target)
2227 print '(bookmark:%s) -> %s' % (ps,target)
2222 ps = target
2228 ps = target
2223 else:
2229 else:
2224 if bkms:
2230 if bkms:
2225 error("Bookmark '%s' not found. "
2231 error("Bookmark '%s' not found. "
2226 "Use '%bookmark -l' to see your bookmarks." % ps)
2232 "Use '%bookmark -l' to see your bookmarks." % ps)
2227 else:
2233 else:
2228 print "Bookmarks not set - use %bookmark <bookmarkname>"
2234 print "Bookmarks not set - use %bookmark <bookmarkname>"
2229 return
2235 return
2230
2236
2231 # at this point ps should point to the target dir
2237 # at this point ps should point to the target dir
2232 if ps:
2238 if ps:
2233 try:
2239 try:
2234 os.chdir(os.path.expanduser(ps))
2240 os.chdir(os.path.expanduser(ps))
2235 except OSError:
2241 except OSError:
2236 print sys.exc_info()[1]
2242 print sys.exc_info()[1]
2237 else:
2243 else:
2238 self.shell.user_ns['_dh'].append(os.getcwd())
2244 self.shell.user_ns['_dh'].append(os.getcwd())
2239 else:
2245 else:
2240 os.chdir(self.home_dir)
2246 os.chdir(self.home_dir)
2241 self.shell.user_ns['_dh'].append(os.getcwd())
2247 self.shell.user_ns['_dh'].append(os.getcwd())
2242 if not 'q' in opts:
2248 if not 'q' in opts:
2243 print self.shell.user_ns['_dh'][-1]
2249 print self.shell.user_ns['_dh'][-1]
2244
2250
2245 def magic_dhist(self, parameter_s=''):
2251 def magic_dhist(self, parameter_s=''):
2246 """Print your history of visited directories.
2252 """Print your history of visited directories.
2247
2253
2248 %dhist -> print full history\\
2254 %dhist -> print full history\\
2249 %dhist n -> print last n entries only\\
2255 %dhist n -> print last n entries only\\
2250 %dhist n1 n2 -> print entries between n1 and n2 (n1 not included)\\
2256 %dhist n1 n2 -> print entries between n1 and n2 (n1 not included)\\
2251
2257
2252 This history is automatically maintained by the %cd command, and
2258 This history is automatically maintained by the %cd command, and
2253 always available as the global list variable _dh. You can use %cd -<n>
2259 always available as the global list variable _dh. You can use %cd -<n>
2254 to go to directory number <n>."""
2260 to go to directory number <n>."""
2255
2261
2256 dh = self.shell.user_ns['_dh']
2262 dh = self.shell.user_ns['_dh']
2257 if parameter_s:
2263 if parameter_s:
2258 try:
2264 try:
2259 args = map(int,parameter_s.split())
2265 args = map(int,parameter_s.split())
2260 except:
2266 except:
2261 self.arg_err(Magic.magic_dhist)
2267 self.arg_err(Magic.magic_dhist)
2262 return
2268 return
2263 if len(args) == 1:
2269 if len(args) == 1:
2264 ini,fin = max(len(dh)-(args[0]),0),len(dh)
2270 ini,fin = max(len(dh)-(args[0]),0),len(dh)
2265 elif len(args) == 2:
2271 elif len(args) == 2:
2266 ini,fin = args
2272 ini,fin = args
2267 else:
2273 else:
2268 self.arg_err(Magic.magic_dhist)
2274 self.arg_err(Magic.magic_dhist)
2269 return
2275 return
2270 else:
2276 else:
2271 ini,fin = 0,len(dh)
2277 ini,fin = 0,len(dh)
2272 nlprint(dh,
2278 nlprint(dh,
2273 header = 'Directory history (kept in _dh)',
2279 header = 'Directory history (kept in _dh)',
2274 start=ini,stop=fin)
2280 start=ini,stop=fin)
2275
2281
2276 def magic_env(self, parameter_s=''):
2282 def magic_env(self, parameter_s=''):
2277 """List environment variables."""
2283 """List environment variables."""
2278
2284
2279 # environ is an instance of UserDict
2285 # environ is an instance of UserDict
2280 return os.environ.data
2286 return os.environ.data
2281
2287
2282 def magic_pushd(self, parameter_s=''):
2288 def magic_pushd(self, parameter_s=''):
2283 """Place the current dir on stack and change directory.
2289 """Place the current dir on stack and change directory.
2284
2290
2285 Usage:\\
2291 Usage:\\
2286 %pushd ['dirname']
2292 %pushd ['dirname']
2287
2293
2288 %pushd with no arguments does a %pushd to your home directory.
2294 %pushd with no arguments does a %pushd to your home directory.
2289 """
2295 """
2290 if parameter_s == '': parameter_s = '~'
2296 if parameter_s == '': parameter_s = '~'
2291 if len(self.dir_stack)>0 and os.path.expanduser(parameter_s) != \
2297 if len(self.dir_stack)>0 and os.path.expanduser(parameter_s) != \
2292 os.path.expanduser(self.dir_stack[0]):
2298 os.path.expanduser(self.dir_stack[0]):
2293 try:
2299 try:
2294 self.magic_cd(parameter_s)
2300 self.magic_cd(parameter_s)
2295 self.dir_stack.insert(0,os.getcwd().replace(self.home_dir,'~'))
2301 self.dir_stack.insert(0,os.getcwd().replace(self.home_dir,'~'))
2296 self.magic_dirs()
2302 self.magic_dirs()
2297 except:
2303 except:
2298 print 'Invalid directory'
2304 print 'Invalid directory'
2299 else:
2305 else:
2300 print 'You are already there!'
2306 print 'You are already there!'
2301
2307
2302 def magic_popd(self, parameter_s=''):
2308 def magic_popd(self, parameter_s=''):
2303 """Change to directory popped off the top of the stack.
2309 """Change to directory popped off the top of the stack.
2304 """
2310 """
2305 if len (self.dir_stack) > 1:
2311 if len (self.dir_stack) > 1:
2306 self.dir_stack.pop(0)
2312 self.dir_stack.pop(0)
2307 self.magic_cd(self.dir_stack[0])
2313 self.magic_cd(self.dir_stack[0])
2308 print self.dir_stack[0]
2314 print self.dir_stack[0]
2309 else:
2315 else:
2310 print "You can't remove the starting directory from the stack:",\
2316 print "You can't remove the starting directory from the stack:",\
2311 self.dir_stack
2317 self.dir_stack
2312
2318
2313 def magic_dirs(self, parameter_s=''):
2319 def magic_dirs(self, parameter_s=''):
2314 """Return the current directory stack."""
2320 """Return the current directory stack."""
2315
2321
2316 return self.dir_stack[:]
2322 return self.dir_stack[:]
2317
2323
2318 def magic_sc(self, parameter_s=''):
2324 def magic_sc(self, parameter_s=''):
2319 """Shell capture - execute a shell command and capture its output.
2325 """Shell capture - execute a shell command and capture its output.
2320
2326
2321 %sc [options] varname=command
2327 %sc [options] varname=command
2322
2328
2323 IPython will run the given command using commands.getoutput(), and
2329 IPython will run the given command using commands.getoutput(), and
2324 will then update the user's interactive namespace with a variable
2330 will then update the user's interactive namespace with a variable
2325 called varname, containing the value of the call. Your command can
2331 called varname, containing the value of the call. Your command can
2326 contain shell wildcards, pipes, etc.
2332 contain shell wildcards, pipes, etc.
2327
2333
2328 The '=' sign in the syntax is mandatory, and the variable name you
2334 The '=' sign in the syntax is mandatory, and the variable name you
2329 supply must follow Python's standard conventions for valid names.
2335 supply must follow Python's standard conventions for valid names.
2330
2336
2331 Options:
2337 Options:
2332
2338
2333 -l: list output. Split the output on newlines into a list before
2339 -l: list output. Split the output on newlines into a list before
2334 assigning it to the given variable. By default the output is stored
2340 assigning it to the given variable. By default the output is stored
2335 as a single string.
2341 as a single string.
2336
2342
2337 -v: verbose. Print the contents of the variable.
2343 -v: verbose. Print the contents of the variable.
2338
2344
2339 In most cases you should not need to split as a list, because the
2345 In most cases you should not need to split as a list, because the
2340 returned value is a special type of string which can automatically
2346 returned value is a special type of string which can automatically
2341 provide its contents either as a list (split on newlines) or as a
2347 provide its contents either as a list (split on newlines) or as a
2342 space-separated string. These are convenient, respectively, either
2348 space-separated string. These are convenient, respectively, either
2343 for sequential processing or to be passed to a shell command.
2349 for sequential processing or to be passed to a shell command.
2344
2350
2345 For example:
2351 For example:
2346
2352
2347 # Capture into variable a
2353 # Capture into variable a
2348 In [9]: sc a=ls *py
2354 In [9]: sc a=ls *py
2349
2355
2350 # a is a string with embedded newlines
2356 # a is a string with embedded newlines
2351 In [10]: a
2357 In [10]: a
2352 Out[10]: 'setup.py\nwin32_manual_post_install.py'
2358 Out[10]: 'setup.py\nwin32_manual_post_install.py'
2353
2359
2354 # which can be seen as a list:
2360 # which can be seen as a list:
2355 In [11]: a.l
2361 In [11]: a.l
2356 Out[11]: ['setup.py', 'win32_manual_post_install.py']
2362 Out[11]: ['setup.py', 'win32_manual_post_install.py']
2357
2363
2358 # or as a whitespace-separated string:
2364 # or as a whitespace-separated string:
2359 In [12]: a.s
2365 In [12]: a.s
2360 Out[12]: 'setup.py win32_manual_post_install.py'
2366 Out[12]: 'setup.py win32_manual_post_install.py'
2361
2367
2362 # a.s is useful to pass as a single command line:
2368 # a.s is useful to pass as a single command line:
2363 In [13]: !wc -l $a.s
2369 In [13]: !wc -l $a.s
2364 146 setup.py
2370 146 setup.py
2365 130 win32_manual_post_install.py
2371 130 win32_manual_post_install.py
2366 276 total
2372 276 total
2367
2373
2368 # while the list form is useful to loop over:
2374 # while the list form is useful to loop over:
2369 In [14]: for f in a.l:
2375 In [14]: for f in a.l:
2370 ....: !wc -l $f
2376 ....: !wc -l $f
2371 ....:
2377 ....:
2372 146 setup.py
2378 146 setup.py
2373 130 win32_manual_post_install.py
2379 130 win32_manual_post_install.py
2374
2380
2375 Similiarly, the lists returned by the -l option are also special, in
2381 Similiarly, the lists returned by the -l option are also special, in
2376 the sense that you can equally invoke the .s attribute on them to
2382 the sense that you can equally invoke the .s attribute on them to
2377 automatically get a whitespace-separated string from their contents:
2383 automatically get a whitespace-separated string from their contents:
2378
2384
2379 In [1]: sc -l b=ls *py
2385 In [1]: sc -l b=ls *py
2380
2386
2381 In [2]: b
2387 In [2]: b
2382 Out[2]: ['setup.py', 'win32_manual_post_install.py']
2388 Out[2]: ['setup.py', 'win32_manual_post_install.py']
2383
2389
2384 In [3]: b.s
2390 In [3]: b.s
2385 Out[3]: 'setup.py win32_manual_post_install.py'
2391 Out[3]: 'setup.py win32_manual_post_install.py'
2386
2392
2387 In summary, both the lists and strings used for ouptut capture have
2393 In summary, both the lists and strings used for ouptut capture have
2388 the following special attributes:
2394 the following special attributes:
2389
2395
2390 .l (or .list) : value as list.
2396 .l (or .list) : value as list.
2391 .n (or .nlstr): value as newline-separated string.
2397 .n (or .nlstr): value as newline-separated string.
2392 .s (or .spstr): value as space-separated string.
2398 .s (or .spstr): value as space-separated string.
2393 """
2399 """
2394
2400
2395 opts,args = self.parse_options(parameter_s,'lv')
2401 opts,args = self.parse_options(parameter_s,'lv')
2396 # Try to get a variable name and command to run
2402 # Try to get a variable name and command to run
2397 try:
2403 try:
2398 # the variable name must be obtained from the parse_options
2404 # the variable name must be obtained from the parse_options
2399 # output, which uses shlex.split to strip options out.
2405 # output, which uses shlex.split to strip options out.
2400 var,_ = args.split('=',1)
2406 var,_ = args.split('=',1)
2401 var = var.strip()
2407 var = var.strip()
2402 # But the the command has to be extracted from the original input
2408 # But the the command has to be extracted from the original input
2403 # parameter_s, not on what parse_options returns, to avoid the
2409 # parameter_s, not on what parse_options returns, to avoid the
2404 # quote stripping which shlex.split performs on it.
2410 # quote stripping which shlex.split performs on it.
2405 _,cmd = parameter_s.split('=',1)
2411 _,cmd = parameter_s.split('=',1)
2406 except ValueError:
2412 except ValueError:
2407 var,cmd = '',''
2413 var,cmd = '',''
2408 if not var:
2414 if not var:
2409 error('you must specify a variable to assign the command to.')
2415 error('you must specify a variable to assign the command to.')
2410 return
2416 return
2411 # If all looks ok, proceed
2417 # If all looks ok, proceed
2412 out,err = self.shell.getoutputerror(cmd)
2418 out,err = self.shell.getoutputerror(cmd)
2413 if err:
2419 if err:
2414 print >> Term.cerr,err
2420 print >> Term.cerr,err
2415 if opts.has_key('l'):
2421 if opts.has_key('l'):
2416 out = SList(out.split('\n'))
2422 out = SList(out.split('\n'))
2417 else:
2423 else:
2418 out = LSString(out)
2424 out = LSString(out)
2419 if opts.has_key('v'):
2425 if opts.has_key('v'):
2420 print '%s ==\n%s' % (var,pformat(out))
2426 print '%s ==\n%s' % (var,pformat(out))
2421 self.shell.user_ns.update({var:out})
2427 self.shell.user_ns.update({var:out})
2422
2428
2423 def magic_sx(self, parameter_s=''):
2429 def magic_sx(self, parameter_s=''):
2424 """Shell execute - run a shell command and capture its output.
2430 """Shell execute - run a shell command and capture its output.
2425
2431
2426 %sx command
2432 %sx command
2427
2433
2428 IPython will run the given command using commands.getoutput(), and
2434 IPython will run the given command using commands.getoutput(), and
2429 return the result formatted as a list (split on '\\n'). Since the
2435 return the result formatted as a list (split on '\\n'). Since the
2430 output is _returned_, it will be stored in ipython's regular output
2436 output is _returned_, it will be stored in ipython's regular output
2431 cache Out[N] and in the '_N' automatic variables.
2437 cache Out[N] and in the '_N' automatic variables.
2432
2438
2433 Notes:
2439 Notes:
2434
2440
2435 1) If an input line begins with '!!', then %sx is automatically
2441 1) If an input line begins with '!!', then %sx is automatically
2436 invoked. That is, while:
2442 invoked. That is, while:
2437 !ls
2443 !ls
2438 causes ipython to simply issue system('ls'), typing
2444 causes ipython to simply issue system('ls'), typing
2439 !!ls
2445 !!ls
2440 is a shorthand equivalent to:
2446 is a shorthand equivalent to:
2441 %sx ls
2447 %sx ls
2442
2448
2443 2) %sx differs from %sc in that %sx automatically splits into a list,
2449 2) %sx differs from %sc in that %sx automatically splits into a list,
2444 like '%sc -l'. The reason for this is to make it as easy as possible
2450 like '%sc -l'. The reason for this is to make it as easy as possible
2445 to process line-oriented shell output via further python commands.
2451 to process line-oriented shell output via further python commands.
2446 %sc is meant to provide much finer control, but requires more
2452 %sc is meant to provide much finer control, but requires more
2447 typing.
2453 typing.
2448
2454
2449 3) Just like %sc -l, this is a list with special attributes:
2455 3) Just like %sc -l, this is a list with special attributes:
2450
2456
2451 .l (or .list) : value as list.
2457 .l (or .list) : value as list.
2452 .n (or .nlstr): value as newline-separated string.
2458 .n (or .nlstr): value as newline-separated string.
2453 .s (or .spstr): value as whitespace-separated string.
2459 .s (or .spstr): value as whitespace-separated string.
2454
2460
2455 This is very useful when trying to use such lists as arguments to
2461 This is very useful when trying to use such lists as arguments to
2456 system commands."""
2462 system commands."""
2457
2463
2458 if parameter_s:
2464 if parameter_s:
2459 out,err = self.shell.getoutputerror(parameter_s)
2465 out,err = self.shell.getoutputerror(parameter_s)
2460 if err:
2466 if err:
2461 print >> Term.cerr,err
2467 print >> Term.cerr,err
2462 return SList(out.split('\n'))
2468 return SList(out.split('\n'))
2463
2469
2464 def magic_bg(self, parameter_s=''):
2470 def magic_bg(self, parameter_s=''):
2465 """Run a job in the background, in a separate thread.
2471 """Run a job in the background, in a separate thread.
2466
2472
2467 For example,
2473 For example,
2468
2474
2469 %bg myfunc(x,y,z=1)
2475 %bg myfunc(x,y,z=1)
2470
2476
2471 will execute 'myfunc(x,y,z=1)' in a background thread. As soon as the
2477 will execute 'myfunc(x,y,z=1)' in a background thread. As soon as the
2472 execution starts, a message will be printed indicating the job
2478 execution starts, a message will be printed indicating the job
2473 number. If your job number is 5, you can use
2479 number. If your job number is 5, you can use
2474
2480
2475 myvar = jobs.result(5) or myvar = jobs[5].result
2481 myvar = jobs.result(5) or myvar = jobs[5].result
2476
2482
2477 to assign this result to variable 'myvar'.
2483 to assign this result to variable 'myvar'.
2478
2484
2479 IPython has a job manager, accessible via the 'jobs' object. You can
2485 IPython has a job manager, accessible via the 'jobs' object. You can
2480 type jobs? to get more information about it, and use jobs.<TAB> to see
2486 type jobs? to get more information about it, and use jobs.<TAB> to see
2481 its attributes. All attributes not starting with an underscore are
2487 its attributes. All attributes not starting with an underscore are
2482 meant for public use.
2488 meant for public use.
2483
2489
2484 In particular, look at the jobs.new() method, which is used to create
2490 In particular, look at the jobs.new() method, which is used to create
2485 new jobs. This magic %bg function is just a convenience wrapper
2491 new jobs. This magic %bg function is just a convenience wrapper
2486 around jobs.new(), for expression-based jobs. If you want to create a
2492 around jobs.new(), for expression-based jobs. If you want to create a
2487 new job with an explicit function object and arguments, you must call
2493 new job with an explicit function object and arguments, you must call
2488 jobs.new() directly.
2494 jobs.new() directly.
2489
2495
2490 The jobs.new docstring also describes in detail several important
2496 The jobs.new docstring also describes in detail several important
2491 caveats associated with a thread-based model for background job
2497 caveats associated with a thread-based model for background job
2492 execution. Type jobs.new? for details.
2498 execution. Type jobs.new? for details.
2493
2499
2494 You can check the status of all jobs with jobs.status().
2500 You can check the status of all jobs with jobs.status().
2495
2501
2496 The jobs variable is set by IPython into the Python builtin namespace.
2502 The jobs variable is set by IPython into the Python builtin namespace.
2497 If you ever declare a variable named 'jobs', you will shadow this
2503 If you ever declare a variable named 'jobs', you will shadow this
2498 name. You can either delete your global jobs variable to regain
2504 name. You can either delete your global jobs variable to regain
2499 access to the job manager, or make a new name and assign it manually
2505 access to the job manager, or make a new name and assign it manually
2500 to the manager (stored in IPython's namespace). For example, to
2506 to the manager (stored in IPython's namespace). For example, to
2501 assign the job manager to the Jobs name, use:
2507 assign the job manager to the Jobs name, use:
2502
2508
2503 Jobs = __builtins__.jobs"""
2509 Jobs = __builtins__.jobs"""
2504
2510
2505 self.shell.jobs.new(parameter_s,self.shell.user_ns)
2511 self.shell.jobs.new(parameter_s,self.shell.user_ns)
2506
2512
2507 def magic_bookmark(self, parameter_s=''):
2513 def magic_bookmark(self, parameter_s=''):
2508 """Manage IPython's bookmark system.
2514 """Manage IPython's bookmark system.
2509
2515
2510 %bookmark <name> - set bookmark to current dir
2516 %bookmark <name> - set bookmark to current dir
2511 %bookmark <name> <dir> - set bookmark to <dir>
2517 %bookmark <name> <dir> - set bookmark to <dir>
2512 %bookmark -l - list all bookmarks
2518 %bookmark -l - list all bookmarks
2513 %bookmark -d <name> - remove bookmark
2519 %bookmark -d <name> - remove bookmark
2514 %bookmark -r - remove all bookmarks
2520 %bookmark -r - remove all bookmarks
2515
2521
2516 You can later on access a bookmarked folder with:
2522 You can later on access a bookmarked folder with:
2517 %cd -b <name>
2523 %cd -b <name>
2518 or simply '%cd <name>' if there is no directory called <name> AND
2524 or simply '%cd <name>' if there is no directory called <name> AND
2519 there is such a bookmark defined.
2525 there is such a bookmark defined.
2520
2526
2521 Your bookmarks persist through IPython sessions, but they are
2527 Your bookmarks persist through IPython sessions, but they are
2522 associated with each profile."""
2528 associated with each profile."""
2523
2529
2524 opts,args = self.parse_options(parameter_s,'drl',mode='list')
2530 opts,args = self.parse_options(parameter_s,'drl',mode='list')
2525 if len(args) > 2:
2531 if len(args) > 2:
2526 error('You can only give at most two arguments')
2532 error('You can only give at most two arguments')
2527 return
2533 return
2528
2534
2529 bkms = self.shell.persist.get('bookmarks',{})
2535 bkms = self.shell.persist.get('bookmarks',{})
2530
2536
2531 if opts.has_key('d'):
2537 if opts.has_key('d'):
2532 try:
2538 try:
2533 todel = args[0]
2539 todel = args[0]
2534 except IndexError:
2540 except IndexError:
2535 error('You must provide a bookmark to delete')
2541 error('You must provide a bookmark to delete')
2536 else:
2542 else:
2537 try:
2543 try:
2538 del bkms[todel]
2544 del bkms[todel]
2539 except:
2545 except:
2540 error("Can't delete bookmark '%s'" % todel)
2546 error("Can't delete bookmark '%s'" % todel)
2541 elif opts.has_key('r'):
2547 elif opts.has_key('r'):
2542 bkms = {}
2548 bkms = {}
2543 elif opts.has_key('l'):
2549 elif opts.has_key('l'):
2544 bks = bkms.keys()
2550 bks = bkms.keys()
2545 bks.sort()
2551 bks.sort()
2546 if bks:
2552 if bks:
2547 size = max(map(len,bks))
2553 size = max(map(len,bks))
2548 else:
2554 else:
2549 size = 0
2555 size = 0
2550 fmt = '%-'+str(size)+'s -> %s'
2556 fmt = '%-'+str(size)+'s -> %s'
2551 print 'Current bookmarks:'
2557 print 'Current bookmarks:'
2552 for bk in bks:
2558 for bk in bks:
2553 print fmt % (bk,bkms[bk])
2559 print fmt % (bk,bkms[bk])
2554 else:
2560 else:
2555 if not args:
2561 if not args:
2556 error("You must specify the bookmark name")
2562 error("You must specify the bookmark name")
2557 elif len(args)==1:
2563 elif len(args)==1:
2558 bkms[args[0]] = os.getcwd()
2564 bkms[args[0]] = os.getcwd()
2559 elif len(args)==2:
2565 elif len(args)==2:
2560 bkms[args[0]] = args[1]
2566 bkms[args[0]] = args[1]
2561 self.persist['bookmarks'] = bkms
2567 self.persist['bookmarks'] = bkms
2562
2568
2563 def magic_pycat(self, parameter_s=''):
2569 def magic_pycat(self, parameter_s=''):
2564 """Show a syntax-highlighted file through a pager.
2570 """Show a syntax-highlighted file through a pager.
2565
2571
2566 This magic is similar to the cat utility, but it will assume the file
2572 This magic is similar to the cat utility, but it will assume the file
2567 to be Python source and will show it with syntax highlighting. """
2573 to be Python source and will show it with syntax highlighting. """
2568
2574
2569 filename = get_py_filename(parameter_s)
2575 filename = get_py_filename(parameter_s)
2570 page(self.shell.colorize(file_read(filename)),
2576 page(self.shell.colorize(file_read(filename)),
2571 screen_lines=self.shell.rc.screen_length)
2577 screen_lines=self.shell.rc.screen_length)
2572
2578
2573 # end Magic
2579 # end Magic
@@ -1,455 +1,459 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Tools for inspecting Python objects.
2 """Tools for inspecting Python objects.
3
3
4 Uses syntax highlighting for presenting the various information elements.
4 Uses syntax highlighting for presenting the various information elements.
5
5
6 Similar in spirit to the inspect module, but all calls take a name argument to
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.
7 reference the name under which an object is being read.
8
8
9 $Id: OInspect.py 923 2005-11-15 08:51:15Z fperez $
9 $Id: OInspect.py 958 2005-12-27 23:17:51Z fperez $
10 """
10 """
11
11
12 #*****************************************************************************
12 #*****************************************************************************
13 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
13 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
14 #
14 #
15 # Distributed under the terms of the BSD License. The full license is in
15 # Distributed under the terms of the BSD License. The full license is in
16 # the file COPYING, distributed as part of this software.
16 # the file COPYING, distributed as part of this software.
17 #*****************************************************************************
17 #*****************************************************************************
18
18
19 from IPython import Release
19 from IPython import Release
20 __author__ = '%s <%s>' % Release.authors['Fernando']
20 __author__ = '%s <%s>' % Release.authors['Fernando']
21 __license__ = Release.license
21 __license__ = Release.license
22
22
23 __all__ = ['Inspector','InspectColors']
23 __all__ = ['Inspector','InspectColors']
24
24
25 # stdlib modules
25 # stdlib modules
26 import __builtin__
26 import __builtin__
27 import inspect,linecache,types,StringIO,string
27 import inspect
28 import linecache
29 import string
30 import StringIO
31 import types
28
32
29 # IPython's own
33 # IPython's own
30 from IPython import PyColorize
34 from IPython import PyColorize
35 from IPython.genutils import page,indent,Term,mkdict
31 from IPython.Itpl import itpl
36 from IPython.Itpl import itpl
32 from IPython.wildcard import list_namespace
37 from IPython.wildcard import list_namespace
33 from IPython.genutils import page,indent,Term,mkdict
34 from IPython.ColorANSI import *
38 from IPython.ColorANSI import *
35
39
36 #****************************************************************************
40 #****************************************************************************
37 # Builtin color schemes
41 # Builtin color schemes
38
42
39 Colors = TermColors # just a shorthand
43 Colors = TermColors # just a shorthand
40
44
41 # Build a few color schemes
45 # Build a few color schemes
42 NoColor = ColorScheme(
46 NoColor = ColorScheme(
43 'NoColor',{
47 'NoColor',{
44 'header' : Colors.NoColor,
48 'header' : Colors.NoColor,
45 'normal' : Colors.NoColor # color off (usu. Colors.Normal)
49 'normal' : Colors.NoColor # color off (usu. Colors.Normal)
46 } )
50 } )
47
51
48 LinuxColors = ColorScheme(
52 LinuxColors = ColorScheme(
49 'Linux',{
53 'Linux',{
50 'header' : Colors.LightRed,
54 'header' : Colors.LightRed,
51 'normal' : Colors.Normal # color off (usu. Colors.Normal)
55 'normal' : Colors.Normal # color off (usu. Colors.Normal)
52 } )
56 } )
53
57
54 LightBGColors = ColorScheme(
58 LightBGColors = ColorScheme(
55 'LightBG',{
59 'LightBG',{
56 'header' : Colors.Red,
60 'header' : Colors.Red,
57 'normal' : Colors.Normal # color off (usu. Colors.Normal)
61 'normal' : Colors.Normal # color off (usu. Colors.Normal)
58 } )
62 } )
59
63
60 # Build table of color schemes (needed by the parser)
64 # Build table of color schemes (needed by the parser)
61 InspectColors = ColorSchemeTable([NoColor,LinuxColors,LightBGColors],
65 InspectColors = ColorSchemeTable([NoColor,LinuxColors,LightBGColors],
62 'Linux')
66 'Linux')
63
67
64 #****************************************************************************
68 #****************************************************************************
65 # Auxiliary functions
69 # Auxiliary functions
66 def getdoc(obj):
70 def getdoc(obj):
67 """Stable wrapper around inspect.getdoc.
71 """Stable wrapper around inspect.getdoc.
68
72
69 This can't crash because of attribute problems.
73 This can't crash because of attribute problems.
70
74
71 It also attempts to call a getdoc() method on the given object. This
75 It also attempts to call a getdoc() method on the given object. This
72 allows objects which provide their docstrings via non-standard mechanisms
76 allows objects which provide their docstrings via non-standard mechanisms
73 (like Pyro proxies) to still be inspected by ipython's ? system."""
77 (like Pyro proxies) to still be inspected by ipython's ? system."""
74
78
75 ds = None # default return value
79 ds = None # default return value
76 try:
80 try:
77 ds = inspect.getdoc(obj)
81 ds = inspect.getdoc(obj)
78 except:
82 except:
79 # Harden against an inspect failure, which can occur with
83 # Harden against an inspect failure, which can occur with
80 # SWIG-wrapped extensions.
84 # SWIG-wrapped extensions.
81 pass
85 pass
82 # Allow objects to offer customized documentation via a getdoc method:
86 # Allow objects to offer customized documentation via a getdoc method:
83 try:
87 try:
84 ds2 = obj.getdoc()
88 ds2 = obj.getdoc()
85 except:
89 except:
86 pass
90 pass
87 else:
91 else:
88 # if we get extra info, we add it to the normal docstring.
92 # if we get extra info, we add it to the normal docstring.
89 if ds is None:
93 if ds is None:
90 ds = ds2
94 ds = ds2
91 else:
95 else:
92 ds = '%s\n%s' % (ds,ds2)
96 ds = '%s\n%s' % (ds,ds2)
93 return ds
97 return ds
94
98
95 #****************************************************************************
99 #****************************************************************************
96 # Class definitions
100 # Class definitions
97
101
98 class myStringIO(StringIO.StringIO):
102 class myStringIO(StringIO.StringIO):
99 """Adds a writeln method to normal StringIO."""
103 """Adds a writeln method to normal StringIO."""
100 def writeln(self,*arg,**kw):
104 def writeln(self,*arg,**kw):
101 """Does a write() and then a write('\n')"""
105 """Does a write() and then a write('\n')"""
102 self.write(*arg,**kw)
106 self.write(*arg,**kw)
103 self.write('\n')
107 self.write('\n')
104
108
105 class Inspector:
109 class Inspector:
106 def __init__(self,color_table,code_color_table,scheme):
110 def __init__(self,color_table,code_color_table,scheme):
107 self.color_table = color_table
111 self.color_table = color_table
108 self.parser = PyColorize.Parser(code_color_table,out='str')
112 self.parser = PyColorize.Parser(code_color_table,out='str')
109 self.format = self.parser.format
113 self.format = self.parser.format
110 self.set_active_scheme(scheme)
114 self.set_active_scheme(scheme)
111
115
112 def __getargspec(self,obj):
116 def __getargspec(self,obj):
113 """Get the names and default values of a function's arguments.
117 """Get the names and default values of a function's arguments.
114
118
115 A tuple of four things is returned: (args, varargs, varkw, defaults).
119 A tuple of four things is returned: (args, varargs, varkw, defaults).
116 'args' is a list of the argument names (it may contain nested lists).
120 'args' is a list of the argument names (it may contain nested lists).
117 'varargs' and 'varkw' are the names of the * and ** arguments or None.
121 'varargs' and 'varkw' are the names of the * and ** arguments or None.
118 'defaults' is an n-tuple of the default values of the last n arguments.
122 'defaults' is an n-tuple of the default values of the last n arguments.
119
123
120 Modified version of inspect.getargspec from the Python Standard
124 Modified version of inspect.getargspec from the Python Standard
121 Library."""
125 Library."""
122
126
123 if inspect.isfunction(obj):
127 if inspect.isfunction(obj):
124 func_obj = obj
128 func_obj = obj
125 elif inspect.ismethod(obj):
129 elif inspect.ismethod(obj):
126 func_obj = obj.im_func
130 func_obj = obj.im_func
127 else:
131 else:
128 raise TypeError, 'arg is not a Python function'
132 raise TypeError, 'arg is not a Python function'
129 args, varargs, varkw = inspect.getargs(func_obj.func_code)
133 args, varargs, varkw = inspect.getargs(func_obj.func_code)
130 return args, varargs, varkw, func_obj.func_defaults
134 return args, varargs, varkw, func_obj.func_defaults
131
135
132 def __getdef(self,obj,oname=''):
136 def __getdef(self,obj,oname=''):
133 """Return the definition header for any callable object.
137 """Return the definition header for any callable object.
134
138
135 If any exception is generated, None is returned instead and the
139 If any exception is generated, None is returned instead and the
136 exception is suppressed."""
140 exception is suppressed."""
137
141
138 try:
142 try:
139 return oname + inspect.formatargspec(*self.__getargspec(obj))
143 return oname + inspect.formatargspec(*self.__getargspec(obj))
140 except:
144 except:
141 return None
145 return None
142
146
143 def __head(self,h):
147 def __head(self,h):
144 """Return a header string with proper colors."""
148 """Return a header string with proper colors."""
145 return '%s%s%s' % (self.color_table.active_colors.header,h,
149 return '%s%s%s' % (self.color_table.active_colors.header,h,
146 self.color_table.active_colors.normal)
150 self.color_table.active_colors.normal)
147
151
148 def set_active_scheme(self,scheme):
152 def set_active_scheme(self,scheme):
149 self.color_table.set_active_scheme(scheme)
153 self.color_table.set_active_scheme(scheme)
150 self.parser.color_table.set_active_scheme(scheme)
154 self.parser.color_table.set_active_scheme(scheme)
151
155
152 def noinfo(self,msg,oname):
156 def noinfo(self,msg,oname):
153 """Generic message when no information is found."""
157 """Generic message when no information is found."""
154 print 'No %s found' % msg,
158 print 'No %s found' % msg,
155 if oname:
159 if oname:
156 print 'for %s' % oname
160 print 'for %s' % oname
157 else:
161 else:
158 print
162 print
159
163
160 def pdef(self,obj,oname=''):
164 def pdef(self,obj,oname=''):
161 """Print the definition header for any callable object.
165 """Print the definition header for any callable object.
162
166
163 If the object is a class, print the constructor information."""
167 If the object is a class, print the constructor information."""
164
168
165 if not callable(obj):
169 if not callable(obj):
166 print 'Object is not callable.'
170 print 'Object is not callable.'
167 return
171 return
168
172
169 header = ''
173 header = ''
170 if type(obj) is types.ClassType:
174 if type(obj) is types.ClassType:
171 header = self.__head('Class constructor information:\n')
175 header = self.__head('Class constructor information:\n')
172 obj = obj.__init__
176 obj = obj.__init__
173 elif type(obj) is types.InstanceType:
177 elif type(obj) is types.InstanceType:
174 obj = obj.__call__
178 obj = obj.__call__
175
179
176 output = self.__getdef(obj,oname)
180 output = self.__getdef(obj,oname)
177 if output is None:
181 if output is None:
178 self.noinfo('definition header',oname)
182 self.noinfo('definition header',oname)
179 else:
183 else:
180 print >>Term.cout, header,self.format(output),
184 print >>Term.cout, header,self.format(output),
181
185
182 def pdoc(self,obj,oname='',formatter = None):
186 def pdoc(self,obj,oname='',formatter = None):
183 """Print the docstring for any object.
187 """Print the docstring for any object.
184
188
185 Optional:
189 Optional:
186 -formatter: a function to run the docstring through for specially
190 -formatter: a function to run the docstring through for specially
187 formatted docstrings."""
191 formatted docstrings."""
188
192
189 head = self.__head # so that itpl can find it even if private
193 head = self.__head # so that itpl can find it even if private
190 ds = getdoc(obj)
194 ds = getdoc(obj)
191 if formatter:
195 if formatter:
192 ds = formatter(ds)
196 ds = formatter(ds)
193 if type(obj) is types.ClassType:
197 if type(obj) is types.ClassType:
194 init_ds = getdoc(obj.__init__)
198 init_ds = getdoc(obj.__init__)
195 output = itpl('$head("Class Docstring:")\n'
199 output = itpl('$head("Class Docstring:")\n'
196 '$indent(ds)\n'
200 '$indent(ds)\n'
197 '$head("Constructor Docstring"):\n'
201 '$head("Constructor Docstring"):\n'
198 '$indent(init_ds)')
202 '$indent(init_ds)')
199 elif type(obj) is types.InstanceType and hasattr(obj,'__call__'):
203 elif type(obj) is types.InstanceType and hasattr(obj,'__call__'):
200 call_ds = getdoc(obj.__call__)
204 call_ds = getdoc(obj.__call__)
201 if call_ds:
205 if call_ds:
202 output = itpl('$head("Class Docstring:")\n$indent(ds)\n'
206 output = itpl('$head("Class Docstring:")\n$indent(ds)\n'
203 '$head("Calling Docstring:")\n$indent(call_ds)')
207 '$head("Calling Docstring:")\n$indent(call_ds)')
204 else:
208 else:
205 output = ds
209 output = ds
206 else:
210 else:
207 output = ds
211 output = ds
208 if output is None:
212 if output is None:
209 self.noinfo('documentation',oname)
213 self.noinfo('documentation',oname)
210 return
214 return
211 page(output)
215 page(output)
212
216
213 def psource(self,obj,oname=''):
217 def psource(self,obj,oname=''):
214 """Print the source code for an object."""
218 """Print the source code for an object."""
215
219
216 # Flush the source cache because inspect can return out-of-date source
220 # Flush the source cache because inspect can return out-of-date source
217 linecache.checkcache()
221 linecache.checkcache()
218 try:
222 try:
219 src = inspect.getsource(obj)
223 src = inspect.getsource(obj)
220 except:
224 except:
221 self.noinfo('source',oname)
225 self.noinfo('source',oname)
222 else:
226 else:
223 page(self.format(src))
227 page(self.format(src))
224
228
225 def pfile(self,obj,oname=''):
229 def pfile(self,obj,oname=''):
226 """Show the whole file where an object was defined."""
230 """Show the whole file where an object was defined."""
227 try:
231 try:
228 sourcelines,lineno = inspect.getsourcelines(obj)
232 sourcelines,lineno = inspect.getsourcelines(obj)
229 except:
233 except:
230 self.noinfo('file',oname)
234 self.noinfo('file',oname)
231 else:
235 else:
232 # run contents of file through pager starting at line
236 # run contents of file through pager starting at line
233 # where the object is defined
237 # where the object is defined
234 page(self.format(open(inspect.getabsfile(obj)).read()),lineno)
238 page(self.format(open(inspect.getabsfile(obj)).read()),lineno)
235
239
236 def pinfo(self,obj,oname='',formatter=None,info=None,detail_level=0):
240 def pinfo(self,obj,oname='',formatter=None,info=None,detail_level=0):
237 """Show detailed information about an object.
241 """Show detailed information about an object.
238
242
239 Optional arguments:
243 Optional arguments:
240
244
241 - oname: name of the variable pointing to the object.
245 - oname: name of the variable pointing to the object.
242
246
243 - formatter: special formatter for docstrings (see pdoc)
247 - formatter: special formatter for docstrings (see pdoc)
244
248
245 - info: a structure with some information fields which may have been
249 - info: a structure with some information fields which may have been
246 precomputed already.
250 precomputed already.
247
251
248 - detail_level: if set to 1, more information is given.
252 - detail_level: if set to 1, more information is given.
249 """
253 """
250
254
251 obj_type = type(obj)
255 obj_type = type(obj)
252
256
253 header = self.__head
257 header = self.__head
254 if info is None:
258 if info is None:
255 ismagic = 0
259 ismagic = 0
256 isalias = 0
260 isalias = 0
257 ospace = ''
261 ospace = ''
258 else:
262 else:
259 ismagic = info.ismagic
263 ismagic = info.ismagic
260 isalias = info.isalias
264 isalias = info.isalias
261 ospace = info.namespace
265 ospace = info.namespace
262 # Get docstring, special-casing aliases:
266 # Get docstring, special-casing aliases:
263 if isalias:
267 if isalias:
264 ds = "Alias to the system command:\n %s" % obj[1]
268 ds = "Alias to the system command:\n %s" % obj[1]
265 else:
269 else:
266 ds = getdoc(obj)
270 ds = getdoc(obj)
267 if formatter is not None:
271 if formatter is not None:
268 ds = formatter(ds)
272 ds = formatter(ds)
269
273
270 # store output in a list which gets joined with \n at the end.
274 # store output in a list which gets joined with \n at the end.
271 out = myStringIO()
275 out = myStringIO()
272
276
273 string_max = 200 # max size of strings to show (snipped if longer)
277 string_max = 200 # max size of strings to show (snipped if longer)
274 shalf = int((string_max -5)/2)
278 shalf = int((string_max -5)/2)
275
279
276 if ismagic:
280 if ismagic:
277 obj_type_name = 'Magic function'
281 obj_type_name = 'Magic function'
278 elif isalias:
282 elif isalias:
279 obj_type_name = 'System alias'
283 obj_type_name = 'System alias'
280 else:
284 else:
281 obj_type_name = obj_type.__name__
285 obj_type_name = obj_type.__name__
282 out.writeln(header('Type:\t\t')+obj_type_name)
286 out.writeln(header('Type:\t\t')+obj_type_name)
283
287
284 try:
288 try:
285 bclass = obj.__class__
289 bclass = obj.__class__
286 out.writeln(header('Base Class:\t')+str(bclass))
290 out.writeln(header('Base Class:\t')+str(bclass))
287 except: pass
291 except: pass
288
292
289 # String form, but snip if too long in ? form (full in ??)
293 # String form, but snip if too long in ? form (full in ??)
290 try:
294 try:
291 ostr = str(obj)
295 ostr = str(obj)
292 str_head = 'String Form:'
296 str_head = 'String Form:'
293 if not detail_level and len(ostr)>string_max:
297 if not detail_level and len(ostr)>string_max:
294 ostr = ostr[:shalf] + ' <...> ' + ostr[-shalf:]
298 ostr = ostr[:shalf] + ' <...> ' + ostr[-shalf:]
295 ostr = ("\n" + " " * len(str_head.expandtabs())).\
299 ostr = ("\n" + " " * len(str_head.expandtabs())).\
296 join(map(string.strip,ostr.split("\n")))
300 join(map(string.strip,ostr.split("\n")))
297 if ostr.find('\n') > -1:
301 if ostr.find('\n') > -1:
298 # Print multi-line strings starting at the next line.
302 # Print multi-line strings starting at the next line.
299 str_sep = '\n'
303 str_sep = '\n'
300 else:
304 else:
301 str_sep = '\t'
305 str_sep = '\t'
302 out.writeln("%s%s%s" % (header(str_head),str_sep,ostr))
306 out.writeln("%s%s%s" % (header(str_head),str_sep,ostr))
303 except:
307 except:
304 pass
308 pass
305
309
306 if ospace:
310 if ospace:
307 out.writeln(header('Namespace:\t')+ospace)
311 out.writeln(header('Namespace:\t')+ospace)
308
312
309 # Length (for strings and lists)
313 # Length (for strings and lists)
310 try:
314 try:
311 length = str(len(obj))
315 length = str(len(obj))
312 out.writeln(header('Length:\t\t')+length)
316 out.writeln(header('Length:\t\t')+length)
313 except: pass
317 except: pass
314
318
315 # Filename where object was defined
319 # Filename where object was defined
316 try:
320 try:
317 file = inspect.getabsfile(obj)
321 file = inspect.getabsfile(obj)
318 if file.endswith('<string>'):
322 if file.endswith('<string>'):
319 file = 'Dynamically generated function. No source code available.'
323 file = 'Dynamically generated function. No source code available.'
320 out.writeln(header('File:\t\t')+file)
324 out.writeln(header('File:\t\t')+file)
321 except: pass
325 except: pass
322
326
323 # reconstruct the function definition and print it:
327 # reconstruct the function definition and print it:
324 defln = self.__getdef(obj,oname)
328 defln = self.__getdef(obj,oname)
325 if defln:
329 if defln:
326 out.write(header('Definition:\t')+self.format(defln))
330 out.write(header('Definition:\t')+self.format(defln))
327
331
328 # Docstrings only in detail 0 mode, since source contains them (we
332 # Docstrings only in detail 0 mode, since source contains them (we
329 # avoid repetitions). If source fails, we add them back, see below.
333 # avoid repetitions). If source fails, we add them back, see below.
330 if ds and detail_level == 0:
334 if ds and detail_level == 0:
331 out.writeln(header('Docstring:\n') + indent(ds))
335 out.writeln(header('Docstring:\n') + indent(ds))
332
336
333 # Original source code for any callable
337 # Original source code for any callable
334 if detail_level:
338 if detail_level:
335 # Flush the source cache because inspect can return out-of-date source
339 # Flush the source cache because inspect can return out-of-date source
336 linecache.checkcache()
340 linecache.checkcache()
337 try:
341 try:
338 source = self.format(inspect.getsource(obj))
342 source = self.format(inspect.getsource(obj))
339 out.write(header('Source:\n')+source.rstrip())
343 out.write(header('Source:\n')+source.rstrip())
340 except:
344 except:
341 if ds:
345 if ds:
342 out.writeln(header('Docstring:\n') + indent(ds))
346 out.writeln(header('Docstring:\n') + indent(ds))
343
347
344 # Constructor docstring for classes
348 # Constructor docstring for classes
345 if obj_type is types.ClassType:
349 if obj_type is types.ClassType:
346 # reconstruct the function definition and print it:
350 # reconstruct the function definition and print it:
347 try:
351 try:
348 obj_init = obj.__init__
352 obj_init = obj.__init__
349 except AttributeError:
353 except AttributeError:
350 init_def = init_ds = None
354 init_def = init_ds = None
351 else:
355 else:
352 init_def = self.__getdef(obj_init,oname)
356 init_def = self.__getdef(obj_init,oname)
353 init_ds = getdoc(obj_init)
357 init_ds = getdoc(obj_init)
354
358
355 if init_def or init_ds:
359 if init_def or init_ds:
356 out.writeln(header('\nConstructor information:'))
360 out.writeln(header('\nConstructor information:'))
357 if init_def:
361 if init_def:
358 out.write(header('Definition:\t')+ self.format(init_def))
362 out.write(header('Definition:\t')+ self.format(init_def))
359 if init_ds:
363 if init_ds:
360 out.writeln(header('Docstring:\n') + indent(init_ds))
364 out.writeln(header('Docstring:\n') + indent(init_ds))
361 # and class docstring for instances:
365 # and class docstring for instances:
362 elif obj_type is types.InstanceType:
366 elif obj_type is types.InstanceType:
363
367
364 # First, check whether the instance docstring is identical to the
368 # First, check whether the instance docstring is identical to the
365 # class one, and print it separately if they don't coincide. In
369 # class one, and print it separately if they don't coincide. In
366 # most cases they will, but it's nice to print all the info for
370 # most cases they will, but it's nice to print all the info for
367 # objects which use instance-customized docstrings.
371 # objects which use instance-customized docstrings.
368 if ds:
372 if ds:
369 class_ds = getdoc(obj.__class__)
373 class_ds = getdoc(obj.__class__)
370 if class_ds and ds != class_ds:
374 if class_ds and ds != class_ds:
371 out.writeln(header('Class Docstring:\n') +
375 out.writeln(header('Class Docstring:\n') +
372 indent(class_ds))
376 indent(class_ds))
373
377
374 # Next, try to show constructor docstrings
378 # Next, try to show constructor docstrings
375 try:
379 try:
376 init_ds = getdoc(obj.__init__)
380 init_ds = getdoc(obj.__init__)
377 except AttributeError:
381 except AttributeError:
378 init_ds = None
382 init_ds = None
379 if init_ds:
383 if init_ds:
380 out.writeln(header('Constructor Docstring:\n') +
384 out.writeln(header('Constructor Docstring:\n') +
381 indent(init_ds))
385 indent(init_ds))
382
386
383 # Call form docstring for callable instances
387 # Call form docstring for callable instances
384 if hasattr(obj,'__call__'):
388 if hasattr(obj,'__call__'):
385 out.writeln(header('Callable:\t')+'Yes')
389 out.writeln(header('Callable:\t')+'Yes')
386 call_def = self.__getdef(obj.__call__,oname)
390 call_def = self.__getdef(obj.__call__,oname)
387 if call_def is None:
391 if call_def is None:
388 out.write(header('Call def:\t')+
392 out.write(header('Call def:\t')+
389 'Calling definition not available.')
393 'Calling definition not available.')
390 else:
394 else:
391 out.write(header('Call def:\t')+self.format(call_def))
395 out.write(header('Call def:\t')+self.format(call_def))
392 call_ds = getdoc(obj.__call__)
396 call_ds = getdoc(obj.__call__)
393 if call_ds:
397 if call_ds:
394 out.writeln(header('Call docstring:\n') + indent(call_ds))
398 out.writeln(header('Call docstring:\n') + indent(call_ds))
395
399
396 # Finally send to printer/pager
400 # Finally send to printer/pager
397 output = out.getvalue()
401 output = out.getvalue()
398 if output:
402 if output:
399 page(output)
403 page(output)
400 # end pinfo
404 # end pinfo
401
405
402 def psearch(self,pattern,ns_table,ns_search=[],
406 def psearch(self,pattern,ns_table,ns_search=[],
403 ignore_case=False,show_all=False):
407 ignore_case=False,show_all=False):
404 """Search namespaces with wildcards for objects.
408 """Search namespaces with wildcards for objects.
405
409
406 Arguments:
410 Arguments:
407
411
408 - pattern: string containing shell-like wildcards to use in namespace
412 - pattern: string containing shell-like wildcards to use in namespace
409 searches and optionally a type specification to narrow the search to
413 searches and optionally a type specification to narrow the search to
410 objects of that type.
414 objects of that type.
411
415
412 - ns_table: dict of name->namespaces for search.
416 - ns_table: dict of name->namespaces for search.
413
417
414 Optional arguments:
418 Optional arguments:
415
419
416 - ns_search: list of namespace names to include in search.
420 - ns_search: list of namespace names to include in search.
417
421
418 - ignore_case(False): make the search case-insensitive.
422 - ignore_case(False): make the search case-insensitive.
419
423
420 - show_all(False): show all names, including those starting with
424 - show_all(False): show all names, including those starting with
421 underscores.
425 underscores.
422 """
426 """
423 # defaults
427 # defaults
424 type_pattern = 'all'
428 type_pattern = 'all'
425 filter = ''
429 filter = ''
426
430
427 cmds = pattern.split()
431 cmds = pattern.split()
428 len_cmds = len(cmds)
432 len_cmds = len(cmds)
429 if len_cmds == 1:
433 if len_cmds == 1:
430 # Only filter pattern given
434 # Only filter pattern given
431 filter = cmds[0]
435 filter = cmds[0]
432 elif len_cmds == 2:
436 elif len_cmds == 2:
433 # Both filter and type specified
437 # Both filter and type specified
434 filter,type_pattern = cmds
438 filter,type_pattern = cmds
435 else:
439 else:
436 raise ValueError('invalid argument string for psearch: <%s>' %
440 raise ValueError('invalid argument string for psearch: <%s>' %
437 pattern)
441 pattern)
438
442
439 # filter search namespaces
443 # filter search namespaces
440 for name in ns_search:
444 for name in ns_search:
441 if name not in ns_table:
445 if name not in ns_table:
442 raise ValueError('invalid namespace <%s>. Valid names: %s' %
446 raise ValueError('invalid namespace <%s>. Valid names: %s' %
443 (name,ns_table.keys()))
447 (name,ns_table.keys()))
444
448
445 #print 'type_pattern:',type_pattern # dbg
449 #print 'type_pattern:',type_pattern # dbg
446 search_result = []
450 search_result = []
447 for ns_name in ns_search:
451 for ns_name in ns_search:
448 ns = ns_table[ns_name]
452 ns = ns_table[ns_name]
449 tmp_res = list(list_namespace(ns,type_pattern,filter,
453 tmp_res = list(list_namespace(ns,type_pattern,filter,
450 ignore_case=ignore_case,
454 ignore_case=ignore_case,
451 show_all=show_all))
455 show_all=show_all))
452 search_result.extend(tmp_res)
456 search_result.extend(tmp_res)
453 search_result.sort()
457 search_result.sort()
454
458
455 page('\n'.join(search_result))
459 page('\n'.join(search_result))
@@ -1,262 +1,263 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Class to trap stdout and stderr and log them separately.
2 """Class to trap stdout and stderr and log them separately.
3
3
4 $Id: OutputTrap.py 542 2005-03-18 09:16:04Z fperez $"""
4 $Id: OutputTrap.py 958 2005-12-27 23:17:51Z fperez $"""
5
5
6 #*****************************************************************************
6 #*****************************************************************************
7 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
7 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
8 #
8 #
9 # Distributed under the terms of the BSD License. The full license is in
9 # Distributed under the terms of the BSD License. The full license is in
10 # the file COPYING, distributed as part of this software.
10 # the file COPYING, distributed as part of this software.
11 #*****************************************************************************
11 #*****************************************************************************
12
12
13 from IPython import Release
13 from IPython import Release
14 __author__ = '%s <%s>' % Release.authors['Fernando']
14 __author__ = '%s <%s>' % Release.authors['Fernando']
15 __license__ = Release.license
15 __license__ = Release.license
16
16
17 import exceptions,sys
17 import exceptions
18 import sys
18 from cStringIO import StringIO
19 from cStringIO import StringIO
19
20
20 class OutputTrapError(exceptions.Exception):
21 class OutputTrapError(exceptions.Exception):
21 """Exception for OutputTrap class."""
22 """Exception for OutputTrap class."""
22
23
23 def __init__(self,args=None):
24 def __init__(self,args=None):
24 exceptions.Exception.__init__(self)
25 exceptions.Exception.__init__(self)
25 self.args = args
26 self.args = args
26
27
27 class OutputTrap:
28 class OutputTrap:
28
29
29 """Class to trap standard output and standard error. They get logged in
30 """Class to trap standard output and standard error. They get logged in
30 StringIO objects which are available as <instance>.out and
31 StringIO objects which are available as <instance>.out and
31 <instance>.err. The class also offers summary methods which format this
32 <instance>.err. The class also offers summary methods which format this
32 data a bit.
33 data a bit.
33
34
34 A word of caution: because it blocks messages, using this class can make
35 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 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 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 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 off, but you can keep the rest of your code unchanged (this has already
39 been a life saver).
40 been a life saver).
40
41
41 Example:
42 Example:
42
43
43 # config: trapper with a line of dots as log separator (final '\\n' needed)
44 # config: trapper with a line of dots as log separator (final '\\n' needed)
44 config = OutputTrap('Config','Out ','Err ','.'*80+'\\n')
45 config = OutputTrap('Config','Out ','Err ','.'*80+'\\n')
45
46
46 # start trapping output
47 # start trapping output
47 config.trap_all()
48 config.trap_all()
48
49
49 # now all output is logged ...
50 # now all output is logged ...
50 # do stuff...
51 # do stuff...
51
52
52 # output back to normal:
53 # output back to normal:
53 config.release_all()
54 config.release_all()
54
55
55 # print all that got logged:
56 # print all that got logged:
56 print config.summary()
57 print config.summary()
57
58
58 # print individual raw data:
59 # print individual raw data:
59 print config.out.getvalue()
60 print config.out.getvalue()
60 print config.err.getvalue()
61 print config.err.getvalue()
61 """
62 """
62
63
63 def __init__(self,name='Generic Output Trap',
64 def __init__(self,name='Generic Output Trap',
64 out_head='Standard Output. ',err_head='Standard Error. ',
65 out_head='Standard Output. ',err_head='Standard Error. ',
65 sum_sep='\n',debug=0,trap_out=0,trap_err=0,
66 sum_sep='\n',debug=0,trap_out=0,trap_err=0,
66 quiet_out=0,quiet_err=0):
67 quiet_out=0,quiet_err=0):
67 self.name = name
68 self.name = name
68 self.out_head = out_head
69 self.out_head = out_head
69 self.err_head = err_head
70 self.err_head = err_head
70 self.sum_sep = sum_sep
71 self.sum_sep = sum_sep
71 self.out = StringIO()
72 self.out = StringIO()
72 self.err = StringIO()
73 self.err = StringIO()
73 self.out_save = None
74 self.out_save = None
74 self.err_save = None
75 self.err_save = None
75 self.debug = debug
76 self.debug = debug
76 self.quiet_out = quiet_out
77 self.quiet_out = quiet_out
77 self.quiet_err = quiet_err
78 self.quiet_err = quiet_err
78 if trap_out:
79 if trap_out:
79 self.trap_out()
80 self.trap_out()
80 if trap_err:
81 if trap_err:
81 self.trap_err()
82 self.trap_err()
82
83
83 def trap_out(self):
84 def trap_out(self):
84 """Trap and log stdout."""
85 """Trap and log stdout."""
85 if sys.stdout is self.out:
86 if sys.stdout is self.out:
86 raise OutputTrapError,'You are already trapping stdout.'
87 raise OutputTrapError,'You are already trapping stdout.'
87 if not self.debug:
88 if not self.debug:
88 self._out_save = sys.stdout
89 self._out_save = sys.stdout
89 sys.stdout = self.out
90 sys.stdout = self.out
90
91
91 def release_out(self):
92 def release_out(self):
92 """Release stdout."""
93 """Release stdout."""
93 if not self.debug:
94 if not self.debug:
94 if not sys.stdout is self.out:
95 if not sys.stdout is self.out:
95 raise OutputTrapError,'You are not trapping stdout.'
96 raise OutputTrapError,'You are not trapping stdout.'
96 sys.stdout = self._out_save
97 sys.stdout = self._out_save
97 self.out_save = None
98 self.out_save = None
98
99
99 def summary_out(self):
100 def summary_out(self):
100 """Return as a string the log from stdout."""
101 """Return as a string the log from stdout."""
101 out = self.out.getvalue()
102 out = self.out.getvalue()
102 if out:
103 if out:
103 if self.quiet_out:
104 if self.quiet_out:
104 return out
105 return out
105 else:
106 else:
106 return self.out_head + 'Log by '+ self.name + ':\n' + out
107 return self.out_head + 'Log by '+ self.name + ':\n' + out
107 else:
108 else:
108 return ''
109 return ''
109
110
110 def flush_out(self):
111 def flush_out(self):
111 """Flush the stdout log. All data held in the log is lost."""
112 """Flush the stdout log. All data held in the log is lost."""
112
113
113 self.out.close()
114 self.out.close()
114 self.out = StringIO()
115 self.out = StringIO()
115
116
116 def trap_err(self):
117 def trap_err(self):
117 """Trap and log stderr."""
118 """Trap and log stderr."""
118 if sys.stderr is self.err:
119 if sys.stderr is self.err:
119 raise OutputTrapError,'You are already trapping stderr.'
120 raise OutputTrapError,'You are already trapping stderr.'
120 if not self.debug:
121 if not self.debug:
121 self._err_save = sys.stderr
122 self._err_save = sys.stderr
122 sys.stderr = self.err
123 sys.stderr = self.err
123
124
124 def release_err(self):
125 def release_err(self):
125 """Release stderr."""
126 """Release stderr."""
126 if not self.debug:
127 if not self.debug:
127 if not sys.stderr is self.err:
128 if not sys.stderr is self.err:
128 raise OutputTrapError,'You are not trapping stderr.'
129 raise OutputTrapError,'You are not trapping stderr.'
129 sys.stderr = self._err_save
130 sys.stderr = self._err_save
130 self.err_save = None
131 self.err_save = None
131
132
132 def summary_err(self):
133 def summary_err(self):
133 """Return as a string the log from stderr."""
134 """Return as a string the log from stderr."""
134 err = self.err.getvalue()
135 err = self.err.getvalue()
135 if err:
136 if err:
136 if self.quiet_err:
137 if self.quiet_err:
137 return err
138 return err
138 else:
139 else:
139 return self.err_head + 'Log by '+ self.name + ':\n' + err
140 return self.err_head + 'Log by '+ self.name + ':\n' + err
140 else:
141 else:
141 return ''
142 return ''
142
143
143 def flush_err(self):
144 def flush_err(self):
144 """Flush the stdout log. All data held in the log is lost."""
145 """Flush the stdout log. All data held in the log is lost."""
145
146
146 self.err.close()
147 self.err.close()
147 self.err = StringIO()
148 self.err = StringIO()
148
149
149 def trap_all(self):
150 def trap_all(self):
150 """Trap and log both stdout and stderr.
151 """Trap and log both stdout and stderr.
151
152
152 Cacthes and discards OutputTrapError exceptions raised."""
153 Cacthes and discards OutputTrapError exceptions raised."""
153 try:
154 try:
154 self.trap_out()
155 self.trap_out()
155 except OutputTrapError:
156 except OutputTrapError:
156 pass
157 pass
157 try:
158 try:
158 self.trap_err()
159 self.trap_err()
159 except OutputTrapError:
160 except OutputTrapError:
160 pass
161 pass
161
162
162 def release_all(self):
163 def release_all(self):
163 """Release both stdout and stderr.
164 """Release both stdout and stderr.
164
165
165 Cacthes and discards OutputTrapError exceptions raised."""
166 Cacthes and discards OutputTrapError exceptions raised."""
166 try:
167 try:
167 self.release_out()
168 self.release_out()
168 except OutputTrapError:
169 except OutputTrapError:
169 pass
170 pass
170 try:
171 try:
171 self.release_err()
172 self.release_err()
172 except OutputTrapError:
173 except OutputTrapError:
173 pass
174 pass
174
175
175 def summary_all(self):
176 def summary_all(self):
176 """Return as a string the log from stdout and stderr, prepending a separator
177 """Return as a string the log from stdout and stderr, prepending a separator
177 to each (defined in __init__ as sum_sep)."""
178 to each (defined in __init__ as sum_sep)."""
178 sum = ''
179 sum = ''
179 sout = self.summary_out()
180 sout = self.summary_out()
180 if sout:
181 if sout:
181 sum += self.sum_sep + sout
182 sum += self.sum_sep + sout
182 serr = self.summary_err()
183 serr = self.summary_err()
183 if serr:
184 if serr:
184 sum += '\n'+self.sum_sep + serr
185 sum += '\n'+self.sum_sep + serr
185 return sum
186 return sum
186
187
187 def flush_all(self):
188 def flush_all(self):
188 """Flush stdout and stderr"""
189 """Flush stdout and stderr"""
189 self.flush_out()
190 self.flush_out()
190 self.flush_err()
191 self.flush_err()
191
192
192 # a few shorthands
193 # a few shorthands
193 trap = trap_all
194 trap = trap_all
194 release = release_all
195 release = release_all
195 summary = summary_all
196 summary = summary_all
196 flush = flush_all
197 flush = flush_all
197 # end OutputTrap
198 # end OutputTrap
198
199
199
200
200 #****************************************************************************
201 #****************************************************************************
201 # Module testing. Incomplete, I'm lazy...
202 # Module testing. Incomplete, I'm lazy...
202
203
203 def _test_all():
204 def _test_all():
204
205
205 """Module testing functions, activated when the module is called as a
206 """Module testing functions, activated when the module is called as a
206 script (not imported)."""
207 script (not imported)."""
207
208
208 # Put tests for this module in here.
209 # Put tests for this module in here.
209 # Define them as nested functions so they don't clobber the
210 # Define them as nested functions so they don't clobber the
210 # pydoc-generated docs
211 # pydoc-generated docs
211
212
212 def _test_():
213 def _test_():
213 name = ''
214 name = ''
214 print '#'*50+'\nRunning test for ' + name
215 print '#'*50+'\nRunning test for ' + name
215 # ...
216 # ...
216 print 'Finished test for '+ name +'\n'+'#'*50
217 print 'Finished test for '+ name +'\n'+'#'*50
217
218
218 def _test_OutputTrap():
219 def _test_OutputTrap():
219 trap = OutputTrap(name = 'Test Trap', sum_sep = '.'*50+'\n',
220 trap = OutputTrap(name = 'Test Trap', sum_sep = '.'*50+'\n',
220 out_head = 'SOut. ', err_head = 'SErr. ')
221 out_head = 'SOut. ', err_head = 'SErr. ')
221
222
222 name = 'OutputTrap class'
223 name = 'OutputTrap class'
223 print '#'*50+'\nRunning test for ' + name
224 print '#'*50+'\nRunning test for ' + name
224 print 'Trapping out'
225 print 'Trapping out'
225 trap.trap_out()
226 trap.trap_out()
226 print >>sys.stdout, '>>stdout. stdout is trapped.'
227 print >>sys.stdout, '>>stdout. stdout is trapped.'
227 print >>sys.stderr, '>>stderr. stdout is trapped.'
228 print >>sys.stderr, '>>stderr. stdout is trapped.'
228 trap.release_out()
229 trap.release_out()
229 print trap.summary_out()
230 print trap.summary_out()
230
231
231 print 'Trapping err'
232 print 'Trapping err'
232 trap.trap_err()
233 trap.trap_err()
233 print >>sys.stdout, '>>stdout. stderr is trapped.'
234 print >>sys.stdout, '>>stdout. stderr is trapped.'
234 print >>sys.stderr, '>>stderr. stderr is trapped.'
235 print >>sys.stderr, '>>stderr. stderr is trapped.'
235 trap.release_err()
236 trap.release_err()
236 print trap.summary_err()
237 print trap.summary_err()
237
238
238 print 'Trapping all (no flushing)'
239 print 'Trapping all (no flushing)'
239 trap.trap_all()
240 trap.trap_all()
240 print >>sys.stdout, '>>stdout. stdout/err is trapped.'
241 print >>sys.stdout, '>>stdout. stdout/err is trapped.'
241 print >>sys.stderr, '>>stderr. stdout/err is trapped.'
242 print >>sys.stderr, '>>stderr. stdout/err is trapped.'
242 trap.release_all()
243 trap.release_all()
243 print trap.summary_all()
244 print trap.summary_all()
244
245
245 print 'Trapping all (flushing first)'
246 print 'Trapping all (flushing first)'
246 trap.flush()
247 trap.flush()
247 trap.trap_all()
248 trap.trap_all()
248 print >>sys.stdout, '>>stdout. stdout/err is trapped.'
249 print >>sys.stdout, '>>stdout. stdout/err is trapped.'
249 print >>sys.stderr, '>>stderr. stdout/err is trapped.'
250 print >>sys.stderr, '>>stderr. stdout/err is trapped.'
250 trap.release_all()
251 trap.release_all()
251 print trap.summary_all()
252 print trap.summary_all()
252 print 'Finished test for '+ name +'\n'+'#'*50
253 print 'Finished test for '+ name +'\n'+'#'*50
253
254
254 # call the actual tests here:
255 # call the actual tests here:
255 _test_OutputTrap()
256 _test_OutputTrap()
256
257
257
258
258 if __name__=="__main__":
259 if __name__=="__main__":
259 # _test_all() # XXX BROKEN.
260 # _test_all() # XXX BROKEN.
260 pass
261 pass
261
262
262 #************************ end of file <OutputTrap.py> ************************
263 #************************ end of file <OutputTrap.py> ************************
@@ -1,574 +1,576 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 Classes for handling input/output prompts.
3 Classes for handling input/output prompts.
4
4
5 $Id: Prompts.py 951 2005-12-25 00:57:24Z fperez $"""
5 $Id: Prompts.py 958 2005-12-27 23:17:51Z fperez $"""
6
6
7 #*****************************************************************************
7 #*****************************************************************************
8 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
8 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
9 #
9 #
10 # Distributed under the terms of the BSD License. The full license is in
10 # Distributed under the terms of the BSD License. The full license is in
11 # the file COPYING, distributed as part of this software.
11 # the file COPYING, distributed as part of this software.
12 #*****************************************************************************
12 #*****************************************************************************
13
13
14 from IPython import Release
14 from IPython import Release
15 __author__ = '%s <%s>' % Release.authors['Fernando']
15 __author__ = '%s <%s>' % Release.authors['Fernando']
16 __license__ = Release.license
16 __license__ = Release.license
17 __version__ = Release.version
17 __version__ = Release.version
18
18
19 #****************************************************************************
19 #****************************************************************************
20 # Required modules
20 # Required modules
21 import __builtin__
21 import __builtin__
22 import os,sys,socket
22 import os
23 import socket
24 import sys
23 import time
25 import time
24 from pprint import pprint,pformat
26 from pprint import pprint,pformat
25
27
26 # IPython's own
28 # IPython's own
27 from IPython.genutils import *
29 from IPython.genutils import *
28 from IPython.Struct import Struct
30 from IPython.Struct import Struct
29 from IPython.Magic import Macro
31 from IPython.Magic import Macro
30 from IPython.Itpl import ItplNS
32 from IPython.Itpl import ItplNS
31 from IPython import ColorANSI
33 from IPython import ColorANSI
32
34
33 #****************************************************************************
35 #****************************************************************************
34 #Color schemes for Prompts.
36 #Color schemes for Prompts.
35
37
36 PromptColors = ColorANSI.ColorSchemeTable()
38 PromptColors = ColorANSI.ColorSchemeTable()
37 InputColors = ColorANSI.InputTermColors # just a shorthand
39 InputColors = ColorANSI.InputTermColors # just a shorthand
38 Colors = ColorANSI.TermColors # just a shorthand
40 Colors = ColorANSI.TermColors # just a shorthand
39
41
40 PromptColors.add_scheme(ColorANSI.ColorScheme(
42 PromptColors.add_scheme(ColorANSI.ColorScheme(
41 'NoColor',
43 'NoColor',
42 in_prompt = InputColors.NoColor, # Input prompt
44 in_prompt = InputColors.NoColor, # Input prompt
43 in_number = InputColors.NoColor, # Input prompt number
45 in_number = InputColors.NoColor, # Input prompt number
44 in_prompt2 = InputColors.NoColor, # Continuation prompt
46 in_prompt2 = InputColors.NoColor, # Continuation prompt
45 in_normal = InputColors.NoColor, # color off (usu. Colors.Normal)
47 in_normal = InputColors.NoColor, # color off (usu. Colors.Normal)
46
48
47 out_prompt = Colors.NoColor, # Output prompt
49 out_prompt = Colors.NoColor, # Output prompt
48 out_number = Colors.NoColor, # Output prompt number
50 out_number = Colors.NoColor, # Output prompt number
49
51
50 normal = Colors.NoColor # color off (usu. Colors.Normal)
52 normal = Colors.NoColor # color off (usu. Colors.Normal)
51 ))
53 ))
52
54
53 # make some schemes as instances so we can copy them for modification easily:
55 # make some schemes as instances so we can copy them for modification easily:
54 __PColLinux = ColorANSI.ColorScheme(
56 __PColLinux = ColorANSI.ColorScheme(
55 'Linux',
57 'Linux',
56 in_prompt = InputColors.Green,
58 in_prompt = InputColors.Green,
57 in_number = InputColors.LightGreen,
59 in_number = InputColors.LightGreen,
58 in_prompt2 = InputColors.Green,
60 in_prompt2 = InputColors.Green,
59 in_normal = InputColors.Normal, # color off (usu. Colors.Normal)
61 in_normal = InputColors.Normal, # color off (usu. Colors.Normal)
60
62
61 out_prompt = Colors.Red,
63 out_prompt = Colors.Red,
62 out_number = Colors.LightRed,
64 out_number = Colors.LightRed,
63
65
64 normal = Colors.Normal
66 normal = Colors.Normal
65 )
67 )
66 # Don't forget to enter it into the table!
68 # Don't forget to enter it into the table!
67 PromptColors.add_scheme(__PColLinux)
69 PromptColors.add_scheme(__PColLinux)
68
70
69 # Slightly modified Linux for light backgrounds
71 # Slightly modified Linux for light backgrounds
70 __PColLightBG = __PColLinux.copy('LightBG')
72 __PColLightBG = __PColLinux.copy('LightBG')
71
73
72 __PColLightBG.colors.update(
74 __PColLightBG.colors.update(
73 in_prompt = InputColors.Blue,
75 in_prompt = InputColors.Blue,
74 in_number = InputColors.LightBlue,
76 in_number = InputColors.LightBlue,
75 in_prompt2 = InputColors.Blue
77 in_prompt2 = InputColors.Blue
76 )
78 )
77 PromptColors.add_scheme(__PColLightBG)
79 PromptColors.add_scheme(__PColLightBG)
78
80
79 del Colors,InputColors
81 del Colors,InputColors
80
82
81 #-----------------------------------------------------------------------------
83 #-----------------------------------------------------------------------------
82 def multiple_replace(dict, text):
84 def multiple_replace(dict, text):
83 """ Replace in 'text' all occurences of any key in the given
85 """ Replace in 'text' all occurences of any key in the given
84 dictionary by its corresponding value. Returns the new string."""
86 dictionary by its corresponding value. Returns the new string."""
85
87
86 # Function by Xavier Defrang, originally found at:
88 # Function by Xavier Defrang, originally found at:
87 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/81330
89 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/81330
88
90
89 # Create a regular expression from the dictionary keys
91 # Create a regular expression from the dictionary keys
90 regex = re.compile("(%s)" % "|".join(map(re.escape, dict.keys())))
92 regex = re.compile("(%s)" % "|".join(map(re.escape, dict.keys())))
91 # For each match, look-up corresponding value in dictionary
93 # For each match, look-up corresponding value in dictionary
92 return regex.sub(lambda mo: dict[mo.string[mo.start():mo.end()]], text)
94 return regex.sub(lambda mo: dict[mo.string[mo.start():mo.end()]], text)
93
95
94 #-----------------------------------------------------------------------------
96 #-----------------------------------------------------------------------------
95 # Special characters that can be used in prompt templates, mainly bash-like
97 # Special characters that can be used in prompt templates, mainly bash-like
96
98
97 # If $HOME isn't defined (Windows), make it an absurd string so that it can
99 # If $HOME isn't defined (Windows), make it an absurd string so that it can
98 # never be expanded out into '~'. Basically anything which can never be a
100 # never be expanded out into '~'. Basically anything which can never be a
99 # reasonable directory name will do, we just want the $HOME -> '~' operation
101 # reasonable directory name will do, we just want the $HOME -> '~' operation
100 # to become a no-op. We pre-compute $HOME here so it's not done on every
102 # to become a no-op. We pre-compute $HOME here so it's not done on every
101 # prompt call.
103 # prompt call.
102
104
103 # FIXME:
105 # FIXME:
104
106
105 # - This should be turned into a class which does proper namespace management,
107 # - This should be turned into a class which does proper namespace management,
106 # since the prompt specials need to be evaluated in a certain namespace.
108 # since the prompt specials need to be evaluated in a certain namespace.
107 # Currently it's just globals, which need to be managed manually by code
109 # Currently it's just globals, which need to be managed manually by code
108 # below.
110 # below.
109
111
110 # - I also need to split up the color schemes from the prompt specials
112 # - I also need to split up the color schemes from the prompt specials
111 # somehow. I don't have a clean design for that quite yet.
113 # somehow. I don't have a clean design for that quite yet.
112
114
113 HOME = os.environ.get("HOME","//////:::::ZZZZZ,,,~~~")
115 HOME = os.environ.get("HOME","//////:::::ZZZZZ,,,~~~")
114
116
115 # We precompute a few more strings here for the prompt_specials, which are
117 # We precompute a few more strings here for the prompt_specials, which are
116 # fixed once ipython starts. This reduces the runtime overhead of computing
118 # fixed once ipython starts. This reduces the runtime overhead of computing
117 # prompt strings.
119 # prompt strings.
118 USER = os.environ.get("USER")
120 USER = os.environ.get("USER")
119 HOSTNAME = socket.gethostname()
121 HOSTNAME = socket.gethostname()
120 HOSTNAME_SHORT = HOSTNAME.split(".")[0]
122 HOSTNAME_SHORT = HOSTNAME.split(".")[0]
121 ROOT_SYMBOL = "$#"[os.name=='nt' or os.getuid()==0]
123 ROOT_SYMBOL = "$#"[os.name=='nt' or os.getuid()==0]
122
124
123 prompt_specials_color = {
125 prompt_specials_color = {
124 # Prompt/history count
126 # Prompt/history count
125 '%n' : '${self.col_num}' '${self.cache.prompt_count}' '${self.col_p}',
127 '%n' : '${self.col_num}' '${self.cache.prompt_count}' '${self.col_p}',
126 '\\#': '${self.col_num}' '${self.cache.prompt_count}' '${self.col_p}',
128 '\\#': '${self.col_num}' '${self.cache.prompt_count}' '${self.col_p}',
127 # Prompt/history count, with the actual digits replaced by dots. Used
129 # Prompt/history count, with the actual digits replaced by dots. Used
128 # mainly in continuation prompts (prompt_in2)
130 # mainly in continuation prompts (prompt_in2)
129 '\\D': '${"."*len(str(self.cache.prompt_count))}',
131 '\\D': '${"."*len(str(self.cache.prompt_count))}',
130 # Current working directory
132 # Current working directory
131 '\\w': '${os.getcwd()}',
133 '\\w': '${os.getcwd()}',
132 # Current time
134 # Current time
133 '\\t' : '${time.strftime("%H:%M:%S")}',
135 '\\t' : '${time.strftime("%H:%M:%S")}',
134 # Basename of current working directory.
136 # Basename of current working directory.
135 # (use os.sep to make this portable across OSes)
137 # (use os.sep to make this portable across OSes)
136 '\\W' : '${os.getcwd().split("%s")[-1]}' % os.sep,
138 '\\W' : '${os.getcwd().split("%s")[-1]}' % os.sep,
137 # These X<N> are an extension to the normal bash prompts. They return
139 # These X<N> are an extension to the normal bash prompts. They return
138 # N terms of the path, after replacing $HOME with '~'
140 # N terms of the path, after replacing $HOME with '~'
139 '\\X0': '${os.getcwd().replace("%s","~")}' % HOME,
141 '\\X0': '${os.getcwd().replace("%s","~")}' % HOME,
140 '\\X1': '${self.cwd_filt(1)}',
142 '\\X1': '${self.cwd_filt(1)}',
141 '\\X2': '${self.cwd_filt(2)}',
143 '\\X2': '${self.cwd_filt(2)}',
142 '\\X3': '${self.cwd_filt(3)}',
144 '\\X3': '${self.cwd_filt(3)}',
143 '\\X4': '${self.cwd_filt(4)}',
145 '\\X4': '${self.cwd_filt(4)}',
144 '\\X5': '${self.cwd_filt(5)}',
146 '\\X5': '${self.cwd_filt(5)}',
145 # Y<N> are similar to X<N>, but they show '~' if it's the directory
147 # Y<N> are similar to X<N>, but they show '~' if it's the directory
146 # N+1 in the list. Somewhat like %cN in tcsh.
148 # N+1 in the list. Somewhat like %cN in tcsh.
147 '\\Y0': '${self.cwd_filt2(0)}',
149 '\\Y0': '${self.cwd_filt2(0)}',
148 '\\Y1': '${self.cwd_filt2(1)}',
150 '\\Y1': '${self.cwd_filt2(1)}',
149 '\\Y2': '${self.cwd_filt2(2)}',
151 '\\Y2': '${self.cwd_filt2(2)}',
150 '\\Y3': '${self.cwd_filt2(3)}',
152 '\\Y3': '${self.cwd_filt2(3)}',
151 '\\Y4': '${self.cwd_filt2(4)}',
153 '\\Y4': '${self.cwd_filt2(4)}',
152 '\\Y5': '${self.cwd_filt2(5)}',
154 '\\Y5': '${self.cwd_filt2(5)}',
153 # Hostname up to first .
155 # Hostname up to first .
154 '\\h': HOSTNAME_SHORT,
156 '\\h': HOSTNAME_SHORT,
155 # Full hostname
157 # Full hostname
156 '\\H': HOSTNAME,
158 '\\H': HOSTNAME,
157 # Username of current user
159 # Username of current user
158 '\\u': USER,
160 '\\u': USER,
159 # Escaped '\'
161 # Escaped '\'
160 '\\\\': '\\',
162 '\\\\': '\\',
161 # Newline
163 # Newline
162 '\\n': '\n',
164 '\\n': '\n',
163 # Carriage return
165 # Carriage return
164 '\\r': '\r',
166 '\\r': '\r',
165 # Release version
167 # Release version
166 '\\v': __version__,
168 '\\v': __version__,
167 # Root symbol ($ or #)
169 # Root symbol ($ or #)
168 '\\$': ROOT_SYMBOL,
170 '\\$': ROOT_SYMBOL,
169 }
171 }
170
172
171 # A copy of the prompt_specials dictionary but with all color escapes removed,
173 # A copy of the prompt_specials dictionary but with all color escapes removed,
172 # so we can correctly compute the prompt length for the auto_rewrite method.
174 # so we can correctly compute the prompt length for the auto_rewrite method.
173 prompt_specials_nocolor = prompt_specials_color.copy()
175 prompt_specials_nocolor = prompt_specials_color.copy()
174 prompt_specials_nocolor['%n'] = '${self.cache.prompt_count}'
176 prompt_specials_nocolor['%n'] = '${self.cache.prompt_count}'
175 prompt_specials_nocolor['\\#'] = '${self.cache.prompt_count}'
177 prompt_specials_nocolor['\\#'] = '${self.cache.prompt_count}'
176
178
177 # Add in all the InputTermColors color escapes as valid prompt characters.
179 # Add in all the InputTermColors color escapes as valid prompt characters.
178 # They all get added as \\C_COLORNAME, so that we don't have any conflicts
180 # They all get added as \\C_COLORNAME, so that we don't have any conflicts
179 # with a color name which may begin with a letter used by any other of the
181 # with a color name which may begin with a letter used by any other of the
180 # allowed specials. This of course means that \\C will never be allowed for
182 # allowed specials. This of course means that \\C will never be allowed for
181 # anything else.
183 # anything else.
182 input_colors = ColorANSI.InputTermColors
184 input_colors = ColorANSI.InputTermColors
183 for _color in dir(input_colors):
185 for _color in dir(input_colors):
184 if _color[0] != '_':
186 if _color[0] != '_':
185 c_name = '\\C_'+_color
187 c_name = '\\C_'+_color
186 prompt_specials_color[c_name] = getattr(input_colors,_color)
188 prompt_specials_color[c_name] = getattr(input_colors,_color)
187 prompt_specials_nocolor[c_name] = ''
189 prompt_specials_nocolor[c_name] = ''
188
190
189 # we default to no color for safety. Note that prompt_specials is a global
191 # we default to no color for safety. Note that prompt_specials is a global
190 # variable used by all prompt objects.
192 # variable used by all prompt objects.
191 prompt_specials = prompt_specials_nocolor
193 prompt_specials = prompt_specials_nocolor
192
194
193 #-----------------------------------------------------------------------------
195 #-----------------------------------------------------------------------------
194 def str_safe(arg):
196 def str_safe(arg):
195 """Convert to a string, without ever raising an exception.
197 """Convert to a string, without ever raising an exception.
196
198
197 If str(arg) fails, <ERROR: ... > is returned, where ... is the exception
199 If str(arg) fails, <ERROR: ... > is returned, where ... is the exception
198 error message."""
200 error message."""
199
201
200 try:
202 try:
201 out = str(arg)
203 out = str(arg)
202 except UnicodeError:
204 except UnicodeError:
203 try:
205 try:
204 out = arg.encode('utf_8','replace')
206 out = arg.encode('utf_8','replace')
205 except Exception,msg:
207 except Exception,msg:
206 # let's keep this little duplication here, so that the most common
208 # let's keep this little duplication here, so that the most common
207 # case doesn't suffer from a double try wrapping.
209 # case doesn't suffer from a double try wrapping.
208 out = '<ERROR: %s>' % msg
210 out = '<ERROR: %s>' % msg
209 except Exception,msg:
211 except Exception,msg:
210 out = '<ERROR: %s>' % msg
212 out = '<ERROR: %s>' % msg
211 return out
213 return out
212
214
213 class BasePrompt:
215 class BasePrompt:
214 """Interactive prompt similar to Mathematica's."""
216 """Interactive prompt similar to Mathematica's."""
215 def __init__(self,cache,sep,prompt,pad_left=False):
217 def __init__(self,cache,sep,prompt,pad_left=False):
216
218
217 # Hack: we access information about the primary prompt through the
219 # Hack: we access information about the primary prompt through the
218 # cache argument. We need this, because we want the secondary prompt
220 # cache argument. We need this, because we want the secondary prompt
219 # to be aligned with the primary one. Color table info is also shared
221 # to be aligned with the primary one. Color table info is also shared
220 # by all prompt classes through the cache. Nice OO spaghetti code!
222 # by all prompt classes through the cache. Nice OO spaghetti code!
221 self.cache = cache
223 self.cache = cache
222 self.sep = sep
224 self.sep = sep
223
225
224 # regexp to count the number of spaces at the end of a prompt
226 # regexp to count the number of spaces at the end of a prompt
225 # expression, useful for prompt auto-rewriting
227 # expression, useful for prompt auto-rewriting
226 self.rspace = re.compile(r'(\s*)$')
228 self.rspace = re.compile(r'(\s*)$')
227 # Flag to left-pad prompt strings to match the length of the primary
229 # Flag to left-pad prompt strings to match the length of the primary
228 # prompt
230 # prompt
229 self.pad_left = pad_left
231 self.pad_left = pad_left
230 # Set template to create each actual prompt (where numbers change)
232 # Set template to create each actual prompt (where numbers change)
231 self.p_template = prompt
233 self.p_template = prompt
232 self.set_p_str()
234 self.set_p_str()
233
235
234 def set_p_str(self):
236 def set_p_str(self):
235 """ Set the interpolating prompt strings.
237 """ Set the interpolating prompt strings.
236
238
237 This must be called every time the color settings change, because the
239 This must be called every time the color settings change, because the
238 prompt_specials global may have changed."""
240 prompt_specials global may have changed."""
239
241
240 import os,time # needed in locals for prompt string handling
242 import os,time # needed in locals for prompt string handling
241 loc = locals()
243 loc = locals()
242 self.p_str = ItplNS('%s%s%s' %
244 self.p_str = ItplNS('%s%s%s' %
243 ('${self.sep}${self.col_p}',
245 ('${self.sep}${self.col_p}',
244 multiple_replace(prompt_specials, self.p_template),
246 multiple_replace(prompt_specials, self.p_template),
245 '${self.col_norm}'),self.cache.user_ns,loc)
247 '${self.col_norm}'),self.cache.user_ns,loc)
246
248
247 self.p_str_nocolor = ItplNS(multiple_replace(prompt_specials_nocolor,
249 self.p_str_nocolor = ItplNS(multiple_replace(prompt_specials_nocolor,
248 self.p_template),
250 self.p_template),
249 self.cache.user_ns,loc)
251 self.cache.user_ns,loc)
250
252
251 def write(self,msg): # dbg
253 def write(self,msg): # dbg
252 sys.stdout.write(msg)
254 sys.stdout.write(msg)
253 return ''
255 return ''
254
256
255 def __str__(self):
257 def __str__(self):
256 """Return a string form of the prompt.
258 """Return a string form of the prompt.
257
259
258 This for is useful for continuation and output prompts, since it is
260 This for is useful for continuation and output prompts, since it is
259 left-padded to match lengths with the primary one (if the
261 left-padded to match lengths with the primary one (if the
260 self.pad_left attribute is set)."""
262 self.pad_left attribute is set)."""
261
263
262 out_str = str_safe(self.p_str)
264 out_str = str_safe(self.p_str)
263 if self.pad_left:
265 if self.pad_left:
264 # We must find the amount of padding required to match lengths,
266 # We must find the amount of padding required to match lengths,
265 # taking the color escapes (which are invisible on-screen) into
267 # taking the color escapes (which are invisible on-screen) into
266 # account.
268 # account.
267 esc_pad = len(out_str) - len(str_safe(self.p_str_nocolor))
269 esc_pad = len(out_str) - len(str_safe(self.p_str_nocolor))
268 format = '%%%ss' % (len(str(self.cache.last_prompt))+esc_pad)
270 format = '%%%ss' % (len(str(self.cache.last_prompt))+esc_pad)
269 return format % out_str
271 return format % out_str
270 else:
272 else:
271 return out_str
273 return out_str
272
274
273 # these path filters are put in as methods so that we can control the
275 # these path filters are put in as methods so that we can control the
274 # namespace where the prompt strings get evaluated
276 # namespace where the prompt strings get evaluated
275 def cwd_filt(self,depth):
277 def cwd_filt(self,depth):
276 """Return the last depth elements of the current working directory.
278 """Return the last depth elements of the current working directory.
277
279
278 $HOME is always replaced with '~'.
280 $HOME is always replaced with '~'.
279 If depth==0, the full path is returned."""
281 If depth==0, the full path is returned."""
280
282
281 cwd = os.getcwd().replace(HOME,"~")
283 cwd = os.getcwd().replace(HOME,"~")
282 out = os.sep.join(cwd.split(os.sep)[-depth:])
284 out = os.sep.join(cwd.split(os.sep)[-depth:])
283 if out:
285 if out:
284 return out
286 return out
285 else:
287 else:
286 return os.sep
288 return os.sep
287
289
288 def cwd_filt2(self,depth):
290 def cwd_filt2(self,depth):
289 """Return the last depth elements of the current working directory.
291 """Return the last depth elements of the current working directory.
290
292
291 $HOME is always replaced with '~'.
293 $HOME is always replaced with '~'.
292 If depth==0, the full path is returned."""
294 If depth==0, the full path is returned."""
293
295
294 cwd = os.getcwd().replace(HOME,"~").split(os.sep)
296 cwd = os.getcwd().replace(HOME,"~").split(os.sep)
295 if '~' in cwd and len(cwd) == depth+1:
297 if '~' in cwd and len(cwd) == depth+1:
296 depth += 1
298 depth += 1
297 out = os.sep.join(cwd[-depth:])
299 out = os.sep.join(cwd[-depth:])
298 if out:
300 if out:
299 return out
301 return out
300 else:
302 else:
301 return os.sep
303 return os.sep
302
304
303 class Prompt1(BasePrompt):
305 class Prompt1(BasePrompt):
304 """Input interactive prompt similar to Mathematica's."""
306 """Input interactive prompt similar to Mathematica's."""
305
307
306 def __init__(self,cache,sep='\n',prompt='In [\\#]: ',pad_left=True):
308 def __init__(self,cache,sep='\n',prompt='In [\\#]: ',pad_left=True):
307 BasePrompt.__init__(self,cache,sep,prompt,pad_left)
309 BasePrompt.__init__(self,cache,sep,prompt,pad_left)
308
310
309 def set_colors(self):
311 def set_colors(self):
310 self.set_p_str()
312 self.set_p_str()
311 Colors = self.cache.color_table.active_colors # shorthand
313 Colors = self.cache.color_table.active_colors # shorthand
312 self.col_p = Colors.in_prompt
314 self.col_p = Colors.in_prompt
313 self.col_num = Colors.in_number
315 self.col_num = Colors.in_number
314 self.col_norm = Colors.in_normal
316 self.col_norm = Colors.in_normal
315 # We need a non-input version of these escapes for the '--->'
317 # We need a non-input version of these escapes for the '--->'
316 # auto-call prompts used in the auto_rewrite() method.
318 # auto-call prompts used in the auto_rewrite() method.
317 self.col_p_ni = self.col_p.replace('\001','').replace('\002','')
319 self.col_p_ni = self.col_p.replace('\001','').replace('\002','')
318 self.col_norm_ni = Colors.normal
320 self.col_norm_ni = Colors.normal
319
321
320 def __str__(self):
322 def __str__(self):
321 self.cache.prompt_count += 1
323 self.cache.prompt_count += 1
322 self.cache.last_prompt = str_safe(self.p_str_nocolor).split('\n')[-1]
324 self.cache.last_prompt = str_safe(self.p_str_nocolor).split('\n')[-1]
323 return str_safe(self.p_str)
325 return str_safe(self.p_str)
324
326
325 def auto_rewrite(self):
327 def auto_rewrite(self):
326 """Print a string of the form '--->' which lines up with the previous
328 """Print a string of the form '--->' which lines up with the previous
327 input string. Useful for systems which re-write the user input when
329 input string. Useful for systems which re-write the user input when
328 handling automatically special syntaxes."""
330 handling automatically special syntaxes."""
329
331
330 curr = str(self.cache.last_prompt)
332 curr = str(self.cache.last_prompt)
331 nrspaces = len(self.rspace.search(curr).group())
333 nrspaces = len(self.rspace.search(curr).group())
332 return '%s%s>%s%s' % (self.col_p_ni,'-'*(len(curr)-nrspaces-1),
334 return '%s%s>%s%s' % (self.col_p_ni,'-'*(len(curr)-nrspaces-1),
333 ' '*nrspaces,self.col_norm_ni)
335 ' '*nrspaces,self.col_norm_ni)
334
336
335 class PromptOut(BasePrompt):
337 class PromptOut(BasePrompt):
336 """Output interactive prompt similar to Mathematica's."""
338 """Output interactive prompt similar to Mathematica's."""
337
339
338 def __init__(self,cache,sep='',prompt='Out[\\#]: ',pad_left=True):
340 def __init__(self,cache,sep='',prompt='Out[\\#]: ',pad_left=True):
339 BasePrompt.__init__(self,cache,sep,prompt,pad_left)
341 BasePrompt.__init__(self,cache,sep,prompt,pad_left)
340 if not self.p_template:
342 if not self.p_template:
341 self.__str__ = lambda: ''
343 self.__str__ = lambda: ''
342
344
343 def set_colors(self):
345 def set_colors(self):
344 self.set_p_str()
346 self.set_p_str()
345 Colors = self.cache.color_table.active_colors # shorthand
347 Colors = self.cache.color_table.active_colors # shorthand
346 self.col_p = Colors.out_prompt
348 self.col_p = Colors.out_prompt
347 self.col_num = Colors.out_number
349 self.col_num = Colors.out_number
348 self.col_norm = Colors.normal
350 self.col_norm = Colors.normal
349
351
350 class Prompt2(BasePrompt):
352 class Prompt2(BasePrompt):
351 """Interactive continuation prompt."""
353 """Interactive continuation prompt."""
352
354
353 def __init__(self,cache,prompt=' .\\D.: ',pad_left=True):
355 def __init__(self,cache,prompt=' .\\D.: ',pad_left=True):
354 self.cache = cache
356 self.cache = cache
355 self.p_template = prompt
357 self.p_template = prompt
356 self.pad_left = pad_left
358 self.pad_left = pad_left
357 self.set_p_str()
359 self.set_p_str()
358
360
359 def set_p_str(self):
361 def set_p_str(self):
360 import os,time # needed in locals for prompt string handling
362 import os,time # needed in locals for prompt string handling
361 loc = locals()
363 loc = locals()
362 self.p_str = ItplNS('%s%s%s' %
364 self.p_str = ItplNS('%s%s%s' %
363 ('${self.col_p2}',
365 ('${self.col_p2}',
364 multiple_replace(prompt_specials, self.p_template),
366 multiple_replace(prompt_specials, self.p_template),
365 '$self.col_norm'),
367 '$self.col_norm'),
366 self.cache.user_ns,loc)
368 self.cache.user_ns,loc)
367 self.p_str_nocolor = ItplNS(multiple_replace(prompt_specials_nocolor,
369 self.p_str_nocolor = ItplNS(multiple_replace(prompt_specials_nocolor,
368 self.p_template),
370 self.p_template),
369 self.cache.user_ns,loc)
371 self.cache.user_ns,loc)
370
372
371 def set_colors(self):
373 def set_colors(self):
372 self.set_p_str()
374 self.set_p_str()
373 Colors = self.cache.color_table.active_colors
375 Colors = self.cache.color_table.active_colors
374 self.col_p2 = Colors.in_prompt2
376 self.col_p2 = Colors.in_prompt2
375 self.col_norm = Colors.in_normal
377 self.col_norm = Colors.in_normal
376 # FIXME (2004-06-16) HACK: prevent crashes for users who haven't
378 # FIXME (2004-06-16) HACK: prevent crashes for users who haven't
377 # updated their prompt_in2 definitions. Remove eventually.
379 # updated their prompt_in2 definitions. Remove eventually.
378 self.col_p = Colors.out_prompt
380 self.col_p = Colors.out_prompt
379 self.col_num = Colors.out_number
381 self.col_num = Colors.out_number
380
382
381 #-----------------------------------------------------------------------------
383 #-----------------------------------------------------------------------------
382 class CachedOutput:
384 class CachedOutput:
383 """Class for printing output from calculations while keeping a cache of
385 """Class for printing output from calculations while keeping a cache of
384 reults. It dynamically creates global variables prefixed with _ which
386 reults. It dynamically creates global variables prefixed with _ which
385 contain these results.
387 contain these results.
386
388
387 Meant to be used as a sys.displayhook replacement, providing numbered
389 Meant to be used as a sys.displayhook replacement, providing numbered
388 prompts and cache services.
390 prompts and cache services.
389
391
390 Initialize with initial and final values for cache counter (this defines
392 Initialize with initial and final values for cache counter (this defines
391 the maximum size of the cache."""
393 the maximum size of the cache."""
392
394
393 def __init__(self,cache_size,Pprint,colors='NoColor',input_sep='\n',
395 def __init__(self,cache_size,Pprint,colors='NoColor',input_sep='\n',
394 output_sep='\n',output_sep2='',user_ns={},
396 output_sep='\n',output_sep2='',user_ns={},
395 ps1 = None, ps2 = None,ps_out = None,
397 ps1 = None, ps2 = None,ps_out = None,
396 input_hist = None,pad_left=True):
398 input_hist = None,pad_left=True):
397
399
398 cache_size_min = 20
400 cache_size_min = 20
399 if cache_size <= 0:
401 if cache_size <= 0:
400 self.do_full_cache = 0
402 self.do_full_cache = 0
401 cache_size = 0
403 cache_size = 0
402 elif cache_size < cache_size_min:
404 elif cache_size < cache_size_min:
403 self.do_full_cache = 0
405 self.do_full_cache = 0
404 cache_size = 0
406 cache_size = 0
405 warn('caching was disabled (min value for cache size is %s).' %
407 warn('caching was disabled (min value for cache size is %s).' %
406 cache_size_min,level=3)
408 cache_size_min,level=3)
407 else:
409 else:
408 self.do_full_cache = 1
410 self.do_full_cache = 1
409
411
410 self.cache_size = cache_size
412 self.cache_size = cache_size
411 self.input_sep = input_sep
413 self.input_sep = input_sep
412
414
413 # we need a reference to the user-level namespace
415 # we need a reference to the user-level namespace
414 self.user_ns = user_ns
416 self.user_ns = user_ns
415 # and to the user's input
417 # and to the user's input
416 self.input_hist = input_hist
418 self.input_hist = input_hist
417
419
418 # Set input prompt strings and colors
420 # Set input prompt strings and colors
419 if cache_size == 0:
421 if cache_size == 0:
420 if ps1.find('%n') > -1 or ps1.find('\\#') > -1: ps1 = '>>> '
422 if ps1.find('%n') > -1 or ps1.find('\\#') > -1: ps1 = '>>> '
421 if ps2.find('%n') > -1 or ps2.find('\\#') > -1: ps2 = '... '
423 if ps2.find('%n') > -1 or ps2.find('\\#') > -1: ps2 = '... '
422 self.ps1_str = self._set_prompt_str(ps1,'In [\\#]: ','>>> ')
424 self.ps1_str = self._set_prompt_str(ps1,'In [\\#]: ','>>> ')
423 self.ps2_str = self._set_prompt_str(ps2,' .\\D.: ','... ')
425 self.ps2_str = self._set_prompt_str(ps2,' .\\D.: ','... ')
424 self.ps_out_str = self._set_prompt_str(ps_out,'Out[\\#]: ','')
426 self.ps_out_str = self._set_prompt_str(ps_out,'Out[\\#]: ','')
425
427
426 self.color_table = PromptColors
428 self.color_table = PromptColors
427 self.prompt1 = Prompt1(self,sep=input_sep,prompt=self.ps1_str,
429 self.prompt1 = Prompt1(self,sep=input_sep,prompt=self.ps1_str,
428 pad_left=pad_left)
430 pad_left=pad_left)
429 self.prompt2 = Prompt2(self,prompt=self.ps2_str,pad_left=pad_left)
431 self.prompt2 = Prompt2(self,prompt=self.ps2_str,pad_left=pad_left)
430 self.prompt_out = PromptOut(self,sep='',prompt=self.ps_out_str,
432 self.prompt_out = PromptOut(self,sep='',prompt=self.ps_out_str,
431 pad_left=pad_left)
433 pad_left=pad_left)
432 self.set_colors(colors)
434 self.set_colors(colors)
433
435
434 # other more normal stuff
436 # other more normal stuff
435 # b/c each call to the In[] prompt raises it by 1, even the first.
437 # b/c each call to the In[] prompt raises it by 1, even the first.
436 self.prompt_count = 0
438 self.prompt_count = 0
437 self.cache_count = 1
439 self.cache_count = 1
438 # Store the last prompt string each time, we need it for aligning
440 # Store the last prompt string each time, we need it for aligning
439 # continuation and auto-rewrite prompts
441 # continuation and auto-rewrite prompts
440 self.last_prompt = ''
442 self.last_prompt = ''
441 self.entries = [None] # output counter starts at 1 for the user
443 self.entries = [None] # output counter starts at 1 for the user
442 self.Pprint = Pprint
444 self.Pprint = Pprint
443 self.output_sep = output_sep
445 self.output_sep = output_sep
444 self.output_sep2 = output_sep2
446 self.output_sep2 = output_sep2
445 self._,self.__,self.___ = '','',''
447 self._,self.__,self.___ = '','',''
446 self.pprint_types = map(type,[(),[],{}])
448 self.pprint_types = map(type,[(),[],{}])
447
449
448 # these are deliberately global:
450 # these are deliberately global:
449 to_user_ns = {'_':self._,'__':self.__,'___':self.___}
451 to_user_ns = {'_':self._,'__':self.__,'___':self.___}
450 self.user_ns.update(to_user_ns)
452 self.user_ns.update(to_user_ns)
451
453
452 def _set_prompt_str(self,p_str,cache_def,no_cache_def):
454 def _set_prompt_str(self,p_str,cache_def,no_cache_def):
453 if p_str is None:
455 if p_str is None:
454 if self.do_full_cache:
456 if self.do_full_cache:
455 return cache_def
457 return cache_def
456 else:
458 else:
457 return no_cache_def
459 return no_cache_def
458 else:
460 else:
459 return p_str
461 return p_str
460
462
461 def set_colors(self,colors):
463 def set_colors(self,colors):
462 """Set the active color scheme and configure colors for the three
464 """Set the active color scheme and configure colors for the three
463 prompt subsystems."""
465 prompt subsystems."""
464
466
465 # FIXME: the prompt_specials global should be gobbled inside this
467 # FIXME: the prompt_specials global should be gobbled inside this
466 # class instead. Do it when cleaning up the whole 3-prompt system.
468 # class instead. Do it when cleaning up the whole 3-prompt system.
467 global prompt_specials
469 global prompt_specials
468 if colors.lower()=='nocolor':
470 if colors.lower()=='nocolor':
469 prompt_specials = prompt_specials_nocolor
471 prompt_specials = prompt_specials_nocolor
470 else:
472 else:
471 prompt_specials = prompt_specials_color
473 prompt_specials = prompt_specials_color
472
474
473 self.color_table.set_active_scheme(colors)
475 self.color_table.set_active_scheme(colors)
474 self.prompt1.set_colors()
476 self.prompt1.set_colors()
475 self.prompt2.set_colors()
477 self.prompt2.set_colors()
476 self.prompt_out.set_colors()
478 self.prompt_out.set_colors()
477
479
478 def __call__(self,arg=None):
480 def __call__(self,arg=None):
479 """Printing with history cache management.
481 """Printing with history cache management.
480
482
481 This is invoked everytime the interpreter needs to print, and is
483 This is invoked everytime the interpreter needs to print, and is
482 activated by setting the variable sys.displayhook to it."""
484 activated by setting the variable sys.displayhook to it."""
483
485
484 # If something injected a '_' variable in __builtin__, delete
486 # If something injected a '_' variable in __builtin__, delete
485 # ipython's automatic one so we don't clobber that. gettext() in
487 # ipython's automatic one so we don't clobber that. gettext() in
486 # particular uses _, so we need to stay away from it.
488 # particular uses _, so we need to stay away from it.
487 if '_' in __builtin__.__dict__:
489 if '_' in __builtin__.__dict__:
488 try:
490 try:
489 del self.user_ns['_']
491 del self.user_ns['_']
490 except KeyError:
492 except KeyError:
491 pass
493 pass
492 if arg is not None:
494 if arg is not None:
493 cout_write = Term.cout.write # fast lookup
495 cout_write = Term.cout.write # fast lookup
494 # first handle the cache and counters
496 # first handle the cache and counters
495 self.update(arg)
497 self.update(arg)
496 # do not print output if input ends in ';'
498 # do not print output if input ends in ';'
497 if self.input_hist[self.prompt_count].endswith(';\n'):
499 if self.input_hist[self.prompt_count].endswith(';\n'):
498 return
500 return
499 # don't use print, puts an extra space
501 # don't use print, puts an extra space
500 cout_write(self.output_sep)
502 cout_write(self.output_sep)
501 if self.do_full_cache:
503 if self.do_full_cache:
502 cout_write(str(self.prompt_out))
504 cout_write(str(self.prompt_out))
503
505
504 if isinstance(arg,Macro):
506 if isinstance(arg,Macro):
505 print 'Executing Macro...'
507 print 'Executing Macro...'
506 # in case the macro takes a long time to execute
508 # in case the macro takes a long time to execute
507 Term.cout.flush()
509 Term.cout.flush()
508 exec arg.value in self.user_ns
510 exec arg.value in self.user_ns
509 return None
511 return None
510
512
511 # and now call a possibly user-defined print mechanism
513 # and now call a possibly user-defined print mechanism
512 self.display(arg)
514 self.display(arg)
513 cout_write(self.output_sep2)
515 cout_write(self.output_sep2)
514 Term.cout.flush()
516 Term.cout.flush()
515
517
516 def _display(self,arg):
518 def _display(self,arg):
517 """Default printer method, uses pprint.
519 """Default printer method, uses pprint.
518
520
519 This can be over-ridden by the users to implement special formatting
521 This can be over-ridden by the users to implement special formatting
520 of certain types of output."""
522 of certain types of output."""
521
523
522 if self.Pprint:
524 if self.Pprint:
523 out = pformat(arg)
525 out = pformat(arg)
524 if '\n' in out:
526 if '\n' in out:
525 # So that multi-line strings line up with the left column of
527 # So that multi-line strings line up with the left column of
526 # the screen, instead of having the output prompt mess up
528 # the screen, instead of having the output prompt mess up
527 # their first line.
529 # their first line.
528 Term.cout.write('\n')
530 Term.cout.write('\n')
529 print >>Term.cout, out
531 print >>Term.cout, out
530 else:
532 else:
531 print >>Term.cout, arg
533 print >>Term.cout, arg
532
534
533 # Assign the default display method:
535 # Assign the default display method:
534 display = _display
536 display = _display
535
537
536 def update(self,arg):
538 def update(self,arg):
537 #print '***cache_count', self.cache_count # dbg
539 #print '***cache_count', self.cache_count # dbg
538 if self.cache_count >= self.cache_size and self.do_full_cache:
540 if self.cache_count >= self.cache_size and self.do_full_cache:
539 self.flush()
541 self.flush()
540 # Don't overwrite '_' and friends if '_' is in __builtin__ (otherwise
542 # Don't overwrite '_' and friends if '_' is in __builtin__ (otherwise
541 # we cause buggy behavior for things like gettext).
543 # we cause buggy behavior for things like gettext).
542 if '_' not in __builtin__.__dict__:
544 if '_' not in __builtin__.__dict__:
543 self.___ = self.__
545 self.___ = self.__
544 self.__ = self._
546 self.__ = self._
545 self._ = arg
547 self._ = arg
546 self.user_ns.update({'_':self._,'__':self.__,'___':self.___})
548 self.user_ns.update({'_':self._,'__':self.__,'___':self.___})
547
549
548 # hackish access to top-level namespace to create _1,_2... dynamically
550 # hackish access to top-level namespace to create _1,_2... dynamically
549 to_main = {}
551 to_main = {}
550 if self.do_full_cache:
552 if self.do_full_cache:
551 self.cache_count += 1
553 self.cache_count += 1
552 self.entries.append(arg)
554 self.entries.append(arg)
553 new_result = '_'+`self.prompt_count`
555 new_result = '_'+`self.prompt_count`
554 to_main[new_result] = self.entries[-1]
556 to_main[new_result] = self.entries[-1]
555 self.user_ns.update(to_main)
557 self.user_ns.update(to_main)
556 self.user_ns['_oh'][self.prompt_count] = arg
558 self.user_ns['_oh'][self.prompt_count] = arg
557
559
558 def flush(self):
560 def flush(self):
559 if not self.do_full_cache:
561 if not self.do_full_cache:
560 raise ValueError,"You shouldn't have reached the cache flush "\
562 raise ValueError,"You shouldn't have reached the cache flush "\
561 "if full caching is not enabled!"
563 "if full caching is not enabled!"
562 warn('Output cache limit (currently '+\
564 warn('Output cache limit (currently '+\
563 `self.cache_count`+' entries) hit.\n'
565 `self.cache_count`+' entries) hit.\n'
564 'Flushing cache and resetting history counter...\n'
566 'Flushing cache and resetting history counter...\n'
565 'The only history variables available will be _,__,___ and _1\n'
567 'The only history variables available will be _,__,___ and _1\n'
566 'with the current result.')
568 'with the current result.')
567 # delete auto-generated vars from global namespace
569 # delete auto-generated vars from global namespace
568 for n in range(1,self.prompt_count + 1):
570 for n in range(1,self.prompt_count + 1):
569 key = '_'+`n`
571 key = '_'+`n`
570 try:
572 try:
571 del self.user_ns[key]
573 del self.user_ns[key]
572 except: pass
574 except: pass
573 self.prompt_count = 1
575 self.prompt_count = 1
574 self.cache_count = 1
576 self.cache_count = 1
@@ -1,255 +1,260 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 Class and program to colorize python source code for ANSI terminals.
3 Class and program to colorize python source code for ANSI terminals.
4
4
5 Based on an HTML code highlighter by Jurgen Hermann found at:
5 Based on an HTML code highlighter by Jurgen Hermann found at:
6 http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52298
6 http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52298
7
7
8 Modifications by Fernando Perez (fperez@colorado.edu).
8 Modifications by Fernando Perez (fperez@colorado.edu).
9
9
10 Information on the original HTML highlighter follows:
10 Information on the original HTML highlighter follows:
11
11
12 MoinMoin - Python Source Parser
12 MoinMoin - Python Source Parser
13
13
14 Title:olorize Python source using the built-in tokenizer
14 Title:olorize Python source using the built-in tokenizer
15
15
16 Submitter: Jurgen Hermann
16 Submitter: Jurgen Hermann
17 Last Updated:2001/04/06
17 Last Updated:2001/04/06
18
18
19 Version no:1.2
19 Version no:1.2
20
20
21 Description:
21 Description:
22
22
23 This code is part of MoinMoin (http://moin.sourceforge.net/) and converts
23 This code is part of MoinMoin (http://moin.sourceforge.net/) and converts
24 Python source code to HTML markup, rendering comments, keywords,
24 Python source code to HTML markup, rendering comments, keywords,
25 operators, numeric and string literals in different colors.
25 operators, numeric and string literals in different colors.
26
26
27 It shows how to use the built-in keyword, token and tokenize modules to
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
28 scan Python source code and re-emit it with no changes to its original
29 formatting (which is the hard part).
29 formatting (which is the hard part).
30
30
31 $Id: PyColorize.py 485 2005-01-27 19:15:39Z fperez $"""
31 $Id: PyColorize.py 958 2005-12-27 23:17:51Z fperez $"""
32
32
33 __all__ = ['ANSICodeColors','Parser']
33 __all__ = ['ANSICodeColors','Parser']
34
34
35 _scheme_default = 'Linux'
35 _scheme_default = 'Linux'
36
36
37 # Imports
37 # Imports
38 import string, sys, os, cStringIO
38 import cStringIO
39 import keyword, token, tokenize
39 import keyword
40 import os
41 import string
42 import sys
43 import token
44 import tokenize
40
45
41 from IPython.ColorANSI import *
46 from IPython.ColorANSI import *
42
47
43 #############################################################################
48 #############################################################################
44 ### Python Source Parser (does Hilighting)
49 ### Python Source Parser (does Hilighting)
45 #############################################################################
50 #############################################################################
46
51
47 _KEYWORD = token.NT_OFFSET + 1
52 _KEYWORD = token.NT_OFFSET + 1
48 _TEXT = token.NT_OFFSET + 2
53 _TEXT = token.NT_OFFSET + 2
49
54
50 #****************************************************************************
55 #****************************************************************************
51 # Builtin color schemes
56 # Builtin color schemes
52
57
53 Colors = TermColors # just a shorthand
58 Colors = TermColors # just a shorthand
54
59
55 # Build a few color schemes
60 # Build a few color schemes
56 NoColor = ColorScheme(
61 NoColor = ColorScheme(
57 'NoColor',{
62 'NoColor',{
58 token.NUMBER : Colors.NoColor,
63 token.NUMBER : Colors.NoColor,
59 token.OP : Colors.NoColor,
64 token.OP : Colors.NoColor,
60 token.STRING : Colors.NoColor,
65 token.STRING : Colors.NoColor,
61 tokenize.COMMENT : Colors.NoColor,
66 tokenize.COMMENT : Colors.NoColor,
62 token.NAME : Colors.NoColor,
67 token.NAME : Colors.NoColor,
63 token.ERRORTOKEN : Colors.NoColor,
68 token.ERRORTOKEN : Colors.NoColor,
64
69
65 _KEYWORD : Colors.NoColor,
70 _KEYWORD : Colors.NoColor,
66 _TEXT : Colors.NoColor,
71 _TEXT : Colors.NoColor,
67
72
68 'normal' : Colors.NoColor # color off (usu. Colors.Normal)
73 'normal' : Colors.NoColor # color off (usu. Colors.Normal)
69 } )
74 } )
70
75
71 LinuxColors = ColorScheme(
76 LinuxColors = ColorScheme(
72 'Linux',{
77 'Linux',{
73 token.NUMBER : Colors.LightCyan,
78 token.NUMBER : Colors.LightCyan,
74 token.OP : Colors.Yellow,
79 token.OP : Colors.Yellow,
75 token.STRING : Colors.LightBlue,
80 token.STRING : Colors.LightBlue,
76 tokenize.COMMENT : Colors.LightRed,
81 tokenize.COMMENT : Colors.LightRed,
77 token.NAME : Colors.White,
82 token.NAME : Colors.White,
78 token.ERRORTOKEN : Colors.Red,
83 token.ERRORTOKEN : Colors.Red,
79
84
80 _KEYWORD : Colors.LightGreen,
85 _KEYWORD : Colors.LightGreen,
81 _TEXT : Colors.Yellow,
86 _TEXT : Colors.Yellow,
82
87
83 'normal' : Colors.Normal # color off (usu. Colors.Normal)
88 'normal' : Colors.Normal # color off (usu. Colors.Normal)
84 } )
89 } )
85
90
86 LightBGColors = ColorScheme(
91 LightBGColors = ColorScheme(
87 'LightBG',{
92 'LightBG',{
88 token.NUMBER : Colors.Cyan,
93 token.NUMBER : Colors.Cyan,
89 token.OP : Colors.Blue,
94 token.OP : Colors.Blue,
90 token.STRING : Colors.Blue,
95 token.STRING : Colors.Blue,
91 tokenize.COMMENT : Colors.Red,
96 tokenize.COMMENT : Colors.Red,
92 token.NAME : Colors.Black,
97 token.NAME : Colors.Black,
93 token.ERRORTOKEN : Colors.Red,
98 token.ERRORTOKEN : Colors.Red,
94
99
95 _KEYWORD : Colors.Green,
100 _KEYWORD : Colors.Green,
96 _TEXT : Colors.Blue,
101 _TEXT : Colors.Blue,
97
102
98 'normal' : Colors.Normal # color off (usu. Colors.Normal)
103 'normal' : Colors.Normal # color off (usu. Colors.Normal)
99 } )
104 } )
100
105
101 # Build table of color schemes (needed by the parser)
106 # Build table of color schemes (needed by the parser)
102 ANSICodeColors = ColorSchemeTable([NoColor,LinuxColors,LightBGColors],
107 ANSICodeColors = ColorSchemeTable([NoColor,LinuxColors,LightBGColors],
103 _scheme_default)
108 _scheme_default)
104
109
105 class Parser:
110 class Parser:
106 """ Format colored Python source.
111 """ Format colored Python source.
107 """
112 """
108
113
109 def __init__(self, color_table=None,out = sys.stdout):
114 def __init__(self, color_table=None,out = sys.stdout):
110 """ Create a parser with a specified color table and output channel.
115 """ Create a parser with a specified color table and output channel.
111
116
112 Call format() to process code.
117 Call format() to process code.
113 """
118 """
114 self.color_table = color_table and color_table or ANSICodeColors
119 self.color_table = color_table and color_table or ANSICodeColors
115 self.out = out
120 self.out = out
116
121
117 def format(self, raw, out = None, scheme = ''):
122 def format(self, raw, out = None, scheme = ''):
118 """ Parse and send the colored source.
123 """ Parse and send the colored source.
119
124
120 If out and scheme are not specified, the defaults (given to
125 If out and scheme are not specified, the defaults (given to
121 constructor) are used.
126 constructor) are used.
122
127
123 out should be a file-type object. Optionally, out can be given as the
128 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
129 string 'str' and the parser will automatically return the output in a
125 string."""
130 string."""
126
131
127 self.raw = string.strip(string.expandtabs(raw))
132 self.raw = string.strip(string.expandtabs(raw))
128 string_output = 0
133 string_output = 0
129 if out == 'str' or self.out == 'str':
134 if out == 'str' or self.out == 'str':
130 out_old = self.out
135 out_old = self.out
131 self.out = cStringIO.StringIO()
136 self.out = cStringIO.StringIO()
132 string_output = 1
137 string_output = 1
133 elif out is not None:
138 elif out is not None:
134 self.out = out
139 self.out = out
135 # local shorthand
140 # local shorthand
136 colors = self.color_table[scheme].colors
141 colors = self.color_table[scheme].colors
137 self.colors = colors # put in object so __call__ sees it
142 self.colors = colors # put in object so __call__ sees it
138 # store line offsets in self.lines
143 # store line offsets in self.lines
139 self.lines = [0, 0]
144 self.lines = [0, 0]
140 pos = 0
145 pos = 0
141 while 1:
146 while 1:
142 pos = string.find(self.raw, '\n', pos) + 1
147 pos = string.find(self.raw, '\n', pos) + 1
143 if not pos: break
148 if not pos: break
144 self.lines.append(pos)
149 self.lines.append(pos)
145 self.lines.append(len(self.raw))
150 self.lines.append(len(self.raw))
146
151
147 # parse the source and write it
152 # parse the source and write it
148 self.pos = 0
153 self.pos = 0
149 text = cStringIO.StringIO(self.raw)
154 text = cStringIO.StringIO(self.raw)
150 #self.out.write('<pre><font face="Courier New">')
155 #self.out.write('<pre><font face="Courier New">')
151 try:
156 try:
152 tokenize.tokenize(text.readline, self)
157 tokenize.tokenize(text.readline, self)
153 except tokenize.TokenError, ex:
158 except tokenize.TokenError, ex:
154 msg = ex[0]
159 msg = ex[0]
155 line = ex[1][0]
160 line = ex[1][0]
156 self.out.write("%s\n\n*** ERROR: %s%s%s\n" %
161 self.out.write("%s\n\n*** ERROR: %s%s%s\n" %
157 (colors[token.ERRORTOKEN],
162 (colors[token.ERRORTOKEN],
158 msg, self.raw[self.lines[line]:],
163 msg, self.raw[self.lines[line]:],
159 colors.normal)
164 colors.normal)
160 )
165 )
161 self.out.write(colors.normal+'\n')
166 self.out.write(colors.normal+'\n')
162 if string_output:
167 if string_output:
163 output = self.out.getvalue()
168 output = self.out.getvalue()
164 self.out = out_old
169 self.out = out_old
165 return output
170 return output
166
171
167 def __call__(self, toktype, toktext, (srow,scol), (erow,ecol), line):
172 def __call__(self, toktype, toktext, (srow,scol), (erow,ecol), line):
168 """ Token handler, with syntax highlighting."""
173 """ Token handler, with syntax highlighting."""
169
174
170 # local shorthand
175 # local shorthand
171 colors = self.colors
176 colors = self.colors
172
177
173 # line separator, so this works across platforms
178 # line separator, so this works across platforms
174 linesep = os.linesep
179 linesep = os.linesep
175
180
176 # calculate new positions
181 # calculate new positions
177 oldpos = self.pos
182 oldpos = self.pos
178 newpos = self.lines[srow] + scol
183 newpos = self.lines[srow] + scol
179 self.pos = newpos + len(toktext)
184 self.pos = newpos + len(toktext)
180
185
181 # handle newlines
186 # handle newlines
182 if toktype in [token.NEWLINE, tokenize.NL]:
187 if toktype in [token.NEWLINE, tokenize.NL]:
183 self.out.write(linesep)
188 self.out.write(linesep)
184 return
189 return
185
190
186 # send the original whitespace, if needed
191 # send the original whitespace, if needed
187 if newpos > oldpos:
192 if newpos > oldpos:
188 self.out.write(self.raw[oldpos:newpos])
193 self.out.write(self.raw[oldpos:newpos])
189
194
190 # skip indenting tokens
195 # skip indenting tokens
191 if toktype in [token.INDENT, token.DEDENT]:
196 if toktype in [token.INDENT, token.DEDENT]:
192 self.pos = newpos
197 self.pos = newpos
193 return
198 return
194
199
195 # map token type to a color group
200 # map token type to a color group
196 if token.LPAR <= toktype and toktype <= token.OP:
201 if token.LPAR <= toktype and toktype <= token.OP:
197 toktype = token.OP
202 toktype = token.OP
198 elif toktype == token.NAME and keyword.iskeyword(toktext):
203 elif toktype == token.NAME and keyword.iskeyword(toktext):
199 toktype = _KEYWORD
204 toktype = _KEYWORD
200 color = colors.get(toktype, colors[_TEXT])
205 color = colors.get(toktype, colors[_TEXT])
201
206
202 #print '<%s>' % toktext, # dbg
207 #print '<%s>' % toktext, # dbg
203
208
204 # Triple quoted strings must be handled carefully so that backtracking
209 # Triple quoted strings must be handled carefully so that backtracking
205 # in pagers works correctly. We need color terminators on _each_ line.
210 # in pagers works correctly. We need color terminators on _each_ line.
206 if linesep in toktext:
211 if linesep in toktext:
207 toktext = toktext.replace(linesep, '%s%s%s' %
212 toktext = toktext.replace(linesep, '%s%s%s' %
208 (colors.normal,linesep,color))
213 (colors.normal,linesep,color))
209
214
210 # send text
215 # send text
211 self.out.write('%s%s%s' % (color,toktext,colors.normal))
216 self.out.write('%s%s%s' % (color,toktext,colors.normal))
212
217
213 def main():
218 def main():
214 """Colorize a python file using ANSI color escapes and print to stdout.
219 """Colorize a python file using ANSI color escapes and print to stdout.
215
220
216 Usage:
221 Usage:
217 %s [-s scheme] filename
222 %s [-s scheme] filename
218
223
219 Options:
224 Options:
220
225
221 -s scheme: give the color scheme to use. Currently only 'Linux'
226 -s scheme: give the color scheme to use. Currently only 'Linux'
222 (default) and 'LightBG' and 'NoColor' are implemented (give without
227 (default) and 'LightBG' and 'NoColor' are implemented (give without
223 quotes). """
228 quotes). """
224
229
225 def usage():
230 def usage():
226 print >> sys.stderr, main.__doc__ % sys.argv[0]
231 print >> sys.stderr, main.__doc__ % sys.argv[0]
227 sys.exit(1)
232 sys.exit(1)
228
233
229 # FIXME: rewrite this to at least use getopt
234 # FIXME: rewrite this to at least use getopt
230 try:
235 try:
231 if sys.argv[1] == '-s':
236 if sys.argv[1] == '-s':
232 scheme_name = sys.argv[2]
237 scheme_name = sys.argv[2]
233 del sys.argv[1:3]
238 del sys.argv[1:3]
234 else:
239 else:
235 scheme_name = _scheme_default
240 scheme_name = _scheme_default
236
241
237 except:
242 except:
238 usage()
243 usage()
239
244
240 try:
245 try:
241 fname = sys.argv[1]
246 fname = sys.argv[1]
242 except:
247 except:
243 usage()
248 usage()
244
249
245 # write colorized version to stdout
250 # write colorized version to stdout
246 parser = Parser()
251 parser = Parser()
247 try:
252 try:
248 parser.format(file(fname).read(),scheme = scheme_name)
253 parser.format(file(fname).read(),scheme = scheme_name)
249 except IOError,msg:
254 except IOError,msg:
250 # if user reads through a pager and quits, don't print traceback
255 # if user reads through a pager and quits, don't print traceback
251 if msg.args != (32,'Broken pipe'):
256 if msg.args != (32,'Broken pipe'):
252 raise
257 raise
253
258
254 if __name__ == "__main__":
259 if __name__ == "__main__":
255 main()
260 main()
@@ -1,901 +1,900 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """IPython Shell classes.
2 """IPython Shell classes.
3
3
4 All the matplotlib support code was co-developed with John Hunter,
4 All the matplotlib support code was co-developed with John Hunter,
5 matplotlib's author.
5 matplotlib's author.
6
6
7 $Id: Shell.py 952 2005-12-26 17:51:33Z fperez $"""
7 $Id: Shell.py 958 2005-12-27 23:17:51Z fperez $"""
8
8
9 #*****************************************************************************
9 #*****************************************************************************
10 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
10 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
11 #
11 #
12 # Distributed under the terms of the BSD License. The full license is in
12 # Distributed under the terms of the BSD License. The full license is in
13 # the file COPYING, distributed as part of this software.
13 # the file COPYING, distributed as part of this software.
14 #*****************************************************************************
14 #*****************************************************************************
15
15
16 from IPython import Release
16 from IPython import Release
17 __author__ = '%s <%s>' % Release.authors['Fernando']
17 __author__ = '%s <%s>' % Release.authors['Fernando']
18 __license__ = Release.license
18 __license__ = Release.license
19
19
20 # Code begins
20 # Code begins
21 import __main__
21 import __main__
22 import __builtin__
22 import __builtin__
23 import sys
24 import os
23 import os
25 import code
24 import sys
26 import threading
27 import signal
25 import signal
26 import threading
28
27
29 import IPython
28 import IPython
29 from IPython import ultraTB
30 from IPython.genutils import Term,warn,error,flag_calls
30 from IPython.iplib import InteractiveShell
31 from IPython.iplib import InteractiveShell
31 from IPython.ipmaker import make_IPython
32 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
33 from IPython.Magic import Magic
35 from IPython import ultraTB
34 from IPython.Struct import Struct
36
35
37 # global flag to pass around information about Ctrl-C without exceptions
36 # global flag to pass around information about Ctrl-C without exceptions
38 KBINT = False
37 KBINT = False
39
38
40 # global flag to turn on/off Tk support.
39 # global flag to turn on/off Tk support.
41 USE_TK = False
40 USE_TK = False
42
41
43 #-----------------------------------------------------------------------------
42 #-----------------------------------------------------------------------------
44 # This class is trivial now, but I want to have it in to publish a clean
43 # 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
44 # interface. Later when the internals are reorganized, code that uses this
46 # shouldn't have to change.
45 # shouldn't have to change.
47
46
48 class IPShell:
47 class IPShell:
49 """Create an IPython instance."""
48 """Create an IPython instance."""
50
49
51 def __init__(self,argv=None,user_ns=None,debug=1,
50 def __init__(self,argv=None,user_ns=None,debug=1,
52 shell_class=InteractiveShell):
51 shell_class=InteractiveShell):
53 self.IP = make_IPython(argv,user_ns=user_ns,debug=debug,
52 self.IP = make_IPython(argv,user_ns=user_ns,debug=debug,
54 shell_class=shell_class)
53 shell_class=shell_class)
55
54
56 def mainloop(self,sys_exit=0,banner=None):
55 def mainloop(self,sys_exit=0,banner=None):
57 self.IP.mainloop(banner)
56 self.IP.mainloop(banner)
58 if sys_exit:
57 if sys_exit:
59 sys.exit()
58 sys.exit()
60
59
61 #-----------------------------------------------------------------------------
60 #-----------------------------------------------------------------------------
62 class IPShellEmbed:
61 class IPShellEmbed:
63 """Allow embedding an IPython shell into a running program.
62 """Allow embedding an IPython shell into a running program.
64
63
65 Instances of this class are callable, with the __call__ method being an
64 Instances of this class are callable, with the __call__ method being an
66 alias to the embed() method of an InteractiveShell instance.
65 alias to the embed() method of an InteractiveShell instance.
67
66
68 Usage (see also the example-embed.py file for a running example):
67 Usage (see also the example-embed.py file for a running example):
69
68
70 ipshell = IPShellEmbed([argv,banner,exit_msg,rc_override])
69 ipshell = IPShellEmbed([argv,banner,exit_msg,rc_override])
71
70
72 - argv: list containing valid command-line options for IPython, as they
71 - argv: list containing valid command-line options for IPython, as they
73 would appear in sys.argv[1:].
72 would appear in sys.argv[1:].
74
73
75 For example, the following command-line options:
74 For example, the following command-line options:
76
75
77 $ ipython -prompt_in1 'Input <\\#>' -colors LightBG
76 $ ipython -prompt_in1 'Input <\\#>' -colors LightBG
78
77
79 would be passed in the argv list as:
78 would be passed in the argv list as:
80
79
81 ['-prompt_in1','Input <\\#>','-colors','LightBG']
80 ['-prompt_in1','Input <\\#>','-colors','LightBG']
82
81
83 - banner: string which gets printed every time the interpreter starts.
82 - banner: string which gets printed every time the interpreter starts.
84
83
85 - exit_msg: string which gets printed every time the interpreter exits.
84 - exit_msg: string which gets printed every time the interpreter exits.
86
85
87 - rc_override: a dict or Struct of configuration options such as those
86 - rc_override: a dict or Struct of configuration options such as those
88 used by IPython. These options are read from your ~/.ipython/ipythonrc
87 used by IPython. These options are read from your ~/.ipython/ipythonrc
89 file when the Shell object is created. Passing an explicit rc_override
88 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
89 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
90 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
91 embeddable instances configured in any way you want without editing any
93 global files (thus keeping your interactive IPython configuration
92 global files (thus keeping your interactive IPython configuration
94 unchanged).
93 unchanged).
95
94
96 Then the ipshell instance can be called anywhere inside your code:
95 Then the ipshell instance can be called anywhere inside your code:
97
96
98 ipshell(header='') -> Opens up an IPython shell.
97 ipshell(header='') -> Opens up an IPython shell.
99
98
100 - header: string printed by the IPython shell upon startup. This can let
99 - 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
100 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
101 that 'banner' gets prepended to all calls, so header is used for
103 location-specific information.
102 location-specific information.
104
103
105 For more details, see the __call__ method below.
104 For more details, see the __call__ method below.
106
105
107 When the IPython shell is exited with Ctrl-D, normal program execution
106 When the IPython shell is exited with Ctrl-D, normal program execution
108 resumes.
107 resumes.
109
108
110 This functionality was inspired by a posting on comp.lang.python by cmkl
109 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
110 <cmkleffner@gmx.de> on Dec. 06/01 concerning similar uses of pyrepl, and
112 by the IDL stop/continue commands."""
111 by the IDL stop/continue commands."""
113
112
114 def __init__(self,argv=None,banner='',exit_msg=None,rc_override=None):
113 def __init__(self,argv=None,banner='',exit_msg=None,rc_override=None):
115 """Note that argv here is a string, NOT a list."""
114 """Note that argv here is a string, NOT a list."""
116 self.set_banner(banner)
115 self.set_banner(banner)
117 self.set_exit_msg(exit_msg)
116 self.set_exit_msg(exit_msg)
118 self.set_dummy_mode(0)
117 self.set_dummy_mode(0)
119
118
120 # sys.displayhook is a global, we need to save the user's original
119 # 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.
120 # Don't rely on __displayhook__, as the user may have changed that.
122 self.sys_displayhook_ori = sys.displayhook
121 self.sys_displayhook_ori = sys.displayhook
123
122
124 # save readline completer status
123 # save readline completer status
125 try:
124 try:
126 #print 'Save completer',sys.ipcompleter # dbg
125 #print 'Save completer',sys.ipcompleter # dbg
127 self.sys_ipcompleter_ori = sys.ipcompleter
126 self.sys_ipcompleter_ori = sys.ipcompleter
128 except:
127 except:
129 pass # not nested with IPython
128 pass # not nested with IPython
130
129
131 # FIXME. Passing user_ns breaks namespace handling.
130 # FIXME. Passing user_ns breaks namespace handling.
132 #self.IP = make_IPython(argv,user_ns=__main__.__dict__)
131 #self.IP = make_IPython(argv,user_ns=__main__.__dict__)
133 self.IP = make_IPython(argv,rc_override=rc_override,embedded=True)
132 self.IP = make_IPython(argv,rc_override=rc_override,embedded=True)
134
133
135 # copy our own displayhook also
134 # copy our own displayhook also
136 self.sys_displayhook_embed = sys.displayhook
135 self.sys_displayhook_embed = sys.displayhook
137 # and leave the system's display hook clean
136 # and leave the system's display hook clean
138 sys.displayhook = self.sys_displayhook_ori
137 sys.displayhook = self.sys_displayhook_ori
139 # don't use the ipython crash handler so that user exceptions aren't
138 # don't use the ipython crash handler so that user exceptions aren't
140 # trapped
139 # trapped
141 sys.excepthook = ultraTB.FormattedTB(color_scheme = self.IP.rc.colors,
140 sys.excepthook = ultraTB.FormattedTB(color_scheme = self.IP.rc.colors,
142 mode = self.IP.rc.xmode,
141 mode = self.IP.rc.xmode,
143 call_pdb = self.IP.rc.pdb)
142 call_pdb = self.IP.rc.pdb)
144 self.restore_system_completer()
143 self.restore_system_completer()
145
144
146 def restore_system_completer(self):
145 def restore_system_completer(self):
147 """Restores the readline completer which was in place.
146 """Restores the readline completer which was in place.
148
147
149 This allows embedded IPython within IPython not to disrupt the
148 This allows embedded IPython within IPython not to disrupt the
150 parent's completion.
149 parent's completion.
151 """
150 """
152
151
153 try:
152 try:
154 self.IP.readline.set_completer(self.sys_ipcompleter_ori)
153 self.IP.readline.set_completer(self.sys_ipcompleter_ori)
155 sys.ipcompleter = self.sys_ipcompleter_ori
154 sys.ipcompleter = self.sys_ipcompleter_ori
156 except:
155 except:
157 pass
156 pass
158
157
159 def __call__(self,header='',local_ns=None,global_ns=None,dummy=None):
158 def __call__(self,header='',local_ns=None,global_ns=None,dummy=None):
160 """Activate the interactive interpreter.
159 """Activate the interactive interpreter.
161
160
162 __call__(self,header='',local_ns=None,global_ns,dummy=None) -> Start
161 __call__(self,header='',local_ns=None,global_ns,dummy=None) -> Start
163 the interpreter shell with the given local and global namespaces, and
162 the interpreter shell with the given local and global namespaces, and
164 optionally print a header string at startup.
163 optionally print a header string at startup.
165
164
166 The shell can be globally activated/deactivated using the
165 The shell can be globally activated/deactivated using the
167 set/get_dummy_mode methods. This allows you to turn off a shell used
166 set/get_dummy_mode methods. This allows you to turn off a shell used
168 for debugging globally.
167 for debugging globally.
169
168
170 However, *each* time you call the shell you can override the current
169 However, *each* time you call the shell you can override the current
171 state of dummy_mode with the optional keyword parameter 'dummy'. For
170 state of dummy_mode with the optional keyword parameter 'dummy'. For
172 example, if you set dummy mode on with IPShell.set_dummy_mode(1), you
171 example, if you set dummy mode on with IPShell.set_dummy_mode(1), you
173 can still have a specific call work by making it as IPShell(dummy=0).
172 can still have a specific call work by making it as IPShell(dummy=0).
174
173
175 The optional keyword parameter dummy controls whether the call
174 The optional keyword parameter dummy controls whether the call
176 actually does anything. """
175 actually does anything. """
177
176
178 # Allow the dummy parameter to override the global __dummy_mode
177 # Allow the dummy parameter to override the global __dummy_mode
179 if dummy or (dummy != 0 and self.__dummy_mode):
178 if dummy or (dummy != 0 and self.__dummy_mode):
180 return
179 return
181
180
182 # Set global subsystems (display,completions) to our values
181 # Set global subsystems (display,completions) to our values
183 sys.displayhook = self.sys_displayhook_embed
182 sys.displayhook = self.sys_displayhook_embed
184 if self.IP.has_readline:
183 if self.IP.has_readline:
185 self.IP.readline.set_completer(self.IP.Completer.complete)
184 self.IP.readline.set_completer(self.IP.Completer.complete)
186
185
187 if self.banner and header:
186 if self.banner and header:
188 format = '%s\n%s\n'
187 format = '%s\n%s\n'
189 else:
188 else:
190 format = '%s%s\n'
189 format = '%s%s\n'
191 banner = format % (self.banner,header)
190 banner = format % (self.banner,header)
192
191
193 # Call the embedding code with a stack depth of 1 so it can skip over
192 # Call the embedding code with a stack depth of 1 so it can skip over
194 # our call and get the original caller's namespaces.
193 # our call and get the original caller's namespaces.
195 self.IP.embed_mainloop(banner,local_ns,global_ns,stack_depth=1)
194 self.IP.embed_mainloop(banner,local_ns,global_ns,stack_depth=1)
196
195
197 if self.exit_msg:
196 if self.exit_msg:
198 print self.exit_msg
197 print self.exit_msg
199
198
200 # Restore global systems (display, completion)
199 # Restore global systems (display, completion)
201 sys.displayhook = self.sys_displayhook_ori
200 sys.displayhook = self.sys_displayhook_ori
202 self.restore_system_completer()
201 self.restore_system_completer()
203
202
204 def set_dummy_mode(self,dummy):
203 def set_dummy_mode(self,dummy):
205 """Sets the embeddable shell's dummy mode parameter.
204 """Sets the embeddable shell's dummy mode parameter.
206
205
207 set_dummy_mode(dummy): dummy = 0 or 1.
206 set_dummy_mode(dummy): dummy = 0 or 1.
208
207
209 This parameter is persistent and makes calls to the embeddable shell
208 This parameter is persistent and makes calls to the embeddable shell
210 silently return without performing any action. This allows you to
209 silently return without performing any action. This allows you to
211 globally activate or deactivate a shell you're using with a single call.
210 globally activate or deactivate a shell you're using with a single call.
212
211
213 If you need to manually"""
212 If you need to manually"""
214
213
215 if dummy not in [0,1,False,True]:
214 if dummy not in [0,1,False,True]:
216 raise ValueError,'dummy parameter must be boolean'
215 raise ValueError,'dummy parameter must be boolean'
217 self.__dummy_mode = dummy
216 self.__dummy_mode = dummy
218
217
219 def get_dummy_mode(self):
218 def get_dummy_mode(self):
220 """Return the current value of the dummy mode parameter.
219 """Return the current value of the dummy mode parameter.
221 """
220 """
222 return self.__dummy_mode
221 return self.__dummy_mode
223
222
224 def set_banner(self,banner):
223 def set_banner(self,banner):
225 """Sets the global banner.
224 """Sets the global banner.
226
225
227 This banner gets prepended to every header printed when the shell
226 This banner gets prepended to every header printed when the shell
228 instance is called."""
227 instance is called."""
229
228
230 self.banner = banner
229 self.banner = banner
231
230
232 def set_exit_msg(self,exit_msg):
231 def set_exit_msg(self,exit_msg):
233 """Sets the global exit_msg.
232 """Sets the global exit_msg.
234
233
235 This exit message gets printed upon exiting every time the embedded
234 This exit message gets printed upon exiting every time the embedded
236 shell is called. It is None by default. """
235 shell is called. It is None by default. """
237
236
238 self.exit_msg = exit_msg
237 self.exit_msg = exit_msg
239
238
240 #-----------------------------------------------------------------------------
239 #-----------------------------------------------------------------------------
241 def sigint_handler (signum,stack_frame):
240 def sigint_handler (signum,stack_frame):
242 """Sigint handler for threaded apps.
241 """Sigint handler for threaded apps.
243
242
244 This is a horrible hack to pass information about SIGINT _without_ using
243 This is a horrible hack to pass information about SIGINT _without_ using
245 exceptions, since I haven't been able to properly manage cross-thread
244 exceptions, since I haven't been able to properly manage cross-thread
246 exceptions in GTK/WX. In fact, I don't think it can be done (or at least
245 exceptions in GTK/WX. In fact, I don't think it can be done (or at least
247 that's my understanding from a c.l.py thread where this was discussed)."""
246 that's my understanding from a c.l.py thread where this was discussed)."""
248
247
249 global KBINT
248 global KBINT
250
249
251 print '\nKeyboardInterrupt - Press <Enter> to continue.',
250 print '\nKeyboardInterrupt - Press <Enter> to continue.',
252 Term.cout.flush()
251 Term.cout.flush()
253 # Set global flag so that runsource can know that Ctrl-C was hit
252 # Set global flag so that runsource can know that Ctrl-C was hit
254 KBINT = True
253 KBINT = True
255
254
256 class MTInteractiveShell(InteractiveShell):
255 class MTInteractiveShell(InteractiveShell):
257 """Simple multi-threaded shell."""
256 """Simple multi-threaded shell."""
258
257
259 # Threading strategy taken from:
258 # Threading strategy taken from:
260 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/65109, by Brian
259 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/65109, by Brian
261 # McErlean and John Finlay. Modified with corrections by Antoon Pardon,
260 # McErlean and John Finlay. Modified with corrections by Antoon Pardon,
262 # from the pygtk mailing list, to avoid lockups with system calls.
261 # from the pygtk mailing list, to avoid lockups with system calls.
263
262
264 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
263 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
265 user_ns = None, banner2='',**kw):
264 user_ns = None, banner2='',**kw):
266 """Similar to the normal InteractiveShell, but with threading control"""
265 """Similar to the normal InteractiveShell, but with threading control"""
267
266
268 IPython.iplib.InteractiveShell.__init__(self,name,usage,rc,user_ns,banner2)
267 IPython.iplib.InteractiveShell.__init__(self,name,usage,rc,user_ns,banner2)
269
268
270 # Locking control variable
269 # Locking control variable
271 self.thread_ready = threading.Condition()
270 self.thread_ready = threading.Condition()
272
271
273 # Stuff to do at closing time
272 # Stuff to do at closing time
274 self._kill = False
273 self._kill = False
275 on_kill = kw.get('on_kill')
274 on_kill = kw.get('on_kill')
276 if on_kill is None:
275 if on_kill is None:
277 on_kill = []
276 on_kill = []
278 # Check that all things to kill are callable:
277 # Check that all things to kill are callable:
279 for t in on_kill:
278 for t in on_kill:
280 if not callable(t):
279 if not callable(t):
281 raise TypeError,'on_kill must be a list of callables'
280 raise TypeError,'on_kill must be a list of callables'
282 self.on_kill = on_kill
281 self.on_kill = on_kill
283
282
284 def runsource(self, source, filename="<input>", symbol="single"):
283 def runsource(self, source, filename="<input>", symbol="single"):
285 """Compile and run some source in the interpreter.
284 """Compile and run some source in the interpreter.
286
285
287 Modified version of code.py's runsource(), to handle threading issues.
286 Modified version of code.py's runsource(), to handle threading issues.
288 See the original for full docstring details."""
287 See the original for full docstring details."""
289
288
290 global KBINT
289 global KBINT
291
290
292 # If Ctrl-C was typed, we reset the flag and return right away
291 # If Ctrl-C was typed, we reset the flag and return right away
293 if KBINT:
292 if KBINT:
294 KBINT = False
293 KBINT = False
295 return False
294 return False
296
295
297 try:
296 try:
298 code = self.compile(source, filename, symbol)
297 code = self.compile(source, filename, symbol)
299 except (OverflowError, SyntaxError, ValueError):
298 except (OverflowError, SyntaxError, ValueError):
300 # Case 1
299 # Case 1
301 self.showsyntaxerror(filename)
300 self.showsyntaxerror(filename)
302 return False
301 return False
303
302
304 if code is None:
303 if code is None:
305 # Case 2
304 # Case 2
306 return True
305 return True
307
306
308 # Case 3
307 # Case 3
309 # Store code in self, so the execution thread can handle it
308 # Store code in self, so the execution thread can handle it
310 self.thread_ready.acquire()
309 self.thread_ready.acquire()
311 self.code_to_run = code
310 self.code_to_run = code
312 self.thread_ready.wait() # Wait until processed in timeout interval
311 self.thread_ready.wait() # Wait until processed in timeout interval
313 self.thread_ready.release()
312 self.thread_ready.release()
314
313
315 return False
314 return False
316
315
317 def runcode(self):
316 def runcode(self):
318 """Execute a code object.
317 """Execute a code object.
319
318
320 Multithreaded wrapper around IPython's runcode()."""
319 Multithreaded wrapper around IPython's runcode()."""
321
320
322 # lock thread-protected stuff
321 # lock thread-protected stuff
323 self.thread_ready.acquire()
322 self.thread_ready.acquire()
324
323
325 # Install sigint handler
324 # Install sigint handler
326 try:
325 try:
327 signal.signal(signal.SIGINT, sigint_handler)
326 signal.signal(signal.SIGINT, sigint_handler)
328 except SystemError:
327 except SystemError:
329 # This happens under Windows, which seems to have all sorts
328 # This happens under Windows, which seems to have all sorts
330 # of problems with signal handling. Oh well...
329 # of problems with signal handling. Oh well...
331 pass
330 pass
332
331
333 if self._kill:
332 if self._kill:
334 print >>Term.cout, 'Closing threads...',
333 print >>Term.cout, 'Closing threads...',
335 Term.cout.flush()
334 Term.cout.flush()
336 for tokill in self.on_kill:
335 for tokill in self.on_kill:
337 tokill()
336 tokill()
338 print >>Term.cout, 'Done.'
337 print >>Term.cout, 'Done.'
339
338
340 # Run pending code by calling parent class
339 # Run pending code by calling parent class
341 if self.code_to_run is not None:
340 if self.code_to_run is not None:
342 self.thread_ready.notify()
341 self.thread_ready.notify()
343 InteractiveShell.runcode(self,self.code_to_run)
342 InteractiveShell.runcode(self,self.code_to_run)
344
343
345 # We're done with thread-protected variables
344 # We're done with thread-protected variables
346 self.thread_ready.release()
345 self.thread_ready.release()
347 # This MUST return true for gtk threading to work
346 # This MUST return true for gtk threading to work
348 return True
347 return True
349
348
350 def kill (self):
349 def kill (self):
351 """Kill the thread, returning when it has been shut down."""
350 """Kill the thread, returning when it has been shut down."""
352 self.thread_ready.acquire()
351 self.thread_ready.acquire()
353 self._kill = True
352 self._kill = True
354 self.thread_ready.release()
353 self.thread_ready.release()
355
354
356 class MatplotlibShellBase:
355 class MatplotlibShellBase:
357 """Mixin class to provide the necessary modifications to regular IPython
356 """Mixin class to provide the necessary modifications to regular IPython
358 shell classes for matplotlib support.
357 shell classes for matplotlib support.
359
358
360 Given Python's MRO, this should be used as the FIRST class in the
359 Given Python's MRO, this should be used as the FIRST class in the
361 inheritance hierarchy, so that it overrides the relevant methods."""
360 inheritance hierarchy, so that it overrides the relevant methods."""
362
361
363 def _matplotlib_config(self,name):
362 def _matplotlib_config(self,name):
364 """Return various items needed to setup the user's shell with matplotlib"""
363 """Return various items needed to setup the user's shell with matplotlib"""
365
364
366 # Initialize matplotlib to interactive mode always
365 # Initialize matplotlib to interactive mode always
367 import matplotlib
366 import matplotlib
368 from matplotlib import backends
367 from matplotlib import backends
369 matplotlib.interactive(True)
368 matplotlib.interactive(True)
370
369
371 def use(arg):
370 def use(arg):
372 """IPython wrapper for matplotlib's backend switcher.
371 """IPython wrapper for matplotlib's backend switcher.
373
372
374 In interactive use, we can not allow switching to a different
373 In interactive use, we can not allow switching to a different
375 interactive backend, since thread conflicts will most likely crash
374 interactive backend, since thread conflicts will most likely crash
376 the python interpreter. This routine does a safety check first,
375 the python interpreter. This routine does a safety check first,
377 and refuses to perform a dangerous switch. It still allows
376 and refuses to perform a dangerous switch. It still allows
378 switching to non-interactive backends."""
377 switching to non-interactive backends."""
379
378
380 if arg in backends.interactive_bk and arg != self.mpl_backend:
379 if arg in backends.interactive_bk and arg != self.mpl_backend:
381 m=('invalid matplotlib backend switch.\n'
380 m=('invalid matplotlib backend switch.\n'
382 'This script attempted to switch to the interactive '
381 'This script attempted to switch to the interactive '
383 'backend: `%s`\n'
382 'backend: `%s`\n'
384 'Your current choice of interactive backend is: `%s`\n\n'
383 'Your current choice of interactive backend is: `%s`\n\n'
385 'Switching interactive matplotlib backends at runtime\n'
384 'Switching interactive matplotlib backends at runtime\n'
386 'would crash the python interpreter, '
385 'would crash the python interpreter, '
387 'and IPython has blocked it.\n\n'
386 'and IPython has blocked it.\n\n'
388 'You need to either change your choice of matplotlib backend\n'
387 'You need to either change your choice of matplotlib backend\n'
389 'by editing your .matplotlibrc file, or run this script as a \n'
388 'by editing your .matplotlibrc file, or run this script as a \n'
390 'standalone file from the command line, not using IPython.\n' %
389 'standalone file from the command line, not using IPython.\n' %
391 (arg,self.mpl_backend) )
390 (arg,self.mpl_backend) )
392 raise RuntimeError, m
391 raise RuntimeError, m
393 else:
392 else:
394 self.mpl_use(arg)
393 self.mpl_use(arg)
395 self.mpl_use._called = True
394 self.mpl_use._called = True
396
395
397 self.matplotlib = matplotlib
396 self.matplotlib = matplotlib
398 self.mpl_backend = matplotlib.rcParams['backend']
397 self.mpl_backend = matplotlib.rcParams['backend']
399
398
400 # we also need to block switching of interactive backends by use()
399 # we also need to block switching of interactive backends by use()
401 self.mpl_use = matplotlib.use
400 self.mpl_use = matplotlib.use
402 self.mpl_use._called = False
401 self.mpl_use._called = False
403 # overwrite the original matplotlib.use with our wrapper
402 # overwrite the original matplotlib.use with our wrapper
404 matplotlib.use = use
403 matplotlib.use = use
405
404
406
405
407 # This must be imported last in the matplotlib series, after
406 # This must be imported last in the matplotlib series, after
408 # backend/interactivity choices have been made
407 # backend/interactivity choices have been made
409 try:
408 try:
410 import matplotlib.pylab as pylab
409 import matplotlib.pylab as pylab
411 self.pylab = pylab
410 self.pylab = pylab
412 self.pylab_name = 'pylab'
411 self.pylab_name = 'pylab'
413 except ImportError:
412 except ImportError:
414 import matplotlib.matlab as matlab
413 import matplotlib.matlab as matlab
415 self.pylab = matlab
414 self.pylab = matlab
416 self.pylab_name = 'matlab'
415 self.pylab_name = 'matlab'
417
416
418 self.pylab.show._needmain = False
417 self.pylab.show._needmain = False
419 # We need to detect at runtime whether show() is called by the user.
418 # We need to detect at runtime whether show() is called by the user.
420 # For this, we wrap it into a decorator which adds a 'called' flag.
419 # For this, we wrap it into a decorator which adds a 'called' flag.
421 self.pylab.draw_if_interactive = flag_calls(self.pylab.draw_if_interactive)
420 self.pylab.draw_if_interactive = flag_calls(self.pylab.draw_if_interactive)
422
421
423 # Build a user namespace initialized with matplotlib/matlab features.
422 # Build a user namespace initialized with matplotlib/matlab features.
424 user_ns = {'__name__':'__main__',
423 user_ns = {'__name__':'__main__',
425 '__builtins__' : __builtin__ }
424 '__builtins__' : __builtin__ }
426
425
427 # Be careful not to remove the final \n in the code string below, or
426 # Be careful not to remove the final \n in the code string below, or
428 # things will break badly with py22 (I think it's a python bug, 2.3 is
427 # things will break badly with py22 (I think it's a python bug, 2.3 is
429 # OK).
428 # OK).
430 pname = self.pylab_name # Python can't interpolate dotted var names
429 pname = self.pylab_name # Python can't interpolate dotted var names
431 exec ("import matplotlib\n"
430 exec ("import matplotlib\n"
432 "import matplotlib.%(pname)s as %(pname)s\n"
431 "import matplotlib.%(pname)s as %(pname)s\n"
433 "from matplotlib.%(pname)s import *\n" % locals()) in user_ns
432 "from matplotlib.%(pname)s import *\n" % locals()) in user_ns
434
433
435 # Build matplotlib info banner
434 # Build matplotlib info banner
436 b="""
435 b="""
437 Welcome to pylab, a matplotlib-based Python environment.
436 Welcome to pylab, a matplotlib-based Python environment.
438 For more information, type 'help(pylab)'.
437 For more information, type 'help(pylab)'.
439 """
438 """
440 return user_ns,b
439 return user_ns,b
441
440
442 def mplot_exec(self,fname,*where,**kw):
441 def mplot_exec(self,fname,*where,**kw):
443 """Execute a matplotlib script.
442 """Execute a matplotlib script.
444
443
445 This is a call to execfile(), but wrapped in safeties to properly
444 This is a call to execfile(), but wrapped in safeties to properly
446 handle interactive rendering and backend switching."""
445 handle interactive rendering and backend switching."""
447
446
448 #print '*** Matplotlib runner ***' # dbg
447 #print '*** Matplotlib runner ***' # dbg
449 # turn off rendering until end of script
448 # turn off rendering until end of script
450 isInteractive = self.matplotlib.rcParams['interactive']
449 isInteractive = self.matplotlib.rcParams['interactive']
451 self.matplotlib.interactive(False)
450 self.matplotlib.interactive(False)
452 self.safe_execfile(fname,*where,**kw)
451 self.safe_execfile(fname,*where,**kw)
453 self.matplotlib.interactive(isInteractive)
452 self.matplotlib.interactive(isInteractive)
454 # make rendering call now, if the user tried to do it
453 # make rendering call now, if the user tried to do it
455 if self.pylab.draw_if_interactive.called:
454 if self.pylab.draw_if_interactive.called:
456 self.pylab.draw()
455 self.pylab.draw()
457 self.pylab.draw_if_interactive.called = False
456 self.pylab.draw_if_interactive.called = False
458
457
459 # if a backend switch was performed, reverse it now
458 # if a backend switch was performed, reverse it now
460 if self.mpl_use._called:
459 if self.mpl_use._called:
461 self.matplotlib.rcParams['backend'] = self.mpl_backend
460 self.matplotlib.rcParams['backend'] = self.mpl_backend
462
461
463 def magic_run(self,parameter_s=''):
462 def magic_run(self,parameter_s=''):
464 Magic.magic_run(self,parameter_s,runner=self.mplot_exec)
463 Magic.magic_run(self,parameter_s,runner=self.mplot_exec)
465
464
466 # Fix the docstring so users see the original as well
465 # Fix the docstring so users see the original as well
467 magic_run.__doc__ = "%s\n%s" % (Magic.magic_run.__doc__,
466 magic_run.__doc__ = "%s\n%s" % (Magic.magic_run.__doc__,
468 "\n *** Modified %run for Matplotlib,"
467 "\n *** Modified %run for Matplotlib,"
469 " with proper interactive handling ***")
468 " with proper interactive handling ***")
470
469
471 # Now we provide 2 versions of a matplotlib-aware IPython base shells, single
470 # Now we provide 2 versions of a matplotlib-aware IPython base shells, single
472 # and multithreaded. Note that these are meant for internal use, the IPShell*
471 # and multithreaded. Note that these are meant for internal use, the IPShell*
473 # classes below are the ones meant for public consumption.
472 # classes below are the ones meant for public consumption.
474
473
475 class MatplotlibShell(MatplotlibShellBase,InteractiveShell):
474 class MatplotlibShell(MatplotlibShellBase,InteractiveShell):
476 """Single-threaded shell with matplotlib support."""
475 """Single-threaded shell with matplotlib support."""
477
476
478 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
477 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
479 user_ns = None, **kw):
478 user_ns = None, **kw):
480 user_ns,b2 = self._matplotlib_config(name)
479 user_ns,b2 = self._matplotlib_config(name)
481 InteractiveShell.__init__(self,name,usage,rc,user_ns,banner2=b2,**kw)
480 InteractiveShell.__init__(self,name,usage,rc,user_ns,banner2=b2,**kw)
482
481
483 class MatplotlibMTShell(MatplotlibShellBase,MTInteractiveShell):
482 class MatplotlibMTShell(MatplotlibShellBase,MTInteractiveShell):
484 """Multi-threaded shell with matplotlib support."""
483 """Multi-threaded shell with matplotlib support."""
485
484
486 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
485 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
487 user_ns = None, **kw):
486 user_ns = None, **kw):
488 user_ns,b2 = self._matplotlib_config(name)
487 user_ns,b2 = self._matplotlib_config(name)
489 MTInteractiveShell.__init__(self,name,usage,rc,user_ns,banner2=b2,**kw)
488 MTInteractiveShell.__init__(self,name,usage,rc,user_ns,banner2=b2,**kw)
490
489
491 #-----------------------------------------------------------------------------
490 #-----------------------------------------------------------------------------
492 # Utility functions for the different GUI enabled IPShell* classes.
491 # Utility functions for the different GUI enabled IPShell* classes.
493
492
494 def get_tk():
493 def get_tk():
495 """Tries to import Tkinter and returns a withdrawn Tkinter root
494 """Tries to import Tkinter and returns a withdrawn Tkinter root
496 window. If Tkinter is already imported or not available, this
495 window. If Tkinter is already imported or not available, this
497 returns None. This function calls `hijack_tk` underneath.
496 returns None. This function calls `hijack_tk` underneath.
498 """
497 """
499 if not USE_TK or sys.modules.has_key('Tkinter'):
498 if not USE_TK or sys.modules.has_key('Tkinter'):
500 return None
499 return None
501 else:
500 else:
502 try:
501 try:
503 import Tkinter
502 import Tkinter
504 except ImportError:
503 except ImportError:
505 return None
504 return None
506 else:
505 else:
507 hijack_tk()
506 hijack_tk()
508 r = Tkinter.Tk()
507 r = Tkinter.Tk()
509 r.withdraw()
508 r.withdraw()
510 return r
509 return r
511
510
512 def hijack_tk():
511 def hijack_tk():
513 """Modifies Tkinter's mainloop with a dummy so when a module calls
512 """Modifies Tkinter's mainloop with a dummy so when a module calls
514 mainloop, it does not block.
513 mainloop, it does not block.
515
514
516 """
515 """
517 def misc_mainloop(self, n=0):
516 def misc_mainloop(self, n=0):
518 pass
517 pass
519 def tkinter_mainloop(n=0):
518 def tkinter_mainloop(n=0):
520 pass
519 pass
521
520
522 import Tkinter
521 import Tkinter
523 Tkinter.Misc.mainloop = misc_mainloop
522 Tkinter.Misc.mainloop = misc_mainloop
524 Tkinter.mainloop = tkinter_mainloop
523 Tkinter.mainloop = tkinter_mainloop
525
524
526 def update_tk(tk):
525 def update_tk(tk):
527 """Updates the Tkinter event loop. This is typically called from
526 """Updates the Tkinter event loop. This is typically called from
528 the respective WX or GTK mainloops.
527 the respective WX or GTK mainloops.
529 """
528 """
530 if tk:
529 if tk:
531 tk.update()
530 tk.update()
532
531
533 def hijack_wx():
532 def hijack_wx():
534 """Modifies wxPython's MainLoop with a dummy so user code does not
533 """Modifies wxPython's MainLoop with a dummy so user code does not
535 block IPython. The hijacked mainloop function is returned.
534 block IPython. The hijacked mainloop function is returned.
536 """
535 """
537 def dummy_mainloop(*args, **kw):
536 def dummy_mainloop(*args, **kw):
538 pass
537 pass
539 import wxPython
538 import wxPython
540 ver = wxPython.__version__
539 ver = wxPython.__version__
541 orig_mainloop = None
540 orig_mainloop = None
542 if ver[:3] >= '2.5':
541 if ver[:3] >= '2.5':
543 import wx
542 import wx
544 if hasattr(wx, '_core_'): core = getattr(wx, '_core_')
543 if hasattr(wx, '_core_'): core = getattr(wx, '_core_')
545 elif hasattr(wx, '_core'): core = getattr(wx, '_core')
544 elif hasattr(wx, '_core'): core = getattr(wx, '_core')
546 else: raise AttributeError('Could not find wx core module')
545 else: raise AttributeError('Could not find wx core module')
547 orig_mainloop = core.PyApp_MainLoop
546 orig_mainloop = core.PyApp_MainLoop
548 core.PyApp_MainLoop = dummy_mainloop
547 core.PyApp_MainLoop = dummy_mainloop
549 elif ver[:3] == '2.4':
548 elif ver[:3] == '2.4':
550 orig_mainloop = wxPython.wxc.wxPyApp_MainLoop
549 orig_mainloop = wxPython.wxc.wxPyApp_MainLoop
551 wxPython.wxc.wxPyApp_MainLoop = dummy_mainloop
550 wxPython.wxc.wxPyApp_MainLoop = dummy_mainloop
552 else:
551 else:
553 warn("Unable to find either wxPython version 2.4 or >= 2.5.")
552 warn("Unable to find either wxPython version 2.4 or >= 2.5.")
554 return orig_mainloop
553 return orig_mainloop
555
554
556 def hijack_gtk():
555 def hijack_gtk():
557 """Modifies pyGTK's mainloop with a dummy so user code does not
556 """Modifies pyGTK's mainloop with a dummy so user code does not
558 block IPython. This function returns the original `gtk.mainloop`
557 block IPython. This function returns the original `gtk.mainloop`
559 function that has been hijacked.
558 function that has been hijacked.
560 """
559 """
561 def dummy_mainloop(*args, **kw):
560 def dummy_mainloop(*args, **kw):
562 pass
561 pass
563 import gtk
562 import gtk
564 if gtk.pygtk_version >= (2,4,0): orig_mainloop = gtk.main
563 if gtk.pygtk_version >= (2,4,0): orig_mainloop = gtk.main
565 else: orig_mainloop = gtk.mainloop
564 else: orig_mainloop = gtk.mainloop
566 gtk.mainloop = dummy_mainloop
565 gtk.mainloop = dummy_mainloop
567 gtk.main = dummy_mainloop
566 gtk.main = dummy_mainloop
568 return orig_mainloop
567 return orig_mainloop
569
568
570 #-----------------------------------------------------------------------------
569 #-----------------------------------------------------------------------------
571 # The IPShell* classes below are the ones meant to be run by external code as
570 # The IPShell* classes below are the ones meant to be run by external code as
572 # IPython instances. Note that unless a specific threading strategy is
571 # IPython instances. Note that unless a specific threading strategy is
573 # desired, the factory function start() below should be used instead (it
572 # desired, the factory function start() below should be used instead (it
574 # selects the proper threaded class).
573 # selects the proper threaded class).
575
574
576 class IPShellGTK(threading.Thread):
575 class IPShellGTK(threading.Thread):
577 """Run a gtk mainloop() in a separate thread.
576 """Run a gtk mainloop() in a separate thread.
578
577
579 Python commands can be passed to the thread where they will be executed.
578 Python commands can be passed to the thread where they will be executed.
580 This is implemented by periodically checking for passed code using a
579 This is implemented by periodically checking for passed code using a
581 GTK timeout callback."""
580 GTK timeout callback."""
582
581
583 TIMEOUT = 100 # Millisecond interval between timeouts.
582 TIMEOUT = 100 # Millisecond interval between timeouts.
584
583
585 def __init__(self,argv=None,user_ns=None,debug=1,
584 def __init__(self,argv=None,user_ns=None,debug=1,
586 shell_class=MTInteractiveShell):
585 shell_class=MTInteractiveShell):
587
586
588 import gtk
587 import gtk
589
588
590 self.gtk = gtk
589 self.gtk = gtk
591 self.gtk_mainloop = hijack_gtk()
590 self.gtk_mainloop = hijack_gtk()
592
591
593 # Allows us to use both Tk and GTK.
592 # Allows us to use both Tk and GTK.
594 self.tk = get_tk()
593 self.tk = get_tk()
595
594
596 if gtk.pygtk_version >= (2,4,0): mainquit = self.gtk.main_quit
595 if gtk.pygtk_version >= (2,4,0): mainquit = self.gtk.main_quit
597 else: mainquit = self.gtk.mainquit
596 else: mainquit = self.gtk.mainquit
598
597
599 self.IP = make_IPython(argv,user_ns=user_ns,debug=debug,
598 self.IP = make_IPython(argv,user_ns=user_ns,debug=debug,
600 shell_class=shell_class,
599 shell_class=shell_class,
601 on_kill=[mainquit])
600 on_kill=[mainquit])
602
601
603 # HACK: slot for banner in self; it will be passed to the mainloop
602 # HACK: slot for banner in self; it will be passed to the mainloop
604 # method only and .run() needs it. The actual value will be set by
603 # method only and .run() needs it. The actual value will be set by
605 # .mainloop().
604 # .mainloop().
606 self._banner = None
605 self._banner = None
607
606
608 threading.Thread.__init__(self)
607 threading.Thread.__init__(self)
609
608
610 def run(self):
609 def run(self):
611 self.IP.mainloop(self._banner)
610 self.IP.mainloop(self._banner)
612 self.IP.kill()
611 self.IP.kill()
613
612
614 def mainloop(self,sys_exit=0,banner=None):
613 def mainloop(self,sys_exit=0,banner=None):
615
614
616 self._banner = banner
615 self._banner = banner
617
616
618 if self.gtk.pygtk_version >= (2,4,0):
617 if self.gtk.pygtk_version >= (2,4,0):
619 import gobject
618 import gobject
620 gobject.idle_add(self.on_timer)
619 gobject.idle_add(self.on_timer)
621 else:
620 else:
622 self.gtk.idle_add(self.on_timer)
621 self.gtk.idle_add(self.on_timer)
623
622
624 if sys.platform != 'win32':
623 if sys.platform != 'win32':
625 try:
624 try:
626 if self.gtk.gtk_version[0] >= 2:
625 if self.gtk.gtk_version[0] >= 2:
627 self.gtk.threads_init()
626 self.gtk.threads_init()
628 except AttributeError:
627 except AttributeError:
629 pass
628 pass
630 except RuntimeError:
629 except RuntimeError:
631 error('Your pyGTK likely has not been compiled with '
630 error('Your pyGTK likely has not been compiled with '
632 'threading support.\n'
631 'threading support.\n'
633 'The exception printout is below.\n'
632 'The exception printout is below.\n'
634 'You can either rebuild pyGTK with threads, or '
633 'You can either rebuild pyGTK with threads, or '
635 'try using \n'
634 'try using \n'
636 'matplotlib with a different backend (like Tk or WX).\n'
635 'matplotlib with a different backend (like Tk or WX).\n'
637 'Note that matplotlib will most likely not work in its '
636 'Note that matplotlib will most likely not work in its '
638 'current state!')
637 'current state!')
639 self.IP.InteractiveTB()
638 self.IP.InteractiveTB()
640 self.start()
639 self.start()
641 self.gtk.threads_enter()
640 self.gtk.threads_enter()
642 self.gtk_mainloop()
641 self.gtk_mainloop()
643 self.gtk.threads_leave()
642 self.gtk.threads_leave()
644 self.join()
643 self.join()
645
644
646 def on_timer(self):
645 def on_timer(self):
647 update_tk(self.tk)
646 update_tk(self.tk)
648 return self.IP.runcode()
647 return self.IP.runcode()
649
648
650
649
651 class IPShellWX(threading.Thread):
650 class IPShellWX(threading.Thread):
652 """Run a wx mainloop() in a separate thread.
651 """Run a wx mainloop() in a separate thread.
653
652
654 Python commands can be passed to the thread where they will be executed.
653 Python commands can be passed to the thread where they will be executed.
655 This is implemented by periodically checking for passed code using a
654 This is implemented by periodically checking for passed code using a
656 GTK timeout callback."""
655 GTK timeout callback."""
657
656
658 TIMEOUT = 100 # Millisecond interval between timeouts.
657 TIMEOUT = 100 # Millisecond interval between timeouts.
659
658
660 def __init__(self,argv=None,user_ns=None,debug=1,
659 def __init__(self,argv=None,user_ns=None,debug=1,
661 shell_class=MTInteractiveShell):
660 shell_class=MTInteractiveShell):
662
661
663 import wxPython.wx as wx
662 import wxPython.wx as wx
664
663
665 threading.Thread.__init__(self)
664 threading.Thread.__init__(self)
666 self.wx = wx
665 self.wx = wx
667 self.wx_mainloop = hijack_wx()
666 self.wx_mainloop = hijack_wx()
668
667
669 # Allows us to use both Tk and GTK.
668 # Allows us to use both Tk and GTK.
670 self.tk = get_tk()
669 self.tk = get_tk()
671
670
672 self.IP = make_IPython(argv,user_ns=user_ns,debug=debug,
671 self.IP = make_IPython(argv,user_ns=user_ns,debug=debug,
673 shell_class=shell_class,
672 shell_class=shell_class,
674 on_kill=[self.wxexit])
673 on_kill=[self.wxexit])
675 # HACK: slot for banner in self; it will be passed to the mainloop
674 # HACK: slot for banner in self; it will be passed to the mainloop
676 # method only and .run() needs it. The actual value will be set by
675 # method only and .run() needs it. The actual value will be set by
677 # .mainloop().
676 # .mainloop().
678 self._banner = None
677 self._banner = None
679
678
680 self.app = None
679 self.app = None
681
680
682 def wxexit(self, *args):
681 def wxexit(self, *args):
683 if self.app is not None:
682 if self.app is not None:
684 self.app.agent.timer.Stop()
683 self.app.agent.timer.Stop()
685 self.app.ExitMainLoop()
684 self.app.ExitMainLoop()
686
685
687 def run(self):
686 def run(self):
688 self.IP.mainloop(self._banner)
687 self.IP.mainloop(self._banner)
689 self.IP.kill()
688 self.IP.kill()
690
689
691 def mainloop(self,sys_exit=0,banner=None):
690 def mainloop(self,sys_exit=0,banner=None):
692
691
693 self._banner = banner
692 self._banner = banner
694
693
695 self.start()
694 self.start()
696
695
697 class TimerAgent(self.wx.wxMiniFrame):
696 class TimerAgent(self.wx.wxMiniFrame):
698 wx = self.wx
697 wx = self.wx
699 IP = self.IP
698 IP = self.IP
700 tk = self.tk
699 tk = self.tk
701 def __init__(self, parent, interval):
700 def __init__(self, parent, interval):
702 style = self.wx.wxDEFAULT_FRAME_STYLE | self.wx.wxTINY_CAPTION_HORIZ
701 style = self.wx.wxDEFAULT_FRAME_STYLE | self.wx.wxTINY_CAPTION_HORIZ
703 self.wx.wxMiniFrame.__init__(self, parent, -1, ' ', pos=(200, 200),
702 self.wx.wxMiniFrame.__init__(self, parent, -1, ' ', pos=(200, 200),
704 size=(100, 100),style=style)
703 size=(100, 100),style=style)
705 self.Show(False)
704 self.Show(False)
706 self.interval = interval
705 self.interval = interval
707 self.timerId = self.wx.wxNewId()
706 self.timerId = self.wx.wxNewId()
708
707
709 def StartWork(self):
708 def StartWork(self):
710 self.timer = self.wx.wxTimer(self, self.timerId)
709 self.timer = self.wx.wxTimer(self, self.timerId)
711 self.wx.EVT_TIMER(self, self.timerId, self.OnTimer)
710 self.wx.EVT_TIMER(self, self.timerId, self.OnTimer)
712 self.timer.Start(self.interval)
711 self.timer.Start(self.interval)
713
712
714 def OnTimer(self, event):
713 def OnTimer(self, event):
715 update_tk(self.tk)
714 update_tk(self.tk)
716 self.IP.runcode()
715 self.IP.runcode()
717
716
718 class App(self.wx.wxApp):
717 class App(self.wx.wxApp):
719 wx = self.wx
718 wx = self.wx
720 TIMEOUT = self.TIMEOUT
719 TIMEOUT = self.TIMEOUT
721 def OnInit(self):
720 def OnInit(self):
722 'Create the main window and insert the custom frame'
721 'Create the main window and insert the custom frame'
723 self.agent = TimerAgent(None, self.TIMEOUT)
722 self.agent = TimerAgent(None, self.TIMEOUT)
724 self.agent.Show(self.wx.false)
723 self.agent.Show(self.wx.false)
725 self.agent.StartWork()
724 self.agent.StartWork()
726 return self.wx.true
725 return self.wx.true
727
726
728 self.app = App(redirect=False)
727 self.app = App(redirect=False)
729 self.wx_mainloop(self.app)
728 self.wx_mainloop(self.app)
730 self.join()
729 self.join()
731
730
732
731
733 class IPShellQt(threading.Thread):
732 class IPShellQt(threading.Thread):
734 """Run a Qt event loop in a separate thread.
733 """Run a Qt event loop in a separate thread.
735
734
736 Python commands can be passed to the thread where they will be executed.
735 Python commands can be passed to the thread where they will be executed.
737 This is implemented by periodically checking for passed code using a
736 This is implemented by periodically checking for passed code using a
738 Qt timer / slot."""
737 Qt timer / slot."""
739
738
740 TIMEOUT = 100 # Millisecond interval between timeouts.
739 TIMEOUT = 100 # Millisecond interval between timeouts.
741
740
742 def __init__(self,argv=None,user_ns=None,debug=0,
741 def __init__(self,argv=None,user_ns=None,debug=0,
743 shell_class=MTInteractiveShell):
742 shell_class=MTInteractiveShell):
744
743
745 import qt
744 import qt
746
745
747 class newQApplication:
746 class newQApplication:
748 def __init__( self ):
747 def __init__( self ):
749 self.QApplication = qt.QApplication
748 self.QApplication = qt.QApplication
750
749
751 def __call__( *args, **kwargs ):
750 def __call__( *args, **kwargs ):
752 return qt.qApp
751 return qt.qApp
753
752
754 def exec_loop( *args, **kwargs ):
753 def exec_loop( *args, **kwargs ):
755 pass
754 pass
756
755
757 def __getattr__( self, name ):
756 def __getattr__( self, name ):
758 return getattr( self.QApplication, name )
757 return getattr( self.QApplication, name )
759
758
760 qt.QApplication = newQApplication()
759 qt.QApplication = newQApplication()
761
760
762 # Allows us to use both Tk and QT.
761 # Allows us to use both Tk and QT.
763 self.tk = get_tk()
762 self.tk = get_tk()
764
763
765 self.IP = make_IPython(argv,user_ns=user_ns,debug=debug,
764 self.IP = make_IPython(argv,user_ns=user_ns,debug=debug,
766 shell_class=shell_class,
765 shell_class=shell_class,
767 on_kill=[qt.qApp.exit])
766 on_kill=[qt.qApp.exit])
768
767
769 # HACK: slot for banner in self; it will be passed to the mainloop
768 # HACK: slot for banner in self; it will be passed to the mainloop
770 # method only and .run() needs it. The actual value will be set by
769 # method only and .run() needs it. The actual value will be set by
771 # .mainloop().
770 # .mainloop().
772 self._banner = None
771 self._banner = None
773
772
774 threading.Thread.__init__(self)
773 threading.Thread.__init__(self)
775
774
776 def run(self):
775 def run(self):
777 self.IP.mainloop(self._banner)
776 self.IP.mainloop(self._banner)
778 self.IP.kill()
777 self.IP.kill()
779
778
780 def mainloop(self,sys_exit=0,banner=None):
779 def mainloop(self,sys_exit=0,banner=None):
781
780
782 import qt
781 import qt
783
782
784 self._banner = banner
783 self._banner = banner
785
784
786 if qt.QApplication.startingUp():
785 if qt.QApplication.startingUp():
787 a = qt.QApplication.QApplication(sys.argv)
786 a = qt.QApplication.QApplication(sys.argv)
788 self.timer = qt.QTimer()
787 self.timer = qt.QTimer()
789 qt.QObject.connect( self.timer, qt.SIGNAL( 'timeout()' ), self.on_timer )
788 qt.QObject.connect( self.timer, qt.SIGNAL( 'timeout()' ), self.on_timer )
790
789
791 self.start()
790 self.start()
792 self.timer.start( self.TIMEOUT, True )
791 self.timer.start( self.TIMEOUT, True )
793 while True:
792 while True:
794 if self.IP._kill: break
793 if self.IP._kill: break
795 qt.qApp.exec_loop()
794 qt.qApp.exec_loop()
796 self.join()
795 self.join()
797
796
798 def on_timer(self):
797 def on_timer(self):
799 update_tk(self.tk)
798 update_tk(self.tk)
800 result = self.IP.runcode()
799 result = self.IP.runcode()
801 self.timer.start( self.TIMEOUT, True )
800 self.timer.start( self.TIMEOUT, True )
802 return result
801 return result
803
802
804 # A set of matplotlib public IPython shell classes, for single-threaded
803 # A set of matplotlib public IPython shell classes, for single-threaded
805 # (Tk* and FLTK* backends) and multithreaded (GTK* and WX* backends) use.
804 # (Tk* and FLTK* backends) and multithreaded (GTK* and WX* backends) use.
806 class IPShellMatplotlib(IPShell):
805 class IPShellMatplotlib(IPShell):
807 """Subclass IPShell with MatplotlibShell as the internal shell.
806 """Subclass IPShell with MatplotlibShell as the internal shell.
808
807
809 Single-threaded class, meant for the Tk* and FLTK* backends.
808 Single-threaded class, meant for the Tk* and FLTK* backends.
810
809
811 Having this on a separate class simplifies the external driver code."""
810 Having this on a separate class simplifies the external driver code."""
812
811
813 def __init__(self,argv=None,user_ns=None,debug=1):
812 def __init__(self,argv=None,user_ns=None,debug=1):
814 IPShell.__init__(self,argv,user_ns,debug,shell_class=MatplotlibShell)
813 IPShell.__init__(self,argv,user_ns,debug,shell_class=MatplotlibShell)
815
814
816 class IPShellMatplotlibGTK(IPShellGTK):
815 class IPShellMatplotlibGTK(IPShellGTK):
817 """Subclass IPShellGTK with MatplotlibMTShell as the internal shell.
816 """Subclass IPShellGTK with MatplotlibMTShell as the internal shell.
818
817
819 Multi-threaded class, meant for the GTK* backends."""
818 Multi-threaded class, meant for the GTK* backends."""
820
819
821 def __init__(self,argv=None,user_ns=None,debug=1):
820 def __init__(self,argv=None,user_ns=None,debug=1):
822 IPShellGTK.__init__(self,argv,user_ns,debug,shell_class=MatplotlibMTShell)
821 IPShellGTK.__init__(self,argv,user_ns,debug,shell_class=MatplotlibMTShell)
823
822
824 class IPShellMatplotlibWX(IPShellWX):
823 class IPShellMatplotlibWX(IPShellWX):
825 """Subclass IPShellWX with MatplotlibMTShell as the internal shell.
824 """Subclass IPShellWX with MatplotlibMTShell as the internal shell.
826
825
827 Multi-threaded class, meant for the WX* backends."""
826 Multi-threaded class, meant for the WX* backends."""
828
827
829 def __init__(self,argv=None,user_ns=None,debug=1):
828 def __init__(self,argv=None,user_ns=None,debug=1):
830 IPShellWX.__init__(self,argv,user_ns,debug,shell_class=MatplotlibMTShell)
829 IPShellWX.__init__(self,argv,user_ns,debug,shell_class=MatplotlibMTShell)
831
830
832 class IPShellMatplotlibQt(IPShellQt):
831 class IPShellMatplotlibQt(IPShellQt):
833 """Subclass IPShellQt with MatplotlibMTShell as the internal shell.
832 """Subclass IPShellQt with MatplotlibMTShell as the internal shell.
834
833
835 Multi-threaded class, meant for the Qt* backends."""
834 Multi-threaded class, meant for the Qt* backends."""
836
835
837 def __init__(self,argv=None,user_ns=None,debug=1):
836 def __init__(self,argv=None,user_ns=None,debug=1):
838 IPShellQt.__init__(self,argv,user_ns,debug,shell_class=MatplotlibMTShell)
837 IPShellQt.__init__(self,argv,user_ns,debug,shell_class=MatplotlibMTShell)
839
838
840 #-----------------------------------------------------------------------------
839 #-----------------------------------------------------------------------------
841 # Factory functions to actually start the proper thread-aware shell
840 # Factory functions to actually start the proper thread-aware shell
842
841
843 def _matplotlib_shell_class():
842 def _matplotlib_shell_class():
844 """Factory function to handle shell class selection for matplotlib.
843 """Factory function to handle shell class selection for matplotlib.
845
844
846 The proper shell class to use depends on the matplotlib backend, since
845 The proper shell class to use depends on the matplotlib backend, since
847 each backend requires a different threading strategy."""
846 each backend requires a different threading strategy."""
848
847
849 try:
848 try:
850 import matplotlib
849 import matplotlib
851 except ImportError:
850 except ImportError:
852 error('matplotlib could NOT be imported! Starting normal IPython.')
851 error('matplotlib could NOT be imported! Starting normal IPython.')
853 sh_class = IPShell
852 sh_class = IPShell
854 else:
853 else:
855 backend = matplotlib.rcParams['backend']
854 backend = matplotlib.rcParams['backend']
856 if backend.startswith('GTK'):
855 if backend.startswith('GTK'):
857 sh_class = IPShellMatplotlibGTK
856 sh_class = IPShellMatplotlibGTK
858 elif backend.startswith('WX'):
857 elif backend.startswith('WX'):
859 sh_class = IPShellMatplotlibWX
858 sh_class = IPShellMatplotlibWX
860 elif backend.startswith('Qt'):
859 elif backend.startswith('Qt'):
861 sh_class = IPShellMatplotlibQt
860 sh_class = IPShellMatplotlibQt
862 else:
861 else:
863 sh_class = IPShellMatplotlib
862 sh_class = IPShellMatplotlib
864 #print 'Using %s with the %s backend.' % (sh_class,backend) # dbg
863 #print 'Using %s with the %s backend.' % (sh_class,backend) # dbg
865 return sh_class
864 return sh_class
866
865
867 # This is the one which should be called by external code.
866 # This is the one which should be called by external code.
868 def start():
867 def start():
869 """Return a running shell instance, dealing with threading options.
868 """Return a running shell instance, dealing with threading options.
870
869
871 This is a factory function which will instantiate the proper IPython shell
870 This is a factory function which will instantiate the proper IPython shell
872 based on the user's threading choice. Such a selector is needed because
871 based on the user's threading choice. Such a selector is needed because
873 different GUI toolkits require different thread handling details."""
872 different GUI toolkits require different thread handling details."""
874
873
875 global USE_TK
874 global USE_TK
876 # Crude sys.argv hack to extract the threading options.
875 # Crude sys.argv hack to extract the threading options.
877 argv = sys.argv
876 argv = sys.argv
878 if len(argv) > 1:
877 if len(argv) > 1:
879 if len(argv) > 2:
878 if len(argv) > 2:
880 arg2 = argv[2]
879 arg2 = argv[2]
881 if arg2.endswith('-tk'):
880 if arg2.endswith('-tk'):
882 USE_TK = True
881 USE_TK = True
883 arg1 = argv[1]
882 arg1 = argv[1]
884 if arg1.endswith('-gthread'):
883 if arg1.endswith('-gthread'):
885 shell = IPShellGTK
884 shell = IPShellGTK
886 elif arg1.endswith( '-qthread' ):
885 elif arg1.endswith( '-qthread' ):
887 shell = IPShellQt
886 shell = IPShellQt
888 elif arg1.endswith('-wthread'):
887 elif arg1.endswith('-wthread'):
889 shell = IPShellWX
888 shell = IPShellWX
890 elif arg1.endswith('-pylab'):
889 elif arg1.endswith('-pylab'):
891 shell = _matplotlib_shell_class()
890 shell = _matplotlib_shell_class()
892 else:
891 else:
893 shell = IPShell
892 shell = IPShell
894 else:
893 else:
895 shell = IPShell
894 shell = IPShell
896 return shell()
895 return shell()
897
896
898 # Some aliases for backwards compatibility
897 # Some aliases for backwards compatibility
899 IPythonShell = IPShell
898 IPythonShell = IPShell
900 IPythonShellEmbed = IPShellEmbed
899 IPythonShellEmbed = IPShellEmbed
901 #************************ End of file <Shell.py> ***************************
900 #************************ End of file <Shell.py> ***************************
@@ -1,375 +1,376 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Mimic C structs with lots of extra functionality.
2 """Mimic C structs with lots of extra functionality.
3
3
4 $Id: Struct.py 638 2005-07-18 03:01:41Z fperez $"""
4 $Id: Struct.py 958 2005-12-27 23:17:51Z fperez $"""
5
5
6 #*****************************************************************************
6 #*****************************************************************************
7 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
7 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
8 #
8 #
9 # Distributed under the terms of the BSD License. The full license is in
9 # Distributed under the terms of the BSD License. The full license is in
10 # the file COPYING, distributed as part of this software.
10 # the file COPYING, distributed as part of this software.
11 #*****************************************************************************
11 #*****************************************************************************
12
12
13 from IPython import Release
13 from IPython import Release
14 __author__ = '%s <%s>' % Release.authors['Fernando']
14 __author__ = '%s <%s>' % Release.authors['Fernando']
15 __license__ = Release.license
15 __license__ = Release.license
16
16
17 __all__ = ['Struct']
17 __all__ = ['Struct']
18
18
19 import types
19 import types
20
20 from IPython.genutils import list2dict2
21 from IPython.genutils import list2dict2
21
22
22 class Struct:
23 class Struct:
23 """Class to mimic C structs but also provide convenient dictionary-like
24 """Class to mimic C structs but also provide convenient dictionary-like
24 functionality.
25 functionality.
25
26
26 Instances can be initialized with a dictionary, a list of key=value pairs
27 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 or both. If both are present, the dictionary must come first.
28
29
29 Because Python classes provide direct assignment to their members, it's
30 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 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 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 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 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 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 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 Python, namespace protection is weakly enforced, so feel free to shoot
37 yourself if you really want to.
38 yourself if you really want to.
38
39
39 Note that this class uses more memory and is *much* slower than a regular
40 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 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 critical. But for day to day use it should behave fine. It is particularly
42 convenient for storing configuration data in programs.
43 convenient for storing configuration data in programs.
43
44
44 +,+=,- and -= are implemented. +/+= do merges (non-destructive updates),
45 +,+=,- and -= are implemented. +/+= do merges (non-destructive updates),
45 -/-= remove keys from the original. See the method descripitions.
46 -/-= remove keys from the original. See the method descripitions.
46
47
47 This class allows a quick access syntax: both s.key and s['key'] are
48 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 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 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 access to the keys via variables whose values evaluate to the desired
51 keys. An example should clarify this:
52 keys. An example should clarify this:
52
53
53 Define a dictionary and initialize both with dict and k=v pairs:
54 Define a dictionary and initialize both with dict and k=v pairs:
54 >>> d={'a':1,'b':2}
55 >>> d={'a':1,'b':2}
55 >>> s=Struct(d,hi=10,ho=20)
56 >>> s=Struct(d,hi=10,ho=20)
56 The return of __repr__ can be used to create a new instance:
57 The return of __repr__ can be used to create a new instance:
57 >>> s
58 >>> s
58 Struct({'ho': 20, 'b': 2, 'hi': 10, 'a': 1})
59 Struct({'ho': 20, 'b': 2, 'hi': 10, 'a': 1})
59 __str__ (called by print) shows it's not quite a regular dictionary:
60 __str__ (called by print) shows it's not quite a regular dictionary:
60 >>> print s
61 >>> print s
61 Struct {a: 1, b: 2, hi: 10, ho: 20}
62 Struct {a: 1, b: 2, hi: 10, ho: 20}
62 Access by explicitly named key with dot notation:
63 Access by explicitly named key with dot notation:
63 >>> s.a
64 >>> s.a
64 1
65 1
65 Or like a dictionary:
66 Or like a dictionary:
66 >>> s['a']
67 >>> s['a']
67 1
68 1
68 If you want a variable to hold the key value, only dictionary access works:
69 If you want a variable to hold the key value, only dictionary access works:
69 >>> key='hi'
70 >>> key='hi'
70 >>> s.key
71 >>> s.key
71 Traceback (most recent call last):
72 Traceback (most recent call last):
72 File "<stdin>", line 1, in ?
73 File "<stdin>", line 1, in ?
73 AttributeError: Struct instance has no attribute 'key'
74 AttributeError: Struct instance has no attribute 'key'
74 >>> s[key]
75 >>> s[key]
75 10
76 10
76
77
77 Another limitation of the s.key syntax (and Struct(key=val)
78 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 initialization): keys can't be numbers. But numeric keys can be used and
79 accessed using the dictionary syntax. Again, an example:
80 accessed using the dictionary syntax. Again, an example:
80
81
81 This doesn't work:
82 This doesn't work:
82 >>> s=Struct(4='hi')
83 >>> s=Struct(4='hi')
83 SyntaxError: keyword can't be an expression
84 SyntaxError: keyword can't be an expression
84 But this does:
85 But this does:
85 >>> s=Struct()
86 >>> s=Struct()
86 >>> s[4]='hi'
87 >>> s[4]='hi'
87 >>> s
88 >>> s
88 Struct({4: 'hi'})
89 Struct({4: 'hi'})
89 >>> s[4]
90 >>> s[4]
90 'hi'
91 'hi'
91 """
92 """
92
93
93 # Attributes to which __setitem__ and __setattr__ will block access.
94 # 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 # Note: much of this will be moot in Python 2.2 and will be done in a much
95 # cleaner way.
96 # cleaner way.
96 __protected = ('copy dict dictcopy get has_attr has_key items keys '
97 __protected = ('copy dict dictcopy get has_attr has_key items keys '
97 'merge popitem setdefault update values '
98 'merge popitem setdefault update values '
98 '__make_dict __dict_invert ').split()
99 '__make_dict __dict_invert ').split()
99
100
100 def __init__(self,dict=None,**kw):
101 def __init__(self,dict=None,**kw):
101 """Initialize with a dictionary, another Struct, or by giving
102 """Initialize with a dictionary, another Struct, or by giving
102 explicitly the list of attributes.
103 explicitly the list of attributes.
103
104
104 Both can be used, but the dictionary must come first:
105 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 Struct(dict), Struct(k1=v1,k2=v2) or Struct(dict,k1=v1,k2=v2).
106 """
107 """
107 if dict is None:
108 if dict is None:
108 dict = {}
109 dict = {}
109 if isinstance(dict,Struct):
110 if isinstance(dict,Struct):
110 dict = dict.dict()
111 dict = dict.dict()
111 elif dict and type(dict) is not types.DictType:
112 elif dict and type(dict) is not types.DictType:
112 raise TypeError,\
113 raise TypeError,\
113 'Initialize with a dictionary or key=val pairs.'
114 'Initialize with a dictionary or key=val pairs.'
114 dict.update(kw)
115 dict.update(kw)
115 # do the updating by hand to guarantee that we go through the
116 # do the updating by hand to guarantee that we go through the
116 # safety-checked __setitem__
117 # safety-checked __setitem__
117 for k,v in dict.items():
118 for k,v in dict.items():
118 self[k] = v
119 self[k] = v
119
120
120 def __setitem__(self,key,value):
121 def __setitem__(self,key,value):
121 """Used when struct[key] = val calls are made."""
122 """Used when struct[key] = val calls are made."""
122 if key in Struct.__protected:
123 if key in Struct.__protected:
123 raise KeyError,'Key '+`key`+' is a protected key of class Struct.'
124 raise KeyError,'Key '+`key`+' is a protected key of class Struct.'
124 self.__dict__[key] = value
125 self.__dict__[key] = value
125
126
126 def __setattr__(self, key, value):
127 def __setattr__(self, key, value):
127 """Used when struct.key = val calls are made."""
128 """Used when struct.key = val calls are made."""
128 self.__setitem__(key,value)
129 self.__setitem__(key,value)
129
130
130 def __str__(self):
131 def __str__(self):
131 """Gets called by print."""
132 """Gets called by print."""
132
133
133 return 'Struct('+str(self.__dict__)+')'
134 return 'Struct('+str(self.__dict__)+')'
134
135
135 def __repr__(self):
136 def __repr__(self):
136 """Gets called by repr.
137 """Gets called by repr.
137
138
138 A Struct can be recreated with S_new=eval(repr(S_old))."""
139 A Struct can be recreated with S_new=eval(repr(S_old))."""
139 return 'Struct('+str(self.__dict__)+')'
140 return 'Struct('+str(self.__dict__)+')'
140
141
141 def __getitem__(self,key):
142 def __getitem__(self,key):
142 """Allows struct[key] access."""
143 """Allows struct[key] access."""
143 return self.__dict__[key]
144 return self.__dict__[key]
144
145
145 def __contains__(self,key):
146 def __contains__(self,key):
146 """Allows use of the 'in' operator."""
147 """Allows use of the 'in' operator."""
147 return self.__dict__.has_key(key)
148 return self.__dict__.has_key(key)
148
149
149 def __iadd__(self,other):
150 def __iadd__(self,other):
150 """S += S2 is a shorthand for S.merge(S2)."""
151 """S += S2 is a shorthand for S.merge(S2)."""
151 self.merge(other)
152 self.merge(other)
152 return self
153 return self
153
154
154 def __add__(self,other):
155 def __add__(self,other):
155 """S + S2 -> New Struct made form S and S.merge(S2)"""
156 """S + S2 -> New Struct made form S and S.merge(S2)"""
156 Sout = self.copy()
157 Sout = self.copy()
157 Sout.merge(other)
158 Sout.merge(other)
158 return Sout
159 return Sout
159
160
160 def __sub__(self,other):
161 def __sub__(self,other):
161 """Return S1-S2, where all keys in S2 have been deleted (if present)
162 """Return S1-S2, where all keys in S2 have been deleted (if present)
162 from S1."""
163 from S1."""
163 Sout = self.copy()
164 Sout = self.copy()
164 Sout -= other
165 Sout -= other
165 return Sout
166 return Sout
166
167
167 def __isub__(self,other):
168 def __isub__(self,other):
168 """Do in place S = S - S2, meaning all keys in S2 have been deleted
169 """Do in place S = S - S2, meaning all keys in S2 have been deleted
169 (if present) from S1."""
170 (if present) from S1."""
170
171
171 for k in other.keys():
172 for k in other.keys():
172 if self.has_key(k):
173 if self.has_key(k):
173 del self.__dict__[k]
174 del self.__dict__[k]
174
175
175 def __make_dict(self,__loc_data__,**kw):
176 def __make_dict(self,__loc_data__,**kw):
176 "Helper function for update and merge. Return a dict from data."
177 "Helper function for update and merge. Return a dict from data."
177
178
178 if __loc_data__ == None:
179 if __loc_data__ == None:
179 dict = {}
180 dict = {}
180 elif type(__loc_data__) is types.DictType:
181 elif type(__loc_data__) is types.DictType:
181 dict = __loc_data__
182 dict = __loc_data__
182 elif isinstance(__loc_data__,Struct):
183 elif isinstance(__loc_data__,Struct):
183 dict = __loc_data__.__dict__
184 dict = __loc_data__.__dict__
184 else:
185 else:
185 raise TypeError, 'Update with a dict, a Struct or key=val pairs.'
186 raise TypeError, 'Update with a dict, a Struct or key=val pairs.'
186 if kw:
187 if kw:
187 dict.update(kw)
188 dict.update(kw)
188 return dict
189 return dict
189
190
190 def __dict_invert(self,dict):
191 def __dict_invert(self,dict):
191 """Helper function for merge. Takes a dictionary whose values are
192 """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 lists and returns a dict. with the elements of each list as keys and
193 the original keys as values."""
194 the original keys as values."""
194
195
195 outdict = {}
196 outdict = {}
196 for k,lst in dict.items():
197 for k,lst in dict.items():
197 if type(lst) is types.StringType:
198 if type(lst) is types.StringType:
198 lst = lst.split()
199 lst = lst.split()
199 for entry in lst:
200 for entry in lst:
200 outdict[entry] = k
201 outdict[entry] = k
201 return outdict
202 return outdict
202
203
203 def clear(self):
204 def clear(self):
204 """Clear all attributes."""
205 """Clear all attributes."""
205 self.__dict__.clear()
206 self.__dict__.clear()
206
207
207 def copy(self):
208 def copy(self):
208 """Return a (shallow) copy of a Struct."""
209 """Return a (shallow) copy of a Struct."""
209 return Struct(self.__dict__.copy())
210 return Struct(self.__dict__.copy())
210
211
211 def dict(self):
212 def dict(self):
212 """Return the Struct's dictionary."""
213 """Return the Struct's dictionary."""
213 return self.__dict__
214 return self.__dict__
214
215
215 def dictcopy(self):
216 def dictcopy(self):
216 """Return a (shallow) copy of the Struct's dictionary."""
217 """Return a (shallow) copy of the Struct's dictionary."""
217 return self.__dict__.copy()
218 return self.__dict__.copy()
218
219
219 def popitem(self):
220 def popitem(self):
220 """S.popitem() -> (k, v), remove and return some (key, value) pair as
221 """S.popitem() -> (k, v), remove and return some (key, value) pair as
221 a 2-tuple; but raise KeyError if S is empty."""
222 a 2-tuple; but raise KeyError if S is empty."""
222 return self.__dict__.popitem()
223 return self.__dict__.popitem()
223
224
224 def update(self,__loc_data__=None,**kw):
225 def update(self,__loc_data__=None,**kw):
225 """Update (merge) with data from another Struct or from a dictionary.
226 """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 Optionally, one or more key=value pairs can be given at the end for
227 direct update."""
228 direct update."""
228
229
229 # The funny name __loc_data__ is to prevent a common variable name which
230 # 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 # 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 # 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 # that a user means to add as a Struct field.
233 newdict = Struct.__make_dict(self,__loc_data__,**kw)
234 newdict = Struct.__make_dict(self,__loc_data__,**kw)
234 for k,v in newdict.items():
235 for k,v in newdict.items():
235 self[k] = v
236 self[k] = v
236
237
237 def merge(self,__loc_data__=None,__conflict_solve=None,**kw):
238 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 """S.merge(data,conflict,k=v1,k=v2,...) -> merge data and k=v into S.
239
240
240 This is similar to update(), but much more flexible. First, a dict is
241 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 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 S, the optional dictionary 'conflict' is used to decide what to do.
243
244
244 If conflict is not given, the default behavior is to preserve any keys
245 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 with their current value (the opposite of the update method's
246 behavior).
247 behavior).
247
248
248 conflict is a dictionary of binary functions which will be used to
249 conflict is a dictionary of binary functions which will be used to
249 solve key conflicts. It must have the following structure:
250 solve key conflicts. It must have the following structure:
250
251
251 conflict == { fn1 : [Skey1,Skey2,...], fn2 : [Skey3], etc }
252 conflict == { fn1 : [Skey1,Skey2,...], fn2 : [Skey3], etc }
252
253
253 Values must be lists or whitespace separated strings which are
254 Values must be lists or whitespace separated strings which are
254 automatically converted to lists of strings by calling string.split().
255 automatically converted to lists of strings by calling string.split().
255
256
256 Each key of conflict is a function which defines a policy for
257 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 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 a binary function which returns the desired outcome for a key
259 conflict. These functions will be called as fn(old,new).
260 conflict. These functions will be called as fn(old,new).
260
261
261 An example is probably in order. Suppose you are merging the struct S
262 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 with a dict D and the following conflict policy dict:
263
264
264 S.merge(D,{fn1:['a','b',4], fn2:'key_c key_d'})
265 S.merge(D,{fn1:['a','b',4], fn2:'key_c key_d'})
265
266
266 If the key 'a' is found in both S and D, the merge method will call:
267 If the key 'a' is found in both S and D, the merge method will call:
267
268
268 S['a'] = fn1(S['a'],D['a'])
269 S['a'] = fn1(S['a'],D['a'])
269
270
270 As a convenience, merge() provides five (the most commonly needed)
271 As a convenience, merge() provides five (the most commonly needed)
271 pre-defined policies: preserve, update, add, add_flip and add_s. The
272 pre-defined policies: preserve, update, add, add_flip and add_s. The
272 easiest explanation is their implementation:
273 easiest explanation is their implementation:
273
274
274 preserve = lambda old,new: old
275 preserve = lambda old,new: old
275 update = lambda old,new: new
276 update = lambda old,new: new
276 add = lambda old,new: old + new
277 add = lambda old,new: old + new
277 add_flip = lambda old,new: new + old # note change of order!
278 add_flip = lambda old,new: new + old # note change of order!
278 add_s = lambda old,new: old + ' ' + new # only works for strings!
279 add_s = lambda old,new: old + ' ' + new # only works for strings!
279
280
280 You can use those four words (as strings) as keys in conflict instead
281 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 of defining them as functions, and the merge method will substitute
282 the appropriate functions for you. That is, the call
283 the appropriate functions for you. That is, the call
283
284
284 S.merge(D,{'preserve':'a b c','add':[4,5,'d'],my_function:[6]})
285 S.merge(D,{'preserve':'a b c','add':[4,5,'d'],my_function:[6]})
285
286
286 will automatically substitute the functions preserve and add for the
287 will automatically substitute the functions preserve and add for the
287 names 'preserve' and 'add' before making any function calls.
288 names 'preserve' and 'add' before making any function calls.
288
289
289 For more complicated conflict resolution policies, you still need to
290 For more complicated conflict resolution policies, you still need to
290 construct your own functions. """
291 construct your own functions. """
291
292
292 data_dict = Struct.__make_dict(self,__loc_data__,**kw)
293 data_dict = Struct.__make_dict(self,__loc_data__,**kw)
293
294
294 # policies for conflict resolution: two argument functions which return
295 # policies for conflict resolution: two argument functions which return
295 # the value that will go in the new struct
296 # the value that will go in the new struct
296 preserve = lambda old,new: old
297 preserve = lambda old,new: old
297 update = lambda old,new: new
298 update = lambda old,new: new
298 add = lambda old,new: old + new
299 add = lambda old,new: old + new
299 add_flip = lambda old,new: new + old # note change of order!
300 add_flip = lambda old,new: new + old # note change of order!
300 add_s = lambda old,new: old + ' ' + new
301 add_s = lambda old,new: old + ' ' + new
301
302
302 # default policy is to keep current keys when there's a conflict
303 # default policy is to keep current keys when there's a conflict
303 conflict_solve = list2dict2(self.keys(),default = preserve)
304 conflict_solve = list2dict2(self.keys(),default = preserve)
304
305
305 # the conflict_solve dictionary is given by the user 'inverted': we
306 # the conflict_solve dictionary is given by the user 'inverted': we
306 # need a name-function mapping, it comes as a function -> names
307 # 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 # dict. Make a local copy (b/c we'll make changes), replace user
308 # strings for the three builtin policies and invert it.
309 # strings for the three builtin policies and invert it.
309 if __conflict_solve:
310 if __conflict_solve:
310 inv_conflict_solve_user = __conflict_solve.copy()
311 inv_conflict_solve_user = __conflict_solve.copy()
311 for name, func in [('preserve',preserve), ('update',update),
312 for name, func in [('preserve',preserve), ('update',update),
312 ('add',add), ('add_flip',add_flip), ('add_s',add_s)]:
313 ('add',add), ('add_flip',add_flip), ('add_s',add_s)]:
313 if name in inv_conflict_solve_user.keys():
314 if name in inv_conflict_solve_user.keys():
314 inv_conflict_solve_user[func] = inv_conflict_solve_user[name]
315 inv_conflict_solve_user[func] = inv_conflict_solve_user[name]
315 del inv_conflict_solve_user[name]
316 del inv_conflict_solve_user[name]
316 conflict_solve.update(Struct.__dict_invert(self,inv_conflict_solve_user))
317 conflict_solve.update(Struct.__dict_invert(self,inv_conflict_solve_user))
317 #print 'merge. conflict_solve: '; pprint(conflict_solve) # dbg
318 #print 'merge. conflict_solve: '; pprint(conflict_solve) # dbg
318 #print '*'*50,'in merger. conflict_solver:'; pprint(conflict_solve)
319 #print '*'*50,'in merger. conflict_solver:'; pprint(conflict_solve)
319 for key in data_dict:
320 for key in data_dict:
320 if key not in self:
321 if key not in self:
321 self[key] = data_dict[key]
322 self[key] = data_dict[key]
322 else:
323 else:
323 self[key] = conflict_solve[key](self[key],data_dict[key])
324 self[key] = conflict_solve[key](self[key],data_dict[key])
324
325
325 def has_key(self,key):
326 def has_key(self,key):
326 """Like has_key() dictionary method."""
327 """Like has_key() dictionary method."""
327 return self.__dict__.has_key(key)
328 return self.__dict__.has_key(key)
328
329
329 def hasattr(self,key):
330 def hasattr(self,key):
330 """hasattr function available as a method.
331 """hasattr function available as a method.
331
332
332 Implemented like has_key, to make sure that all available keys in the
333 Implemented like has_key, to make sure that all available keys in the
333 internal dictionary of the Struct appear also as attributes (even
334 internal dictionary of the Struct appear also as attributes (even
334 numeric keys)."""
335 numeric keys)."""
335 return self.__dict__.has_key(key)
336 return self.__dict__.has_key(key)
336
337
337 def items(self):
338 def items(self):
338 """Return the items in the Struct's dictionary, in the same format
339 """Return the items in the Struct's dictionary, in the same format
339 as a call to {}.items()."""
340 as a call to {}.items()."""
340 return self.__dict__.items()
341 return self.__dict__.items()
341
342
342 def keys(self):
343 def keys(self):
343 """Return the keys in the Struct's dictionary, in the same format
344 """Return the keys in the Struct's dictionary, in the same format
344 as a call to {}.keys()."""
345 as a call to {}.keys()."""
345 return self.__dict__.keys()
346 return self.__dict__.keys()
346
347
347 def values(self,keys=None):
348 def values(self,keys=None):
348 """Return the values in the Struct's dictionary, in the same format
349 """Return the values in the Struct's dictionary, in the same format
349 as a call to {}.values().
350 as a call to {}.values().
350
351
351 Can be called with an optional argument keys, which must be a list or
352 Can be called with an optional argument keys, which must be a list or
352 tuple of keys. In this case it returns only the values corresponding
353 tuple of keys. In this case it returns only the values corresponding
353 to those keys (allowing a form of 'slicing' for Structs)."""
354 to those keys (allowing a form of 'slicing' for Structs)."""
354 if not keys:
355 if not keys:
355 return self.__dict__.values()
356 return self.__dict__.values()
356 else:
357 else:
357 ret=[]
358 ret=[]
358 for k in keys:
359 for k in keys:
359 ret.append(self[k])
360 ret.append(self[k])
360 return ret
361 return ret
361
362
362 def get(self,attr,val=None):
363 def get(self,attr,val=None):
363 """S.get(k[,d]) -> S[k] if S.has_key(k), else d. d defaults to None."""
364 """S.get(k[,d]) -> S[k] if S.has_key(k), else d. d defaults to None."""
364 try:
365 try:
365 return self[attr]
366 return self[attr]
366 except KeyError:
367 except KeyError:
367 return val
368 return val
368
369
369 def setdefault(self,attr,val=None):
370 def setdefault(self,attr,val=None):
370 """S.setdefault(k[,d]) -> S.get(k,d), also set S[k]=d if not S.has_key(k)"""
371 """S.setdefault(k[,d]) -> S.get(k,d), also set S[k]=d if not S.has_key(k)"""
371 if not self.has_key(attr):
372 if not self.has_key(attr):
372 self[attr] = val
373 self[attr] = val
373 return self.get(attr,val)
374 return self.get(attr,val)
374 # end class Struct
375 # end class Struct
375
376
@@ -1,495 +1,496 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Manage background (threaded) jobs conveniently from an interactive shell.
2 """Manage background (threaded) jobs conveniently from an interactive shell.
3
3
4 This module provides a BackgroundJobManager class. This is the main class
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
5 meant for public usage, it implements an object which can create and manage
6 new background jobs.
6 new background jobs.
7
7
8 It also provides the actual job classes managed by these BackgroundJobManager
8 It also provides the actual job classes managed by these BackgroundJobManager
9 objects, see their docstrings below.
9 objects, see their docstrings below.
10
10
11
11
12 This system was inspired by discussions with B. Granger and the
12 This system was inspired by discussions with B. Granger and the
13 BackgroundCommand class described in the book Python Scripting for
13 BackgroundCommand class described in the book Python Scripting for
14 Computational Science, by H. P. Langtangen:
14 Computational Science, by H. P. Langtangen:
15
15
16 http://folk.uio.no/hpl/scripting
16 http://folk.uio.no/hpl/scripting
17
17
18 (although ultimately no code from this text was used, as IPython's system is a
18 (although ultimately no code from this text was used, as IPython's system is a
19 separate implementation).
19 separate implementation).
20
20
21 $Id: background_jobs.py 638 2005-07-18 03:01:41Z fperez $
21 $Id: background_jobs.py 958 2005-12-27 23:17:51Z fperez $
22 """
22 """
23
23
24 #*****************************************************************************
24 #*****************************************************************************
25 # Copyright (C) 2005 Fernando Perez <fperez@colorado.edu>
25 # Copyright (C) 2005 Fernando Perez <fperez@colorado.edu>
26 #
26 #
27 # Distributed under the terms of the BSD License. The full license is in
27 # Distributed under the terms of the BSD License. The full license is in
28 # the file COPYING, distributed as part of this software.
28 # the file COPYING, distributed as part of this software.
29 #*****************************************************************************
29 #*****************************************************************************
30
30
31 from IPython import Release
31 from IPython import Release
32 __author__ = '%s <%s>' % Release.authors['Fernando']
32 __author__ = '%s <%s>' % Release.authors['Fernando']
33 __license__ = Release.license
33 __license__ = Release.license
34
34
35 # Code begins
35 # Code begins
36 import threading,sys
36 import sys
37 import threading
37
38
38 from IPython.ultraTB import AutoFormattedTB
39 from IPython.ultraTB import AutoFormattedTB
39 from IPython.genutils import warn,error
40 from IPython.genutils import warn,error
40
41
41 class BackgroundJobManager:
42 class BackgroundJobManager:
42 """Class to manage a pool of backgrounded threaded jobs.
43 """Class to manage a pool of backgrounded threaded jobs.
43
44
44 Below, we assume that 'jobs' is a BackgroundJobManager instance.
45 Below, we assume that 'jobs' is a BackgroundJobManager instance.
45
46
46 Usage summary (see the method docstrings for details):
47 Usage summary (see the method docstrings for details):
47
48
48 jobs.new(...) -> start a new job
49 jobs.new(...) -> start a new job
49
50
50 jobs() or jobs.status() -> print status summary of all jobs
51 jobs() or jobs.status() -> print status summary of all jobs
51
52
52 jobs[N] -> returns job number N.
53 jobs[N] -> returns job number N.
53
54
54 foo = jobs[N].result -> assign to variable foo the result of job N
55 foo = jobs[N].result -> assign to variable foo the result of job N
55
56
56 jobs[N].traceback() -> print the traceback of dead job N
57 jobs[N].traceback() -> print the traceback of dead job N
57
58
58 jobs.remove(N) -> remove (finished) job N
59 jobs.remove(N) -> remove (finished) job N
59
60
60 jobs.flush_finished() -> remove all finished jobs
61 jobs.flush_finished() -> remove all finished jobs
61
62
62 As a convenience feature, BackgroundJobManager instances provide the
63 As a convenience feature, BackgroundJobManager instances provide the
63 utility result and traceback methods which retrieve the corresponding
64 utility result and traceback methods which retrieve the corresponding
64 information from the jobs list:
65 information from the jobs list:
65
66
66 jobs.result(N) <--> jobs[N].result
67 jobs.result(N) <--> jobs[N].result
67 jobs.traceback(N) <--> jobs[N].traceback()
68 jobs.traceback(N) <--> jobs[N].traceback()
68
69
69 While this appears minor, it allows you to use tab completion
70 While this appears minor, it allows you to use tab completion
70 interactively on the job manager instance.
71 interactively on the job manager instance.
71
72
72 In interactive mode, IPython provides the magic fuction %bg for quick
73 In interactive mode, IPython provides the magic fuction %bg for quick
73 creation of backgrounded expression-based jobs. Type bg? for details."""
74 creation of backgrounded expression-based jobs. Type bg? for details."""
74
75
75 def __init__(self):
76 def __init__(self):
76 # Lists for job management
77 # Lists for job management
77 self.jobs_run = []
78 self.jobs_run = []
78 self.jobs_comp = []
79 self.jobs_comp = []
79 self.jobs_dead = []
80 self.jobs_dead = []
80 # A dict of all jobs, so users can easily access any of them
81 # A dict of all jobs, so users can easily access any of them
81 self.jobs_all = {}
82 self.jobs_all = {}
82 # For reporting
83 # For reporting
83 self._comp_report = []
84 self._comp_report = []
84 self._dead_report = []
85 self._dead_report = []
85 # Store status codes locally for fast lookups
86 # Store status codes locally for fast lookups
86 self._s_created = BackgroundJobBase.stat_created_c
87 self._s_created = BackgroundJobBase.stat_created_c
87 self._s_running = BackgroundJobBase.stat_running_c
88 self._s_running = BackgroundJobBase.stat_running_c
88 self._s_completed = BackgroundJobBase.stat_completed_c
89 self._s_completed = BackgroundJobBase.stat_completed_c
89 self._s_dead = BackgroundJobBase.stat_dead_c
90 self._s_dead = BackgroundJobBase.stat_dead_c
90
91
91 def new(self,func_or_exp,*args,**kwargs):
92 def new(self,func_or_exp,*args,**kwargs):
92 """Add a new background job and start it in a separate thread.
93 """Add a new background job and start it in a separate thread.
93
94
94 There are two types of jobs which can be created:
95 There are two types of jobs which can be created:
95
96
96 1. Jobs based on expressions which can be passed to an eval() call.
97 1. Jobs based on expressions which can be passed to an eval() call.
97 The expression must be given as a string. For example:
98 The expression must be given as a string. For example:
98
99
99 job_manager.new('myfunc(x,y,z=1)'[,glob[,loc]])
100 job_manager.new('myfunc(x,y,z=1)'[,glob[,loc]])
100
101
101 The given expression is passed to eval(), along with the optional
102 The given expression is passed to eval(), along with the optional
102 global/local dicts provided. If no dicts are given, they are
103 global/local dicts provided. If no dicts are given, they are
103 extracted automatically from the caller's frame.
104 extracted automatically from the caller's frame.
104
105
105 A Python statement is NOT a valid eval() expression. Basically, you
106 A Python statement is NOT a valid eval() expression. Basically, you
106 can only use as an eval() argument something which can go on the right
107 can only use as an eval() argument something which can go on the right
107 of an '=' sign and be assigned to a variable.
108 of an '=' sign and be assigned to a variable.
108
109
109 For example,"print 'hello'" is not valid, but '2+3' is.
110 For example,"print 'hello'" is not valid, but '2+3' is.
110
111
111 2. Jobs given a function object, optionally passing additional
112 2. Jobs given a function object, optionally passing additional
112 positional arguments:
113 positional arguments:
113
114
114 job_manager.new(myfunc,x,y)
115 job_manager.new(myfunc,x,y)
115
116
116 The function is called with the given arguments.
117 The function is called with the given arguments.
117
118
118 If you need to pass keyword arguments to your function, you must
119 If you need to pass keyword arguments to your function, you must
119 supply them as a dict named kw:
120 supply them as a dict named kw:
120
121
121 job_manager.new(myfunc,x,y,kw=dict(z=1))
122 job_manager.new(myfunc,x,y,kw=dict(z=1))
122
123
123 The reason for this assymmetry is that the new() method needs to
124 The reason for this assymmetry is that the new() method needs to
124 maintain access to its own keywords, and this prevents name collisions
125 maintain access to its own keywords, and this prevents name collisions
125 between arguments to new() and arguments to your own functions.
126 between arguments to new() and arguments to your own functions.
126
127
127 In both cases, the result is stored in the job.result field of the
128 In both cases, the result is stored in the job.result field of the
128 background job object.
129 background job object.
129
130
130
131
131 Notes and caveats:
132 Notes and caveats:
132
133
133 1. All threads running share the same standard output. Thus, if your
134 1. All threads running share the same standard output. Thus, if your
134 background jobs generate output, it will come out on top of whatever
135 background jobs generate output, it will come out on top of whatever
135 you are currently writing. For this reason, background jobs are best
136 you are currently writing. For this reason, background jobs are best
136 used with silent functions which simply return their output.
137 used with silent functions which simply return their output.
137
138
138 2. Threads also all work within the same global namespace, and this
139 2. Threads also all work within the same global namespace, and this
139 system does not lock interactive variables. So if you send job to the
140 system does not lock interactive variables. So if you send job to the
140 background which operates on a mutable object for a long time, and
141 background which operates on a mutable object for a long time, and
141 start modifying that same mutable object interactively (or in another
142 start modifying that same mutable object interactively (or in another
142 backgrounded job), all sorts of bizarre behaviour will occur.
143 backgrounded job), all sorts of bizarre behaviour will occur.
143
144
144 3. If a background job is spending a lot of time inside a C extension
145 3. If a background job is spending a lot of time inside a C extension
145 module which does not release the Python Global Interpreter Lock
146 module which does not release the Python Global Interpreter Lock
146 (GIL), this will block the IPython prompt. This is simply because the
147 (GIL), this will block the IPython prompt. This is simply because the
147 Python interpreter can only switch between threads at Python
148 Python interpreter can only switch between threads at Python
148 bytecodes. While the execution is inside C code, the interpreter must
149 bytecodes. While the execution is inside C code, the interpreter must
149 simply wait unless the extension module releases the GIL.
150 simply wait unless the extension module releases the GIL.
150
151
151 4. There is no way, due to limitations in the Python threads library,
152 4. There is no way, due to limitations in the Python threads library,
152 to kill a thread once it has started."""
153 to kill a thread once it has started."""
153
154
154 if callable(func_or_exp):
155 if callable(func_or_exp):
155 kw = kwargs.get('kw',{})
156 kw = kwargs.get('kw',{})
156 job = BackgroundJobFunc(func_or_exp,*args,**kw)
157 job = BackgroundJobFunc(func_or_exp,*args,**kw)
157 elif isinstance(func_or_exp,basestring):
158 elif isinstance(func_or_exp,basestring):
158 if not args:
159 if not args:
159 frame = sys._getframe(1)
160 frame = sys._getframe(1)
160 glob, loc = frame.f_globals, frame.f_locals
161 glob, loc = frame.f_globals, frame.f_locals
161 elif len(args)==1:
162 elif len(args)==1:
162 glob = loc = args[0]
163 glob = loc = args[0]
163 elif len(args)==2:
164 elif len(args)==2:
164 glob,loc = args
165 glob,loc = args
165 else:
166 else:
166 raise ValueError,\
167 raise ValueError,\
167 'Expression jobs take at most 2 args (globals,locals)'
168 'Expression jobs take at most 2 args (globals,locals)'
168 job = BackgroundJobExpr(func_or_exp,glob,loc)
169 job = BackgroundJobExpr(func_or_exp,glob,loc)
169 else:
170 else:
170 raise
171 raise
171 jkeys = self.jobs_all.keys()
172 jkeys = self.jobs_all.keys()
172 if jkeys:
173 if jkeys:
173 job.num = max(jkeys)+1
174 job.num = max(jkeys)+1
174 else:
175 else:
175 job.num = 0
176 job.num = 0
176 self.jobs_run.append(job)
177 self.jobs_run.append(job)
177 self.jobs_all[job.num] = job
178 self.jobs_all[job.num] = job
178 print 'Starting job # %s in a separate thread.' % job.num
179 print 'Starting job # %s in a separate thread.' % job.num
179 job.start()
180 job.start()
180 return job
181 return job
181
182
182 def __getitem__(self,key):
183 def __getitem__(self,key):
183 return self.jobs_all[key]
184 return self.jobs_all[key]
184
185
185 def __call__(self):
186 def __call__(self):
186 """An alias to self.status(),
187 """An alias to self.status(),
187
188
188 This allows you to simply call a job manager instance much like the
189 This allows you to simply call a job manager instance much like the
189 Unix jobs shell command."""
190 Unix jobs shell command."""
190
191
191 return self.status()
192 return self.status()
192
193
193 def _update_status(self):
194 def _update_status(self):
194 """Update the status of the job lists.
195 """Update the status of the job lists.
195
196
196 This method moves finished jobs to one of two lists:
197 This method moves finished jobs to one of two lists:
197 - self.jobs_comp: jobs which completed successfully
198 - self.jobs_comp: jobs which completed successfully
198 - self.jobs_dead: jobs which finished but died.
199 - self.jobs_dead: jobs which finished but died.
199
200
200 It also copies those jobs to corresponding _report lists. These lists
201 It also copies those jobs to corresponding _report lists. These lists
201 are used to report jobs completed/dead since the last update, and are
202 are used to report jobs completed/dead since the last update, and are
202 then cleared by the reporting function after each call."""
203 then cleared by the reporting function after each call."""
203
204
204 run,comp,dead = self._s_running,self._s_completed,self._s_dead
205 run,comp,dead = self._s_running,self._s_completed,self._s_dead
205 jobs_run = self.jobs_run
206 jobs_run = self.jobs_run
206 for num in range(len(jobs_run)):
207 for num in range(len(jobs_run)):
207 job = jobs_run[num]
208 job = jobs_run[num]
208 stat = job.stat_code
209 stat = job.stat_code
209 if stat == run:
210 if stat == run:
210 continue
211 continue
211 elif stat == comp:
212 elif stat == comp:
212 self.jobs_comp.append(job)
213 self.jobs_comp.append(job)
213 self._comp_report.append(job)
214 self._comp_report.append(job)
214 jobs_run[num] = False
215 jobs_run[num] = False
215 elif stat == dead:
216 elif stat == dead:
216 self.jobs_dead.append(job)
217 self.jobs_dead.append(job)
217 self._dead_report.append(job)
218 self._dead_report.append(job)
218 jobs_run[num] = False
219 jobs_run[num] = False
219 self.jobs_run = filter(None,self.jobs_run)
220 self.jobs_run = filter(None,self.jobs_run)
220
221
221 def _group_report(self,group,name):
222 def _group_report(self,group,name):
222 """Report summary for a given job group.
223 """Report summary for a given job group.
223
224
224 Return True if the group had any elements."""
225 Return True if the group had any elements."""
225
226
226 if group:
227 if group:
227 print '%s jobs:' % name
228 print '%s jobs:' % name
228 for job in group:
229 for job in group:
229 print '%s : %s' % (job.num,job)
230 print '%s : %s' % (job.num,job)
230 print
231 print
231 return True
232 return True
232
233
233 def _group_flush(self,group,name):
234 def _group_flush(self,group,name):
234 """Flush a given job group
235 """Flush a given job group
235
236
236 Return True if the group had any elements."""
237 Return True if the group had any elements."""
237
238
238 njobs = len(group)
239 njobs = len(group)
239 if njobs:
240 if njobs:
240 plural = {1:''}.setdefault(njobs,'s')
241 plural = {1:''}.setdefault(njobs,'s')
241 print 'Flushing %s %s job%s.' % (njobs,name,plural)
242 print 'Flushing %s %s job%s.' % (njobs,name,plural)
242 group[:] = []
243 group[:] = []
243 return True
244 return True
244
245
245 def _status_new(self):
246 def _status_new(self):
246 """Print the status of newly finished jobs.
247 """Print the status of newly finished jobs.
247
248
248 Return True if any new jobs are reported.
249 Return True if any new jobs are reported.
249
250
250 This call resets its own state every time, so it only reports jobs
251 This call resets its own state every time, so it only reports jobs
251 which have finished since the last time it was called."""
252 which have finished since the last time it was called."""
252
253
253 self._update_status()
254 self._update_status()
254 new_comp = self._group_report(self._comp_report,'Completed')
255 new_comp = self._group_report(self._comp_report,'Completed')
255 new_dead = self._group_report(self._dead_report,
256 new_dead = self._group_report(self._dead_report,
256 'Dead, call job.traceback() for details')
257 'Dead, call job.traceback() for details')
257 self._comp_report[:] = []
258 self._comp_report[:] = []
258 self._dead_report[:] = []
259 self._dead_report[:] = []
259 return new_comp or new_dead
260 return new_comp or new_dead
260
261
261 def status(self,verbose=0):
262 def status(self,verbose=0):
262 """Print a status of all jobs currently being managed."""
263 """Print a status of all jobs currently being managed."""
263
264
264 self._update_status()
265 self._update_status()
265 self._group_report(self.jobs_run,'Running')
266 self._group_report(self.jobs_run,'Running')
266 self._group_report(self.jobs_comp,'Completed')
267 self._group_report(self.jobs_comp,'Completed')
267 self._group_report(self.jobs_dead,'Dead')
268 self._group_report(self.jobs_dead,'Dead')
268 # Also flush the report queues
269 # Also flush the report queues
269 self._comp_report[:] = []
270 self._comp_report[:] = []
270 self._dead_report[:] = []
271 self._dead_report[:] = []
271
272
272 def remove(self,num):
273 def remove(self,num):
273 """Remove a finished (completed or dead) job."""
274 """Remove a finished (completed or dead) job."""
274
275
275 try:
276 try:
276 job = self.jobs_all[num]
277 job = self.jobs_all[num]
277 except KeyError:
278 except KeyError:
278 error('Job #%s not found' % num)
279 error('Job #%s not found' % num)
279 else:
280 else:
280 stat_code = job.stat_code
281 stat_code = job.stat_code
281 if stat_code == self._s_running:
282 if stat_code == self._s_running:
282 error('Job #%s is still running, it can not be removed.' % num)
283 error('Job #%s is still running, it can not be removed.' % num)
283 return
284 return
284 elif stat_code == self._s_completed:
285 elif stat_code == self._s_completed:
285 self.jobs_comp.remove(job)
286 self.jobs_comp.remove(job)
286 elif stat_code == self._s_dead:
287 elif stat_code == self._s_dead:
287 self.jobs_dead.remove(job)
288 self.jobs_dead.remove(job)
288
289
289 def flush_finished(self):
290 def flush_finished(self):
290 """Flush all jobs finished (completed and dead) from lists.
291 """Flush all jobs finished (completed and dead) from lists.
291
292
292 Running jobs are never flushed.
293 Running jobs are never flushed.
293
294
294 It first calls _status_new(), to update info. If any jobs have
295 It first calls _status_new(), to update info. If any jobs have
295 completed since the last _status_new() call, the flush operation
296 completed since the last _status_new() call, the flush operation
296 aborts."""
297 aborts."""
297
298
298 if self._status_new():
299 if self._status_new():
299 error('New jobs completed since last '\
300 error('New jobs completed since last '\
300 '_status_new(), aborting flush.')
301 '_status_new(), aborting flush.')
301 return
302 return
302
303
303 # Remove the finished jobs from the master dict
304 # Remove the finished jobs from the master dict
304 jobs_all = self.jobs_all
305 jobs_all = self.jobs_all
305 for job in self.jobs_comp+self.jobs_dead:
306 for job in self.jobs_comp+self.jobs_dead:
306 del(jobs_all[job.num])
307 del(jobs_all[job.num])
307
308
308 # Now flush these lists completely
309 # Now flush these lists completely
309 fl_comp = self._group_flush(self.jobs_comp,'Completed')
310 fl_comp = self._group_flush(self.jobs_comp,'Completed')
310 fl_dead = self._group_flush(self.jobs_dead,'Dead')
311 fl_dead = self._group_flush(self.jobs_dead,'Dead')
311 if not (fl_comp or fl_dead):
312 if not (fl_comp or fl_dead):
312 print 'No jobs to flush.'
313 print 'No jobs to flush.'
313
314
314 def result(self,num):
315 def result(self,num):
315 """result(N) -> return the result of job N."""
316 """result(N) -> return the result of job N."""
316 try:
317 try:
317 return self.jobs_all[num].result
318 return self.jobs_all[num].result
318 except KeyError:
319 except KeyError:
319 error('Job #%s not found' % num)
320 error('Job #%s not found' % num)
320
321
321 def traceback(self,num):
322 def traceback(self,num):
322 try:
323 try:
323 self.jobs_all[num].traceback()
324 self.jobs_all[num].traceback()
324 except KeyError:
325 except KeyError:
325 error('Job #%s not found' % num)
326 error('Job #%s not found' % num)
326
327
327
328
328 class BackgroundJobBase(threading.Thread):
329 class BackgroundJobBase(threading.Thread):
329 """Base class to build BackgroundJob classes.
330 """Base class to build BackgroundJob classes.
330
331
331 The derived classes must implement:
332 The derived classes must implement:
332
333
333 - Their own __init__, since the one here raises NotImplementedError. The
334 - Their own __init__, since the one here raises NotImplementedError. The
334 derived constructor must call self._init() at the end, to provide common
335 derived constructor must call self._init() at the end, to provide common
335 initialization.
336 initialization.
336
337
337 - A strform attribute used in calls to __str__.
338 - A strform attribute used in calls to __str__.
338
339
339 - A call() method, which will make the actual execution call and must
340 - A call() method, which will make the actual execution call and must
340 return a value to be held in the 'result' field of the job object."""
341 return a value to be held in the 'result' field of the job object."""
341
342
342 # Class constants for status, in string and as numerical codes (when
343 # Class constants for status, in string and as numerical codes (when
343 # updating jobs lists, we don't want to do string comparisons). This will
344 # updating jobs lists, we don't want to do string comparisons). This will
344 # be done at every user prompt, so it has to be as fast as possible
345 # be done at every user prompt, so it has to be as fast as possible
345 stat_created = 'Created'; stat_created_c = 0
346 stat_created = 'Created'; stat_created_c = 0
346 stat_running = 'Running'; stat_running_c = 1
347 stat_running = 'Running'; stat_running_c = 1
347 stat_completed = 'Completed'; stat_completed_c = 2
348 stat_completed = 'Completed'; stat_completed_c = 2
348 stat_dead = 'Dead (Exception), call job.traceback() for details'
349 stat_dead = 'Dead (Exception), call job.traceback() for details'
349 stat_dead_c = -1
350 stat_dead_c = -1
350
351
351 def __init__(self):
352 def __init__(self):
352 raise NotImplementedError, \
353 raise NotImplementedError, \
353 "This class can not be instantiated directly."
354 "This class can not be instantiated directly."
354
355
355 def _init(self):
356 def _init(self):
356 """Common initialization for all BackgroundJob objects"""
357 """Common initialization for all BackgroundJob objects"""
357
358
358 for attr in ['call','strform']:
359 for attr in ['call','strform']:
359 assert hasattr(self,attr), "Missing attribute <%s>" % attr
360 assert hasattr(self,attr), "Missing attribute <%s>" % attr
360
361
361 # The num tag can be set by an external job manager
362 # The num tag can be set by an external job manager
362 self.num = None
363 self.num = None
363
364
364 self.status = BackgroundJobBase.stat_created
365 self.status = BackgroundJobBase.stat_created
365 self.stat_code = BackgroundJobBase.stat_created_c
366 self.stat_code = BackgroundJobBase.stat_created_c
366 self.finished = False
367 self.finished = False
367 self.result = '<BackgroundJob has not completed>'
368 self.result = '<BackgroundJob has not completed>'
368 # reuse the ipython traceback handler if we can get to it, otherwise
369 # reuse the ipython traceback handler if we can get to it, otherwise
369 # make a new one
370 # make a new one
370 try:
371 try:
371 self._make_tb = __IPYTHON__.InteractiveTB.text
372 self._make_tb = __IPYTHON__.InteractiveTB.text
372 except:
373 except:
373 self._make_tb = AutoFormattedTB(mode = 'Context',
374 self._make_tb = AutoFormattedTB(mode = 'Context',
374 color_scheme='NoColor',
375 color_scheme='NoColor',
375 tb_offset = 1).text
376 tb_offset = 1).text
376 # Hold a formatted traceback if one is generated.
377 # Hold a formatted traceback if one is generated.
377 self._tb = None
378 self._tb = None
378
379
379 threading.Thread.__init__(self)
380 threading.Thread.__init__(self)
380
381
381 def __str__(self):
382 def __str__(self):
382 return self.strform
383 return self.strform
383
384
384 def __repr__(self):
385 def __repr__(self):
385 return '<BackgroundJob: %s>' % self.strform
386 return '<BackgroundJob: %s>' % self.strform
386
387
387 def traceback(self):
388 def traceback(self):
388 print self._tb
389 print self._tb
389
390
390 def run(self):
391 def run(self):
391 try:
392 try:
392 self.status = BackgroundJobBase.stat_running
393 self.status = BackgroundJobBase.stat_running
393 self.stat_code = BackgroundJobBase.stat_running_c
394 self.stat_code = BackgroundJobBase.stat_running_c
394 self.result = self.call()
395 self.result = self.call()
395 except:
396 except:
396 self.status = BackgroundJobBase.stat_dead
397 self.status = BackgroundJobBase.stat_dead
397 self.stat_code = BackgroundJobBase.stat_dead_c
398 self.stat_code = BackgroundJobBase.stat_dead_c
398 self.finished = None
399 self.finished = None
399 self.result = ('<BackgroundJob died, call job.traceback() for details>')
400 self.result = ('<BackgroundJob died, call job.traceback() for details>')
400 self._tb = self._make_tb()
401 self._tb = self._make_tb()
401 else:
402 else:
402 self.status = BackgroundJobBase.stat_completed
403 self.status = BackgroundJobBase.stat_completed
403 self.stat_code = BackgroundJobBase.stat_completed_c
404 self.stat_code = BackgroundJobBase.stat_completed_c
404 self.finished = True
405 self.finished = True
405
406
406 class BackgroundJobExpr(BackgroundJobBase):
407 class BackgroundJobExpr(BackgroundJobBase):
407 """Evaluate an expression as a background job (uses a separate thread)."""
408 """Evaluate an expression as a background job (uses a separate thread)."""
408
409
409 def __init__(self,expression,glob=None,loc=None):
410 def __init__(self,expression,glob=None,loc=None):
410 """Create a new job from a string which can be fed to eval().
411 """Create a new job from a string which can be fed to eval().
411
412
412 global/locals dicts can be provided, which will be passed to the eval
413 global/locals dicts can be provided, which will be passed to the eval
413 call."""
414 call."""
414
415
415 # fail immediately if the given expression can't be compiled
416 # fail immediately if the given expression can't be compiled
416 self.code = compile(expression,'<BackgroundJob compilation>','eval')
417 self.code = compile(expression,'<BackgroundJob compilation>','eval')
417
418
418 if glob is None:
419 if glob is None:
419 glob = {}
420 glob = {}
420 if loc is None:
421 if loc is None:
421 loc = {}
422 loc = {}
422
423
423 self.expression = self.strform = expression
424 self.expression = self.strform = expression
424 self.glob = glob
425 self.glob = glob
425 self.loc = loc
426 self.loc = loc
426 self._init()
427 self._init()
427
428
428 def call(self):
429 def call(self):
429 return eval(self.code,self.glob,self.loc)
430 return eval(self.code,self.glob,self.loc)
430
431
431 class BackgroundJobFunc(BackgroundJobBase):
432 class BackgroundJobFunc(BackgroundJobBase):
432 """Run a function call as a background job (uses a separate thread)."""
433 """Run a function call as a background job (uses a separate thread)."""
433
434
434 def __init__(self,func,*args,**kwargs):
435 def __init__(self,func,*args,**kwargs):
435 """Create a new job from a callable object.
436 """Create a new job from a callable object.
436
437
437 Any positional arguments and keyword args given to this constructor
438 Any positional arguments and keyword args given to this constructor
438 after the initial callable are passed directly to it."""
439 after the initial callable are passed directly to it."""
439
440
440 assert callable(func),'first argument must be callable'
441 assert callable(func),'first argument must be callable'
441
442
442 if args is None:
443 if args is None:
443 args = []
444 args = []
444 if kwargs is None:
445 if kwargs is None:
445 kwargs = {}
446 kwargs = {}
446
447
447 self.func = func
448 self.func = func
448 self.args = args
449 self.args = args
449 self.kwargs = kwargs
450 self.kwargs = kwargs
450 # The string form will only include the function passed, because
451 # The string form will only include the function passed, because
451 # generating string representations of the arguments is a potentially
452 # generating string representations of the arguments is a potentially
452 # _very_ expensive operation (e.g. with large arrays).
453 # _very_ expensive operation (e.g. with large arrays).
453 self.strform = str(func)
454 self.strform = str(func)
454 self._init()
455 self._init()
455
456
456 def call(self):
457 def call(self):
457 return self.func(*self.args,**self.kwargs)
458 return self.func(*self.args,**self.kwargs)
458
459
459
460
460 if __name__=='__main__':
461 if __name__=='__main__':
461
462
462 import time
463 import time
463
464
464 def sleepfunc(interval=2,*a,**kw):
465 def sleepfunc(interval=2,*a,**kw):
465 args = dict(interval=interval,
466 args = dict(interval=interval,
466 args=a,
467 args=a,
467 kwargs=kw)
468 kwargs=kw)
468 time.sleep(interval)
469 time.sleep(interval)
469 return args
470 return args
470
471
471 def diefunc(interval=2,*a,**kw):
472 def diefunc(interval=2,*a,**kw):
472 time.sleep(interval)
473 time.sleep(interval)
473 die
474 die
474
475
475 def printfunc(interval=1,reps=5):
476 def printfunc(interval=1,reps=5):
476 for n in range(reps):
477 for n in range(reps):
477 time.sleep(interval)
478 time.sleep(interval)
478 print 'In the background...'
479 print 'In the background...'
479
480
480 jobs = BackgroundJobManager()
481 jobs = BackgroundJobManager()
481 # first job will have # 0
482 # first job will have # 0
482 jobs.new(sleepfunc,4)
483 jobs.new(sleepfunc,4)
483 jobs.new(sleepfunc,kw={'reps':2})
484 jobs.new(sleepfunc,kw={'reps':2})
484 # This makes a job which will die
485 # This makes a job which will die
485 jobs.new(diefunc,1)
486 jobs.new(diefunc,1)
486 jobs.new('printfunc(1,3)')
487 jobs.new('printfunc(1,3)')
487
488
488 # after a while, you can get the traceback of a dead job. Run the line
489 # after a while, you can get the traceback of a dead job. Run the line
489 # below again interactively until it prints a traceback (check the status
490 # below again interactively until it prints a traceback (check the status
490 # of the job):
491 # of the job):
491 print jobs[1].status
492 print jobs[1].status
492 jobs[1].traceback()
493 jobs[1].traceback()
493
494
494 # Run this line again until the printed result changes
495 # Run this line again until the printed result changes
495 print "The result of job #0 is:",jobs[0].result
496 print "The result of job #0 is:",jobs[0].result
@@ -1,523 +1,523 b''
1 """Word completion for IPython.
1 """Word completion for IPython.
2
2
3 This module is a fork of the rlcompleter module in the Python standard
3 This module is a fork of the rlcompleter module in the Python standard
4 library. The original enhancements made to rlcompleter have been sent
4 library. The original enhancements made to rlcompleter have been sent
5 upstream and were accepted as of Python 2.3, but we need a lot more
5 upstream and were accepted as of Python 2.3, but we need a lot more
6 functionality specific to IPython, so this module will continue to live as an
6 functionality specific to IPython, so this module will continue to live as an
7 IPython-specific utility.
7 IPython-specific utility.
8
8
9 ---------------------------------------------------------------------------
9 ---------------------------------------------------------------------------
10 Original rlcompleter documentation:
10 Original rlcompleter documentation:
11
11
12 This requires the latest extension to the readline module (the
12 This requires the latest extension to the readline module (the
13 completes keywords, built-ins and globals in __main__; when completing
13 completes keywords, built-ins and globals in __main__; when completing
14 NAME.NAME..., it evaluates (!) the expression up to the last dot and
14 NAME.NAME..., it evaluates (!) the expression up to the last dot and
15 completes its attributes.
15 completes its attributes.
16
16
17 It's very cool to do "import string" type "string.", hit the
17 It's very cool to do "import string" type "string.", hit the
18 completion key (twice), and see the list of names defined by the
18 completion key (twice), and see the list of names defined by the
19 string module!
19 string module!
20
20
21 Tip: to use the tab key as the completion key, call
21 Tip: to use the tab key as the completion key, call
22
22
23 readline.parse_and_bind("tab: complete")
23 readline.parse_and_bind("tab: complete")
24
24
25 Notes:
25 Notes:
26
26
27 - Exceptions raised by the completer function are *ignored* (and
27 - Exceptions raised by the completer function are *ignored* (and
28 generally cause the completion to fail). This is a feature -- since
28 generally cause the completion to fail). This is a feature -- since
29 readline sets the tty device in raw (or cbreak) mode, printing a
29 readline sets the tty device in raw (or cbreak) mode, printing a
30 traceback wouldn't work well without some complicated hoopla to save,
30 traceback wouldn't work well without some complicated hoopla to save,
31 reset and restore the tty state.
31 reset and restore the tty state.
32
32
33 - The evaluation of the NAME.NAME... form may cause arbitrary
33 - The evaluation of the NAME.NAME... form may cause arbitrary
34 application defined code to be executed if an object with a
34 application defined code to be executed if an object with a
35 __getattr__ hook is found. Since it is the responsibility of the
35 __getattr__ hook is found. Since it is the responsibility of the
36 application (or the user) to enable this feature, I consider this an
36 application (or the user) to enable this feature, I consider this an
37 acceptable risk. More complicated expressions (e.g. function calls or
37 acceptable risk. More complicated expressions (e.g. function calls or
38 indexing operations) are *not* evaluated.
38 indexing operations) are *not* evaluated.
39
39
40 - GNU readline is also used by the built-in functions input() and
40 - GNU readline is also used by the built-in functions input() and
41 raw_input(), and thus these also benefit/suffer from the completer
41 raw_input(), and thus these also benefit/suffer from the completer
42 features. Clearly an interactive application can benefit by
42 features. Clearly an interactive application can benefit by
43 specifying its own completer function and using raw_input() for all
43 specifying its own completer function and using raw_input() for all
44 its input.
44 its input.
45
45
46 - When the original stdin is not a tty device, GNU readline is never
46 - When the original stdin is not a tty device, GNU readline is never
47 used, and this module (and the readline module) are silently inactive.
47 used, and this module (and the readline module) are silently inactive.
48
48
49 """
49 """
50
50
51 #*****************************************************************************
51 #*****************************************************************************
52 #
52 #
53 # Since this file is essentially a minimally modified copy of the rlcompleter
53 # Since this file is essentially a minimally modified copy of the rlcompleter
54 # module which is part of the standard Python distribution, I assume that the
54 # module which is part of the standard Python distribution, I assume that the
55 # proper procedure is to maintain its copyright as belonging to the Python
55 # proper procedure is to maintain its copyright as belonging to the Python
56 # Software Foundation (in addition to my own, for all new code).
56 # Software Foundation (in addition to my own, for all new code).
57 #
57 #
58 # Copyright (C) 2001 Python Software Foundation, www.python.org
58 # Copyright (C) 2001 Python Software Foundation, www.python.org
59 # Copyright (C) 2001-2005 Fernando Perez. <fperez@colorado.edu>
59 # Copyright (C) 2001-2005 Fernando Perez. <fperez@colorado.edu>
60 #
60 #
61 # Distributed under the terms of the BSD License. The full license is in
61 # Distributed under the terms of the BSD License. The full license is in
62 # the file COPYING, distributed as part of this software.
62 # the file COPYING, distributed as part of this software.
63 #
63 #
64 #*****************************************************************************
64 #*****************************************************************************
65
65
66 import __builtin__
66 import __builtin__
67 import __main__
67 import __main__
68 import glob
68 import glob
69 import keyword
69 import keyword
70 import os
70 import os
71 import re
71 import re
72 import readline
72 import readline
73 import sys
73 import sys
74 import types
74 import types
75
75
76 from IPython.genutils import shlex_split
76 from IPython.genutils import shlex_split
77
77
78 __all__ = ['Completer','IPCompleter']
78 __all__ = ['Completer','IPCompleter']
79
79
80 def get_class_members(klass):
80 def get_class_members(cls):
81 ret = dir(klass)
81 ret = dir(cls)
82 if hasattr(klass,'__bases__'):
82 if hasattr(cls,'__bases__'):
83 for base in klass.__bases__:
83 for base in cls.__bases__:
84 ret.extend(get_class_members(base))
84 ret.extend(get_class_members(base))
85 return ret
85 return ret
86
86
87 class Completer:
87 class Completer:
88 def __init__(self,namespace=None,global_namespace=None):
88 def __init__(self,namespace=None,global_namespace=None):
89 """Create a new completer for the command line.
89 """Create a new completer for the command line.
90
90
91 Completer([namespace,global_namespace]) -> completer instance.
91 Completer([namespace,global_namespace]) -> completer instance.
92
92
93 If unspecified, the default namespace where completions are performed
93 If unspecified, the default namespace where completions are performed
94 is __main__ (technically, __main__.__dict__). Namespaces should be
94 is __main__ (technically, __main__.__dict__). Namespaces should be
95 given as dictionaries.
95 given as dictionaries.
96
96
97 An optional second namespace can be given. This allows the completer
97 An optional second namespace can be given. This allows the completer
98 to handle cases where both the local and global scopes need to be
98 to handle cases where both the local and global scopes need to be
99 distinguished.
99 distinguished.
100
100
101 Completer instances should be used as the completion mechanism of
101 Completer instances should be used as the completion mechanism of
102 readline via the set_completer() call:
102 readline via the set_completer() call:
103
103
104 readline.set_completer(Completer(my_namespace).complete)
104 readline.set_completer(Completer(my_namespace).complete)
105 """
105 """
106
106
107 if namespace and type(namespace) != types.DictType:
107 if namespace and type(namespace) != types.DictType:
108 raise TypeError,'namespace must be a dictionary'
108 raise TypeError,'namespace must be a dictionary'
109
109
110 if global_namespace and type(global_namespace) != types.DictType:
110 if global_namespace and type(global_namespace) != types.DictType:
111 raise TypeError,'global_namespace must be a dictionary'
111 raise TypeError,'global_namespace must be a dictionary'
112
112
113 # Don't bind to namespace quite yet, but flag whether the user wants a
113 # Don't bind to namespace quite yet, but flag whether the user wants a
114 # specific namespace or to use __main__.__dict__. This will allow us
114 # specific namespace or to use __main__.__dict__. This will allow us
115 # to bind to __main__.__dict__ at completion time, not now.
115 # to bind to __main__.__dict__ at completion time, not now.
116 if namespace is None:
116 if namespace is None:
117 self.use_main_ns = 1
117 self.use_main_ns = 1
118 else:
118 else:
119 self.use_main_ns = 0
119 self.use_main_ns = 0
120 self.namespace = namespace
120 self.namespace = namespace
121
121
122 # The global namespace, if given, can be bound directly
122 # The global namespace, if given, can be bound directly
123 if global_namespace is None:
123 if global_namespace is None:
124 self.global_namespace = {}
124 self.global_namespace = {}
125 else:
125 else:
126 self.global_namespace = global_namespace
126 self.global_namespace = global_namespace
127
127
128 def complete(self, text, state):
128 def complete(self, text, state):
129 """Return the next possible completion for 'text'.
129 """Return the next possible completion for 'text'.
130
130
131 This is called successively with state == 0, 1, 2, ... until it
131 This is called successively with state == 0, 1, 2, ... until it
132 returns None. The completion should begin with 'text'.
132 returns None. The completion should begin with 'text'.
133
133
134 """
134 """
135 if self.use_main_ns:
135 if self.use_main_ns:
136 self.namespace = __main__.__dict__
136 self.namespace = __main__.__dict__
137
137
138 if state == 0:
138 if state == 0:
139 if "." in text:
139 if "." in text:
140 self.matches = self.attr_matches(text)
140 self.matches = self.attr_matches(text)
141 else:
141 else:
142 self.matches = self.global_matches(text)
142 self.matches = self.global_matches(text)
143 try:
143 try:
144 return self.matches[state]
144 return self.matches[state]
145 except IndexError:
145 except IndexError:
146 return None
146 return None
147
147
148 def global_matches(self, text):
148 def global_matches(self, text):
149 """Compute matches when text is a simple name.
149 """Compute matches when text is a simple name.
150
150
151 Return a list of all keywords, built-in functions and names currently
151 Return a list of all keywords, built-in functions and names currently
152 defined in self.namespace or self.global_namespace that match.
152 defined in self.namespace or self.global_namespace that match.
153
153
154 """
154 """
155 matches = []
155 matches = []
156 match_append = matches.append
156 match_append = matches.append
157 n = len(text)
157 n = len(text)
158 for lst in [keyword.kwlist,
158 for lst in [keyword.kwlist,
159 __builtin__.__dict__.keys(),
159 __builtin__.__dict__.keys(),
160 self.namespace.keys(),
160 self.namespace.keys(),
161 self.global_namespace.keys()]:
161 self.global_namespace.keys()]:
162 for word in lst:
162 for word in lst:
163 if word[:n] == text and word != "__builtins__":
163 if word[:n] == text and word != "__builtins__":
164 match_append(word)
164 match_append(word)
165 return matches
165 return matches
166
166
167 def attr_matches(self, text):
167 def attr_matches(self, text):
168 """Compute matches when text contains a dot.
168 """Compute matches when text contains a dot.
169
169
170 Assuming the text is of the form NAME.NAME....[NAME], and is
170 Assuming the text is of the form NAME.NAME....[NAME], and is
171 evaluatable in self.namespace or self.global_namespace, it will be
171 evaluatable in self.namespace or self.global_namespace, it will be
172 evaluated and its attributes (as revealed by dir()) are used as
172 evaluated and its attributes (as revealed by dir()) are used as
173 possible completions. (For class instances, class members are are
173 possible completions. (For class instances, class members are are
174 also considered.)
174 also considered.)
175
175
176 WARNING: this can still invoke arbitrary C code, if an object
176 WARNING: this can still invoke arbitrary C code, if an object
177 with a __getattr__ hook is evaluated.
177 with a __getattr__ hook is evaluated.
178
178
179 """
179 """
180 import re
180 import re
181
181
182 # Another option, seems to work great. Catches things like ''.<tab>
182 # Another option, seems to work great. Catches things like ''.<tab>
183 m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text)
183 m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text)
184
184
185 if not m:
185 if not m:
186 return []
186 return []
187 expr, attr = m.group(1, 3)
187 expr, attr = m.group(1, 3)
188 try:
188 try:
189 object = eval(expr, self.namespace)
189 object = eval(expr, self.namespace)
190 except:
190 except:
191 object = eval(expr, self.global_namespace)
191 object = eval(expr, self.global_namespace)
192 words = [w for w in dir(object) if isinstance(w, basestring)]
192 words = [w for w in dir(object) if isinstance(w, basestring)]
193 if hasattr(object,'__class__'):
193 if hasattr(object,'__class__'):
194 words.append('__class__')
194 words.append('__class__')
195 words.extend(get_class_members(object.__class__))
195 words.extend(get_class_members(object.__class__))
196 n = len(attr)
196 n = len(attr)
197 matches = []
197 matches = []
198 for word in words:
198 for word in words:
199 if word[:n] == attr and word != "__builtins__":
199 if word[:n] == attr and word != "__builtins__":
200 matches.append("%s.%s" % (expr, word))
200 matches.append("%s.%s" % (expr, word))
201 return matches
201 return matches
202
202
203 class IPCompleter(Completer):
203 class IPCompleter(Completer):
204 """Extension of the completer class with IPython-specific features"""
204 """Extension of the completer class with IPython-specific features"""
205
205
206 def __init__(self,shell,namespace=None,global_namespace=None,
206 def __init__(self,shell,namespace=None,global_namespace=None,
207 omit__names=0,alias_table=None):
207 omit__names=0,alias_table=None):
208 """IPCompleter() -> completer
208 """IPCompleter() -> completer
209
209
210 Return a completer object suitable for use by the readline library
210 Return a completer object suitable for use by the readline library
211 via readline.set_completer().
211 via readline.set_completer().
212
212
213 Inputs:
213 Inputs:
214
214
215 - shell: a pointer to the ipython shell itself. This is needed
215 - shell: a pointer to the ipython shell itself. This is needed
216 because this completer knows about magic functions, and those can
216 because this completer knows about magic functions, and those can
217 only be accessed via the ipython instance.
217 only be accessed via the ipython instance.
218
218
219 - namespace: an optional dict where completions are performed.
219 - namespace: an optional dict where completions are performed.
220
220
221 - global_namespace: secondary optional dict for completions, to
221 - global_namespace: secondary optional dict for completions, to
222 handle cases (such as IPython embedded inside functions) where
222 handle cases (such as IPython embedded inside functions) where
223 both Python scopes are visible.
223 both Python scopes are visible.
224
224
225 - The optional omit__names parameter sets the completer to omit the
225 - The optional omit__names parameter sets the completer to omit the
226 'magic' names (__magicname__) for python objects unless the text
226 'magic' names (__magicname__) for python objects unless the text
227 to be completed explicitly starts with one or more underscores.
227 to be completed explicitly starts with one or more underscores.
228
228
229 - If alias_table is supplied, it should be a dictionary of aliases
229 - If alias_table is supplied, it should be a dictionary of aliases
230 to complete. """
230 to complete. """
231
231
232 Completer.__init__(self,namespace,global_namespace)
232 Completer.__init__(self,namespace,global_namespace)
233 self.magic_prefix = shell.name+'.magic_'
233 self.magic_prefix = shell.name+'.magic_'
234 self.magic_escape = shell.ESC_MAGIC
234 self.magic_escape = shell.ESC_MAGIC
235 self.readline = readline
235 self.readline = readline
236 delims = self.readline.get_completer_delims()
236 delims = self.readline.get_completer_delims()
237 delims = delims.replace(self.magic_escape,'')
237 delims = delims.replace(self.magic_escape,'')
238 self.readline.set_completer_delims(delims)
238 self.readline.set_completer_delims(delims)
239 self.get_line_buffer = self.readline.get_line_buffer
239 self.get_line_buffer = self.readline.get_line_buffer
240 self.omit__names = omit__names
240 self.omit__names = omit__names
241 self.merge_completions = shell.rc.readline_merge_completions
241 self.merge_completions = shell.rc.readline_merge_completions
242
242
243 if alias_table is None:
243 if alias_table is None:
244 alias_table = {}
244 alias_table = {}
245 self.alias_table = alias_table
245 self.alias_table = alias_table
246 # Regexp to split filenames with spaces in them
246 # Regexp to split filenames with spaces in them
247 self.space_name_re = re.compile(r'([^\\] )')
247 self.space_name_re = re.compile(r'([^\\] )')
248 # Hold a local ref. to glob.glob for speed
248 # Hold a local ref. to glob.glob for speed
249 self.glob = glob.glob
249 self.glob = glob.glob
250 # Special handling of backslashes needed in win32 platforms
250 # Special handling of backslashes needed in win32 platforms
251 if sys.platform == "win32":
251 if sys.platform == "win32":
252 self.clean_glob = self._clean_glob_win32
252 self.clean_glob = self._clean_glob_win32
253 else:
253 else:
254 self.clean_glob = self._clean_glob
254 self.clean_glob = self._clean_glob
255 self.matchers = [self.python_matches,
255 self.matchers = [self.python_matches,
256 self.file_matches,
256 self.file_matches,
257 self.alias_matches,
257 self.alias_matches,
258 self.python_func_kw_matches]
258 self.python_func_kw_matches]
259
259
260 # Code contributed by Alex Schmolck, for ipython/emacs integration
260 # Code contributed by Alex Schmolck, for ipython/emacs integration
261 def all_completions(self, text):
261 def all_completions(self, text):
262 """Return all possible completions for the benefit of emacs."""
262 """Return all possible completions for the benefit of emacs."""
263
263
264 completions = []
264 completions = []
265 comp_append = completions.append
265 comp_append = completions.append
266 try:
266 try:
267 for i in xrange(sys.maxint):
267 for i in xrange(sys.maxint):
268 res = self.complete(text, i)
268 res = self.complete(text, i)
269
269
270 if not res: break
270 if not res: break
271
271
272 comp_append(res)
272 comp_append(res)
273 #XXX workaround for ``notDefined.<tab>``
273 #XXX workaround for ``notDefined.<tab>``
274 except NameError:
274 except NameError:
275 pass
275 pass
276 return completions
276 return completions
277 # /end Alex Schmolck code.
277 # /end Alex Schmolck code.
278
278
279 def _clean_glob(self,text):
279 def _clean_glob(self,text):
280 return self.glob("%s*" % text)
280 return self.glob("%s*" % text)
281
281
282 def _clean_glob_win32(self,text):
282 def _clean_glob_win32(self,text):
283 return [f.replace("\\","/")
283 return [f.replace("\\","/")
284 for f in self.glob("%s*" % text)]
284 for f in self.glob("%s*" % text)]
285
285
286 def file_matches(self, text):
286 def file_matches(self, text):
287 """Match filneames, expanding ~USER type strings.
287 """Match filneames, expanding ~USER type strings.
288
288
289 Most of the seemingly convoluted logic in this completer is an
289 Most of the seemingly convoluted logic in this completer is an
290 attempt to handle filenames with spaces in them. And yet it's not
290 attempt to handle filenames with spaces in them. And yet it's not
291 quite perfect, because Python's readline doesn't expose all of the
291 quite perfect, because Python's readline doesn't expose all of the
292 GNU readline details needed for this to be done correctly.
292 GNU readline details needed for this to be done correctly.
293
293
294 For a filename with a space in it, the printed completions will be
294 For a filename with a space in it, the printed completions will be
295 only the parts after what's already been typed (instead of the
295 only the parts after what's already been typed (instead of the
296 full completions, as is normally done). I don't think with the
296 full completions, as is normally done). I don't think with the
297 current (as of Python 2.3) Python readline it's possible to do
297 current (as of Python 2.3) Python readline it's possible to do
298 better."""
298 better."""
299
299
300 #print 'Completer->file_matches: <%s>' % text # dbg
300 #print 'Completer->file_matches: <%s>' % text # dbg
301
301
302 # chars that require escaping with backslash - i.e. chars
302 # chars that require escaping with backslash - i.e. chars
303 # that readline treats incorrectly as delimiters, but we
303 # that readline treats incorrectly as delimiters, but we
304 # don't want to treat as delimiters in filename matching
304 # don't want to treat as delimiters in filename matching
305 # when escaped with backslash
305 # when escaped with backslash
306
306
307 protectables = ' ()[]{}'
307 protectables = ' ()[]{}'
308
308
309 def protect_filename(s):
309 def protect_filename(s):
310 return "".join([(ch in protectables and '\\' + ch or ch)
310 return "".join([(ch in protectables and '\\' + ch or ch)
311 for ch in s])
311 for ch in s])
312
312
313 lbuf = self.get_line_buffer()[:self.readline.get_endidx()]
313 lbuf = self.get_line_buffer()[:self.readline.get_endidx()]
314 open_quotes = 0 # track strings with open quotes
314 open_quotes = 0 # track strings with open quotes
315 try:
315 try:
316 lsplit = shlex_split(lbuf)[-1]
316 lsplit = shlex_split(lbuf)[-1]
317 except ValueError:
317 except ValueError:
318 # typically an unmatched ", or backslash without escaped char.
318 # typically an unmatched ", or backslash without escaped char.
319 if lbuf.count('"')==1:
319 if lbuf.count('"')==1:
320 open_quotes = 1
320 open_quotes = 1
321 lsplit = lbuf.split('"')[-1]
321 lsplit = lbuf.split('"')[-1]
322 elif lbuf.count("'")==1:
322 elif lbuf.count("'")==1:
323 open_quotes = 1
323 open_quotes = 1
324 lsplit = lbuf.split("'")[-1]
324 lsplit = lbuf.split("'")[-1]
325 else:
325 else:
326 return None
326 return None
327 except IndexError:
327 except IndexError:
328 # tab pressed on empty line
328 # tab pressed on empty line
329 lsplit = ""
329 lsplit = ""
330
330
331 if lsplit != protect_filename(lsplit):
331 if lsplit != protect_filename(lsplit):
332 # if protectables are found, do matching on the whole escaped
332 # if protectables are found, do matching on the whole escaped
333 # name
333 # name
334 has_protectables = 1
334 has_protectables = 1
335 text0,text = text,lsplit
335 text0,text = text,lsplit
336 else:
336 else:
337 has_protectables = 0
337 has_protectables = 0
338 text = os.path.expanduser(text)
338 text = os.path.expanduser(text)
339
339
340 if text == "":
340 if text == "":
341 return [protect_filename(f) for f in self.glob("*")]
341 return [protect_filename(f) for f in self.glob("*")]
342
342
343 m0 = self.clean_glob(text.replace('\\',''))
343 m0 = self.clean_glob(text.replace('\\',''))
344 if has_protectables:
344 if has_protectables:
345 # If we had protectables, we need to revert our changes to the
345 # If we had protectables, we need to revert our changes to the
346 # beginning of filename so that we don't double-write the part
346 # beginning of filename so that we don't double-write the part
347 # of the filename we have so far
347 # of the filename we have so far
348 len_lsplit = len(lsplit)
348 len_lsplit = len(lsplit)
349 matches = [text0 + protect_filename(f[len_lsplit:]) for f in m0]
349 matches = [text0 + protect_filename(f[len_lsplit:]) for f in m0]
350 else:
350 else:
351 if open_quotes:
351 if open_quotes:
352 # if we have a string with an open quote, we don't need to
352 # if we have a string with an open quote, we don't need to
353 # protect the names at all (and we _shouldn't_, as it
353 # protect the names at all (and we _shouldn't_, as it
354 # would cause bugs when the filesystem call is made).
354 # would cause bugs when the filesystem call is made).
355 matches = m0
355 matches = m0
356 else:
356 else:
357 matches = [protect_filename(f) for f in m0]
357 matches = [protect_filename(f) for f in m0]
358 if len(matches) == 1 and os.path.isdir(matches[0]):
358 if len(matches) == 1 and os.path.isdir(matches[0]):
359 # Takes care of links to directories also. Use '/'
359 # Takes care of links to directories also. Use '/'
360 # explicitly, even under Windows, so that name completions
360 # explicitly, even under Windows, so that name completions
361 # don't end up escaped.
361 # don't end up escaped.
362 matches[0] += '/'
362 matches[0] += '/'
363 return matches
363 return matches
364
364
365 def alias_matches(self, text):
365 def alias_matches(self, text):
366 """Match internal system aliases"""
366 """Match internal system aliases"""
367 #print 'Completer->alias_matches:',text # dbg
367 #print 'Completer->alias_matches:',text # dbg
368 text = os.path.expanduser(text)
368 text = os.path.expanduser(text)
369 aliases = self.alias_table.keys()
369 aliases = self.alias_table.keys()
370 if text == "":
370 if text == "":
371 return aliases
371 return aliases
372 else:
372 else:
373 return [alias for alias in aliases if alias.startswith(text)]
373 return [alias for alias in aliases if alias.startswith(text)]
374
374
375 def python_matches(self,text):
375 def python_matches(self,text):
376 """Match attributes or global python names"""
376 """Match attributes or global python names"""
377 #print 'Completer->python_matches' # dbg
377 #print 'Completer->python_matches' # dbg
378 if "." in text:
378 if "." in text:
379 try:
379 try:
380 matches = self.attr_matches(text)
380 matches = self.attr_matches(text)
381 if text.endswith('.') and self.omit__names:
381 if text.endswith('.') and self.omit__names:
382 if self.omit__names == 1:
382 if self.omit__names == 1:
383 # true if txt is _not_ a __ name, false otherwise:
383 # true if txt is _not_ a __ name, false otherwise:
384 no__name = (lambda txt:
384 no__name = (lambda txt:
385 re.match(r'.*\.__.*?__',txt) is None)
385 re.match(r'.*\.__.*?__',txt) is None)
386 else:
386 else:
387 # true if txt is _not_ a _ name, false otherwise:
387 # true if txt is _not_ a _ name, false otherwise:
388 no__name = (lambda txt:
388 no__name = (lambda txt:
389 re.match(r'.*\._.*?',txt) is None)
389 re.match(r'.*\._.*?',txt) is None)
390 matches = filter(no__name, matches)
390 matches = filter(no__name, matches)
391 except NameError:
391 except NameError:
392 # catches <undefined attributes>.<tab>
392 # catches <undefined attributes>.<tab>
393 matches = []
393 matches = []
394 else:
394 else:
395 matches = self.global_matches(text)
395 matches = self.global_matches(text)
396 # this is so completion finds magics when automagic is on:
396 # this is so completion finds magics when automagic is on:
397 if matches == [] and not text.startswith(os.sep):
397 if matches == [] and not text.startswith(os.sep):
398 matches = self.attr_matches(self.magic_prefix+text)
398 matches = self.attr_matches(self.magic_prefix+text)
399 return matches
399 return matches
400
400
401 def _default_arguments(self, obj):
401 def _default_arguments(self, obj):
402 """Return the list of default arguments of obj if it is callable,
402 """Return the list of default arguments of obj if it is callable,
403 or empty list otherwise."""
403 or empty list otherwise."""
404
404
405 if not (inspect.isfunction(obj) or inspect.ismethod(obj)):
405 if not (inspect.isfunction(obj) or inspect.ismethod(obj)):
406 # for classes, check for __init__,__new__
406 # for classes, check for __init__,__new__
407 if inspect.isclass(obj):
407 if inspect.isclass(obj):
408 obj = (getattr(obj,'__init__',None) or
408 obj = (getattr(obj,'__init__',None) or
409 getattr(obj,'__new__',None))
409 getattr(obj,'__new__',None))
410 # for all others, check if they are __call__able
410 # for all others, check if they are __call__able
411 elif hasattr(obj, '__call__'):
411 elif hasattr(obj, '__call__'):
412 obj = obj.__call__
412 obj = obj.__call__
413 # XXX: is there a way to handle the builtins ?
413 # XXX: is there a way to handle the builtins ?
414 try:
414 try:
415 args,_,_1,defaults = inspect.getargspec(obj)
415 args,_,_1,defaults = inspect.getargspec(obj)
416 if defaults:
416 if defaults:
417 return args[-len(defaults):]
417 return args[-len(defaults):]
418 except TypeError: pass
418 except TypeError: pass
419 return []
419 return []
420
420
421 def python_func_kw_matches(self,text):
421 def python_func_kw_matches(self,text):
422 """Match named parameters (kwargs) of the last open function"""
422 """Match named parameters (kwargs) of the last open function"""
423
423
424 if "." in text: # a parameter cannot be dotted
424 if "." in text: # a parameter cannot be dotted
425 return []
425 return []
426 try: regexp = self.__funcParamsRegex
426 try: regexp = self.__funcParamsRegex
427 except AttributeError:
427 except AttributeError:
428 regexp = self.__funcParamsRegex = re.compile(r'''
428 regexp = self.__funcParamsRegex = re.compile(r'''
429 '.*?' | # single quoted strings or
429 '.*?' | # single quoted strings or
430 ".*?" | # double quoted strings or
430 ".*?" | # double quoted strings or
431 \w+ | # identifier
431 \w+ | # identifier
432 \S # other characters
432 \S # other characters
433 ''', re.VERBOSE | re.DOTALL)
433 ''', re.VERBOSE | re.DOTALL)
434 # 1. find the nearest identifier that comes before an unclosed
434 # 1. find the nearest identifier that comes before an unclosed
435 # parenthesis e.g. for "foo (1+bar(x), pa", the candidate is "foo"
435 # parenthesis e.g. for "foo (1+bar(x), pa", the candidate is "foo"
436 tokens = regexp.findall(self.get_line_buffer())
436 tokens = regexp.findall(self.get_line_buffer())
437 tokens.reverse()
437 tokens.reverse()
438 iterTokens = iter(tokens); openPar = 0
438 iterTokens = iter(tokens); openPar = 0
439 for token in iterTokens:
439 for token in iterTokens:
440 if token == ')':
440 if token == ')':
441 openPar -= 1
441 openPar -= 1
442 elif token == '(':
442 elif token == '(':
443 openPar += 1
443 openPar += 1
444 if openPar > 0:
444 if openPar > 0:
445 # found the last unclosed parenthesis
445 # found the last unclosed parenthesis
446 break
446 break
447 else:
447 else:
448 return []
448 return []
449 # 2. Concatenate dotted names ("foo.bar" for "foo.bar(x, pa" )
449 # 2. Concatenate dotted names ("foo.bar" for "foo.bar(x, pa" )
450 ids = []
450 ids = []
451 isId = re.compile(r'\w+$').match
451 isId = re.compile(r'\w+$').match
452 while True:
452 while True:
453 try:
453 try:
454 ids.append(iterTokens.next())
454 ids.append(iterTokens.next())
455 if not isId(ids[-1]):
455 if not isId(ids[-1]):
456 ids.pop(); break
456 ids.pop(); break
457 if not iterTokens.next() == '.':
457 if not iterTokens.next() == '.':
458 break
458 break
459 except StopIteration:
459 except StopIteration:
460 break
460 break
461 # lookup the candidate callable matches either using global_matches
461 # lookup the candidate callable matches either using global_matches
462 # or attr_matches for dotted names
462 # or attr_matches for dotted names
463 if len(ids) == 1:
463 if len(ids) == 1:
464 callableMatches = self.global_matches(ids[0])
464 callableMatches = self.global_matches(ids[0])
465 else:
465 else:
466 callableMatches = self.attr_matches('.'.join(ids[::-1]))
466 callableMatches = self.attr_matches('.'.join(ids[::-1]))
467 argMatches = []
467 argMatches = []
468 for callableMatch in callableMatches:
468 for callableMatch in callableMatches:
469 try: namedArgs = self._default_arguments(eval(callableMatch,
469 try: namedArgs = self._default_arguments(eval(callableMatch,
470 self.namespace))
470 self.namespace))
471 except: continue
471 except: continue
472 for namedArg in namedArgs:
472 for namedArg in namedArgs:
473 if namedArg.startswith(text):
473 if namedArg.startswith(text):
474 argMatches.append("%s=" %namedArg)
474 argMatches.append("%s=" %namedArg)
475 return argMatches
475 return argMatches
476
476
477 def complete(self, text, state):
477 def complete(self, text, state):
478 """Return the next possible completion for 'text'.
478 """Return the next possible completion for 'text'.
479
479
480 This is called successively with state == 0, 1, 2, ... until it
480 This is called successively with state == 0, 1, 2, ... until it
481 returns None. The completion should begin with 'text'. """
481 returns None. The completion should begin with 'text'. """
482
482
483 #print '\n*** COMPLETE: <%s> (%s)' % (text,state) # dbg
483 #print '\n*** COMPLETE: <%s> (%s)' % (text,state) # dbg
484
484
485 # if there is only a tab on a line with only whitespace, instead
485 # if there is only a tab on a line with only whitespace, instead
486 # of the mostly useless 'do you want to see all million
486 # of the mostly useless 'do you want to see all million
487 # completions' message, just do the right thing and give the user
487 # completions' message, just do the right thing and give the user
488 # his tab! Incidentally, this enables pasting of tabbed text from
488 # his tab! Incidentally, this enables pasting of tabbed text from
489 # an editor (as long as autoindent is off).
489 # an editor (as long as autoindent is off).
490 if not self.get_line_buffer().strip():
490 if not self.get_line_buffer().strip():
491 self.readline.insert_text('\t')
491 self.readline.insert_text('\t')
492 return None
492 return None
493
493
494 magic_escape = self.magic_escape
494 magic_escape = self.magic_escape
495 magic_prefix = self.magic_prefix
495 magic_prefix = self.magic_prefix
496
496
497 try:
497 try:
498 if text.startswith(magic_escape):
498 if text.startswith(magic_escape):
499 text = text.replace(magic_escape,magic_prefix)
499 text = text.replace(magic_escape,magic_prefix)
500 elif text.startswith('~'):
500 elif text.startswith('~'):
501 text = os.path.expanduser(text)
501 text = os.path.expanduser(text)
502 if state == 0:
502 if state == 0:
503 # Extend the list of completions with the results of each
503 # Extend the list of completions with the results of each
504 # matcher, so we return results to the user from all
504 # matcher, so we return results to the user from all
505 # namespaces.
505 # namespaces.
506 if self.merge_completions:
506 if self.merge_completions:
507 self.matches = []
507 self.matches = []
508 for matcher in self.matchers:
508 for matcher in self.matchers:
509 self.matches.extend(matcher(text))
509 self.matches.extend(matcher(text))
510 else:
510 else:
511 for matcher in self.matchers:
511 for matcher in self.matchers:
512 self.matches = matcher(text)
512 self.matches = matcher(text)
513 if self.matches:
513 if self.matches:
514 break
514 break
515
515
516 try:
516 try:
517 return self.matches[state].replace(magic_prefix,magic_escape)
517 return self.matches[state].replace(magic_prefix,magic_escape)
518 except IndexError:
518 except IndexError:
519 return None
519 return None
520 except:
520 except:
521 #import traceback; traceback.print_exc() # dbg
521 #import traceback; traceback.print_exc() # dbg
522 # If completion fails, don't annoy the user.
522 # If completion fails, don't annoy the user.
523 return None
523 return None
@@ -1,184 +1,186 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 A module to change reload() so that it acts recursively.
3 A module to change reload() so that it acts recursively.
4 To enable it type:
4 To enable it type:
5 >>> import __builtin__, deep_reload
5 >>> import __builtin__, deep_reload
6 >>> __builtin__.reload = deep_reload.reload
6 >>> __builtin__.reload = deep_reload.reload
7 You can then disable it with:
7 You can then disable it with:
8 >>> __builtin__.reload = deep_reload.original_reload
8 >>> __builtin__.reload = deep_reload.original_reload
9
9
10 Alternatively, you can add a dreload builtin alongside normal reload with:
10 Alternatively, you can add a dreload builtin alongside normal reload with:
11 >>> __builtin__.dreload = deep_reload.reload
11 >>> __builtin__.dreload = deep_reload.reload
12
12
13 This code is almost entirely based on knee.py from the standard library.
13 This code is almost entirely based on knee.py from the standard library.
14
14
15 $Id: deep_reload.py 410 2004-11-04 07:58:17Z fperez $"""
15 $Id: deep_reload.py 958 2005-12-27 23:17:51Z fperez $"""
16
16
17 #*****************************************************************************
17 #*****************************************************************************
18 # Copyright (C) 2001 Nathaniel Gray <n8gray@caltech.edu>
18 # Copyright (C) 2001 Nathaniel Gray <n8gray@caltech.edu>
19 #
19 #
20 # Distributed under the terms of the BSD License. The full license is in
20 # Distributed under the terms of the BSD License. The full license is in
21 # the file COPYING, distributed as part of this software.
21 # the file COPYING, distributed as part of this software.
22 #*****************************************************************************
22 #*****************************************************************************
23
23
24 from IPython import Release # do it explicitly so pydoc can see it - pydoc bug
24 from IPython import Release # do it explicitly so pydoc can see it - pydoc bug
25 __author__ = '%s <%s>' % Release.authors['Nathan']
25 __author__ = '%s <%s>' % Release.authors['Nathan']
26 __license__ = Release.license
26 __license__ = Release.license
27 __version__ = "0.5"
27 __version__ = "0.5"
28 __date__ = "21 August 2001"
28 __date__ = "21 August 2001"
29
29
30 import sys, imp, __builtin__
30 import __builtin__
31 import imp
32 import sys
31
33
32 # Replacement for __import__()
34 # Replacement for __import__()
33 def deep_import_hook(name, globals=None, locals=None, fromlist=None):
35 def deep_import_hook(name, globals=None, locals=None, fromlist=None):
34 parent = determine_parent(globals)
36 parent = determine_parent(globals)
35 q, tail = find_head_package(parent, name)
37 q, tail = find_head_package(parent, name)
36 m = load_tail(q, tail)
38 m = load_tail(q, tail)
37 if not fromlist:
39 if not fromlist:
38 return q
40 return q
39 if hasattr(m, "__path__"):
41 if hasattr(m, "__path__"):
40 ensure_fromlist(m, fromlist)
42 ensure_fromlist(m, fromlist)
41 return m
43 return m
42
44
43 def determine_parent(globals):
45 def determine_parent(globals):
44 if not globals or not globals.has_key("__name__"):
46 if not globals or not globals.has_key("__name__"):
45 return None
47 return None
46 pname = globals['__name__']
48 pname = globals['__name__']
47 if globals.has_key("__path__"):
49 if globals.has_key("__path__"):
48 parent = sys.modules[pname]
50 parent = sys.modules[pname]
49 assert globals is parent.__dict__
51 assert globals is parent.__dict__
50 return parent
52 return parent
51 if '.' in pname:
53 if '.' in pname:
52 i = pname.rfind('.')
54 i = pname.rfind('.')
53 pname = pname[:i]
55 pname = pname[:i]
54 parent = sys.modules[pname]
56 parent = sys.modules[pname]
55 assert parent.__name__ == pname
57 assert parent.__name__ == pname
56 return parent
58 return parent
57 return None
59 return None
58
60
59 def find_head_package(parent, name):
61 def find_head_package(parent, name):
60 # Import the first
62 # Import the first
61 if '.' in name:
63 if '.' in name:
62 # 'some.nested.package' -> head = 'some', tail = 'nested.package'
64 # 'some.nested.package' -> head = 'some', tail = 'nested.package'
63 i = name.find('.')
65 i = name.find('.')
64 head = name[:i]
66 head = name[:i]
65 tail = name[i+1:]
67 tail = name[i+1:]
66 else:
68 else:
67 # 'packagename' -> head = 'packagename', tail = ''
69 # 'packagename' -> head = 'packagename', tail = ''
68 head = name
70 head = name
69 tail = ""
71 tail = ""
70 if parent:
72 if parent:
71 # If this is a subpackage then qname = parent's name + head
73 # If this is a subpackage then qname = parent's name + head
72 qname = "%s.%s" % (parent.__name__, head)
74 qname = "%s.%s" % (parent.__name__, head)
73 else:
75 else:
74 qname = head
76 qname = head
75 q = import_module(head, qname, parent)
77 q = import_module(head, qname, parent)
76 if q: return q, tail
78 if q: return q, tail
77 if parent:
79 if parent:
78 qname = head
80 qname = head
79 parent = None
81 parent = None
80 q = import_module(head, qname, parent)
82 q = import_module(head, qname, parent)
81 if q: return q, tail
83 if q: return q, tail
82 raise ImportError, "No module named " + qname
84 raise ImportError, "No module named " + qname
83
85
84 def load_tail(q, tail):
86 def load_tail(q, tail):
85 m = q
87 m = q
86 while tail:
88 while tail:
87 i = tail.find('.')
89 i = tail.find('.')
88 if i < 0: i = len(tail)
90 if i < 0: i = len(tail)
89 head, tail = tail[:i], tail[i+1:]
91 head, tail = tail[:i], tail[i+1:]
90
92
91 # fperez: fix dotted.name reloading failures by changing:
93 # fperez: fix dotted.name reloading failures by changing:
92 #mname = "%s.%s" % (m.__name__, head)
94 #mname = "%s.%s" % (m.__name__, head)
93 # to:
95 # to:
94 mname = m.__name__
96 mname = m.__name__
95 # This needs more testing!!! (I don't understand this module too well)
97 # This needs more testing!!! (I don't understand this module too well)
96
98
97 #print '** head,tail=|%s|->|%s|, mname=|%s|' % (head,tail,mname) # dbg
99 #print '** head,tail=|%s|->|%s|, mname=|%s|' % (head,tail,mname) # dbg
98 m = import_module(head, mname, m)
100 m = import_module(head, mname, m)
99 if not m:
101 if not m:
100 raise ImportError, "No module named " + mname
102 raise ImportError, "No module named " + mname
101 return m
103 return m
102
104
103 def ensure_fromlist(m, fromlist, recursive=0):
105 def ensure_fromlist(m, fromlist, recursive=0):
104 for sub in fromlist:
106 for sub in fromlist:
105 if sub == "*":
107 if sub == "*":
106 if not recursive:
108 if not recursive:
107 try:
109 try:
108 all = m.__all__
110 all = m.__all__
109 except AttributeError:
111 except AttributeError:
110 pass
112 pass
111 else:
113 else:
112 ensure_fromlist(m, all, 1)
114 ensure_fromlist(m, all, 1)
113 continue
115 continue
114 if sub != "*" and not hasattr(m, sub):
116 if sub != "*" and not hasattr(m, sub):
115 subname = "%s.%s" % (m.__name__, sub)
117 subname = "%s.%s" % (m.__name__, sub)
116 submod = import_module(sub, subname, m)
118 submod = import_module(sub, subname, m)
117 if not submod:
119 if not submod:
118 raise ImportError, "No module named " + subname
120 raise ImportError, "No module named " + subname
119
121
120 # Need to keep track of what we've already reloaded to prevent cyclic evil
122 # Need to keep track of what we've already reloaded to prevent cyclic evil
121 found_now = {}
123 found_now = {}
122
124
123 def import_module(partname, fqname, parent):
125 def import_module(partname, fqname, parent):
124 global found_now
126 global found_now
125 if found_now.has_key(fqname):
127 if found_now.has_key(fqname):
126 try:
128 try:
127 return sys.modules[fqname]
129 return sys.modules[fqname]
128 except KeyError:
130 except KeyError:
129 pass
131 pass
130
132
131 print 'Reloading', fqname #, sys.excepthook is sys.__excepthook__, \
133 print 'Reloading', fqname #, sys.excepthook is sys.__excepthook__, \
132 #sys.displayhook is sys.__displayhook__
134 #sys.displayhook is sys.__displayhook__
133
135
134 found_now[fqname] = 1
136 found_now[fqname] = 1
135 try:
137 try:
136 fp, pathname, stuff = imp.find_module(partname,
138 fp, pathname, stuff = imp.find_module(partname,
137 parent and parent.__path__)
139 parent and parent.__path__)
138 except ImportError:
140 except ImportError:
139 return None
141 return None
140
142
141 try:
143 try:
142 m = imp.load_module(fqname, fp, pathname, stuff)
144 m = imp.load_module(fqname, fp, pathname, stuff)
143 finally:
145 finally:
144 if fp: fp.close()
146 if fp: fp.close()
145
147
146 if parent:
148 if parent:
147 setattr(parent, partname, m)
149 setattr(parent, partname, m)
148
150
149 return m
151 return m
150
152
151 def deep_reload_hook(module):
153 def deep_reload_hook(module):
152 name = module.__name__
154 name = module.__name__
153 if '.' not in name:
155 if '.' not in name:
154 return import_module(name, name, None)
156 return import_module(name, name, None)
155 i = name.rfind('.')
157 i = name.rfind('.')
156 pname = name[:i]
158 pname = name[:i]
157 parent = sys.modules[pname]
159 parent = sys.modules[pname]
158 return import_module(name[i+1:], name, parent)
160 return import_module(name[i+1:], name, parent)
159
161
160 # Save the original hooks
162 # Save the original hooks
161 original_reload = __builtin__.reload
163 original_reload = __builtin__.reload
162
164
163 # Replacement for reload()
165 # Replacement for reload()
164 def reload(module, exclude=['sys', '__builtin__', '__main__']):
166 def reload(module, exclude=['sys', '__builtin__', '__main__']):
165 """Recursively reload all modules used in the given module. Optionally
167 """Recursively reload all modules used in the given module. Optionally
166 takes a list of modules to exclude from reloading. The default exclude
168 takes a list of modules to exclude from reloading. The default exclude
167 list contains sys, __main__, and __builtin__, to prevent, e.g., resetting
169 list contains sys, __main__, and __builtin__, to prevent, e.g., resetting
168 display, exception, and io hooks.
170 display, exception, and io hooks.
169 """
171 """
170 global found_now
172 global found_now
171 for i in exclude:
173 for i in exclude:
172 found_now[i] = 1
174 found_now[i] = 1
173 original_import = __builtin__.__import__
175 original_import = __builtin__.__import__
174 __builtin__.__import__ = deep_import_hook
176 __builtin__.__import__ = deep_import_hook
175 try:
177 try:
176 ret = deep_reload_hook(module)
178 ret = deep_reload_hook(module)
177 finally:
179 finally:
178 __builtin__.__import__ = original_import
180 __builtin__.__import__ = original_import
179 found_now = {}
181 found_now = {}
180 return ret
182 return ret
181
183
182 # Uncomment the following to automatically activate deep reloading whenever
184 # Uncomment the following to automatically activate deep reloading whenever
183 # this module is imported
185 # this module is imported
184 #__builtin__.reload = reload
186 #__builtin__.reload = reload
@@ -1,309 +1,309 b''
1 """Module for interactive demos using IPython.
1 """Module for interactive demos using IPython.
2
2
3 This module implements a single class, Demo, for running Python scripts
3 This module implements a single class, Demo, for running Python scripts
4 interactively in IPython for demonstrations. With very simple markup (a few
4 interactively in IPython for demonstrations. With very simple markup (a few
5 tags in comments), you can control points where the script stops executing and
5 tags in comments), you can control points where the script stops executing and
6 returns control to IPython.
6 returns control to IPython.
7
7
8 The file is run in its own empty namespace (though you can pass it a string of
8 The file is run in its own empty namespace (though you can pass it a string of
9 arguments as if in a command line environment, and it will see those as
9 arguments as if in a command line environment, and it will see those as
10 sys.argv). But at each stop, the global IPython namespace is updated with the
10 sys.argv). But at each stop, the global IPython namespace is updated with the
11 current internal demo namespace, so you can work interactively with the data
11 current internal demo namespace, so you can work interactively with the data
12 accumulated so far.
12 accumulated so far.
13
13
14 By default, each block of code is printed (with syntax highlighting) before
14 By default, each block of code is printed (with syntax highlighting) before
15 executing it and you have to confirm execution. This is intended to show the
15 executing it and you have to confirm execution. This is intended to show the
16 code to an audience first so you can discuss it, and only proceed with
16 code to an audience first so you can discuss it, and only proceed with
17 execution once you agree. There are a few tags which allow you to modify this
17 execution once you agree. There are a few tags which allow you to modify this
18 behavior.
18 behavior.
19
19
20 The supported tags are:
20 The supported tags are:
21
21
22 # <demo> --- stop ---
22 # <demo> --- stop ---
23
23
24 Defines block boundaries, the points where IPython stops execution of the
24 Defines block boundaries, the points where IPython stops execution of the
25 file and returns to the interactive prompt.
25 file and returns to the interactive prompt.
26
26
27 # <demo> silent
27 # <demo> silent
28
28
29 Make a block execute silently (and hence automatically). Typically used in
29 Make a block execute silently (and hence automatically). Typically used in
30 cases where you have some boilerplate or initialization code which you need
30 cases where you have some boilerplate or initialization code which you need
31 executed but do not want to be seen in the demo.
31 executed but do not want to be seen in the demo.
32
32
33 # <demo> auto
33 # <demo> auto
34
34
35 Make a block execute automatically, but still being printed. Useful for
35 Make a block execute automatically, but still being printed. Useful for
36 simple code which does not warrant discussion, since it avoids the extra
36 simple code which does not warrant discussion, since it avoids the extra
37 manual confirmation.
37 manual confirmation.
38
38
39 # <demo> auto_all
39 # <demo> auto_all
40
40
41 This tag can _only_ be in the first block, and if given it overrides the
41 This tag can _only_ be in the first block, and if given it overrides the
42 individual auto tags to make the whole demo fully automatic (no block asks
42 individual auto tags to make the whole demo fully automatic (no block asks
43 for confirmation). It can also be given at creation time (or the attribute
43 for confirmation). It can also be given at creation time (or the attribute
44 set later) to override what's in the file.
44 set later) to override what's in the file.
45
45
46 While _any_ python file can be run as a Demo instance, if there are no stop
46 While _any_ python file can be run as a Demo instance, if there are no stop
47 tags the whole file will run in a single block (no different that calling
47 tags the whole file will run in a single block (no different that calling
48 first %pycat and then %run). The minimal markup to make this useful is to
48 first %pycat and then %run). The minimal markup to make this useful is to
49 place a set of stop tags; the other tags are only there to let you fine-tune
49 place a set of stop tags; the other tags are only there to let you fine-tune
50 the execution.
50 the execution.
51
51
52 This is probably best explained with the simple example file below. You can
52 This is probably best explained with the simple example file below. You can
53 copy this into a file named ex_demo.py, and try running it via:
53 copy this into a file named ex_demo.py, and try running it via:
54
54
55 from IPython.demo import Demo
55 from IPython.demo import Demo
56 d = Demo('ex_demo.py')
56 d = Demo('ex_demo.py')
57 d() <--- Call the d object (omit the parens if you have autocall on).
57 d() <--- Call the d object (omit the parens if you have autocall on).
58
58
59 Each time you call the demo object, it runs the next block. The demo object
59 Each time you call the demo object, it runs the next block. The demo object
60 has a few useful methods for navigation, like again(), jump(), seek() and
60 has a few useful methods for navigation, like again(), jump(), seek() and
61 back(). It can be reset for a new run via reset() or reloaded from disk (in
61 back(). It can be reset for a new run via reset() or reloaded from disk (in
62 case you've edited the source) via reload(). See their docstrings below.
62 case you've edited the source) via reload(). See their docstrings below.
63
63
64 #################### EXAMPLE DEMO <ex_demo.py> ###############################
64 #################### EXAMPLE DEMO <ex_demo.py> ###############################
65 '''A simple interactive demo to illustrate the use of IPython's Demo class.'''
65 '''A simple interactive demo to illustrate the use of IPython's Demo class.'''
66
66
67 print 'Hello, welcome to an interactive IPython demo.'
67 print 'Hello, welcome to an interactive IPython demo.'
68
68
69 # The mark below defines a block boundary, which is a point where IPython will
69 # The mark below defines a block boundary, which is a point where IPython will
70 # stop execution and return to the interactive prompt.
70 # stop execution and return to the interactive prompt.
71 # Note that in actual interactive execution,
71 # Note that in actual interactive execution,
72 # <demo> --- stop ---
72 # <demo> --- stop ---
73
73
74 x = 1
74 x = 1
75 y = 2
75 y = 2
76
76
77 # <demo> --- stop ---
77 # <demo> --- stop ---
78
78
79 # the mark below makes this block as silent
79 # the mark below makes this block as silent
80 # <demo> silent
80 # <demo> silent
81
81
82 print 'This is a silent block, which gets executed but not printed.'
82 print 'This is a silent block, which gets executed but not printed.'
83
83
84 # <demo> --- stop ---
84 # <demo> --- stop ---
85 # <demo> auto
85 # <demo> auto
86 print 'This is an automatic block.'
86 print 'This is an automatic block.'
87 print 'It is executed without asking for confirmation, but printed.'
87 print 'It is executed without asking for confirmation, but printed.'
88 z = x+y
88 z = x+y
89
89
90 print 'z=',x
90 print 'z=',x
91
91
92 # <demo> --- stop ---
92 # <demo> --- stop ---
93 # This is just another normal block.
93 # This is just another normal block.
94 print 'z is now:', z
94 print 'z is now:', z
95
95
96 print 'bye!'
96 print 'bye!'
97 ################### END EXAMPLE DEMO <ex_demo.py> ############################
97 ################### END EXAMPLE DEMO <ex_demo.py> ############################
98
98
99 WARNING: this module uses Python 2.3 features, so it won't work in 2.2
99 WARNING: this module uses Python 2.3 features, so it won't work in 2.2
100 environments.
100 environments.
101 """
101 """
102 #*****************************************************************************
102 #*****************************************************************************
103 # Copyright (C) 2005 Fernando Perez. <Fernando.Perez@colorado.edu>
103 # Copyright (C) 2005 Fernando Perez. <Fernando.Perez@colorado.edu>
104 #
104 #
105 # Distributed under the terms of the BSD License. The full license is in
105 # Distributed under the terms of the BSD License. The full license is in
106 # the file COPYING, distributed as part of this software.
106 # the file COPYING, distributed as part of this software.
107 #
107 #
108 #*****************************************************************************
108 #*****************************************************************************
109
109
110 import sys
111 import exceptions
110 import exceptions
112 import re
111 import re
112 import sys
113
113
114 from IPython.PyColorize import Parser
114 from IPython.PyColorize import Parser
115 from IPython.genutils import marquee, shlex_split, file_read
115 from IPython.genutils import marquee, shlex_split, file_read
116
116
117 __all__ = ['Demo','DemoError']
117 __all__ = ['Demo','DemoError']
118
118
119 class DemoError(exceptions.Exception): pass
119 class DemoError(exceptions.Exception): pass
120
120
121 def re_mark(mark):
121 def re_mark(mark):
122 return re.compile(r'^\s*#\s+<demo>\s+%s\s*$' % mark,re.MULTILINE)
122 return re.compile(r'^\s*#\s+<demo>\s+%s\s*$' % mark,re.MULTILINE)
123
123
124 class Demo:
124 class Demo:
125
125
126 re_stop = re_mark('---\s?stop\s?---')
126 re_stop = re_mark('---\s?stop\s?---')
127 re_silent = re_mark('silent')
127 re_silent = re_mark('silent')
128 re_auto = re_mark('auto')
128 re_auto = re_mark('auto')
129 re_auto_all = re_mark('auto_all')
129 re_auto_all = re_mark('auto_all')
130
130
131 def __init__(self,fname,arg_str='',auto_all=None):
131 def __init__(self,fname,arg_str='',auto_all=None):
132 """Make a new demo object. To run the demo, simply call the object.
132 """Make a new demo object. To run the demo, simply call the object.
133
133
134 See the module docstring for full details and an example (you can use
134 See the module docstring for full details and an example (you can use
135 IPython.Demo? in IPython to see it).
135 IPython.Demo? in IPython to see it).
136
136
137 Inputs:
137 Inputs:
138
138
139 - fname = filename.
139 - fname = filename.
140
140
141 Optional inputs:
141 Optional inputs:
142
142
143 - arg_str(''): a string of arguments, internally converted to a list
143 - arg_str(''): a string of arguments, internally converted to a list
144 just like sys.argv, so the demo script can see a similar
144 just like sys.argv, so the demo script can see a similar
145 environment.
145 environment.
146
146
147 - auto_all(None): global flag to run all blocks automatically without
147 - auto_all(None): global flag to run all blocks automatically without
148 confirmation. This attribute overrides the block-level tags and
148 confirmation. This attribute overrides the block-level tags and
149 applies to the whole demo. It is an attribute of the object, and
149 applies to the whole demo. It is an attribute of the object, and
150 can be changed at runtime simply by reassigning it to a boolean
150 can be changed at runtime simply by reassigning it to a boolean
151 value.
151 value.
152 """
152 """
153
153
154 self.fname = fname
154 self.fname = fname
155 self.sys_argv = [fname] + shlex_split(arg_str)
155 self.sys_argv = [fname] + shlex_split(arg_str)
156 self.auto_all = auto_all
156 self.auto_all = auto_all
157
157
158 # get a few things from ipython. While it's a bit ugly design-wise,
158 # get a few things from ipython. While it's a bit ugly design-wise,
159 # it ensures that things like color scheme and the like are always in
159 # it ensures that things like color scheme and the like are always in
160 # sync with the ipython mode being used. This class is only meant to
160 # sync with the ipython mode being used. This class is only meant to
161 # be used inside ipython anyways, so it's OK.
161 # be used inside ipython anyways, so it's OK.
162 self.ip_showtb = __IPYTHON__.showtraceback
162 self.ip_showtb = __IPYTHON__.showtraceback
163 self.ip_ns = __IPYTHON__.user_ns
163 self.ip_ns = __IPYTHON__.user_ns
164 self.ip_colorize = __IPYTHON__.pycolorize
164 self.ip_colorize = __IPYTHON__.pycolorize
165
165
166 # load user data and initialize data structures
166 # load user data and initialize data structures
167 self.reload()
167 self.reload()
168
168
169 def reload(self):
169 def reload(self):
170 """Reload source from disk and initialize state."""
170 """Reload source from disk and initialize state."""
171 # read data and parse into blocks
171 # read data and parse into blocks
172 self.src = file_read(self.fname)
172 self.src = file_read(self.fname)
173 src_b = [b.strip() for b in self.re_stop.split(self.src) if b]
173 src_b = [b.strip() for b in self.re_stop.split(self.src) if b]
174 self._silent = [bool(self.re_silent.findall(b)) for b in src_b]
174 self._silent = [bool(self.re_silent.findall(b)) for b in src_b]
175 self._auto = [bool(self.re_auto.findall(b)) for b in src_b]
175 self._auto = [bool(self.re_auto.findall(b)) for b in src_b]
176
176
177 # if auto_all is not given (def. None), we read it from the file
177 # if auto_all is not given (def. None), we read it from the file
178 if self.auto_all is None:
178 if self.auto_all is None:
179 self.auto_all = bool(self.re_auto_all.findall(src_b[0]))
179 self.auto_all = bool(self.re_auto_all.findall(src_b[0]))
180 else:
180 else:
181 self.auto_all = bool(self.auto_all)
181 self.auto_all = bool(self.auto_all)
182
182
183 # Clean the sources from all markup so it doesn't get displayed when
183 # Clean the sources from all markup so it doesn't get displayed when
184 # running the demo
184 # running the demo
185 src_blocks = []
185 src_blocks = []
186 auto_strip = lambda s: self.re_auto.sub('',s)
186 auto_strip = lambda s: self.re_auto.sub('',s)
187 for i,b in enumerate(src_b):
187 for i,b in enumerate(src_b):
188 if self._auto[i]:
188 if self._auto[i]:
189 src_blocks.append(auto_strip(b))
189 src_blocks.append(auto_strip(b))
190 else:
190 else:
191 src_blocks.append(b)
191 src_blocks.append(b)
192 # remove the auto_all marker
192 # remove the auto_all marker
193 src_blocks[0] = self.re_auto_all.sub('',src_blocks[0])
193 src_blocks[0] = self.re_auto_all.sub('',src_blocks[0])
194
194
195 self.nblocks = len(src_blocks)
195 self.nblocks = len(src_blocks)
196 self.src_blocks = src_blocks
196 self.src_blocks = src_blocks
197
197
198 # also build syntax-highlighted source
198 # also build syntax-highlighted source
199 self.src_blocks_colored = map(self.ip_colorize,self.src_blocks)
199 self.src_blocks_colored = map(self.ip_colorize,self.src_blocks)
200
200
201 # ensure clean namespace and seek offset
201 # ensure clean namespace and seek offset
202 self.reset()
202 self.reset()
203
203
204 def reset(self):
204 def reset(self):
205 """Reset the namespace and seek pointer to restart the demo"""
205 """Reset the namespace and seek pointer to restart the demo"""
206 self.user_ns = {}
206 self.user_ns = {}
207 self.finished = False
207 self.finished = False
208 self.block_index = 0
208 self.block_index = 0
209
209
210 def _validate_index(self,index):
210 def _validate_index(self,index):
211 if index<0 or index>=self.nblocks:
211 if index<0 or index>=self.nblocks:
212 raise ValueError('invalid block index %s' % index)
212 raise ValueError('invalid block index %s' % index)
213
213
214 def seek(self,index):
214 def seek(self,index):
215 """Move the current seek pointer to the given block"""
215 """Move the current seek pointer to the given block"""
216 self._validate_index(index)
216 self._validate_index(index)
217 self.block_index = index
217 self.block_index = index
218 self.finished = False
218 self.finished = False
219
219
220 def back(self,num=1):
220 def back(self,num=1):
221 """Move the seek pointer back num blocks (default is 1)."""
221 """Move the seek pointer back num blocks (default is 1)."""
222 self.seek(self.block_index-num)
222 self.seek(self.block_index-num)
223
223
224 def jump(self,num):
224 def jump(self,num):
225 """Jump a given number of blocks relative to the current one."""
225 """Jump a given number of blocks relative to the current one."""
226 self.seek(self.block_index+num)
226 self.seek(self.block_index+num)
227
227
228 def again(self):
228 def again(self):
229 """Move the seek pointer back one block and re-execute."""
229 """Move the seek pointer back one block and re-execute."""
230 self.back(1)
230 self.back(1)
231 self()
231 self()
232
232
233 def show(self,index=None):
233 def show(self,index=None):
234 """Show a single block on screen"""
234 """Show a single block on screen"""
235 if index is None:
235 if index is None:
236 if self.finished:
236 if self.finished:
237 print 'Demo finished. Use reset() if you want to rerun it.'
237 print 'Demo finished. Use reset() if you want to rerun it.'
238 return
238 return
239 index = self.block_index
239 index = self.block_index
240 else:
240 else:
241 self._validate_index(index)
241 self._validate_index(index)
242 print marquee('<%s> block # %s (%s remaining)' %
242 print marquee('<%s> block # %s (%s remaining)' %
243 (self.fname,index,self.nblocks-index-1))
243 (self.fname,index,self.nblocks-index-1))
244 print self.src_blocks_colored[index],
244 print self.src_blocks_colored[index],
245
245
246 def show_all(self):
246 def show_all(self):
247 """Show entire demo on screen, block by block"""
247 """Show entire demo on screen, block by block"""
248
248
249 fname = self.fname
249 fname = self.fname
250 nblocks = self.nblocks
250 nblocks = self.nblocks
251 silent = self._silent
251 silent = self._silent
252 for index,block in enumerate(self.src_blocks_colored):
252 for index,block in enumerate(self.src_blocks_colored):
253 if silent[index]:
253 if silent[index]:
254 print marquee('<%s> SILENT block # %s (%s remaining)' %
254 print marquee('<%s> SILENT block # %s (%s remaining)' %
255 (fname,index,nblocks-index-1))
255 (fname,index,nblocks-index-1))
256 else:
256 else:
257 print marquee('<%s> block # %s (%s remaining)' %
257 print marquee('<%s> block # %s (%s remaining)' %
258 (fname,index,nblocks-index-1))
258 (fname,index,nblocks-index-1))
259 print block,
259 print block,
260
260
261 def __call__(self,index=None):
261 def __call__(self,index=None):
262 """run a block of the demo.
262 """run a block of the demo.
263
263
264 If index is given, it should be an integer >=1 and <= nblocks. This
264 If index is given, it should be an integer >=1 and <= nblocks. This
265 means that the calling convention is one off from typical Python
265 means that the calling convention is one off from typical Python
266 lists. The reason for the inconsistency is that the demo always
266 lists. The reason for the inconsistency is that the demo always
267 prints 'Block n/N, and N is the total, so it would be very odd to use
267 prints 'Block n/N, and N is the total, so it would be very odd to use
268 zero-indexing here."""
268 zero-indexing here."""
269
269
270 if index is None and self.finished:
270 if index is None and self.finished:
271 print 'Demo finished. Use reset() if you want to rerun it.'
271 print 'Demo finished. Use reset() if you want to rerun it.'
272 return
272 return
273 if index is None:
273 if index is None:
274 index = self.block_index
274 index = self.block_index
275 self._validate_index(index)
275 self._validate_index(index)
276 try:
276 try:
277 next_block = self.src_blocks[index]
277 next_block = self.src_blocks[index]
278 self.block_index += 1
278 self.block_index += 1
279 if self._silent[index]:
279 if self._silent[index]:
280 print marquee('Executing silent block # %s (%s remaining)' %
280 print marquee('Executing silent block # %s (%s remaining)' %
281 (index,self.nblocks-index-1))
281 (index,self.nblocks-index-1))
282 else:
282 else:
283 self.show(index)
283 self.show(index)
284 if self.auto_all or self._auto[index]:
284 if self.auto_all or self._auto[index]:
285 print marquee('output')
285 print marquee('output')
286 else:
286 else:
287 print marquee('Press <q> to quit, <Enter> to execute...'),
287 print marquee('Press <q> to quit, <Enter> to execute...'),
288 ans = raw_input().strip()
288 ans = raw_input().strip()
289 if ans:
289 if ans:
290 print marquee('Block NOT executed')
290 print marquee('Block NOT executed')
291 return
291 return
292 try:
292 try:
293 save_argv = sys.argv
293 save_argv = sys.argv
294 sys.argv = self.sys_argv
294 sys.argv = self.sys_argv
295 exec next_block in self.user_ns
295 exec next_block in self.user_ns
296 finally:
296 finally:
297 sys.argv = save_argv
297 sys.argv = save_argv
298
298
299 except:
299 except:
300 self.ip_showtb(filename=self.fname)
300 self.ip_showtb(filename=self.fname)
301 else:
301 else:
302 self.ip_ns.update(self.user_ns)
302 self.ip_ns.update(self.user_ns)
303
303
304 if self.block_index == self.nblocks:
304 if self.block_index == self.nblocks:
305 print
305 print
306 print marquee(' END OF DEMO ')
306 print marquee(' END OF DEMO ')
307 print marquee('Use reset() if you want to rerun it.')
307 print marquee('Use reset() if you want to rerun it.')
308 self.finished = True
308 self.finished = True
309
309
@@ -1,1601 +1,1609 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 General purpose utilities.
3 General purpose utilities.
4
4
5 This is a grab-bag of stuff I find useful in most programs I write. Some of
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.
6 these things are also convenient when working at the command line.
7
7
8 $Id: genutils.py 908 2005-09-26 16:05:48Z fperez $"""
8 $Id: genutils.py 958 2005-12-27 23:17:51Z fperez $"""
9
9
10 #*****************************************************************************
10 #*****************************************************************************
11 # Copyright (C) 2001-2004 Fernando Perez. <fperez@colorado.edu>
11 # Copyright (C) 2001-2004 Fernando Perez. <fperez@colorado.edu>
12 #
12 #
13 # Distributed under the terms of the BSD License. The full license is in
13 # Distributed under the terms of the BSD License. The full license is in
14 # the file COPYING, distributed as part of this software.
14 # the file COPYING, distributed as part of this software.
15 #*****************************************************************************
15 #*****************************************************************************
16
16
17 from __future__ import generators # 2.2 compatibility
17 from __future__ import generators # 2.2 compatibility
18
18
19 from IPython import Release
19 from IPython import Release
20 __author__ = '%s <%s>' % Release.authors['Fernando']
20 __author__ = '%s <%s>' % Release.authors['Fernando']
21 __license__ = Release.license
21 __license__ = Release.license
22
22
23 #****************************************************************************
23 #****************************************************************************
24 # required modules
24 # required modules from the Python standard library
25 import __main__
25 import __main__
26 import types,commands,time,sys,os,re,shutil
26 import commands
27 import os
28 import re
27 import shlex
29 import shlex
30 import shutil
31 import sys
28 import tempfile
32 import tempfile
33 import time
34 import types
35
36 # Other IPython utilities
29 from IPython.Itpl import Itpl,itpl,printpl
37 from IPython.Itpl import Itpl,itpl,printpl
30 from IPython import DPyGetOpt
38 from IPython import DPyGetOpt
31
39
32 # Build objects which appeared in Python 2.3 for 2.2, to make ipython
40 # Build objects which appeared in Python 2.3 for 2.2, to make ipython
33 # 2.2-friendly
41 # 2.2-friendly
34 try:
42 try:
35 basestring
43 basestring
36 except NameError:
44 except NameError:
37 import types
45 import types
38 basestring = (types.StringType, types.UnicodeType)
46 basestring = (types.StringType, types.UnicodeType)
39 True = 1==1
47 True = 1==1
40 False = 1==0
48 False = 1==0
41
49
42 def enumerate(obj):
50 def enumerate(obj):
43 i = -1
51 i = -1
44 for item in obj:
52 for item in obj:
45 i += 1
53 i += 1
46 yield i, item
54 yield i, item
47
55
48 # add these to the builtin namespace, so that all modules find them
56 # add these to the builtin namespace, so that all modules find them
49 import __builtin__
57 import __builtin__
50 __builtin__.basestring = basestring
58 __builtin__.basestring = basestring
51 __builtin__.True = True
59 __builtin__.True = True
52 __builtin__.False = False
60 __builtin__.False = False
53 __builtin__.enumerate = enumerate
61 __builtin__.enumerate = enumerate
54
62
55 # Try to use shlex.split for converting an input string into a sys.argv-type
63 # Try to use shlex.split for converting an input string into a sys.argv-type
56 # list. This appeared in Python 2.3, so here's a quick backport for 2.2.
64 # list. This appeared in Python 2.3, so here's a quick backport for 2.2.
57 try:
65 try:
58 shlex_split = shlex.split
66 shlex_split = shlex.split
59 except AttributeError:
67 except AttributeError:
60 _quotesre = re.compile(r'[\'"](.*)[\'"]')
68 _quotesre = re.compile(r'[\'"](.*)[\'"]')
61 _wordchars = ('abcdfeghijklmnopqrstuvwxyz'
69 _wordchars = ('abcdfeghijklmnopqrstuvwxyz'
62 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-.~*?'
70 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-.~*?'
63 'ßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ'
71 'ßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ'
64 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ%s'
72 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ%s'
65 % os.sep)
73 % os.sep)
66
74
67 def shlex_split(s):
75 def shlex_split(s):
68 """Simplified backport to Python 2.2 of shlex.split().
76 """Simplified backport to Python 2.2 of shlex.split().
69
77
70 This is a quick and dirty hack, since the shlex module under 2.2 lacks
78 This is a quick and dirty hack, since the shlex module under 2.2 lacks
71 several of the features needed to really match the functionality of
79 several of the features needed to really match the functionality of
72 shlex.split() in 2.3."""
80 shlex.split() in 2.3."""
73
81
74 lex = shlex.shlex(StringIO(s))
82 lex = shlex.shlex(StringIO(s))
75 # Try to get options, extensions and path separators as characters
83 # Try to get options, extensions and path separators as characters
76 lex.wordchars = _wordchars
84 lex.wordchars = _wordchars
77 lex.commenters = ''
85 lex.commenters = ''
78 # Make a list out of the lexer by hand, since in 2.2 it's not an
86 # Make a list out of the lexer by hand, since in 2.2 it's not an
79 # iterator.
87 # iterator.
80 lout = []
88 lout = []
81 while 1:
89 while 1:
82 token = lex.get_token()
90 token = lex.get_token()
83 if token == '':
91 if token == '':
84 break
92 break
85 # Try to handle quoted tokens correctly
93 # Try to handle quoted tokens correctly
86 quotes = _quotesre.match(token)
94 quotes = _quotesre.match(token)
87 if quotes:
95 if quotes:
88 token = quotes.group(1)
96 token = quotes.group(1)
89 lout.append(token)
97 lout.append(token)
90 return lout
98 return lout
91
99
92 #****************************************************************************
100 #****************************************************************************
93 # Exceptions
101 # Exceptions
94 class Error(Exception):
102 class Error(Exception):
95 """Base class for exceptions in this module."""
103 """Base class for exceptions in this module."""
96 pass
104 pass
97
105
98 #----------------------------------------------------------------------------
106 #----------------------------------------------------------------------------
99 class IOStream:
107 class IOStream:
100 def __init__(self,stream,fallback):
108 def __init__(self,stream,fallback):
101 if not hasattr(stream,'write') or not hasattr(stream,'flush'):
109 if not hasattr(stream,'write') or not hasattr(stream,'flush'):
102 stream = fallback
110 stream = fallback
103 self.stream = stream
111 self.stream = stream
104 self._swrite = stream.write
112 self._swrite = stream.write
105 self.flush = stream.flush
113 self.flush = stream.flush
106
114
107 def write(self,data):
115 def write(self,data):
108 try:
116 try:
109 self._swrite(data)
117 self._swrite(data)
110 except:
118 except:
111 try:
119 try:
112 # print handles some unicode issues which may trip a plain
120 # print handles some unicode issues which may trip a plain
113 # write() call. Attempt to emulate write() by using a
121 # write() call. Attempt to emulate write() by using a
114 # trailing comma
122 # trailing comma
115 print >> self.stream, data,
123 print >> self.stream, data,
116 except:
124 except:
117 # if we get here, something is seriously broken.
125 # if we get here, something is seriously broken.
118 print >> sys.stderr, \
126 print >> sys.stderr, \
119 'ERROR - failed to write data to stream:', stream
127 'ERROR - failed to write data to stream:', stream
120
128
121 class IOTerm:
129 class IOTerm:
122 """ Term holds the file or file-like objects for handling I/O operations.
130 """ Term holds the file or file-like objects for handling I/O operations.
123
131
124 These are normally just sys.stdin, sys.stdout and sys.stderr but for
132 These are normally just sys.stdin, sys.stdout and sys.stderr but for
125 Windows they can can replaced to allow editing the strings before they are
133 Windows they can can replaced to allow editing the strings before they are
126 displayed."""
134 displayed."""
127
135
128 # In the future, having IPython channel all its I/O operations through
136 # In the future, having IPython channel all its I/O operations through
129 # this class will make it easier to embed it into other environments which
137 # this class will make it easier to embed it into other environments which
130 # are not a normal terminal (such as a GUI-based shell)
138 # are not a normal terminal (such as a GUI-based shell)
131 def __init__(self,cin=None,cout=None,cerr=None):
139 def __init__(self,cin=None,cout=None,cerr=None):
132 self.cin = IOStream(cin,sys.stdin)
140 self.cin = IOStream(cin,sys.stdin)
133 self.cout = IOStream(cout,sys.stdout)
141 self.cout = IOStream(cout,sys.stdout)
134 self.cerr = IOStream(cerr,sys.stderr)
142 self.cerr = IOStream(cerr,sys.stderr)
135
143
136 # Global variable to be used for all I/O
144 # Global variable to be used for all I/O
137 Term = IOTerm()
145 Term = IOTerm()
138
146
139 # Windows-specific code to load Gary Bishop's readline and configure it
147 # Windows-specific code to load Gary Bishop's readline and configure it
140 # automatically for the users
148 # automatically for the users
141 # Note: os.name on cygwin returns posix, so this should only pick up 'native'
149 # Note: os.name on cygwin returns posix, so this should only pick up 'native'
142 # windows. Cygwin returns 'cygwin' for sys.platform.
150 # windows. Cygwin returns 'cygwin' for sys.platform.
143 if os.name == 'nt':
151 if os.name == 'nt':
144 try:
152 try:
145 import readline
153 import readline
146 except ImportError:
154 except ImportError:
147 pass
155 pass
148 else:
156 else:
149 try:
157 try:
150 _out = readline.GetOutputFile()
158 _out = readline.GetOutputFile()
151 except AttributeError:
159 except AttributeError:
152 pass
160 pass
153 else:
161 else:
154 # Remake Term to use the readline i/o facilities
162 # Remake Term to use the readline i/o facilities
155 Term = IOTerm(cout=_out,cerr=_out)
163 Term = IOTerm(cout=_out,cerr=_out)
156 del _out
164 del _out
157
165
158 #****************************************************************************
166 #****************************************************************************
159 # Generic warning/error printer, used by everything else
167 # Generic warning/error printer, used by everything else
160 def warn(msg,level=2,exit_val=1):
168 def warn(msg,level=2,exit_val=1):
161 """Standard warning printer. Gives formatting consistency.
169 """Standard warning printer. Gives formatting consistency.
162
170
163 Output is sent to Term.cerr (sys.stderr by default).
171 Output is sent to Term.cerr (sys.stderr by default).
164
172
165 Options:
173 Options:
166
174
167 -level(2): allows finer control:
175 -level(2): allows finer control:
168 0 -> Do nothing, dummy function.
176 0 -> Do nothing, dummy function.
169 1 -> Print message.
177 1 -> Print message.
170 2 -> Print 'WARNING:' + message. (Default level).
178 2 -> Print 'WARNING:' + message. (Default level).
171 3 -> Print 'ERROR:' + message.
179 3 -> Print 'ERROR:' + message.
172 4 -> Print 'FATAL ERROR:' + message and trigger a sys.exit(exit_val).
180 4 -> Print 'FATAL ERROR:' + message and trigger a sys.exit(exit_val).
173
181
174 -exit_val (1): exit value returned by sys.exit() for a level 4
182 -exit_val (1): exit value returned by sys.exit() for a level 4
175 warning. Ignored for all other levels."""
183 warning. Ignored for all other levels."""
176
184
177 if level>0:
185 if level>0:
178 header = ['','','WARNING: ','ERROR: ','FATAL ERROR: ']
186 header = ['','','WARNING: ','ERROR: ','FATAL ERROR: ']
179 print >> Term.cerr, '%s%s' % (header[level],msg)
187 print >> Term.cerr, '%s%s' % (header[level],msg)
180 if level == 4:
188 if level == 4:
181 print >> Term.cerr,'Exiting.\n'
189 print >> Term.cerr,'Exiting.\n'
182 sys.exit(exit_val)
190 sys.exit(exit_val)
183
191
184 def info(msg):
192 def info(msg):
185 """Equivalent to warn(msg,level=1)."""
193 """Equivalent to warn(msg,level=1)."""
186
194
187 warn(msg,level=1)
195 warn(msg,level=1)
188
196
189 def error(msg):
197 def error(msg):
190 """Equivalent to warn(msg,level=3)."""
198 """Equivalent to warn(msg,level=3)."""
191
199
192 warn(msg,level=3)
200 warn(msg,level=3)
193
201
194 def fatal(msg,exit_val=1):
202 def fatal(msg,exit_val=1):
195 """Equivalent to warn(msg,exit_val=exit_val,level=4)."""
203 """Equivalent to warn(msg,exit_val=exit_val,level=4)."""
196
204
197 warn(msg,exit_val=exit_val,level=4)
205 warn(msg,exit_val=exit_val,level=4)
198
206
199 #----------------------------------------------------------------------------
207 #----------------------------------------------------------------------------
200 StringTypes = types.StringTypes
208 StringTypes = types.StringTypes
201
209
202 # Basic timing functionality
210 # Basic timing functionality
203
211
204 # If possible (Unix), use the resource module instead of time.clock()
212 # If possible (Unix), use the resource module instead of time.clock()
205 try:
213 try:
206 import resource
214 import resource
207 def clock():
215 def clock():
208 """clock() -> floating point number
216 """clock() -> floating point number
209
217
210 Return the CPU time in seconds (user time only, system time is
218 Return the CPU time in seconds (user time only, system time is
211 ignored) since the start of the process. This is done via a call to
219 ignored) since the start of the process. This is done via a call to
212 resource.getrusage, so it avoids the wraparound problems in
220 resource.getrusage, so it avoids the wraparound problems in
213 time.clock()."""
221 time.clock()."""
214
222
215 return resource.getrusage(resource.RUSAGE_SELF)[0]
223 return resource.getrusage(resource.RUSAGE_SELF)[0]
216
224
217 def clock2():
225 def clock2():
218 """clock2() -> (t_user,t_system)
226 """clock2() -> (t_user,t_system)
219
227
220 Similar to clock(), but return a tuple of user/system times."""
228 Similar to clock(), but return a tuple of user/system times."""
221 return resource.getrusage(resource.RUSAGE_SELF)[:2]
229 return resource.getrusage(resource.RUSAGE_SELF)[:2]
222
230
223 except ImportError:
231 except ImportError:
224 clock = time.clock
232 clock = time.clock
225 def clock2():
233 def clock2():
226 """Under windows, system CPU time can't be measured.
234 """Under windows, system CPU time can't be measured.
227
235
228 This just returns clock() and zero."""
236 This just returns clock() and zero."""
229 return time.clock(),0.0
237 return time.clock(),0.0
230
238
231 def timings_out(reps,func,*args,**kw):
239 def timings_out(reps,func,*args,**kw):
232 """timings_out(reps,func,*args,**kw) -> (t_total,t_per_call,output)
240 """timings_out(reps,func,*args,**kw) -> (t_total,t_per_call,output)
233
241
234 Execute a function reps times, return a tuple with the elapsed total
242 Execute a function reps times, return a tuple with the elapsed total
235 CPU time in seconds, the time per call and the function's output.
243 CPU time in seconds, the time per call and the function's output.
236
244
237 Under Unix, the return value is the sum of user+system time consumed by
245 Under Unix, the return value is the sum of user+system time consumed by
238 the process, computed via the resource module. This prevents problems
246 the process, computed via the resource module. This prevents problems
239 related to the wraparound effect which the time.clock() function has.
247 related to the wraparound effect which the time.clock() function has.
240
248
241 Under Windows the return value is in wall clock seconds. See the
249 Under Windows the return value is in wall clock seconds. See the
242 documentation for the time module for more details."""
250 documentation for the time module for more details."""
243
251
244 reps = int(reps)
252 reps = int(reps)
245 assert reps >=1, 'reps must be >= 1'
253 assert reps >=1, 'reps must be >= 1'
246 if reps==1:
254 if reps==1:
247 start = clock()
255 start = clock()
248 out = func(*args,**kw)
256 out = func(*args,**kw)
249 tot_time = clock()-start
257 tot_time = clock()-start
250 else:
258 else:
251 rng = xrange(reps-1) # the last time is executed separately to store output
259 rng = xrange(reps-1) # the last time is executed separately to store output
252 start = clock()
260 start = clock()
253 for dummy in rng: func(*args,**kw)
261 for dummy in rng: func(*args,**kw)
254 out = func(*args,**kw) # one last time
262 out = func(*args,**kw) # one last time
255 tot_time = clock()-start
263 tot_time = clock()-start
256 av_time = tot_time / reps
264 av_time = tot_time / reps
257 return tot_time,av_time,out
265 return tot_time,av_time,out
258
266
259 def timings(reps,func,*args,**kw):
267 def timings(reps,func,*args,**kw):
260 """timings(reps,func,*args,**kw) -> (t_total,t_per_call)
268 """timings(reps,func,*args,**kw) -> (t_total,t_per_call)
261
269
262 Execute a function reps times, return a tuple with the elapsed total CPU
270 Execute a function reps times, return a tuple with the elapsed total CPU
263 time in seconds and the time per call. These are just the first two values
271 time in seconds and the time per call. These are just the first two values
264 in timings_out()."""
272 in timings_out()."""
265
273
266 return timings_out(reps,func,*args,**kw)[0:2]
274 return timings_out(reps,func,*args,**kw)[0:2]
267
275
268 def timing(func,*args,**kw):
276 def timing(func,*args,**kw):
269 """timing(func,*args,**kw) -> t_total
277 """timing(func,*args,**kw) -> t_total
270
278
271 Execute a function once, return the elapsed total CPU time in
279 Execute a function once, return the elapsed total CPU time in
272 seconds. This is just the first value in timings_out()."""
280 seconds. This is just the first value in timings_out()."""
273
281
274 return timings_out(1,func,*args,**kw)[0]
282 return timings_out(1,func,*args,**kw)[0]
275
283
276 #****************************************************************************
284 #****************************************************************************
277 # file and system
285 # file and system
278
286
279 def system(cmd,verbose=0,debug=0,header=''):
287 def system(cmd,verbose=0,debug=0,header=''):
280 """Execute a system command, return its exit status.
288 """Execute a system command, return its exit status.
281
289
282 Options:
290 Options:
283
291
284 - verbose (0): print the command to be executed.
292 - verbose (0): print the command to be executed.
285
293
286 - debug (0): only print, do not actually execute.
294 - debug (0): only print, do not actually execute.
287
295
288 - header (''): Header to print on screen prior to the executed command (it
296 - header (''): Header to print on screen prior to the executed command (it
289 is only prepended to the command, no newlines are added).
297 is only prepended to the command, no newlines are added).
290
298
291 Note: a stateful version of this function is available through the
299 Note: a stateful version of this function is available through the
292 SystemExec class."""
300 SystemExec class."""
293
301
294 stat = 0
302 stat = 0
295 if verbose or debug: print header+cmd
303 if verbose or debug: print header+cmd
296 sys.stdout.flush()
304 sys.stdout.flush()
297 if not debug: stat = os.system(cmd)
305 if not debug: stat = os.system(cmd)
298 return stat
306 return stat
299
307
300 def shell(cmd,verbose=0,debug=0,header=''):
308 def shell(cmd,verbose=0,debug=0,header=''):
301 """Execute a command in the system shell, always return None.
309 """Execute a command in the system shell, always return None.
302
310
303 Options:
311 Options:
304
312
305 - verbose (0): print the command to be executed.
313 - verbose (0): print the command to be executed.
306
314
307 - debug (0): only print, do not actually execute.
315 - debug (0): only print, do not actually execute.
308
316
309 - header (''): Header to print on screen prior to the executed command (it
317 - header (''): Header to print on screen prior to the executed command (it
310 is only prepended to the command, no newlines are added).
318 is only prepended to the command, no newlines are added).
311
319
312 Note: this is similar to genutils.system(), but it returns None so it can
320 Note: this is similar to genutils.system(), but it returns None so it can
313 be conveniently used in interactive loops without getting the return value
321 be conveniently used in interactive loops without getting the return value
314 (typically 0) printed many times."""
322 (typically 0) printed many times."""
315
323
316 stat = 0
324 stat = 0
317 if verbose or debug: print header+cmd
325 if verbose or debug: print header+cmd
318 # flush stdout so we don't mangle python's buffering
326 # flush stdout so we don't mangle python's buffering
319 sys.stdout.flush()
327 sys.stdout.flush()
320 if not debug:
328 if not debug:
321 os.system(cmd)
329 os.system(cmd)
322
330
323 def getoutput(cmd,verbose=0,debug=0,header='',split=0):
331 def getoutput(cmd,verbose=0,debug=0,header='',split=0):
324 """Dummy substitute for perl's backquotes.
332 """Dummy substitute for perl's backquotes.
325
333
326 Executes a command and returns the output.
334 Executes a command and returns the output.
327
335
328 Accepts the same arguments as system(), plus:
336 Accepts the same arguments as system(), plus:
329
337
330 - split(0): if true, the output is returned as a list split on newlines.
338 - split(0): if true, the output is returned as a list split on newlines.
331
339
332 Note: a stateful version of this function is available through the
340 Note: a stateful version of this function is available through the
333 SystemExec class."""
341 SystemExec class."""
334
342
335 if verbose or debug: print header+cmd
343 if verbose or debug: print header+cmd
336 if not debug:
344 if not debug:
337 output = commands.getoutput(cmd)
345 output = commands.getoutput(cmd)
338 if split:
346 if split:
339 return output.split('\n')
347 return output.split('\n')
340 else:
348 else:
341 return output
349 return output
342
350
343 def getoutputerror(cmd,verbose=0,debug=0,header='',split=0):
351 def getoutputerror(cmd,verbose=0,debug=0,header='',split=0):
344 """Return (standard output,standard error) of executing cmd in a shell.
352 """Return (standard output,standard error) of executing cmd in a shell.
345
353
346 Accepts the same arguments as system(), plus:
354 Accepts the same arguments as system(), plus:
347
355
348 - split(0): if true, each of stdout/err is returned as a list split on
356 - split(0): if true, each of stdout/err is returned as a list split on
349 newlines.
357 newlines.
350
358
351 Note: a stateful version of this function is available through the
359 Note: a stateful version of this function is available through the
352 SystemExec class."""
360 SystemExec class."""
353
361
354 if verbose or debug: print header+cmd
362 if verbose or debug: print header+cmd
355 if not cmd:
363 if not cmd:
356 if split:
364 if split:
357 return [],[]
365 return [],[]
358 else:
366 else:
359 return '',''
367 return '',''
360 if not debug:
368 if not debug:
361 pin,pout,perr = os.popen3(cmd)
369 pin,pout,perr = os.popen3(cmd)
362 tout = pout.read().rstrip()
370 tout = pout.read().rstrip()
363 terr = perr.read().rstrip()
371 terr = perr.read().rstrip()
364 pin.close()
372 pin.close()
365 pout.close()
373 pout.close()
366 perr.close()
374 perr.close()
367 if split:
375 if split:
368 return tout.split('\n'),terr.split('\n')
376 return tout.split('\n'),terr.split('\n')
369 else:
377 else:
370 return tout,terr
378 return tout,terr
371
379
372 # for compatibility with older naming conventions
380 # for compatibility with older naming conventions
373 xsys = system
381 xsys = system
374 bq = getoutput
382 bq = getoutput
375
383
376 class SystemExec:
384 class SystemExec:
377 """Access the system and getoutput functions through a stateful interface.
385 """Access the system and getoutput functions through a stateful interface.
378
386
379 Note: here we refer to the system and getoutput functions from this
387 Note: here we refer to the system and getoutput functions from this
380 library, not the ones from the standard python library.
388 library, not the ones from the standard python library.
381
389
382 This class offers the system and getoutput functions as methods, but the
390 This class offers the system and getoutput functions as methods, but the
383 verbose, debug and header parameters can be set for the instance (at
391 verbose, debug and header parameters can be set for the instance (at
384 creation time or later) so that they don't need to be specified on each
392 creation time or later) so that they don't need to be specified on each
385 call.
393 call.
386
394
387 For efficiency reasons, there's no way to override the parameters on a
395 For efficiency reasons, there's no way to override the parameters on a
388 per-call basis other than by setting instance attributes. If you need
396 per-call basis other than by setting instance attributes. If you need
389 local overrides, it's best to directly call system() or getoutput().
397 local overrides, it's best to directly call system() or getoutput().
390
398
391 The following names are provided as alternate options:
399 The following names are provided as alternate options:
392 - xsys: alias to system
400 - xsys: alias to system
393 - bq: alias to getoutput
401 - bq: alias to getoutput
394
402
395 An instance can then be created as:
403 An instance can then be created as:
396 >>> sysexec = SystemExec(verbose=1,debug=0,header='Calling: ')
404 >>> sysexec = SystemExec(verbose=1,debug=0,header='Calling: ')
397
405
398 And used as:
406 And used as:
399 >>> sysexec.xsys('pwd')
407 >>> sysexec.xsys('pwd')
400 >>> dirlist = sysexec.bq('ls -l')
408 >>> dirlist = sysexec.bq('ls -l')
401 """
409 """
402
410
403 def __init__(self,verbose=0,debug=0,header='',split=0):
411 def __init__(self,verbose=0,debug=0,header='',split=0):
404 """Specify the instance's values for verbose, debug and header."""
412 """Specify the instance's values for verbose, debug and header."""
405 setattr_list(self,'verbose debug header split')
413 setattr_list(self,'verbose debug header split')
406
414
407 def system(self,cmd):
415 def system(self,cmd):
408 """Stateful interface to system(), with the same keyword parameters."""
416 """Stateful interface to system(), with the same keyword parameters."""
409
417
410 system(cmd,self.verbose,self.debug,self.header)
418 system(cmd,self.verbose,self.debug,self.header)
411
419
412 def shell(self,cmd):
420 def shell(self,cmd):
413 """Stateful interface to shell(), with the same keyword parameters."""
421 """Stateful interface to shell(), with the same keyword parameters."""
414
422
415 shell(cmd,self.verbose,self.debug,self.header)
423 shell(cmd,self.verbose,self.debug,self.header)
416
424
417 xsys = system # alias
425 xsys = system # alias
418
426
419 def getoutput(self,cmd):
427 def getoutput(self,cmd):
420 """Stateful interface to getoutput()."""
428 """Stateful interface to getoutput()."""
421
429
422 return getoutput(cmd,self.verbose,self.debug,self.header,self.split)
430 return getoutput(cmd,self.verbose,self.debug,self.header,self.split)
423
431
424 def getoutputerror(self,cmd):
432 def getoutputerror(self,cmd):
425 """Stateful interface to getoutputerror()."""
433 """Stateful interface to getoutputerror()."""
426
434
427 return getoutputerror(cmd,self.verbose,self.debug,self.header,self.split)
435 return getoutputerror(cmd,self.verbose,self.debug,self.header,self.split)
428
436
429 bq = getoutput # alias
437 bq = getoutput # alias
430
438
431 #-----------------------------------------------------------------------------
439 #-----------------------------------------------------------------------------
432 def mutex_opts(dict,ex_op):
440 def mutex_opts(dict,ex_op):
433 """Check for presence of mutually exclusive keys in a dict.
441 """Check for presence of mutually exclusive keys in a dict.
434
442
435 Call: mutex_opts(dict,[[op1a,op1b],[op2a,op2b]...]"""
443 Call: mutex_opts(dict,[[op1a,op1b],[op2a,op2b]...]"""
436 for op1,op2 in ex_op:
444 for op1,op2 in ex_op:
437 if op1 in dict and op2 in dict:
445 if op1 in dict and op2 in dict:
438 raise ValueError,'\n*** ERROR in Arguments *** '\
446 raise ValueError,'\n*** ERROR in Arguments *** '\
439 'Options '+op1+' and '+op2+' are mutually exclusive.'
447 'Options '+op1+' and '+op2+' are mutually exclusive.'
440
448
441 #-----------------------------------------------------------------------------
449 #-----------------------------------------------------------------------------
442 def get_py_filename(name):
450 def get_py_filename(name):
443 """Return a valid python filename in the current directory.
451 """Return a valid python filename in the current directory.
444
452
445 If the given name is not a file, it adds '.py' and searches again.
453 If the given name is not a file, it adds '.py' and searches again.
446 Raises IOError with an informative message if the file isn't found."""
454 Raises IOError with an informative message if the file isn't found."""
447
455
448 name = os.path.expanduser(name)
456 name = os.path.expanduser(name)
449 if not os.path.isfile(name) and not name.endswith('.py'):
457 if not os.path.isfile(name) and not name.endswith('.py'):
450 name += '.py'
458 name += '.py'
451 if os.path.isfile(name):
459 if os.path.isfile(name):
452 return name
460 return name
453 else:
461 else:
454 raise IOError,'File `%s` not found.' % name
462 raise IOError,'File `%s` not found.' % name
455
463
456 #-----------------------------------------------------------------------------
464 #-----------------------------------------------------------------------------
457 def filefind(fname,alt_dirs = None):
465 def filefind(fname,alt_dirs = None):
458 """Return the given filename either in the current directory, if it
466 """Return the given filename either in the current directory, if it
459 exists, or in a specified list of directories.
467 exists, or in a specified list of directories.
460
468
461 ~ expansion is done on all file and directory names.
469 ~ expansion is done on all file and directory names.
462
470
463 Upon an unsuccessful search, raise an IOError exception."""
471 Upon an unsuccessful search, raise an IOError exception."""
464
472
465 if alt_dirs is None:
473 if alt_dirs is None:
466 try:
474 try:
467 alt_dirs = get_home_dir()
475 alt_dirs = get_home_dir()
468 except HomeDirError:
476 except HomeDirError:
469 alt_dirs = os.getcwd()
477 alt_dirs = os.getcwd()
470 search = [fname] + list_strings(alt_dirs)
478 search = [fname] + list_strings(alt_dirs)
471 search = map(os.path.expanduser,search)
479 search = map(os.path.expanduser,search)
472 #print 'search list for',fname,'list:',search # dbg
480 #print 'search list for',fname,'list:',search # dbg
473 fname = search[0]
481 fname = search[0]
474 if os.path.isfile(fname):
482 if os.path.isfile(fname):
475 return fname
483 return fname
476 for direc in search[1:]:
484 for direc in search[1:]:
477 testname = os.path.join(direc,fname)
485 testname = os.path.join(direc,fname)
478 #print 'testname',testname # dbg
486 #print 'testname',testname # dbg
479 if os.path.isfile(testname):
487 if os.path.isfile(testname):
480 return testname
488 return testname
481 raise IOError,'File' + `fname` + \
489 raise IOError,'File' + `fname` + \
482 ' not found in current or supplied directories:' + `alt_dirs`
490 ' not found in current or supplied directories:' + `alt_dirs`
483
491
484 #----------------------------------------------------------------------------
492 #----------------------------------------------------------------------------
485 def file_read(filename):
493 def file_read(filename):
486 """Read a file and close it. Returns the file source."""
494 """Read a file and close it. Returns the file source."""
487 fobj=open(filename,'r');
495 fobj=open(filename,'r');
488 source = fobj.read();
496 source = fobj.read();
489 fobj.close()
497 fobj.close()
490 return source
498 return source
491
499
492 #----------------------------------------------------------------------------
500 #----------------------------------------------------------------------------
493 def target_outdated(target,deps):
501 def target_outdated(target,deps):
494 """Determine whether a target is out of date.
502 """Determine whether a target is out of date.
495
503
496 target_outdated(target,deps) -> 1/0
504 target_outdated(target,deps) -> 1/0
497
505
498 deps: list of filenames which MUST exist.
506 deps: list of filenames which MUST exist.
499 target: single filename which may or may not exist.
507 target: single filename which may or may not exist.
500
508
501 If target doesn't exist or is older than any file listed in deps, return
509 If target doesn't exist or is older than any file listed in deps, return
502 true, otherwise return false.
510 true, otherwise return false.
503 """
511 """
504 try:
512 try:
505 target_time = os.path.getmtime(target)
513 target_time = os.path.getmtime(target)
506 except os.error:
514 except os.error:
507 return 1
515 return 1
508 for dep in deps:
516 for dep in deps:
509 dep_time = os.path.getmtime(dep)
517 dep_time = os.path.getmtime(dep)
510 if dep_time > target_time:
518 if dep_time > target_time:
511 #print "For target",target,"Dep failed:",dep # dbg
519 #print "For target",target,"Dep failed:",dep # dbg
512 #print "times (dep,tar):",dep_time,target_time # dbg
520 #print "times (dep,tar):",dep_time,target_time # dbg
513 return 1
521 return 1
514 return 0
522 return 0
515
523
516 #-----------------------------------------------------------------------------
524 #-----------------------------------------------------------------------------
517 def target_update(target,deps,cmd):
525 def target_update(target,deps,cmd):
518 """Update a target with a given command given a list of dependencies.
526 """Update a target with a given command given a list of dependencies.
519
527
520 target_update(target,deps,cmd) -> runs cmd if target is outdated.
528 target_update(target,deps,cmd) -> runs cmd if target is outdated.
521
529
522 This is just a wrapper around target_outdated() which calls the given
530 This is just a wrapper around target_outdated() which calls the given
523 command if target is outdated."""
531 command if target is outdated."""
524
532
525 if target_outdated(target,deps):
533 if target_outdated(target,deps):
526 xsys(cmd)
534 xsys(cmd)
527
535
528 #----------------------------------------------------------------------------
536 #----------------------------------------------------------------------------
529 def unquote_ends(istr):
537 def unquote_ends(istr):
530 """Remove a single pair of quotes from the endpoints of a string."""
538 """Remove a single pair of quotes from the endpoints of a string."""
531
539
532 if not istr:
540 if not istr:
533 return istr
541 return istr
534 if (istr[0]=="'" and istr[-1]=="'") or \
542 if (istr[0]=="'" and istr[-1]=="'") or \
535 (istr[0]=='"' and istr[-1]=='"'):
543 (istr[0]=='"' and istr[-1]=='"'):
536 return istr[1:-1]
544 return istr[1:-1]
537 else:
545 else:
538 return istr
546 return istr
539
547
540 #----------------------------------------------------------------------------
548 #----------------------------------------------------------------------------
541 def process_cmdline(argv,names=[],defaults={},usage=''):
549 def process_cmdline(argv,names=[],defaults={},usage=''):
542 """ Process command-line options and arguments.
550 """ Process command-line options and arguments.
543
551
544 Arguments:
552 Arguments:
545
553
546 - argv: list of arguments, typically sys.argv.
554 - argv: list of arguments, typically sys.argv.
547
555
548 - names: list of option names. See DPyGetOpt docs for details on options
556 - names: list of option names. See DPyGetOpt docs for details on options
549 syntax.
557 syntax.
550
558
551 - defaults: dict of default values.
559 - defaults: dict of default values.
552
560
553 - usage: optional usage notice to print if a wrong argument is passed.
561 - usage: optional usage notice to print if a wrong argument is passed.
554
562
555 Return a dict of options and a list of free arguments."""
563 Return a dict of options and a list of free arguments."""
556
564
557 getopt = DPyGetOpt.DPyGetOpt()
565 getopt = DPyGetOpt.DPyGetOpt()
558 getopt.setIgnoreCase(0)
566 getopt.setIgnoreCase(0)
559 getopt.parseConfiguration(names)
567 getopt.parseConfiguration(names)
560
568
561 try:
569 try:
562 getopt.processArguments(argv)
570 getopt.processArguments(argv)
563 except:
571 except:
564 print usage
572 print usage
565 warn(`sys.exc_value`,level=4)
573 warn(`sys.exc_value`,level=4)
566
574
567 defaults.update(getopt.optionValues)
575 defaults.update(getopt.optionValues)
568 args = getopt.freeValues
576 args = getopt.freeValues
569
577
570 return defaults,args
578 return defaults,args
571
579
572 #----------------------------------------------------------------------------
580 #----------------------------------------------------------------------------
573 def optstr2types(ostr):
581 def optstr2types(ostr):
574 """Convert a string of option names to a dict of type mappings.
582 """Convert a string of option names to a dict of type mappings.
575
583
576 optstr2types(str) -> {None:'string_opts',int:'int_opts',float:'float_opts'}
584 optstr2types(str) -> {None:'string_opts',int:'int_opts',float:'float_opts'}
577
585
578 This is used to get the types of all the options in a string formatted
586 This is used to get the types of all the options in a string formatted
579 with the conventions of DPyGetOpt. The 'type' None is used for options
587 with the conventions of DPyGetOpt. The 'type' None is used for options
580 which are strings (they need no further conversion). This function's main
588 which are strings (they need no further conversion). This function's main
581 use is to get a typemap for use with read_dict().
589 use is to get a typemap for use with read_dict().
582 """
590 """
583
591
584 typeconv = {None:'',int:'',float:''}
592 typeconv = {None:'',int:'',float:''}
585 typemap = {'s':None,'i':int,'f':float}
593 typemap = {'s':None,'i':int,'f':float}
586 opt_re = re.compile(r'([\w]*)([^:=]*:?=?)([sif]?)')
594 opt_re = re.compile(r'([\w]*)([^:=]*:?=?)([sif]?)')
587
595
588 for w in ostr.split():
596 for w in ostr.split():
589 oname,alias,otype = opt_re.match(w).groups()
597 oname,alias,otype = opt_re.match(w).groups()
590 if otype == '' or alias == '!': # simple switches are integers too
598 if otype == '' or alias == '!': # simple switches are integers too
591 otype = 'i'
599 otype = 'i'
592 typeconv[typemap[otype]] += oname + ' '
600 typeconv[typemap[otype]] += oname + ' '
593 return typeconv
601 return typeconv
594
602
595 #----------------------------------------------------------------------------
603 #----------------------------------------------------------------------------
596 def read_dict(filename,type_conv=None,**opt):
604 def read_dict(filename,type_conv=None,**opt):
597
605
598 """Read a dictionary of key=value pairs from an input file, optionally
606 """Read a dictionary of key=value pairs from an input file, optionally
599 performing conversions on the resulting values.
607 performing conversions on the resulting values.
600
608
601 read_dict(filename,type_conv,**opt) -> dict
609 read_dict(filename,type_conv,**opt) -> dict
602
610
603 Only one value per line is accepted, the format should be
611 Only one value per line is accepted, the format should be
604 # optional comments are ignored
612 # optional comments are ignored
605 key value\n
613 key value\n
606
614
607 Args:
615 Args:
608
616
609 - type_conv: A dictionary specifying which keys need to be converted to
617 - type_conv: A dictionary specifying which keys need to be converted to
610 which types. By default all keys are read as strings. This dictionary
618 which types. By default all keys are read as strings. This dictionary
611 should have as its keys valid conversion functions for strings
619 should have as its keys valid conversion functions for strings
612 (int,long,float,complex, or your own). The value for each key
620 (int,long,float,complex, or your own). The value for each key
613 (converter) should be a whitespace separated string containing the names
621 (converter) should be a whitespace separated string containing the names
614 of all the entries in the file to be converted using that function. For
622 of all the entries in the file to be converted using that function. For
615 keys to be left alone, use None as the conversion function (only needed
623 keys to be left alone, use None as the conversion function (only needed
616 with purge=1, see below).
624 with purge=1, see below).
617
625
618 - opt: dictionary with extra options as below (default in parens)
626 - opt: dictionary with extra options as below (default in parens)
619
627
620 purge(0): if set to 1, all keys *not* listed in type_conv are purged out
628 purge(0): if set to 1, all keys *not* listed in type_conv are purged out
621 of the dictionary to be returned. If purge is going to be used, the
629 of the dictionary to be returned. If purge is going to be used, the
622 set of keys to be left as strings also has to be explicitly specified
630 set of keys to be left as strings also has to be explicitly specified
623 using the (non-existent) conversion function None.
631 using the (non-existent) conversion function None.
624
632
625 fs(None): field separator. This is the key/value separator to be used
633 fs(None): field separator. This is the key/value separator to be used
626 when parsing the file. The None default means any whitespace [behavior
634 when parsing the file. The None default means any whitespace [behavior
627 of string.split()].
635 of string.split()].
628
636
629 strip(0): if 1, strip string values of leading/trailinig whitespace.
637 strip(0): if 1, strip string values of leading/trailinig whitespace.
630
638
631 warn(1): warning level if requested keys are not found in file.
639 warn(1): warning level if requested keys are not found in file.
632 - 0: silently ignore.
640 - 0: silently ignore.
633 - 1: inform but proceed.
641 - 1: inform but proceed.
634 - 2: raise KeyError exception.
642 - 2: raise KeyError exception.
635
643
636 no_empty(0): if 1, remove keys with whitespace strings as a value.
644 no_empty(0): if 1, remove keys with whitespace strings as a value.
637
645
638 unique([]): list of keys (or space separated string) which can't be
646 unique([]): list of keys (or space separated string) which can't be
639 repeated. If one such key is found in the file, each new instance
647 repeated. If one such key is found in the file, each new instance
640 overwrites the previous one. For keys not listed here, the behavior is
648 overwrites the previous one. For keys not listed here, the behavior is
641 to make a list of all appearances.
649 to make a list of all appearances.
642
650
643 Example:
651 Example:
644 If the input file test.ini has:
652 If the input file test.ini has:
645 i 3
653 i 3
646 x 4.5
654 x 4.5
647 y 5.5
655 y 5.5
648 s hi ho
656 s hi ho
649 Then:
657 Then:
650
658
651 >>> type_conv={int:'i',float:'x',None:'s'}
659 >>> type_conv={int:'i',float:'x',None:'s'}
652 >>> read_dict('test.ini')
660 >>> read_dict('test.ini')
653 {'i': '3', 's': 'hi ho', 'x': '4.5', 'y': '5.5'}
661 {'i': '3', 's': 'hi ho', 'x': '4.5', 'y': '5.5'}
654 >>> read_dict('test.ini',type_conv)
662 >>> read_dict('test.ini',type_conv)
655 {'i': 3, 's': 'hi ho', 'x': 4.5, 'y': '5.5'}
663 {'i': 3, 's': 'hi ho', 'x': 4.5, 'y': '5.5'}
656 >>> read_dict('test.ini',type_conv,purge=1)
664 >>> read_dict('test.ini',type_conv,purge=1)
657 {'i': 3, 's': 'hi ho', 'x': 4.5}
665 {'i': 3, 's': 'hi ho', 'x': 4.5}
658 """
666 """
659
667
660 # starting config
668 # starting config
661 opt.setdefault('purge',0)
669 opt.setdefault('purge',0)
662 opt.setdefault('fs',None) # field sep defaults to any whitespace
670 opt.setdefault('fs',None) # field sep defaults to any whitespace
663 opt.setdefault('strip',0)
671 opt.setdefault('strip',0)
664 opt.setdefault('warn',1)
672 opt.setdefault('warn',1)
665 opt.setdefault('no_empty',0)
673 opt.setdefault('no_empty',0)
666 opt.setdefault('unique','')
674 opt.setdefault('unique','')
667 if type(opt['unique']) in StringTypes:
675 if type(opt['unique']) in StringTypes:
668 unique_keys = qw(opt['unique'])
676 unique_keys = qw(opt['unique'])
669 elif type(opt['unique']) in (types.TupleType,types.ListType):
677 elif type(opt['unique']) in (types.TupleType,types.ListType):
670 unique_keys = opt['unique']
678 unique_keys = opt['unique']
671 else:
679 else:
672 raise ValueError, 'Unique keys must be given as a string, List or Tuple'
680 raise ValueError, 'Unique keys must be given as a string, List or Tuple'
673
681
674 dict = {}
682 dict = {}
675 # first read in table of values as strings
683 # first read in table of values as strings
676 file = open(filename,'r')
684 file = open(filename,'r')
677 for line in file.readlines():
685 for line in file.readlines():
678 line = line.strip()
686 line = line.strip()
679 if len(line) and line[0]=='#': continue
687 if len(line) and line[0]=='#': continue
680 if len(line)>0:
688 if len(line)>0:
681 lsplit = line.split(opt['fs'],1)
689 lsplit = line.split(opt['fs'],1)
682 try:
690 try:
683 key,val = lsplit
691 key,val = lsplit
684 except ValueError:
692 except ValueError:
685 key,val = lsplit[0],''
693 key,val = lsplit[0],''
686 key = key.strip()
694 key = key.strip()
687 if opt['strip']: val = val.strip()
695 if opt['strip']: val = val.strip()
688 if val == "''" or val == '""': val = ''
696 if val == "''" or val == '""': val = ''
689 if opt['no_empty'] and (val=='' or val.isspace()):
697 if opt['no_empty'] and (val=='' or val.isspace()):
690 continue
698 continue
691 # if a key is found more than once in the file, build a list
699 # if a key is found more than once in the file, build a list
692 # unless it's in the 'unique' list. In that case, last found in file
700 # unless it's in the 'unique' list. In that case, last found in file
693 # takes precedence. User beware.
701 # takes precedence. User beware.
694 try:
702 try:
695 if dict[key] and key in unique_keys:
703 if dict[key] and key in unique_keys:
696 dict[key] = val
704 dict[key] = val
697 elif type(dict[key]) is types.ListType:
705 elif type(dict[key]) is types.ListType:
698 dict[key].append(val)
706 dict[key].append(val)
699 else:
707 else:
700 dict[key] = [dict[key],val]
708 dict[key] = [dict[key],val]
701 except KeyError:
709 except KeyError:
702 dict[key] = val
710 dict[key] = val
703 # purge if requested
711 # purge if requested
704 if opt['purge']:
712 if opt['purge']:
705 accepted_keys = qwflat(type_conv.values())
713 accepted_keys = qwflat(type_conv.values())
706 for key in dict.keys():
714 for key in dict.keys():
707 if key in accepted_keys: continue
715 if key in accepted_keys: continue
708 del(dict[key])
716 del(dict[key])
709 # now convert if requested
717 # now convert if requested
710 if type_conv==None: return dict
718 if type_conv==None: return dict
711 conversions = type_conv.keys()
719 conversions = type_conv.keys()
712 try: conversions.remove(None)
720 try: conversions.remove(None)
713 except: pass
721 except: pass
714 for convert in conversions:
722 for convert in conversions:
715 for val in qw(type_conv[convert]):
723 for val in qw(type_conv[convert]):
716 try:
724 try:
717 dict[val] = convert(dict[val])
725 dict[val] = convert(dict[val])
718 except KeyError,e:
726 except KeyError,e:
719 if opt['warn'] == 0:
727 if opt['warn'] == 0:
720 pass
728 pass
721 elif opt['warn'] == 1:
729 elif opt['warn'] == 1:
722 print >>sys.stderr, 'Warning: key',val,\
730 print >>sys.stderr, 'Warning: key',val,\
723 'not found in file',filename
731 'not found in file',filename
724 elif opt['warn'] == 2:
732 elif opt['warn'] == 2:
725 raise KeyError,e
733 raise KeyError,e
726 else:
734 else:
727 raise ValueError,'Warning level must be 0,1 or 2'
735 raise ValueError,'Warning level must be 0,1 or 2'
728
736
729 return dict
737 return dict
730
738
731 #----------------------------------------------------------------------------
739 #----------------------------------------------------------------------------
732 def flag_calls(func):
740 def flag_calls(func):
733 """Wrap a function to detect and flag when it gets called.
741 """Wrap a function to detect and flag when it gets called.
734
742
735 This is a decorator which takes a function and wraps it in a function with
743 This is a decorator which takes a function and wraps it in a function with
736 a 'called' attribute. wrapper.called is initialized to False.
744 a 'called' attribute. wrapper.called is initialized to False.
737
745
738 The wrapper.called attribute is set to False right before each call to the
746 The wrapper.called attribute is set to False right before each call to the
739 wrapped function, so if the call fails it remains False. After the call
747 wrapped function, so if the call fails it remains False. After the call
740 completes, wrapper.called is set to True and the output is returned.
748 completes, wrapper.called is set to True and the output is returned.
741
749
742 Testing for truth in wrapper.called allows you to determine if a call to
750 Testing for truth in wrapper.called allows you to determine if a call to
743 func() was attempted and succeeded."""
751 func() was attempted and succeeded."""
744
752
745 def wrapper(*args,**kw):
753 def wrapper(*args,**kw):
746 wrapper.called = False
754 wrapper.called = False
747 out = func(*args,**kw)
755 out = func(*args,**kw)
748 wrapper.called = True
756 wrapper.called = True
749 return out
757 return out
750
758
751 wrapper.called = False
759 wrapper.called = False
752 wrapper.__doc__ = func.__doc__
760 wrapper.__doc__ = func.__doc__
753 return wrapper
761 return wrapper
754
762
755 #----------------------------------------------------------------------------
763 #----------------------------------------------------------------------------
756 class HomeDirError(Error):
764 class HomeDirError(Error):
757 pass
765 pass
758
766
759 def get_home_dir():
767 def get_home_dir():
760 """Return the closest possible equivalent to a 'home' directory.
768 """Return the closest possible equivalent to a 'home' directory.
761
769
762 We first try $HOME. Absent that, on NT it's $HOMEDRIVE\$HOMEPATH.
770 We first try $HOME. Absent that, on NT it's $HOMEDRIVE\$HOMEPATH.
763
771
764 Currently only Posix and NT are implemented, a HomeDirError exception is
772 Currently only Posix and NT are implemented, a HomeDirError exception is
765 raised for all other OSes. """
773 raised for all other OSes. """
766
774
767 isdir = os.path.isdir
775 isdir = os.path.isdir
768 env = os.environ
776 env = os.environ
769 try:
777 try:
770 homedir = env['HOME']
778 homedir = env['HOME']
771 if not isdir(homedir):
779 if not isdir(homedir):
772 # in case a user stuck some string which does NOT resolve to a
780 # in case a user stuck some string which does NOT resolve to a
773 # valid path, it's as good as if we hadn't foud it
781 # valid path, it's as good as if we hadn't foud it
774 raise KeyError
782 raise KeyError
775 return homedir
783 return homedir
776 except KeyError:
784 except KeyError:
777 if os.name == 'posix':
785 if os.name == 'posix':
778 raise HomeDirError,'undefined $HOME, IPython can not proceed.'
786 raise HomeDirError,'undefined $HOME, IPython can not proceed.'
779 elif os.name == 'nt':
787 elif os.name == 'nt':
780 # For some strange reason, win9x returns 'nt' for os.name.
788 # For some strange reason, win9x returns 'nt' for os.name.
781 try:
789 try:
782 homedir = os.path.join(env['HOMEDRIVE'],env['HOMEPATH'])
790 homedir = os.path.join(env['HOMEDRIVE'],env['HOMEPATH'])
783 if not isdir(homedir):
791 if not isdir(homedir):
784 homedir = os.path.join(env['USERPROFILE'])
792 homedir = os.path.join(env['USERPROFILE'])
785 if not isdir(homedir):
793 if not isdir(homedir):
786 raise HomeDirError
794 raise HomeDirError
787 return homedir
795 return homedir
788 except:
796 except:
789 try:
797 try:
790 # Use the registry to get the 'My Documents' folder.
798 # Use the registry to get the 'My Documents' folder.
791 import _winreg as wreg
799 import _winreg as wreg
792 key = wreg.OpenKey(wreg.HKEY_CURRENT_USER,
800 key = wreg.OpenKey(wreg.HKEY_CURRENT_USER,
793 "Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders")
801 "Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders")
794 homedir = wreg.QueryValueEx(key,'Personal')[0]
802 homedir = wreg.QueryValueEx(key,'Personal')[0]
795 key.Close()
803 key.Close()
796 if not isdir(homedir):
804 if not isdir(homedir):
797 e = ('Invalid "Personal" folder registry key '
805 e = ('Invalid "Personal" folder registry key '
798 'typically "My Documents".\n'
806 'typically "My Documents".\n'
799 'Value: %s\n'
807 'Value: %s\n'
800 'This is not a valid directory on your system.' %
808 'This is not a valid directory on your system.' %
801 homedir)
809 homedir)
802 raise HomeDirError(e)
810 raise HomeDirError(e)
803 return homedir
811 return homedir
804 except HomeDirError:
812 except HomeDirError:
805 raise
813 raise
806 except:
814 except:
807 return 'C:\\'
815 return 'C:\\'
808 elif os.name == 'dos':
816 elif os.name == 'dos':
809 # Desperate, may do absurd things in classic MacOS. May work under DOS.
817 # Desperate, may do absurd things in classic MacOS. May work under DOS.
810 return 'C:\\'
818 return 'C:\\'
811 else:
819 else:
812 raise HomeDirError,'support for your operating system not implemented.'
820 raise HomeDirError,'support for your operating system not implemented.'
813
821
814 #****************************************************************************
822 #****************************************************************************
815 # strings and text
823 # strings and text
816
824
817 class LSString(str):
825 class LSString(str):
818 """String derivative with a special access attributes.
826 """String derivative with a special access attributes.
819
827
820 These are normal strings, but with the special attributes:
828 These are normal strings, but with the special attributes:
821
829
822 .l (or .list) : value as list (split on newlines).
830 .l (or .list) : value as list (split on newlines).
823 .n (or .nlstr): original value (the string itself).
831 .n (or .nlstr): original value (the string itself).
824 .s (or .spstr): value as whitespace-separated string.
832 .s (or .spstr): value as whitespace-separated string.
825
833
826 Any values which require transformations are computed only once and
834 Any values which require transformations are computed only once and
827 cached.
835 cached.
828
836
829 Such strings are very useful to efficiently interact with the shell, which
837 Such strings are very useful to efficiently interact with the shell, which
830 typically only understands whitespace-separated options for commands."""
838 typically only understands whitespace-separated options for commands."""
831
839
832 def get_list(self):
840 def get_list(self):
833 try:
841 try:
834 return self.__list
842 return self.__list
835 except AttributeError:
843 except AttributeError:
836 self.__list = self.split('\n')
844 self.__list = self.split('\n')
837 return self.__list
845 return self.__list
838
846
839 l = list = property(get_list)
847 l = list = property(get_list)
840
848
841 def get_spstr(self):
849 def get_spstr(self):
842 try:
850 try:
843 return self.__spstr
851 return self.__spstr
844 except AttributeError:
852 except AttributeError:
845 self.__spstr = self.replace('\n',' ')
853 self.__spstr = self.replace('\n',' ')
846 return self.__spstr
854 return self.__spstr
847
855
848 s = spstr = property(get_spstr)
856 s = spstr = property(get_spstr)
849
857
850 def get_nlstr(self):
858 def get_nlstr(self):
851 return self
859 return self
852
860
853 n = nlstr = property(get_nlstr)
861 n = nlstr = property(get_nlstr)
854
862
855 class SList(list):
863 class SList(list):
856 """List derivative with a special access attributes.
864 """List derivative with a special access attributes.
857
865
858 These are normal lists, but with the special attributes:
866 These are normal lists, but with the special attributes:
859
867
860 .l (or .list) : value as list (the list itself).
868 .l (or .list) : value as list (the list itself).
861 .n (or .nlstr): value as a string, joined on newlines.
869 .n (or .nlstr): value as a string, joined on newlines.
862 .s (or .spstr): value as a string, joined on spaces.
870 .s (or .spstr): value as a string, joined on spaces.
863
871
864 Any values which require transformations are computed only once and
872 Any values which require transformations are computed only once and
865 cached."""
873 cached."""
866
874
867 def get_list(self):
875 def get_list(self):
868 return self
876 return self
869
877
870 l = list = property(get_list)
878 l = list = property(get_list)
871
879
872 def get_spstr(self):
880 def get_spstr(self):
873 try:
881 try:
874 return self.__spstr
882 return self.__spstr
875 except AttributeError:
883 except AttributeError:
876 self.__spstr = ' '.join(self)
884 self.__spstr = ' '.join(self)
877 return self.__spstr
885 return self.__spstr
878
886
879 s = spstr = property(get_spstr)
887 s = spstr = property(get_spstr)
880
888
881 def get_nlstr(self):
889 def get_nlstr(self):
882 try:
890 try:
883 return self.__nlstr
891 return self.__nlstr
884 except AttributeError:
892 except AttributeError:
885 self.__nlstr = '\n'.join(self)
893 self.__nlstr = '\n'.join(self)
886 return self.__nlstr
894 return self.__nlstr
887
895
888 n = nlstr = property(get_nlstr)
896 n = nlstr = property(get_nlstr)
889
897
890 def raw_input_multi(header='', ps1='==> ', ps2='..> ',terminate_str = '.'):
898 def raw_input_multi(header='', ps1='==> ', ps2='..> ',terminate_str = '.'):
891 """Take multiple lines of input.
899 """Take multiple lines of input.
892
900
893 A list with each line of input as a separate element is returned when a
901 A list with each line of input as a separate element is returned when a
894 termination string is entered (defaults to a single '.'). Input can also
902 termination string is entered (defaults to a single '.'). Input can also
895 terminate via EOF (^D in Unix, ^Z-RET in Windows).
903 terminate via EOF (^D in Unix, ^Z-RET in Windows).
896
904
897 Lines of input which end in \\ are joined into single entries (and a
905 Lines of input which end in \\ are joined into single entries (and a
898 secondary continuation prompt is issued as long as the user terminates
906 secondary continuation prompt is issued as long as the user terminates
899 lines with \\). This allows entering very long strings which are still
907 lines with \\). This allows entering very long strings which are still
900 meant to be treated as single entities.
908 meant to be treated as single entities.
901 """
909 """
902
910
903 try:
911 try:
904 if header:
912 if header:
905 header += '\n'
913 header += '\n'
906 lines = [raw_input(header + ps1)]
914 lines = [raw_input(header + ps1)]
907 except EOFError:
915 except EOFError:
908 return []
916 return []
909 terminate = [terminate_str]
917 terminate = [terminate_str]
910 try:
918 try:
911 while lines[-1:] != terminate:
919 while lines[-1:] != terminate:
912 new_line = raw_input(ps1)
920 new_line = raw_input(ps1)
913 while new_line.endswith('\\'):
921 while new_line.endswith('\\'):
914 new_line = new_line[:-1] + raw_input(ps2)
922 new_line = new_line[:-1] + raw_input(ps2)
915 lines.append(new_line)
923 lines.append(new_line)
916
924
917 return lines[:-1] # don't return the termination command
925 return lines[:-1] # don't return the termination command
918 except EOFError:
926 except EOFError:
919 print
927 print
920 return lines
928 return lines
921
929
922 #----------------------------------------------------------------------------
930 #----------------------------------------------------------------------------
923 def raw_input_ext(prompt='', ps2='... '):
931 def raw_input_ext(prompt='', ps2='... '):
924 """Similar to raw_input(), but accepts extended lines if input ends with \\."""
932 """Similar to raw_input(), but accepts extended lines if input ends with \\."""
925
933
926 line = raw_input(prompt)
934 line = raw_input(prompt)
927 while line.endswith('\\'):
935 while line.endswith('\\'):
928 line = line[:-1] + raw_input(ps2)
936 line = line[:-1] + raw_input(ps2)
929 return line
937 return line
930
938
931 #----------------------------------------------------------------------------
939 #----------------------------------------------------------------------------
932 def ask_yes_no(prompt,default=None):
940 def ask_yes_no(prompt,default=None):
933 """Asks a question and returns an integer 1/0 (y/n) answer.
941 """Asks a question and returns an integer 1/0 (y/n) answer.
934
942
935 If default is given (one of 'y','n'), it is used if the user input is
943 If default is given (one of 'y','n'), it is used if the user input is
936 empty. Otherwise the question is repeated until an answer is given.
944 empty. Otherwise the question is repeated until an answer is given.
937 If EOF occurs 20 times consecutively, the default answer is assumed,
945 If EOF occurs 20 times consecutively, the default answer is assumed,
938 or if there is no default, an exception is raised to prevent infinite
946 or if there is no default, an exception is raised to prevent infinite
939 loops.
947 loops.
940
948
941 Valid answers are: y/yes/n/no (match is not case sensitive)."""
949 Valid answers are: y/yes/n/no (match is not case sensitive)."""
942
950
943 answers = {'y':1,'n':0,'yes':1,'no':0}
951 answers = {'y':1,'n':0,'yes':1,'no':0}
944 ans = None
952 ans = None
945 eofs, max_eofs = 0, 20
953 eofs, max_eofs = 0, 20
946 while ans not in answers.keys():
954 while ans not in answers.keys():
947 try:
955 try:
948 ans = raw_input(prompt+' ').lower()
956 ans = raw_input(prompt+' ').lower()
949 if not ans: # response was an empty string
957 if not ans: # response was an empty string
950 ans = default
958 ans = default
951 eofs = 0
959 eofs = 0
952 except (EOFError,KeyboardInterrupt):
960 except (EOFError,KeyboardInterrupt):
953 eofs = eofs + 1
961 eofs = eofs + 1
954 if eofs >= max_eofs:
962 if eofs >= max_eofs:
955 if default in answers.keys():
963 if default in answers.keys():
956 ans = default
964 ans = default
957 else:
965 else:
958 raise
966 raise
959
967
960 return answers[ans]
968 return answers[ans]
961
969
962 #----------------------------------------------------------------------------
970 #----------------------------------------------------------------------------
963 def marquee(txt='',width=78,mark='*'):
971 def marquee(txt='',width=78,mark='*'):
964 """Return the input string centered in a 'marquee'."""
972 """Return the input string centered in a 'marquee'."""
965 if not txt:
973 if not txt:
966 return (mark*width)[:width]
974 return (mark*width)[:width]
967 nmark = (width-len(txt)-2)/len(mark)/2
975 nmark = (width-len(txt)-2)/len(mark)/2
968 if nmark < 0: nmark =0
976 if nmark < 0: nmark =0
969 marks = mark*nmark
977 marks = mark*nmark
970 return '%s %s %s' % (marks,txt,marks)
978 return '%s %s %s' % (marks,txt,marks)
971
979
972 #----------------------------------------------------------------------------
980 #----------------------------------------------------------------------------
973 class EvalDict:
981 class EvalDict:
974 """
982 """
975 Emulate a dict which evaluates its contents in the caller's frame.
983 Emulate a dict which evaluates its contents in the caller's frame.
976
984
977 Usage:
985 Usage:
978 >>>number = 19
986 >>>number = 19
979 >>>text = "python"
987 >>>text = "python"
980 >>>print "%(text.capitalize())s %(number/9.0).1f rules!" % EvalDict()
988 >>>print "%(text.capitalize())s %(number/9.0).1f rules!" % EvalDict()
981 """
989 """
982
990
983 # This version is due to sismex01@hebmex.com on c.l.py, and is basically a
991 # This version is due to sismex01@hebmex.com on c.l.py, and is basically a
984 # modified (shorter) version of:
992 # modified (shorter) version of:
985 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66018 by
993 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66018 by
986 # Skip Montanaro (skip@pobox.com).
994 # Skip Montanaro (skip@pobox.com).
987
995
988 def __getitem__(self, name):
996 def __getitem__(self, name):
989 frame = sys._getframe(1)
997 frame = sys._getframe(1)
990 return eval(name, frame.f_globals, frame.f_locals)
998 return eval(name, frame.f_globals, frame.f_locals)
991
999
992 EvalString = EvalDict # for backwards compatibility
1000 EvalString = EvalDict # for backwards compatibility
993 #----------------------------------------------------------------------------
1001 #----------------------------------------------------------------------------
994 def qw(words,flat=0,sep=None,maxsplit=-1):
1002 def qw(words,flat=0,sep=None,maxsplit=-1):
995 """Similar to Perl's qw() operator, but with some more options.
1003 """Similar to Perl's qw() operator, but with some more options.
996
1004
997 qw(words,flat=0,sep=' ',maxsplit=-1) -> words.split(sep,maxsplit)
1005 qw(words,flat=0,sep=' ',maxsplit=-1) -> words.split(sep,maxsplit)
998
1006
999 words can also be a list itself, and with flat=1, the output will be
1007 words can also be a list itself, and with flat=1, the output will be
1000 recursively flattened. Examples:
1008 recursively flattened. Examples:
1001
1009
1002 >>> qw('1 2')
1010 >>> qw('1 2')
1003 ['1', '2']
1011 ['1', '2']
1004 >>> qw(['a b','1 2',['m n','p q']])
1012 >>> qw(['a b','1 2',['m n','p q']])
1005 [['a', 'b'], ['1', '2'], [['m', 'n'], ['p', 'q']]]
1013 [['a', 'b'], ['1', '2'], [['m', 'n'], ['p', 'q']]]
1006 >>> qw(['a b','1 2',['m n','p q']],flat=1)
1014 >>> qw(['a b','1 2',['m n','p q']],flat=1)
1007 ['a', 'b', '1', '2', 'm', 'n', 'p', 'q'] """
1015 ['a', 'b', '1', '2', 'm', 'n', 'p', 'q'] """
1008
1016
1009 if type(words) in StringTypes:
1017 if type(words) in StringTypes:
1010 return [word.strip() for word in words.split(sep,maxsplit)
1018 return [word.strip() for word in words.split(sep,maxsplit)
1011 if word and not word.isspace() ]
1019 if word and not word.isspace() ]
1012 if flat:
1020 if flat:
1013 return flatten(map(qw,words,[1]*len(words)))
1021 return flatten(map(qw,words,[1]*len(words)))
1014 return map(qw,words)
1022 return map(qw,words)
1015
1023
1016 #----------------------------------------------------------------------------
1024 #----------------------------------------------------------------------------
1017 def qwflat(words,sep=None,maxsplit=-1):
1025 def qwflat(words,sep=None,maxsplit=-1):
1018 """Calls qw(words) in flat mode. It's just a convenient shorthand."""
1026 """Calls qw(words) in flat mode. It's just a convenient shorthand."""
1019 return qw(words,1,sep,maxsplit)
1027 return qw(words,1,sep,maxsplit)
1020
1028
1021 #-----------------------------------------------------------------------------
1029 #-----------------------------------------------------------------------------
1022 def list_strings(arg):
1030 def list_strings(arg):
1023 """Always return a list of strings, given a string or list of strings
1031 """Always return a list of strings, given a string or list of strings
1024 as input."""
1032 as input."""
1025
1033
1026 if type(arg) in StringTypes: return [arg]
1034 if type(arg) in StringTypes: return [arg]
1027 else: return arg
1035 else: return arg
1028
1036
1029 #----------------------------------------------------------------------------
1037 #----------------------------------------------------------------------------
1030 def grep(pat,list,case=1):
1038 def grep(pat,list,case=1):
1031 """Simple minded grep-like function.
1039 """Simple minded grep-like function.
1032 grep(pat,list) returns occurrences of pat in list, None on failure.
1040 grep(pat,list) returns occurrences of pat in list, None on failure.
1033
1041
1034 It only does simple string matching, with no support for regexps. Use the
1042 It only does simple string matching, with no support for regexps. Use the
1035 option case=0 for case-insensitive matching."""
1043 option case=0 for case-insensitive matching."""
1036
1044
1037 # This is pretty crude. At least it should implement copying only references
1045 # This is pretty crude. At least it should implement copying only references
1038 # to the original data in case it's big. Now it copies the data for output.
1046 # to the original data in case it's big. Now it copies the data for output.
1039 out=[]
1047 out=[]
1040 if case:
1048 if case:
1041 for term in list:
1049 for term in list:
1042 if term.find(pat)>-1: out.append(term)
1050 if term.find(pat)>-1: out.append(term)
1043 else:
1051 else:
1044 lpat=pat.lower()
1052 lpat=pat.lower()
1045 for term in list:
1053 for term in list:
1046 if term.lower().find(lpat)>-1: out.append(term)
1054 if term.lower().find(lpat)>-1: out.append(term)
1047
1055
1048 if len(out): return out
1056 if len(out): return out
1049 else: return None
1057 else: return None
1050
1058
1051 #----------------------------------------------------------------------------
1059 #----------------------------------------------------------------------------
1052 def dgrep(pat,*opts):
1060 def dgrep(pat,*opts):
1053 """Return grep() on dir()+dir(__builtins__).
1061 """Return grep() on dir()+dir(__builtins__).
1054
1062
1055 A very common use of grep() when working interactively."""
1063 A very common use of grep() when working interactively."""
1056
1064
1057 return grep(pat,dir(__main__)+dir(__main__.__builtins__),*opts)
1065 return grep(pat,dir(__main__)+dir(__main__.__builtins__),*opts)
1058
1066
1059 #----------------------------------------------------------------------------
1067 #----------------------------------------------------------------------------
1060 def idgrep(pat):
1068 def idgrep(pat):
1061 """Case-insensitive dgrep()"""
1069 """Case-insensitive dgrep()"""
1062
1070
1063 return dgrep(pat,0)
1071 return dgrep(pat,0)
1064
1072
1065 #----------------------------------------------------------------------------
1073 #----------------------------------------------------------------------------
1066 def igrep(pat,list):
1074 def igrep(pat,list):
1067 """Synonym for case-insensitive grep."""
1075 """Synonym for case-insensitive grep."""
1068
1076
1069 return grep(pat,list,case=0)
1077 return grep(pat,list,case=0)
1070
1078
1071 #----------------------------------------------------------------------------
1079 #----------------------------------------------------------------------------
1072 def indent(str,nspaces=4,ntabs=0):
1080 def indent(str,nspaces=4,ntabs=0):
1073 """Indent a string a given number of spaces or tabstops.
1081 """Indent a string a given number of spaces or tabstops.
1074
1082
1075 indent(str,nspaces=4,ntabs=0) -> indent str by ntabs+nspaces.
1083 indent(str,nspaces=4,ntabs=0) -> indent str by ntabs+nspaces.
1076 """
1084 """
1077 if str is None:
1085 if str is None:
1078 return
1086 return
1079 ind = '\t'*ntabs+' '*nspaces
1087 ind = '\t'*ntabs+' '*nspaces
1080 outstr = '%s%s' % (ind,str.replace(os.linesep,os.linesep+ind))
1088 outstr = '%s%s' % (ind,str.replace(os.linesep,os.linesep+ind))
1081 if outstr.endswith(os.linesep+ind):
1089 if outstr.endswith(os.linesep+ind):
1082 return outstr[:-len(ind)]
1090 return outstr[:-len(ind)]
1083 else:
1091 else:
1084 return outstr
1092 return outstr
1085
1093
1086 #-----------------------------------------------------------------------------
1094 #-----------------------------------------------------------------------------
1087 def native_line_ends(filename,backup=1):
1095 def native_line_ends(filename,backup=1):
1088 """Convert (in-place) a file to line-ends native to the current OS.
1096 """Convert (in-place) a file to line-ends native to the current OS.
1089
1097
1090 If the optional backup argument is given as false, no backup of the
1098 If the optional backup argument is given as false, no backup of the
1091 original file is left. """
1099 original file is left. """
1092
1100
1093 backup_suffixes = {'posix':'~','dos':'.bak','nt':'.bak','mac':'.bak'}
1101 backup_suffixes = {'posix':'~','dos':'.bak','nt':'.bak','mac':'.bak'}
1094
1102
1095 bak_filename = filename + backup_suffixes[os.name]
1103 bak_filename = filename + backup_suffixes[os.name]
1096
1104
1097 original = open(filename).read()
1105 original = open(filename).read()
1098 shutil.copy2(filename,bak_filename)
1106 shutil.copy2(filename,bak_filename)
1099 try:
1107 try:
1100 new = open(filename,'wb')
1108 new = open(filename,'wb')
1101 new.write(os.linesep.join(original.splitlines()))
1109 new.write(os.linesep.join(original.splitlines()))
1102 new.write(os.linesep) # ALWAYS put an eol at the end of the file
1110 new.write(os.linesep) # ALWAYS put an eol at the end of the file
1103 new.close()
1111 new.close()
1104 except:
1112 except:
1105 os.rename(bak_filename,filename)
1113 os.rename(bak_filename,filename)
1106 if not backup:
1114 if not backup:
1107 try:
1115 try:
1108 os.remove(bak_filename)
1116 os.remove(bak_filename)
1109 except:
1117 except:
1110 pass
1118 pass
1111
1119
1112 #----------------------------------------------------------------------------
1120 #----------------------------------------------------------------------------
1113 def get_pager_cmd(pager_cmd = None):
1121 def get_pager_cmd(pager_cmd = None):
1114 """Return a pager command.
1122 """Return a pager command.
1115
1123
1116 Makes some attempts at finding an OS-correct one."""
1124 Makes some attempts at finding an OS-correct one."""
1117
1125
1118 if os.name == 'posix':
1126 if os.name == 'posix':
1119 default_pager_cmd = 'less -r' # -r for color control sequences
1127 default_pager_cmd = 'less -r' # -r for color control sequences
1120 elif os.name in ['nt','dos']:
1128 elif os.name in ['nt','dos']:
1121 default_pager_cmd = 'type'
1129 default_pager_cmd = 'type'
1122
1130
1123 if pager_cmd is None:
1131 if pager_cmd is None:
1124 try:
1132 try:
1125 pager_cmd = os.environ['PAGER']
1133 pager_cmd = os.environ['PAGER']
1126 except:
1134 except:
1127 pager_cmd = default_pager_cmd
1135 pager_cmd = default_pager_cmd
1128 return pager_cmd
1136 return pager_cmd
1129
1137
1130 #-----------------------------------------------------------------------------
1138 #-----------------------------------------------------------------------------
1131 def get_pager_start(pager,start):
1139 def get_pager_start(pager,start):
1132 """Return the string for paging files with an offset.
1140 """Return the string for paging files with an offset.
1133
1141
1134 This is the '+N' argument which less and more (under Unix) accept.
1142 This is the '+N' argument which less and more (under Unix) accept.
1135 """
1143 """
1136
1144
1137 if pager in ['less','more']:
1145 if pager in ['less','more']:
1138 if start:
1146 if start:
1139 start_string = '+' + str(start)
1147 start_string = '+' + str(start)
1140 else:
1148 else:
1141 start_string = ''
1149 start_string = ''
1142 else:
1150 else:
1143 start_string = ''
1151 start_string = ''
1144 return start_string
1152 return start_string
1145
1153
1146 #----------------------------------------------------------------------------
1154 #----------------------------------------------------------------------------
1147 def page_dumb(strng,start=0,screen_lines=25):
1155 def page_dumb(strng,start=0,screen_lines=25):
1148 """Very dumb 'pager' in Python, for when nothing else works.
1156 """Very dumb 'pager' in Python, for when nothing else works.
1149
1157
1150 Only moves forward, same interface as page(), except for pager_cmd and
1158 Only moves forward, same interface as page(), except for pager_cmd and
1151 mode."""
1159 mode."""
1152
1160
1153 out_ln = strng.splitlines()[start:]
1161 out_ln = strng.splitlines()[start:]
1154 screens = chop(out_ln,screen_lines-1)
1162 screens = chop(out_ln,screen_lines-1)
1155 if len(screens) == 1:
1163 if len(screens) == 1:
1156 print >>Term.cout, os.linesep.join(screens[0])
1164 print >>Term.cout, os.linesep.join(screens[0])
1157 else:
1165 else:
1158 for scr in screens[0:-1]:
1166 for scr in screens[0:-1]:
1159 print >>Term.cout, os.linesep.join(scr)
1167 print >>Term.cout, os.linesep.join(scr)
1160 ans = raw_input('---Return to continue, q to quit--- ')
1168 ans = raw_input('---Return to continue, q to quit--- ')
1161 if ans.lower().startswith('q'):
1169 if ans.lower().startswith('q'):
1162 return
1170 return
1163 print >>Term.cout, os.linesep.join(screens[-1])
1171 print >>Term.cout, os.linesep.join(screens[-1])
1164
1172
1165 #----------------------------------------------------------------------------
1173 #----------------------------------------------------------------------------
1166 def page(strng,start=0,screen_lines=0,pager_cmd = None):
1174 def page(strng,start=0,screen_lines=0,pager_cmd = None):
1167 """Print a string, piping through a pager after a certain length.
1175 """Print a string, piping through a pager after a certain length.
1168
1176
1169 The screen_lines parameter specifies the number of *usable* lines of your
1177 The screen_lines parameter specifies the number of *usable* lines of your
1170 terminal screen (total lines minus lines you need to reserve to show other
1178 terminal screen (total lines minus lines you need to reserve to show other
1171 information).
1179 information).
1172
1180
1173 If you set screen_lines to a number <=0, page() will try to auto-determine
1181 If you set screen_lines to a number <=0, page() will try to auto-determine
1174 your screen size and will only use up to (screen_size+screen_lines) for
1182 your screen size and will only use up to (screen_size+screen_lines) for
1175 printing, paging after that. That is, if you want auto-detection but need
1183 printing, paging after that. That is, if you want auto-detection but need
1176 to reserve the bottom 3 lines of the screen, use screen_lines = -3, and for
1184 to reserve the bottom 3 lines of the screen, use screen_lines = -3, and for
1177 auto-detection without any lines reserved simply use screen_lines = 0.
1185 auto-detection without any lines reserved simply use screen_lines = 0.
1178
1186
1179 If a string won't fit in the allowed lines, it is sent through the
1187 If a string won't fit in the allowed lines, it is sent through the
1180 specified pager command. If none given, look for PAGER in the environment,
1188 specified pager command. If none given, look for PAGER in the environment,
1181 and ultimately default to less.
1189 and ultimately default to less.
1182
1190
1183 If no system pager works, the string is sent through a 'dumb pager'
1191 If no system pager works, the string is sent through a 'dumb pager'
1184 written in python, very simplistic.
1192 written in python, very simplistic.
1185 """
1193 """
1186
1194
1187 # Ugly kludge, but calling curses.initscr() flat out crashes in emacs
1195 # Ugly kludge, but calling curses.initscr() flat out crashes in emacs
1188 TERM = os.environ.get('TERM','dumb')
1196 TERM = os.environ.get('TERM','dumb')
1189 if TERM in ['dumb','emacs'] and os.name != 'nt':
1197 if TERM in ['dumb','emacs'] and os.name != 'nt':
1190 print strng
1198 print strng
1191 return
1199 return
1192 # chop off the topmost part of the string we don't want to see
1200 # chop off the topmost part of the string we don't want to see
1193 str_lines = strng.split(os.linesep)[start:]
1201 str_lines = strng.split(os.linesep)[start:]
1194 str_toprint = os.linesep.join(str_lines)
1202 str_toprint = os.linesep.join(str_lines)
1195 num_newlines = len(str_lines)
1203 num_newlines = len(str_lines)
1196 len_str = len(str_toprint)
1204 len_str = len(str_toprint)
1197
1205
1198 # Dumb heuristics to guesstimate number of on-screen lines the string
1206 # Dumb heuristics to guesstimate number of on-screen lines the string
1199 # takes. Very basic, but good enough for docstrings in reasonable
1207 # takes. Very basic, but good enough for docstrings in reasonable
1200 # terminals. If someone later feels like refining it, it's not hard.
1208 # terminals. If someone later feels like refining it, it's not hard.
1201 numlines = max(num_newlines,int(len_str/80)+1)
1209 numlines = max(num_newlines,int(len_str/80)+1)
1202
1210
1203 screen_lines_def = 25 # default value if we can't auto-determine
1211 screen_lines_def = 25 # default value if we can't auto-determine
1204
1212
1205 # auto-determine screen size
1213 # auto-determine screen size
1206 if screen_lines <= 0:
1214 if screen_lines <= 0:
1207 if TERM=='xterm':
1215 if TERM=='xterm':
1208 try:
1216 try:
1209 import curses
1217 import curses
1210 if hasattr(curses,'initscr'):
1218 if hasattr(curses,'initscr'):
1211 use_curses = 1
1219 use_curses = 1
1212 else:
1220 else:
1213 use_curses = 0
1221 use_curses = 0
1214 except ImportError:
1222 except ImportError:
1215 use_curses = 0
1223 use_curses = 0
1216 else:
1224 else:
1217 # curses causes problems on many terminals other than xterm.
1225 # curses causes problems on many terminals other than xterm.
1218 use_curses = 0
1226 use_curses = 0
1219 if use_curses:
1227 if use_curses:
1220 scr = curses.initscr()
1228 scr = curses.initscr()
1221 screen_lines_real,screen_cols = scr.getmaxyx()
1229 screen_lines_real,screen_cols = scr.getmaxyx()
1222 curses.endwin()
1230 curses.endwin()
1223 screen_lines += screen_lines_real
1231 screen_lines += screen_lines_real
1224 #print '***Screen size:',screen_lines_real,'lines x',\
1232 #print '***Screen size:',screen_lines_real,'lines x',\
1225 #screen_cols,'columns.' # dbg
1233 #screen_cols,'columns.' # dbg
1226 else:
1234 else:
1227 screen_lines += screen_lines_def
1235 screen_lines += screen_lines_def
1228
1236
1229 #print 'numlines',numlines,'screenlines',screen_lines # dbg
1237 #print 'numlines',numlines,'screenlines',screen_lines # dbg
1230 if numlines <= screen_lines :
1238 if numlines <= screen_lines :
1231 #print '*** normal print' # dbg
1239 #print '*** normal print' # dbg
1232 print >>Term.cout, str_toprint
1240 print >>Term.cout, str_toprint
1233 else:
1241 else:
1234 # Try to open pager and default to internal one if that fails.
1242 # Try to open pager and default to internal one if that fails.
1235 # All failure modes are tagged as 'retval=1', to match the return
1243 # All failure modes are tagged as 'retval=1', to match the return
1236 # value of a failed system command. If any intermediate attempt
1244 # value of a failed system command. If any intermediate attempt
1237 # sets retval to 1, at the end we resort to our own page_dumb() pager.
1245 # sets retval to 1, at the end we resort to our own page_dumb() pager.
1238 pager_cmd = get_pager_cmd(pager_cmd)
1246 pager_cmd = get_pager_cmd(pager_cmd)
1239 pager_cmd += ' ' + get_pager_start(pager_cmd,start)
1247 pager_cmd += ' ' + get_pager_start(pager_cmd,start)
1240 if os.name == 'nt':
1248 if os.name == 'nt':
1241 if pager_cmd.startswith('type'):
1249 if pager_cmd.startswith('type'):
1242 # The default WinXP 'type' command is failing on complex strings.
1250 # The default WinXP 'type' command is failing on complex strings.
1243 retval = 1
1251 retval = 1
1244 else:
1252 else:
1245 tmpname = tempfile.mktemp('.txt')
1253 tmpname = tempfile.mktemp('.txt')
1246 tmpfile = file(tmpname,'wt')
1254 tmpfile = file(tmpname,'wt')
1247 tmpfile.write(strng)
1255 tmpfile.write(strng)
1248 tmpfile.close()
1256 tmpfile.close()
1249 cmd = "%s < %s" % (pager_cmd,tmpname)
1257 cmd = "%s < %s" % (pager_cmd,tmpname)
1250 if os.system(cmd):
1258 if os.system(cmd):
1251 retval = 1
1259 retval = 1
1252 else:
1260 else:
1253 retval = None
1261 retval = None
1254 os.remove(tmpname)
1262 os.remove(tmpname)
1255 else:
1263 else:
1256 try:
1264 try:
1257 retval = None
1265 retval = None
1258 # if I use popen4, things hang. No idea why.
1266 # if I use popen4, things hang. No idea why.
1259 #pager,shell_out = os.popen4(pager_cmd)
1267 #pager,shell_out = os.popen4(pager_cmd)
1260 pager = os.popen(pager_cmd,'w')
1268 pager = os.popen(pager_cmd,'w')
1261 pager.write(strng)
1269 pager.write(strng)
1262 pager.close()
1270 pager.close()
1263 retval = pager.close() # success returns None
1271 retval = pager.close() # success returns None
1264 except IOError,msg: # broken pipe when user quits
1272 except IOError,msg: # broken pipe when user quits
1265 if msg.args == (32,'Broken pipe'):
1273 if msg.args == (32,'Broken pipe'):
1266 retval = None
1274 retval = None
1267 else:
1275 else:
1268 retval = 1
1276 retval = 1
1269 except OSError:
1277 except OSError:
1270 # Other strange problems, sometimes seen in Win2k/cygwin
1278 # Other strange problems, sometimes seen in Win2k/cygwin
1271 retval = 1
1279 retval = 1
1272 if retval is not None:
1280 if retval is not None:
1273 page_dumb(strng,screen_lines=screen_lines)
1281 page_dumb(strng,screen_lines=screen_lines)
1274
1282
1275 #----------------------------------------------------------------------------
1283 #----------------------------------------------------------------------------
1276 def page_file(fname,start = 0, pager_cmd = None):
1284 def page_file(fname,start = 0, pager_cmd = None):
1277 """Page a file, using an optional pager command and starting line.
1285 """Page a file, using an optional pager command and starting line.
1278 """
1286 """
1279
1287
1280 pager_cmd = get_pager_cmd(pager_cmd)
1288 pager_cmd = get_pager_cmd(pager_cmd)
1281 pager_cmd += ' ' + get_pager_start(pager_cmd,start)
1289 pager_cmd += ' ' + get_pager_start(pager_cmd,start)
1282
1290
1283 try:
1291 try:
1284 if os.environ['TERM'] in ['emacs','dumb']:
1292 if os.environ['TERM'] in ['emacs','dumb']:
1285 raise EnvironmentError
1293 raise EnvironmentError
1286 xsys(pager_cmd + ' ' + fname)
1294 xsys(pager_cmd + ' ' + fname)
1287 except:
1295 except:
1288 try:
1296 try:
1289 if start > 0:
1297 if start > 0:
1290 start -= 1
1298 start -= 1
1291 page(open(fname).read(),start)
1299 page(open(fname).read(),start)
1292 except:
1300 except:
1293 print 'Unable to show file',`fname`
1301 print 'Unable to show file',`fname`
1294
1302
1295 #----------------------------------------------------------------------------
1303 #----------------------------------------------------------------------------
1296 def snip_print(str,width = 75,print_full = 0,header = ''):
1304 def snip_print(str,width = 75,print_full = 0,header = ''):
1297 """Print a string snipping the midsection to fit in width.
1305 """Print a string snipping the midsection to fit in width.
1298
1306
1299 print_full: mode control:
1307 print_full: mode control:
1300 - 0: only snip long strings
1308 - 0: only snip long strings
1301 - 1: send to page() directly.
1309 - 1: send to page() directly.
1302 - 2: snip long strings and ask for full length viewing with page()
1310 - 2: snip long strings and ask for full length viewing with page()
1303 Return 1 if snipping was necessary, 0 otherwise."""
1311 Return 1 if snipping was necessary, 0 otherwise."""
1304
1312
1305 if print_full == 1:
1313 if print_full == 1:
1306 page(header+str)
1314 page(header+str)
1307 return 0
1315 return 0
1308
1316
1309 print header,
1317 print header,
1310 if len(str) < width:
1318 if len(str) < width:
1311 print str
1319 print str
1312 snip = 0
1320 snip = 0
1313 else:
1321 else:
1314 whalf = int((width -5)/2)
1322 whalf = int((width -5)/2)
1315 print str[:whalf] + ' <...> ' + str[-whalf:]
1323 print str[:whalf] + ' <...> ' + str[-whalf:]
1316 snip = 1
1324 snip = 1
1317 if snip and print_full == 2:
1325 if snip and print_full == 2:
1318 if raw_input(header+' Snipped. View (y/n)? [N]').lower() == 'y':
1326 if raw_input(header+' Snipped. View (y/n)? [N]').lower() == 'y':
1319 page(str)
1327 page(str)
1320 return snip
1328 return snip
1321
1329
1322 #****************************************************************************
1330 #****************************************************************************
1323 # lists, dicts and structures
1331 # lists, dicts and structures
1324
1332
1325 def belong(candidates,checklist):
1333 def belong(candidates,checklist):
1326 """Check whether a list of items appear in a given list of options.
1334 """Check whether a list of items appear in a given list of options.
1327
1335
1328 Returns a list of 1 and 0, one for each candidate given."""
1336 Returns a list of 1 and 0, one for each candidate given."""
1329
1337
1330 return [x in checklist for x in candidates]
1338 return [x in checklist for x in candidates]
1331
1339
1332 #----------------------------------------------------------------------------
1340 #----------------------------------------------------------------------------
1333 def uniq_stable(elems):
1341 def uniq_stable(elems):
1334 """uniq_stable(elems) -> list
1342 """uniq_stable(elems) -> list
1335
1343
1336 Return from an iterable, a list of all the unique elements in the input,
1344 Return from an iterable, a list of all the unique elements in the input,
1337 but maintaining the order in which they first appear.
1345 but maintaining the order in which they first appear.
1338
1346
1339 A naive solution to this problem which just makes a dictionary with the
1347 A naive solution to this problem which just makes a dictionary with the
1340 elements as keys fails to respect the stability condition, since
1348 elements as keys fails to respect the stability condition, since
1341 dictionaries are unsorted by nature.
1349 dictionaries are unsorted by nature.
1342
1350
1343 Note: All elements in the input must be valid dictionary keys for this
1351 Note: All elements in the input must be valid dictionary keys for this
1344 routine to work, as it internally uses a dictionary for efficiency
1352 routine to work, as it internally uses a dictionary for efficiency
1345 reasons."""
1353 reasons."""
1346
1354
1347 unique = []
1355 unique = []
1348 unique_dict = {}
1356 unique_dict = {}
1349 for nn in elems:
1357 for nn in elems:
1350 if nn not in unique_dict:
1358 if nn not in unique_dict:
1351 unique.append(nn)
1359 unique.append(nn)
1352 unique_dict[nn] = None
1360 unique_dict[nn] = None
1353 return unique
1361 return unique
1354
1362
1355 #----------------------------------------------------------------------------
1363 #----------------------------------------------------------------------------
1356 class NLprinter:
1364 class NLprinter:
1357 """Print an arbitrarily nested list, indicating index numbers.
1365 """Print an arbitrarily nested list, indicating index numbers.
1358
1366
1359 An instance of this class called nlprint is available and callable as a
1367 An instance of this class called nlprint is available and callable as a
1360 function.
1368 function.
1361
1369
1362 nlprint(list,indent=' ',sep=': ') -> prints indenting each level by 'indent'
1370 nlprint(list,indent=' ',sep=': ') -> prints indenting each level by 'indent'
1363 and using 'sep' to separate the index from the value. """
1371 and using 'sep' to separate the index from the value. """
1364
1372
1365 def __init__(self):
1373 def __init__(self):
1366 self.depth = 0
1374 self.depth = 0
1367
1375
1368 def __call__(self,lst,pos='',**kw):
1376 def __call__(self,lst,pos='',**kw):
1369 """Prints the nested list numbering levels."""
1377 """Prints the nested list numbering levels."""
1370 kw.setdefault('indent',' ')
1378 kw.setdefault('indent',' ')
1371 kw.setdefault('sep',': ')
1379 kw.setdefault('sep',': ')
1372 kw.setdefault('start',0)
1380 kw.setdefault('start',0)
1373 kw.setdefault('stop',len(lst))
1381 kw.setdefault('stop',len(lst))
1374 # we need to remove start and stop from kw so they don't propagate
1382 # we need to remove start and stop from kw so they don't propagate
1375 # into a recursive call for a nested list.
1383 # into a recursive call for a nested list.
1376 start = kw['start']; del kw['start']
1384 start = kw['start']; del kw['start']
1377 stop = kw['stop']; del kw['stop']
1385 stop = kw['stop']; del kw['stop']
1378 if self.depth == 0 and 'header' in kw.keys():
1386 if self.depth == 0 and 'header' in kw.keys():
1379 print kw['header']
1387 print kw['header']
1380
1388
1381 for idx in range(start,stop):
1389 for idx in range(start,stop):
1382 elem = lst[idx]
1390 elem = lst[idx]
1383 if type(elem)==type([]):
1391 if type(elem)==type([]):
1384 self.depth += 1
1392 self.depth += 1
1385 self.__call__(elem,itpl('$pos$idx,'),**kw)
1393 self.__call__(elem,itpl('$pos$idx,'),**kw)
1386 self.depth -= 1
1394 self.depth -= 1
1387 else:
1395 else:
1388 printpl(kw['indent']*self.depth+'$pos$idx$kw["sep"]$elem')
1396 printpl(kw['indent']*self.depth+'$pos$idx$kw["sep"]$elem')
1389
1397
1390 nlprint = NLprinter()
1398 nlprint = NLprinter()
1391 #----------------------------------------------------------------------------
1399 #----------------------------------------------------------------------------
1392 def all_belong(candidates,checklist):
1400 def all_belong(candidates,checklist):
1393 """Check whether a list of items ALL appear in a given list of options.
1401 """Check whether a list of items ALL appear in a given list of options.
1394
1402
1395 Returns a single 1 or 0 value."""
1403 Returns a single 1 or 0 value."""
1396
1404
1397 return 1-(0 in [x in checklist for x in candidates])
1405 return 1-(0 in [x in checklist for x in candidates])
1398
1406
1399 #----------------------------------------------------------------------------
1407 #----------------------------------------------------------------------------
1400 def sort_compare(lst1,lst2,inplace = 1):
1408 def sort_compare(lst1,lst2,inplace = 1):
1401 """Sort and compare two lists.
1409 """Sort and compare two lists.
1402
1410
1403 By default it does it in place, thus modifying the lists. Use inplace = 0
1411 By default it does it in place, thus modifying the lists. Use inplace = 0
1404 to avoid that (at the cost of temporary copy creation)."""
1412 to avoid that (at the cost of temporary copy creation)."""
1405 if not inplace:
1413 if not inplace:
1406 lst1 = lst1[:]
1414 lst1 = lst1[:]
1407 lst2 = lst2[:]
1415 lst2 = lst2[:]
1408 lst1.sort(); lst2.sort()
1416 lst1.sort(); lst2.sort()
1409 return lst1 == lst2
1417 return lst1 == lst2
1410
1418
1411 #----------------------------------------------------------------------------
1419 #----------------------------------------------------------------------------
1412 def mkdict(**kwargs):
1420 def mkdict(**kwargs):
1413 """Return a dict from a keyword list.
1421 """Return a dict from a keyword list.
1414
1422
1415 It's just syntactic sugar for making ditcionary creation more convenient:
1423 It's just syntactic sugar for making ditcionary creation more convenient:
1416 # the standard way
1424 # the standard way
1417 >>>data = { 'red' : 1, 'green' : 2, 'blue' : 3 }
1425 >>>data = { 'red' : 1, 'green' : 2, 'blue' : 3 }
1418 # a cleaner way
1426 # a cleaner way
1419 >>>data = dict(red=1, green=2, blue=3)
1427 >>>data = dict(red=1, green=2, blue=3)
1420
1428
1421 If you need more than this, look at the Struct() class."""
1429 If you need more than this, look at the Struct() class."""
1422
1430
1423 return kwargs
1431 return kwargs
1424
1432
1425 #----------------------------------------------------------------------------
1433 #----------------------------------------------------------------------------
1426 def list2dict(lst):
1434 def list2dict(lst):
1427 """Takes a list of (key,value) pairs and turns it into a dict."""
1435 """Takes a list of (key,value) pairs and turns it into a dict."""
1428
1436
1429 dic = {}
1437 dic = {}
1430 for k,v in lst: dic[k] = v
1438 for k,v in lst: dic[k] = v
1431 return dic
1439 return dic
1432
1440
1433 #----------------------------------------------------------------------------
1441 #----------------------------------------------------------------------------
1434 def list2dict2(lst,default=''):
1442 def list2dict2(lst,default=''):
1435 """Takes a list and turns it into a dict.
1443 """Takes a list and turns it into a dict.
1436 Much slower than list2dict, but more versatile. This version can take
1444 Much slower than list2dict, but more versatile. This version can take
1437 lists with sublists of arbitrary length (including sclars)."""
1445 lists with sublists of arbitrary length (including sclars)."""
1438
1446
1439 dic = {}
1447 dic = {}
1440 for elem in lst:
1448 for elem in lst:
1441 if type(elem) in (types.ListType,types.TupleType):
1449 if type(elem) in (types.ListType,types.TupleType):
1442 size = len(elem)
1450 size = len(elem)
1443 if size == 0:
1451 if size == 0:
1444 pass
1452 pass
1445 elif size == 1:
1453 elif size == 1:
1446 dic[elem] = default
1454 dic[elem] = default
1447 else:
1455 else:
1448 k,v = elem[0], elem[1:]
1456 k,v = elem[0], elem[1:]
1449 if len(v) == 1: v = v[0]
1457 if len(v) == 1: v = v[0]
1450 dic[k] = v
1458 dic[k] = v
1451 else:
1459 else:
1452 dic[elem] = default
1460 dic[elem] = default
1453 return dic
1461 return dic
1454
1462
1455 #----------------------------------------------------------------------------
1463 #----------------------------------------------------------------------------
1456 def flatten(seq):
1464 def flatten(seq):
1457 """Flatten a list of lists (NOT recursive, only works for 2d lists)."""
1465 """Flatten a list of lists (NOT recursive, only works for 2d lists)."""
1458
1466
1459 # bug in python??? (YES. Fixed in 2.2, let's leave the kludgy fix in).
1467 # bug in python??? (YES. Fixed in 2.2, let's leave the kludgy fix in).
1460
1468
1461 # if the x=0 isn't made, a *global* variable x is left over after calling
1469 # if the x=0 isn't made, a *global* variable x is left over after calling
1462 # this function, with the value of the last element in the return
1470 # this function, with the value of the last element in the return
1463 # list. This does seem like a bug big time to me.
1471 # list. This does seem like a bug big time to me.
1464
1472
1465 # the problem is fixed with the x=0, which seems to force the creation of
1473 # the problem is fixed with the x=0, which seems to force the creation of
1466 # a local name
1474 # a local name
1467
1475
1468 x = 0
1476 x = 0
1469 return [x for subseq in seq for x in subseq]
1477 return [x for subseq in seq for x in subseq]
1470
1478
1471 #----------------------------------------------------------------------------
1479 #----------------------------------------------------------------------------
1472 def get_slice(seq,start=0,stop=None,step=1):
1480 def get_slice(seq,start=0,stop=None,step=1):
1473 """Get a slice of a sequence with variable step. Specify start,stop,step."""
1481 """Get a slice of a sequence with variable step. Specify start,stop,step."""
1474 if stop == None:
1482 if stop == None:
1475 stop = len(seq)
1483 stop = len(seq)
1476 item = lambda i: seq[i]
1484 item = lambda i: seq[i]
1477 return map(item,xrange(start,stop,step))
1485 return map(item,xrange(start,stop,step))
1478
1486
1479 #----------------------------------------------------------------------------
1487 #----------------------------------------------------------------------------
1480 def chop(seq,size):
1488 def chop(seq,size):
1481 """Chop a sequence into chunks of the given size."""
1489 """Chop a sequence into chunks of the given size."""
1482 chunk = lambda i: seq[i:i+size]
1490 chunk = lambda i: seq[i:i+size]
1483 return map(chunk,xrange(0,len(seq),size))
1491 return map(chunk,xrange(0,len(seq),size))
1484
1492
1485 #----------------------------------------------------------------------------
1493 #----------------------------------------------------------------------------
1486 def with(object, **args):
1494 def with(object, **args):
1487 """Set multiple attributes for an object, similar to Pascal's with.
1495 """Set multiple attributes for an object, similar to Pascal's with.
1488
1496
1489 Example:
1497 Example:
1490 with(jim,
1498 with(jim,
1491 born = 1960,
1499 born = 1960,
1492 haircolour = 'Brown',
1500 haircolour = 'Brown',
1493 eyecolour = 'Green')
1501 eyecolour = 'Green')
1494
1502
1495 Credit: Greg Ewing, in
1503 Credit: Greg Ewing, in
1496 http://mail.python.org/pipermail/python-list/2001-May/040703.html"""
1504 http://mail.python.org/pipermail/python-list/2001-May/040703.html"""
1497
1505
1498 object.__dict__.update(args)
1506 object.__dict__.update(args)
1499
1507
1500 #----------------------------------------------------------------------------
1508 #----------------------------------------------------------------------------
1501 def setattr_list(obj,alist,nspace = None):
1509 def setattr_list(obj,alist,nspace = None):
1502 """Set a list of attributes for an object taken from a namespace.
1510 """Set a list of attributes for an object taken from a namespace.
1503
1511
1504 setattr_list(obj,alist,nspace) -> sets in obj all the attributes listed in
1512 setattr_list(obj,alist,nspace) -> sets in obj all the attributes listed in
1505 alist with their values taken from nspace, which must be a dict (something
1513 alist with their values taken from nspace, which must be a dict (something
1506 like locals() will often do) If nspace isn't given, locals() of the
1514 like locals() will often do) If nspace isn't given, locals() of the
1507 *caller* is used, so in most cases you can omit it.
1515 *caller* is used, so in most cases you can omit it.
1508
1516
1509 Note that alist can be given as a string, which will be automatically
1517 Note that alist can be given as a string, which will be automatically
1510 split into a list on whitespace. If given as a list, it must be a list of
1518 split into a list on whitespace. If given as a list, it must be a list of
1511 *strings* (the variable names themselves), not of variables."""
1519 *strings* (the variable names themselves), not of variables."""
1512
1520
1513 # this grabs the local variables from the *previous* call frame -- that is
1521 # this grabs the local variables from the *previous* call frame -- that is
1514 # the locals from the function that called setattr_list().
1522 # the locals from the function that called setattr_list().
1515 # - snipped from weave.inline()
1523 # - snipped from weave.inline()
1516 if nspace is None:
1524 if nspace is None:
1517 call_frame = sys._getframe().f_back
1525 call_frame = sys._getframe().f_back
1518 nspace = call_frame.f_locals
1526 nspace = call_frame.f_locals
1519
1527
1520 if type(alist) in StringTypes:
1528 if type(alist) in StringTypes:
1521 alist = alist.split()
1529 alist = alist.split()
1522 for attr in alist:
1530 for attr in alist:
1523 val = eval(attr,nspace)
1531 val = eval(attr,nspace)
1524 setattr(obj,attr,val)
1532 setattr(obj,attr,val)
1525
1533
1526 #----------------------------------------------------------------------------
1534 #----------------------------------------------------------------------------
1527 def getattr_list(obj,alist,*args):
1535 def getattr_list(obj,alist,*args):
1528 """getattr_list(obj,alist[, default]) -> attribute list.
1536 """getattr_list(obj,alist[, default]) -> attribute list.
1529
1537
1530 Get a list of named attributes for an object. When a default argument is
1538 Get a list of named attributes for an object. When a default argument is
1531 given, it is returned when the attribute doesn't exist; without it, an
1539 given, it is returned when the attribute doesn't exist; without it, an
1532 exception is raised in that case.
1540 exception is raised in that case.
1533
1541
1534 Note that alist can be given as a string, which will be automatically
1542 Note that alist can be given as a string, which will be automatically
1535 split into a list on whitespace. If given as a list, it must be a list of
1543 split into a list on whitespace. If given as a list, it must be a list of
1536 *strings* (the variable names themselves), not of variables."""
1544 *strings* (the variable names themselves), not of variables."""
1537
1545
1538 if type(alist) in StringTypes:
1546 if type(alist) in StringTypes:
1539 alist = alist.split()
1547 alist = alist.split()
1540 if args:
1548 if args:
1541 if len(args)==1:
1549 if len(args)==1:
1542 default = args[0]
1550 default = args[0]
1543 return map(lambda attr: getattr(obj,attr,default),alist)
1551 return map(lambda attr: getattr(obj,attr,default),alist)
1544 else:
1552 else:
1545 raise ValueError,'getattr_list() takes only one optional argument'
1553 raise ValueError,'getattr_list() takes only one optional argument'
1546 else:
1554 else:
1547 return map(lambda attr: getattr(obj,attr),alist)
1555 return map(lambda attr: getattr(obj,attr),alist)
1548
1556
1549 #----------------------------------------------------------------------------
1557 #----------------------------------------------------------------------------
1550 def map_method(method,object_list,*argseq,**kw):
1558 def map_method(method,object_list,*argseq,**kw):
1551 """map_method(method,object_list,*args,**kw) -> list
1559 """map_method(method,object_list,*args,**kw) -> list
1552
1560
1553 Return a list of the results of applying the methods to the items of the
1561 Return a list of the results of applying the methods to the items of the
1554 argument sequence(s). If more than one sequence is given, the method is
1562 argument sequence(s). If more than one sequence is given, the method is
1555 called with an argument list consisting of the corresponding item of each
1563 called with an argument list consisting of the corresponding item of each
1556 sequence. All sequences must be of the same length.
1564 sequence. All sequences must be of the same length.
1557
1565
1558 Keyword arguments are passed verbatim to all objects called.
1566 Keyword arguments are passed verbatim to all objects called.
1559
1567
1560 This is Python code, so it's not nearly as fast as the builtin map()."""
1568 This is Python code, so it's not nearly as fast as the builtin map()."""
1561
1569
1562 out_list = []
1570 out_list = []
1563 idx = 0
1571 idx = 0
1564 for object in object_list:
1572 for object in object_list:
1565 try:
1573 try:
1566 handler = getattr(object, method)
1574 handler = getattr(object, method)
1567 except AttributeError:
1575 except AttributeError:
1568 out_list.append(None)
1576 out_list.append(None)
1569 else:
1577 else:
1570 if argseq:
1578 if argseq:
1571 args = map(lambda lst:lst[idx],argseq)
1579 args = map(lambda lst:lst[idx],argseq)
1572 #print 'ob',object,'hand',handler,'ar',args # dbg
1580 #print 'ob',object,'hand',handler,'ar',args # dbg
1573 out_list.append(handler(args,**kw))
1581 out_list.append(handler(args,**kw))
1574 else:
1582 else:
1575 out_list.append(handler(**kw))
1583 out_list.append(handler(**kw))
1576 idx += 1
1584 idx += 1
1577 return out_list
1585 return out_list
1578
1586
1579 #----------------------------------------------------------------------------
1587 #----------------------------------------------------------------------------
1580 # Proposed popitem() extension, written as a method
1588 # Proposed popitem() extension, written as a method
1581
1589
1582 class NotGiven: pass
1590 class NotGiven: pass
1583
1591
1584 def popkey(dct,key,default=NotGiven):
1592 def popkey(dct,key,default=NotGiven):
1585 """Return dct[key] and delete dct[key].
1593 """Return dct[key] and delete dct[key].
1586
1594
1587 If default is given, return it if dct[key] doesn't exist, otherwise raise
1595 If default is given, return it if dct[key] doesn't exist, otherwise raise
1588 KeyError. """
1596 KeyError. """
1589
1597
1590 try:
1598 try:
1591 val = dct[key]
1599 val = dct[key]
1592 except KeyError:
1600 except KeyError:
1593 if default is NotGiven:
1601 if default is NotGiven:
1594 raise
1602 raise
1595 else:
1603 else:
1596 return default
1604 return default
1597 else:
1605 else:
1598 del dct[key]
1606 del dct[key]
1599 return val
1607 return val
1600 #*************************** end of file <genutils.py> **********************
1608 #*************************** end of file <genutils.py> **********************
1601
1609
@@ -1,1887 +1,1883 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 IPython -- An enhanced Interactive Python
3 IPython -- An enhanced Interactive Python
4
4
5 Requires Python 2.1 or newer.
5 Requires Python 2.1 or newer.
6
6
7 This file contains all the classes and helper functions specific to IPython.
7 This file contains all the classes and helper functions specific to IPython.
8
8
9 $Id: iplib.py 957 2005-12-27 22:33:22Z fperez $
9 $Id: iplib.py 958 2005-12-27 23:17:51Z fperez $
10 """
10 """
11
11
12 #*****************************************************************************
12 #*****************************************************************************
13 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de> and
13 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de> and
14 # Copyright (C) 2001-2005 Fernando Perez. <fperez@colorado.edu>
14 # Copyright (C) 2001-2005 Fernando Perez. <fperez@colorado.edu>
15 #
15 #
16 # Distributed under the terms of the BSD License. The full license is in
16 # Distributed under the terms of the BSD License. The full license is in
17 # the file COPYING, distributed as part of this software.
17 # the file COPYING, distributed as part of this software.
18 #
18 #
19 # Note: this code originally subclassed code.InteractiveConsole from the
19 # Note: this code originally subclassed code.InteractiveConsole from the
20 # Python standard library. Over time, all of that class has been copied
20 # Python standard library. Over time, all of that class has been copied
21 # verbatim here for modifications which could not be accomplished by
21 # verbatim here for modifications which could not be accomplished by
22 # subclassing. At this point, there are no dependencies at all on the code
22 # subclassing. At this point, there are no dependencies at all on the code
23 # module anymore (it is not even imported). The Python License (sec. 2)
23 # module anymore (it is not even imported). The Python License (sec. 2)
24 # allows for this, but it's always nice to acknowledge credit where credit is
24 # allows for this, but it's always nice to acknowledge credit where credit is
25 # due.
25 # due.
26 #*****************************************************************************
26 #*****************************************************************************
27
27
28 #****************************************************************************
28 #****************************************************************************
29 # Modules and globals
29 # Modules and globals
30
30
31 from __future__ import generators # for 2.2 backwards-compatibility
31 from __future__ import generators # for 2.2 backwards-compatibility
32
32
33 from IPython import Release
33 from IPython import Release
34 __author__ = '%s <%s>\n%s <%s>' % \
34 __author__ = '%s <%s>\n%s <%s>' % \
35 ( Release.authors['Janko'] + Release.authors['Fernando'] )
35 ( Release.authors['Janko'] + Release.authors['Fernando'] )
36 __license__ = Release.license
36 __license__ = Release.license
37 __version__ = Release.version
37 __version__ = Release.version
38
38
39 # Python standard modules
39 # Python standard modules
40 import __main__
40 import __main__
41 import __builtin__
41 import __builtin__
42 import bdb
42 import bdb
43 import codeop
43 import codeop
44 import cPickle as pickle
44 import cPickle as pickle
45 import exceptions
45 import exceptions
46 import glob
46 import glob
47 import inspect
47 import inspect
48 import keyword
48 import keyword
49 import new
49 import new
50 import os
50 import os
51 import pdb
51 import pdb
52 import pydoc
52 import pydoc
53 import re
53 import re
54 import shutil
54 import shutil
55 import string
55 import string
56 import StringIO
56 import StringIO
57 import sys
57 import sys
58 import traceback
58 import traceback
59 import types
59 import types
60
60
61 from pprint import pprint, pformat
61 from pprint import pprint, pformat
62
62
63 # IPython's own modules
63 # IPython's own modules
64 import IPython
64 import IPython
65 from IPython import OInspect,PyColorize,ultraTB
65 from IPython import OInspect,PyColorize,ultraTB
66 from IPython.ColorANSI import ColorScheme,ColorSchemeTable # too long names
66 from IPython.ColorANSI import ColorScheme,ColorSchemeTable # too long names
67 from IPython.FakeModule import FakeModule
68 from IPython.Itpl import Itpl,itpl,printpl,ItplNS,itplns
67 from IPython.Logger import Logger
69 from IPython.Logger import Logger
68 from IPython.Magic import Magic,magic2python
70 from IPython.Magic import Magic,magic2python
69 from IPython.usage import cmd_line_usage,interactive_usage
70 from IPython.Struct import Struct
71 from IPython.Struct import Struct
71 from IPython.Itpl import Itpl,itpl,printpl,ItplNS,itplns
72 from IPython.FakeModule import FakeModule
73 from IPython.background_jobs import BackgroundJobManager
72 from IPython.background_jobs import BackgroundJobManager
74 from IPython.PyColorize import Parser
73 from IPython.usage import cmd_line_usage,interactive_usage
75 from IPython.genutils import *
74 from IPython.genutils import *
76
75
77 # Global pointer to the running
78
79 # store the builtin raw_input globally, and use this always, in case user code
76 # store the builtin raw_input globally, and use this always, in case user code
80 # overwrites it (like wx.py.PyShell does)
77 # overwrites it (like wx.py.PyShell does)
81 raw_input_original = raw_input
78 raw_input_original = raw_input
82
79
83 #****************************************************************************
80 #****************************************************************************
84 # Some utility function definitions
81 # Some utility function definitions
85
82
86 def esc_quotes(strng):
83 def esc_quotes(strng):
87 """Return the input string with single and double quotes escaped out"""
84 """Return the input string with single and double quotes escaped out"""
88
85
89 return strng.replace('"','\\"').replace("'","\\'")
86 return strng.replace('"','\\"').replace("'","\\'")
90
87
91 def import_fail_info(mod_name,fns=None):
88 def import_fail_info(mod_name,fns=None):
92 """Inform load failure for a module."""
89 """Inform load failure for a module."""
93
90
94 if fns == None:
91 if fns == None:
95 warn("Loading of %s failed.\n" % (mod_name,))
92 warn("Loading of %s failed.\n" % (mod_name,))
96 else:
93 else:
97 warn("Loading of %s from %s failed.\n" % (fns,mod_name))
94 warn("Loading of %s from %s failed.\n" % (fns,mod_name))
98
95
99 def qw_lol(indata):
96 def qw_lol(indata):
100 """qw_lol('a b') -> [['a','b']],
97 """qw_lol('a b') -> [['a','b']],
101 otherwise it's just a call to qw().
98 otherwise it's just a call to qw().
102
99
103 We need this to make sure the modules_some keys *always* end up as a
100 We need this to make sure the modules_some keys *always* end up as a
104 list of lists."""
101 list of lists."""
105
102
106 if type(indata) in StringTypes:
103 if type(indata) in StringTypes:
107 return [qw(indata)]
104 return [qw(indata)]
108 else:
105 else:
109 return qw(indata)
106 return qw(indata)
110
107
111 def ipmagic(arg_s):
108 def ipmagic(arg_s):
112 """Call a magic function by name.
109 """Call a magic function by name.
113
110
114 Input: a string containing the name of the magic function to call and any
111 Input: a string containing the name of the magic function to call and any
115 additional arguments to be passed to the magic.
112 additional arguments to be passed to the magic.
116
113
117 ipmagic('name -opt foo bar') is equivalent to typing at the ipython
114 ipmagic('name -opt foo bar') is equivalent to typing at the ipython
118 prompt:
115 prompt:
119
116
120 In[1]: %name -opt foo bar
117 In[1]: %name -opt foo bar
121
118
122 To call a magic without arguments, simply use ipmagic('name').
119 To call a magic without arguments, simply use ipmagic('name').
123
120
124 This provides a proper Python function to call IPython's magics in any
121 This provides a proper Python function to call IPython's magics in any
125 valid Python code you can type at the interpreter, including loops and
122 valid Python code you can type at the interpreter, including loops and
126 compound statements. It is added by IPython to the Python builtin
123 compound statements. It is added by IPython to the Python builtin
127 namespace upon initialization."""
124 namespace upon initialization."""
128
125
129 args = arg_s.split(' ',1)
126 args = arg_s.split(' ',1)
130 magic_name = args[0]
127 magic_name = args[0]
131 if magic_name.startswith(__IPYTHON__.ESC_MAGIC):
128 if magic_name.startswith(__IPYTHON__.ESC_MAGIC):
132 magic_name = magic_name[1:]
129 magic_name = magic_name[1:]
133 try:
130 try:
134 magic_args = args[1]
131 magic_args = args[1]
135 except IndexError:
132 except IndexError:
136 magic_args = ''
133 magic_args = ''
137 fn = getattr(__IPYTHON__,'magic_'+magic_name,None)
134 fn = getattr(__IPYTHON__,'magic_'+magic_name,None)
138 if fn is None:
135 if fn is None:
139 error("Magic function `%s` not found." % magic_name)
136 error("Magic function `%s` not found." % magic_name)
140 else:
137 else:
141 magic_args = __IPYTHON__.var_expand(magic_args)
138 magic_args = __IPYTHON__.var_expand(magic_args)
142 return fn(magic_args)
139 return fn(magic_args)
143
140
144 def ipalias(arg_s):
141 def ipalias(arg_s):
145 """Call an alias by name.
142 """Call an alias by name.
146
143
147 Input: a string containing the name of the alias to call and any
144 Input: a string containing the name of the alias to call and any
148 additional arguments to be passed to the magic.
145 additional arguments to be passed to the magic.
149
146
150 ipalias('name -opt foo bar') is equivalent to typing at the ipython
147 ipalias('name -opt foo bar') is equivalent to typing at the ipython
151 prompt:
148 prompt:
152
149
153 In[1]: name -opt foo bar
150 In[1]: name -opt foo bar
154
151
155 To call an alias without arguments, simply use ipalias('name').
152 To call an alias without arguments, simply use ipalias('name').
156
153
157 This provides a proper Python function to call IPython's aliases in any
154 This provides a proper Python function to call IPython's aliases in any
158 valid Python code you can type at the interpreter, including loops and
155 valid Python code you can type at the interpreter, including loops and
159 compound statements. It is added by IPython to the Python builtin
156 compound statements. It is added by IPython to the Python builtin
160 namespace upon initialization."""
157 namespace upon initialization."""
161
158
162 args = arg_s.split(' ',1)
159 args = arg_s.split(' ',1)
163 alias_name = args[0]
160 alias_name = args[0]
164 try:
161 try:
165 alias_args = args[1]
162 alias_args = args[1]
166 except IndexError:
163 except IndexError:
167 alias_args = ''
164 alias_args = ''
168 if alias_name in __IPYTHON__.alias_table:
165 if alias_name in __IPYTHON__.alias_table:
169 __IPYTHON__.call_alias(alias_name,alias_args)
166 __IPYTHON__.call_alias(alias_name,alias_args)
170 else:
167 else:
171 error("Alias `%s` not found." % alias_name)
168 error("Alias `%s` not found." % alias_name)
172
169
173 def softspace(file, newvalue):
170 def softspace(file, newvalue):
174 """Copied from code.py, to remove the dependency"""
171 """Copied from code.py, to remove the dependency"""
175 oldvalue = 0
172 oldvalue = 0
176 try:
173 try:
177 oldvalue = file.softspace
174 oldvalue = file.softspace
178 except AttributeError:
175 except AttributeError:
179 pass
176 pass
180 try:
177 try:
181 file.softspace = newvalue
178 file.softspace = newvalue
182 except (AttributeError, TypeError):
179 except (AttributeError, TypeError):
183 # "attribute-less object" or "read-only attributes"
180 # "attribute-less object" or "read-only attributes"
184 pass
181 pass
185 return oldvalue
182 return oldvalue
186
183
187
184
188 #****************************************************************************
185 #****************************************************************************
189 # Local use exceptions
186 # Local use exceptions
190 class SpaceInInput(exceptions.Exception): pass
187 class SpaceInInput(exceptions.Exception): pass
191
188
192 class IPythonExit(exceptions.Exception): pass
189 class IPythonExit(exceptions.Exception): pass
193
190
194 #****************************************************************************
191 #****************************************************************************
195 # Local use classes
192 # Local use classes
196 class Bunch: pass
193 class Bunch: pass
197
194
198 class InputList(list):
195 class InputList(list):
199 """Class to store user input.
196 """Class to store user input.
200
197
201 It's basically a list, but slices return a string instead of a list, thus
198 It's basically a list, but slices return a string instead of a list, thus
202 allowing things like (assuming 'In' is an instance):
199 allowing things like (assuming 'In' is an instance):
203
200
204 exec In[4:7]
201 exec In[4:7]
205
202
206 or
203 or
207
204
208 exec In[5:9] + In[14] + In[21:25]"""
205 exec In[5:9] + In[14] + In[21:25]"""
209
206
210 def __getslice__(self,i,j):
207 def __getslice__(self,i,j):
211 return ''.join(list.__getslice__(self,i,j))
208 return ''.join(list.__getslice__(self,i,j))
212
209
213 #****************************************************************************
210 #****************************************************************************
214 # Main IPython class
211 # Main IPython class
215 class InteractiveShell(Logger, Magic):
212 class InteractiveShell(Logger, Magic):
216 """An enhanced console for Python."""
213 """An enhanced console for Python."""
217
214
218 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
215 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
219 user_ns = None,user_global_ns=None,banner2='',
216 user_ns = None,user_global_ns=None,banner2='',
220 custom_exceptions=((),None),embedded=False):
217 custom_exceptions=((),None),embedded=False):
221
218
222 # Put a reference to self in builtins so that any form of embedded or
219 # Put a reference to self in builtins so that any form of embedded or
223 # imported code can test for being inside IPython.
220 # imported code can test for being inside IPython.
224 __builtin__.__IPYTHON__ = self
221 __builtin__.__IPYTHON__ = self
225
222
226 # And load into builtins ipmagic/ipalias as well
223 # And load into builtins ipmagic/ipalias as well
227 __builtin__.ipmagic = ipmagic
224 __builtin__.ipmagic = ipmagic
228 __builtin__.ipalias = ipalias
225 __builtin__.ipalias = ipalias
229
226
230 # Add to __builtin__ other parts of IPython's public API
227 # Add to __builtin__ other parts of IPython's public API
231 __builtin__.ip_set_hook = self.set_hook
228 __builtin__.ip_set_hook = self.set_hook
232
229
233 # Keep in the builtins a flag for when IPython is active. We set it
230 # Keep in the builtins a flag for when IPython is active. We set it
234 # with setdefault so that multiple nested IPythons don't clobber one
231 # with setdefault so that multiple nested IPythons don't clobber one
235 # another. Each will increase its value by one upon being activated,
232 # another. Each will increase its value by one upon being activated,
236 # which also gives us a way to determine the nesting level.
233 # which also gives us a way to determine the nesting level.
237 __builtin__.__dict__.setdefault('__IPYTHON__active',0)
234 __builtin__.__dict__.setdefault('__IPYTHON__active',0)
238
235
239 # Do the intuitively correct thing for quit/exit: we remove the
236 # Do the intuitively correct thing for quit/exit: we remove the
240 # builtins if they exist, and our own prefilter routine will handle
237 # builtins if they exist, and our own prefilter routine will handle
241 # these special cases
238 # these special cases
242 try:
239 try:
243 del __builtin__.exit, __builtin__.quit
240 del __builtin__.exit, __builtin__.quit
244 except AttributeError:
241 except AttributeError:
245 pass
242 pass
246
243
247 # We need to know whether the instance is meant for embedding, since
244 # We need to know whether the instance is meant for embedding, since
248 # global/local namespaces need to be handled differently in that case
245 # global/local namespaces need to be handled differently in that case
249 self.embedded = embedded
246 self.embedded = embedded
250
247
251 # compiler command
248 # compiler command
252 self.compile = codeop.CommandCompiler()
249 self.compile = codeop.CommandCompiler()
253
250
254 # User input buffer
251 # User input buffer
255 self.buffer = []
252 self.buffer = []
256
253
257 # Default name given in compilation of code
254 # Default name given in compilation of code
258 self.filename = '<ipython console>'
255 self.filename = '<ipython console>'
259
256
260 # Create the namespace where the user will operate. user_ns is
257 # Create the namespace where the user will operate. user_ns is
261 # normally the only one used, and it is passed to the exec calls as
258 # normally the only one used, and it is passed to the exec calls as
262 # the locals argument. But we do carry a user_global_ns namespace
259 # the locals argument. But we do carry a user_global_ns namespace
263 # given as the exec 'globals' argument, This is useful in embedding
260 # given as the exec 'globals' argument, This is useful in embedding
264 # situations where the ipython shell opens in a context where the
261 # situations where the ipython shell opens in a context where the
265 # distinction between locals and globals is meaningful.
262 # distinction between locals and globals is meaningful.
266
263
267 # FIXME. For some strange reason, __builtins__ is showing up at user
264 # FIXME. For some strange reason, __builtins__ is showing up at user
268 # level as a dict instead of a module. This is a manual fix, but I
265 # level as a dict instead of a module. This is a manual fix, but I
269 # should really track down where the problem is coming from. Alex
266 # should really track down where the problem is coming from. Alex
270 # Schmolck reported this problem first.
267 # Schmolck reported this problem first.
271
268
272 # A useful post by Alex Martelli on this topic:
269 # A useful post by Alex Martelli on this topic:
273 # Re: inconsistent value from __builtins__
270 # Re: inconsistent value from __builtins__
274 # Von: Alex Martelli <aleaxit@yahoo.com>
271 # Von: Alex Martelli <aleaxit@yahoo.com>
275 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
272 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
276 # Gruppen: comp.lang.python
273 # Gruppen: comp.lang.python
277 # Referenzen: 1
274 # Referenzen: 1
278
275
279 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
276 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
280 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
277 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
281 # > <type 'dict'>
278 # > <type 'dict'>
282 # > >>> print type(__builtins__)
279 # > >>> print type(__builtins__)
283 # > <type 'module'>
280 # > <type 'module'>
284 # > Is this difference in return value intentional?
281 # > Is this difference in return value intentional?
285
282
286 # Well, it's documented that '__builtins__' can be either a dictionary
283 # Well, it's documented that '__builtins__' can be either a dictionary
287 # or a module, and it's been that way for a long time. Whether it's
284 # or a module, and it's been that way for a long time. Whether it's
288 # intentional (or sensible), I don't know. In any case, the idea is
285 # intentional (or sensible), I don't know. In any case, the idea is
289 # that if you need to access the built-in namespace directly, you
286 # that if you need to access the built-in namespace directly, you
290 # should start with "import __builtin__" (note, no 's') which will
287 # should start with "import __builtin__" (note, no 's') which will
291 # definitely give you a module. Yeah, it's somewhat confusing:-(.
288 # definitely give you a module. Yeah, it's somewhat confusing:-(.
292
289
293 if user_ns is None:
290 if user_ns is None:
294 # Set __name__ to __main__ to better match the behavior of the
291 # Set __name__ to __main__ to better match the behavior of the
295 # normal interpreter.
292 # normal interpreter.
296 user_ns = {'__name__' :'__main__',
293 user_ns = {'__name__' :'__main__',
297 '__builtins__' : __builtin__,
294 '__builtins__' : __builtin__,
298 }
295 }
299
296
300 if user_global_ns is None:
297 if user_global_ns is None:
301 user_global_ns = {}
298 user_global_ns = {}
302
299
303 # Assign namespaces
300 # Assign namespaces
304 # This is the namespace where all normal user variables live
301 # This is the namespace where all normal user variables live
305 self.user_ns = user_ns
302 self.user_ns = user_ns
306 # Embedded instances require a separate namespace for globals.
303 # Embedded instances require a separate namespace for globals.
307 # Normally this one is unused by non-embedded instances.
304 # Normally this one is unused by non-embedded instances.
308 self.user_global_ns = user_global_ns
305 self.user_global_ns = user_global_ns
309 # A namespace to keep track of internal data structures to prevent
306 # A namespace to keep track of internal data structures to prevent
310 # them from cluttering user-visible stuff. Will be updated later
307 # them from cluttering user-visible stuff. Will be updated later
311 self.internal_ns = {}
308 self.internal_ns = {}
312
309
313 # Namespace of system aliases. Each entry in the alias
310 # Namespace of system aliases. Each entry in the alias
314 # table must be a 2-tuple of the form (N,name), where N is the number
311 # table must be a 2-tuple of the form (N,name), where N is the number
315 # of positional arguments of the alias.
312 # of positional arguments of the alias.
316 self.alias_table = {}
313 self.alias_table = {}
317
314
318 # A table holding all the namespaces IPython deals with, so that
315 # A table holding all the namespaces IPython deals with, so that
319 # introspection facilities can search easily.
316 # introspection facilities can search easily.
320 self.ns_table = {'user':user_ns,
317 self.ns_table = {'user':user_ns,
321 'user_global':user_global_ns,
318 'user_global':user_global_ns,
322 'alias':self.alias_table,
319 'alias':self.alias_table,
323 'internal':self.internal_ns,
320 'internal':self.internal_ns,
324 'builtin':__builtin__.__dict__
321 'builtin':__builtin__.__dict__
325 }
322 }
326
323
327 # The user namespace MUST have a pointer to the shell itself.
324 # The user namespace MUST have a pointer to the shell itself.
328 self.user_ns[name] = self
325 self.user_ns[name] = self
329
326
330 # We need to insert into sys.modules something that looks like a
327 # We need to insert into sys.modules something that looks like a
331 # module but which accesses the IPython namespace, for shelve and
328 # module but which accesses the IPython namespace, for shelve and
332 # pickle to work interactively. Normally they rely on getting
329 # pickle to work interactively. Normally they rely on getting
333 # everything out of __main__, but for embedding purposes each IPython
330 # everything out of __main__, but for embedding purposes each IPython
334 # instance has its own private namespace, so we can't go shoving
331 # instance has its own private namespace, so we can't go shoving
335 # everything into __main__.
332 # everything into __main__.
336
333
337 # note, however, that we should only do this for non-embedded
334 # note, however, that we should only do this for non-embedded
338 # ipythons, which really mimic the __main__.__dict__ with their own
335 # ipythons, which really mimic the __main__.__dict__ with their own
339 # namespace. Embedded instances, on the other hand, should not do
336 # namespace. Embedded instances, on the other hand, should not do
340 # this because they need to manage the user local/global namespaces
337 # this because they need to manage the user local/global namespaces
341 # only, but they live within a 'normal' __main__ (meaning, they
338 # only, but they live within a 'normal' __main__ (meaning, they
342 # shouldn't overtake the execution environment of the script they're
339 # shouldn't overtake the execution environment of the script they're
343 # embedded in).
340 # embedded in).
344
341
345 if not embedded:
342 if not embedded:
346 try:
343 try:
347 main_name = self.user_ns['__name__']
344 main_name = self.user_ns['__name__']
348 except KeyError:
345 except KeyError:
349 raise KeyError,'user_ns dictionary MUST have a "__name__" key'
346 raise KeyError,'user_ns dictionary MUST have a "__name__" key'
350 else:
347 else:
351 #print "pickle hack in place" # dbg
348 #print "pickle hack in place" # dbg
352 sys.modules[main_name] = FakeModule(self.user_ns)
349 sys.modules[main_name] = FakeModule(self.user_ns)
353
350
354 # List of input with multi-line handling.
351 # List of input with multi-line handling.
355 # Fill its zero entry, user counter starts at 1
352 # Fill its zero entry, user counter starts at 1
356 self.input_hist = InputList(['\n'])
353 self.input_hist = InputList(['\n'])
357
354
358 # list of visited directories
355 # list of visited directories
359 try:
356 try:
360 self.dir_hist = [os.getcwd()]
357 self.dir_hist = [os.getcwd()]
361 except IOError, e:
358 except IOError, e:
362 self.dir_hist = []
359 self.dir_hist = []
363
360
364 # dict of output history
361 # dict of output history
365 self.output_hist = {}
362 self.output_hist = {}
366
363
367 # dict of things NOT to alias (keywords, builtins and some magics)
364 # dict of things NOT to alias (keywords, builtins and some magics)
368 no_alias = {}
365 no_alias = {}
369 no_alias_magics = ['cd','popd','pushd','dhist','alias','unalias']
366 no_alias_magics = ['cd','popd','pushd','dhist','alias','unalias']
370 for key in keyword.kwlist + no_alias_magics:
367 for key in keyword.kwlist + no_alias_magics:
371 no_alias[key] = 1
368 no_alias[key] = 1
372 no_alias.update(__builtin__.__dict__)
369 no_alias.update(__builtin__.__dict__)
373 self.no_alias = no_alias
370 self.no_alias = no_alias
374
371
375 # make global variables for user access to these
372 # make global variables for user access to these
376 self.user_ns['_ih'] = self.input_hist
373 self.user_ns['_ih'] = self.input_hist
377 self.user_ns['_oh'] = self.output_hist
374 self.user_ns['_oh'] = self.output_hist
378 self.user_ns['_dh'] = self.dir_hist
375 self.user_ns['_dh'] = self.dir_hist
379
376
380 # user aliases to input and output histories
377 # user aliases to input and output histories
381 self.user_ns['In'] = self.input_hist
378 self.user_ns['In'] = self.input_hist
382 self.user_ns['Out'] = self.output_hist
379 self.user_ns['Out'] = self.output_hist
383
380
384 # Store the actual shell's name
381 # Store the actual shell's name
385 self.name = name
382 self.name = name
386
383
387 # Object variable to store code object waiting execution. This is
384 # Object variable to store code object waiting execution. This is
388 # used mainly by the multithreaded shells, but it can come in handy in
385 # used mainly by the multithreaded shells, but it can come in handy in
389 # other situations. No need to use a Queue here, since it's a single
386 # other situations. No need to use a Queue here, since it's a single
390 # item which gets cleared once run.
387 # item which gets cleared once run.
391 self.code_to_run = None
388 self.code_to_run = None
392
389
393 # Job manager (for jobs run as background threads)
390 # Job manager (for jobs run as background threads)
394 self.jobs = BackgroundJobManager()
391 self.jobs = BackgroundJobManager()
395 # Put the job manager into builtins so it's always there.
392 # Put the job manager into builtins so it's always there.
396 __builtin__.jobs = self.jobs
393 __builtin__.jobs = self.jobs
397
394
398 # escapes for automatic behavior on the command line
395 # escapes for automatic behavior on the command line
399 self.ESC_SHELL = '!'
396 self.ESC_SHELL = '!'
400 self.ESC_HELP = '?'
397 self.ESC_HELP = '?'
401 self.ESC_MAGIC = '%'
398 self.ESC_MAGIC = '%'
402 self.ESC_QUOTE = ','
399 self.ESC_QUOTE = ','
403 self.ESC_QUOTE2 = ';'
400 self.ESC_QUOTE2 = ';'
404 self.ESC_PAREN = '/'
401 self.ESC_PAREN = '/'
405
402
406 # And their associated handlers
403 # And their associated handlers
407 self.esc_handlers = {self.ESC_PAREN:self.handle_auto,
404 self.esc_handlers = {self.ESC_PAREN:self.handle_auto,
408 self.ESC_QUOTE:self.handle_auto,
405 self.ESC_QUOTE:self.handle_auto,
409 self.ESC_QUOTE2:self.handle_auto,
406 self.ESC_QUOTE2:self.handle_auto,
410 self.ESC_MAGIC:self.handle_magic,
407 self.ESC_MAGIC:self.handle_magic,
411 self.ESC_HELP:self.handle_help,
408 self.ESC_HELP:self.handle_help,
412 self.ESC_SHELL:self.handle_shell_escape,
409 self.ESC_SHELL:self.handle_shell_escape,
413 }
410 }
414
411
415 # class initializations
412 # class initializations
416 Logger.__init__(self,log_ns = self.user_ns)
413 Logger.__init__(self,log_ns = self.user_ns)
417 Magic.__init__(self,self)
414 Magic.__init__(self,self)
418
415
419 # an ugly hack to get a pointer to the shell, so I can start writing
416 # an ugly hack to get a pointer to the shell, so I can start writing
420 # magic code via this pointer instead of the current mixin salad.
417 # magic code via this pointer instead of the current mixin salad.
421 Magic.set_shell(self,self)
418 Magic.set_shell(self,self)
422
419
423 # Python source parser/formatter for syntax highlighting
420 # Python source parser/formatter for syntax highlighting
424 pyformat = Parser().format
421 pyformat = PyColorize.Parser().format
425 self.pycolorize = lambda src: pyformat(src,'str',self.rc['colors'])
422 self.pycolorize = lambda src: pyformat(src,'str',self.rc['colors'])
426
423
427 # hooks holds pointers used for user-side customizations
424 # hooks holds pointers used for user-side customizations
428 self.hooks = Struct()
425 self.hooks = Struct()
429
426
430 # Set all default hooks, defined in the IPython.hooks module.
427 # Set all default hooks, defined in the IPython.hooks module.
431 hooks = IPython.hooks
428 hooks = IPython.hooks
432 for hook_name in hooks.__all__:
429 for hook_name in hooks.__all__:
433 self.set_hook(hook_name,getattr(hooks,hook_name))
430 self.set_hook(hook_name,getattr(hooks,hook_name))
434
431
435 # Flag to mark unconditional exit
432 # Flag to mark unconditional exit
436 self.exit_now = False
433 self.exit_now = False
437
434
438 self.usage_min = """\
435 self.usage_min = """\
439 An enhanced console for Python.
436 An enhanced console for Python.
440 Some of its features are:
437 Some of its features are:
441 - Readline support if the readline library is present.
438 - Readline support if the readline library is present.
442 - Tab completion in the local namespace.
439 - Tab completion in the local namespace.
443 - Logging of input, see command-line options.
440 - Logging of input, see command-line options.
444 - System shell escape via ! , eg !ls.
441 - System shell escape via ! , eg !ls.
445 - Magic commands, starting with a % (like %ls, %pwd, %cd, etc.)
442 - Magic commands, starting with a % (like %ls, %pwd, %cd, etc.)
446 - Keeps track of locally defined variables via %who, %whos.
443 - Keeps track of locally defined variables via %who, %whos.
447 - Show object information with a ? eg ?x or x? (use ?? for more info).
444 - Show object information with a ? eg ?x or x? (use ?? for more info).
448 """
445 """
449 if usage: self.usage = usage
446 if usage: self.usage = usage
450 else: self.usage = self.usage_min
447 else: self.usage = self.usage_min
451
448
452 # Storage
449 # Storage
453 self.rc = rc # This will hold all configuration information
450 self.rc = rc # This will hold all configuration information
454 self.inputcache = []
451 self.inputcache = []
455 self._boundcache = []
452 self._boundcache = []
456 self.pager = 'less'
453 self.pager = 'less'
457 # temporary files used for various purposes. Deleted at exit.
454 # temporary files used for various purposes. Deleted at exit.
458 self.tempfiles = []
455 self.tempfiles = []
459
456
460 # Keep track of readline usage (later set by init_readline)
457 # Keep track of readline usage (later set by init_readline)
461 self.has_readline = False
458 self.has_readline = False
462
459
463 # for pushd/popd management
460 # for pushd/popd management
464 try:
461 try:
465 self.home_dir = get_home_dir()
462 self.home_dir = get_home_dir()
466 except HomeDirError,msg:
463 except HomeDirError,msg:
467 fatal(msg)
464 fatal(msg)
468
465
469 self.dir_stack = [os.getcwd().replace(self.home_dir,'~')]
466 self.dir_stack = [os.getcwd().replace(self.home_dir,'~')]
470
467
471 # Functions to call the underlying shell.
468 # Functions to call the underlying shell.
472
469
473 # utility to expand user variables via Itpl
470 # utility to expand user variables via Itpl
474 self.var_expand = lambda cmd: str(ItplNS(cmd.replace('#','\#'),
471 self.var_expand = lambda cmd: str(ItplNS(cmd.replace('#','\#'),
475 self.user_ns))
472 self.user_ns))
476 # The first is similar to os.system, but it doesn't return a value,
473 # The first is similar to os.system, but it doesn't return a value,
477 # and it allows interpolation of variables in the user's namespace.
474 # and it allows interpolation of variables in the user's namespace.
478 self.system = lambda cmd: shell(self.var_expand(cmd),
475 self.system = lambda cmd: shell(self.var_expand(cmd),
479 header='IPython system call: ',
476 header='IPython system call: ',
480 verbose=self.rc.system_verbose)
477 verbose=self.rc.system_verbose)
481 # These are for getoutput and getoutputerror:
478 # These are for getoutput and getoutputerror:
482 self.getoutput = lambda cmd: \
479 self.getoutput = lambda cmd: \
483 getoutput(self.var_expand(cmd),
480 getoutput(self.var_expand(cmd),
484 header='IPython system call: ',
481 header='IPython system call: ',
485 verbose=self.rc.system_verbose)
482 verbose=self.rc.system_verbose)
486 self.getoutputerror = lambda cmd: \
483 self.getoutputerror = lambda cmd: \
487 getoutputerror(str(ItplNS(cmd.replace('#','\#'),
484 getoutputerror(str(ItplNS(cmd.replace('#','\#'),
488 self.user_ns)),
485 self.user_ns)),
489 header='IPython system call: ',
486 header='IPython system call: ',
490 verbose=self.rc.system_verbose)
487 verbose=self.rc.system_verbose)
491
488
492 # RegExp for splitting line contents into pre-char//first
489 # RegExp for splitting line contents into pre-char//first
493 # word-method//rest. For clarity, each group in on one line.
490 # word-method//rest. For clarity, each group in on one line.
494
491
495 # WARNING: update the regexp if the above escapes are changed, as they
492 # WARNING: update the regexp if the above escapes are changed, as they
496 # are hardwired in.
493 # are hardwired in.
497
494
498 # Don't get carried away with trying to make the autocalling catch too
495 # Don't get carried away with trying to make the autocalling catch too
499 # much: it's better to be conservative rather than to trigger hidden
496 # much: it's better to be conservative rather than to trigger hidden
500 # evals() somewhere and end up causing side effects.
497 # evals() somewhere and end up causing side effects.
501
498
502 self.line_split = re.compile(r'^([\s*,;/])'
499 self.line_split = re.compile(r'^([\s*,;/])'
503 r'([\?\w\.]+\w*\s*)'
500 r'([\?\w\.]+\w*\s*)'
504 r'(\(?.*$)')
501 r'(\(?.*$)')
505
502
506 # Original re, keep around for a while in case changes break something
503 # Original re, keep around for a while in case changes break something
507 #self.line_split = re.compile(r'(^[\s*!\?%,/]?)'
504 #self.line_split = re.compile(r'(^[\s*!\?%,/]?)'
508 # r'(\s*[\?\w\.]+\w*\s*)'
505 # r'(\s*[\?\w\.]+\w*\s*)'
509 # r'(\(?.*$)')
506 # r'(\(?.*$)')
510
507
511 # RegExp to identify potential function names
508 # RegExp to identify potential function names
512 self.re_fun_name = re.compile(r'[a-zA-Z_]([a-zA-Z0-9_.]*) *$')
509 self.re_fun_name = re.compile(r'[a-zA-Z_]([a-zA-Z0-9_.]*) *$')
513 # RegExp to exclude strings with this start from autocalling
510 # RegExp to exclude strings with this start from autocalling
514 self.re_exclude_auto = re.compile('^[!=()<>,\*/\+-]|^is ')
511 self.re_exclude_auto = re.compile('^[!=()<>,\*/\+-]|^is ')
515
512
516 # try to catch also methods for stuff in lists/tuples/dicts: off
513 # try to catch also methods for stuff in lists/tuples/dicts: off
517 # (experimental). For this to work, the line_split regexp would need
514 # (experimental). For this to work, the line_split regexp would need
518 # to be modified so it wouldn't break things at '['. That line is
515 # to be modified so it wouldn't break things at '['. That line is
519 # nasty enough that I shouldn't change it until I can test it _well_.
516 # nasty enough that I shouldn't change it until I can test it _well_.
520 #self.re_fun_name = re.compile (r'[a-zA-Z_]([a-zA-Z0-9_.\[\]]*) ?$')
517 #self.re_fun_name = re.compile (r'[a-zA-Z_]([a-zA-Z0-9_.\[\]]*) ?$')
521
518
522 # keep track of where we started running (mainly for crash post-mortem)
519 # keep track of where we started running (mainly for crash post-mortem)
523 self.starting_dir = os.getcwd()
520 self.starting_dir = os.getcwd()
524
521
525 # Attributes for Logger mixin class, make defaults here
522 # Attributes for Logger mixin class, make defaults here
526 self._dolog = False
523 self._dolog = False
527 self.LOG = ''
524 self.LOG = ''
528 self.LOGDEF = '.InteractiveShell.log'
525 self.LOGDEF = '.InteractiveShell.log'
529 self.LOGMODE = 'over'
526 self.LOGMODE = 'over'
530 self.LOGHEAD = Itpl(
527 self.LOGHEAD = Itpl(
531 """#log# Automatic Logger file. *** THIS MUST BE THE FIRST LINE ***
528 """#log# Automatic Logger file. *** THIS MUST BE THE FIRST LINE ***
532 #log# DO NOT CHANGE THIS LINE OR THE TWO BELOW
529 #log# DO NOT CHANGE THIS LINE OR THE TWO BELOW
533 #log# opts = $self.rc.opts
530 #log# opts = $self.rc.opts
534 #log# args = $self.rc.args
531 #log# args = $self.rc.args
535 #log# It is safe to make manual edits below here.
532 #log# It is safe to make manual edits below here.
536 #log#-----------------------------------------------------------------------
533 #log#-----------------------------------------------------------------------
537 """)
534 """)
538 # Various switches which can be set
535 # Various switches which can be set
539 self.CACHELENGTH = 5000 # this is cheap, it's just text
536 self.CACHELENGTH = 5000 # this is cheap, it's just text
540 self.BANNER = "Python %(version)s on %(platform)s\n" % sys.__dict__
537 self.BANNER = "Python %(version)s on %(platform)s\n" % sys.__dict__
541 self.banner2 = banner2
538 self.banner2 = banner2
542
539
543 # TraceBack handlers:
540 # TraceBack handlers:
544 # Need two, one for syntax errors and one for other exceptions.
541 # Need two, one for syntax errors and one for other exceptions.
545 self.SyntaxTB = ultraTB.ListTB(color_scheme='NoColor')
542 self.SyntaxTB = ultraTB.ListTB(color_scheme='NoColor')
546 # This one is initialized with an offset, meaning we always want to
543 # This one is initialized with an offset, meaning we always want to
547 # remove the topmost item in the traceback, which is our own internal
544 # remove the topmost item in the traceback, which is our own internal
548 # code. Valid modes: ['Plain','Context','Verbose']
545 # code. Valid modes: ['Plain','Context','Verbose']
549 self.InteractiveTB = ultraTB.AutoFormattedTB(mode = 'Plain',
546 self.InteractiveTB = ultraTB.AutoFormattedTB(mode = 'Plain',
550 color_scheme='NoColor',
547 color_scheme='NoColor',
551 tb_offset = 1)
548 tb_offset = 1)
552 # and add any custom exception handlers the user may have specified
549 # and add any custom exception handlers the user may have specified
553 self.set_custom_exc(*custom_exceptions)
550 self.set_custom_exc(*custom_exceptions)
554
551
555 # Object inspector
552 # Object inspector
556 ins_colors = OInspect.InspectColors
553 self.inspector = OInspect.Inspector(OInspect.InspectColors,
557 code_colors = PyColorize.ANSICodeColors
554 PyColorize.ANSICodeColors,
558 self.inspector = OInspect.Inspector(ins_colors,code_colors,'NoColor')
555 'NoColor')
559 self.autoindent = False
556 self.autoindent = False
560
557
561 # Make some aliases automatically
558 # Make some aliases automatically
562 # Prepare list of shell aliases to auto-define
559 # Prepare list of shell aliases to auto-define
563 if os.name == 'posix':
560 if os.name == 'posix':
564 auto_alias = ('mkdir mkdir', 'rmdir rmdir',
561 auto_alias = ('mkdir mkdir', 'rmdir rmdir',
565 'mv mv -i','rm rm -i','cp cp -i',
562 'mv mv -i','rm rm -i','cp cp -i',
566 'cat cat','less less','clear clear',
563 'cat cat','less less','clear clear',
567 # a better ls
564 # a better ls
568 'ls ls -F',
565 'ls ls -F',
569 # long ls
566 # long ls
570 'll ls -lF',
567 'll ls -lF',
571 # color ls
568 # color ls
572 'lc ls -F -o --color',
569 'lc ls -F -o --color',
573 # ls normal files only
570 # ls normal files only
574 'lf ls -F -o --color %l | grep ^-',
571 'lf ls -F -o --color %l | grep ^-',
575 # ls symbolic links
572 # ls symbolic links
576 'lk ls -F -o --color %l | grep ^l',
573 'lk ls -F -o --color %l | grep ^l',
577 # directories or links to directories,
574 # directories or links to directories,
578 'ldir ls -F -o --color %l | grep /$',
575 'ldir ls -F -o --color %l | grep /$',
579 # things which are executable
576 # things which are executable
580 'lx ls -F -o --color %l | grep ^-..x',
577 'lx ls -F -o --color %l | grep ^-..x',
581 )
578 )
582 elif os.name in ['nt','dos']:
579 elif os.name in ['nt','dos']:
583 auto_alias = ('dir dir /on', 'ls dir /on',
580 auto_alias = ('dir dir /on', 'ls dir /on',
584 'ddir dir /ad /on', 'ldir dir /ad /on',
581 'ddir dir /ad /on', 'ldir dir /ad /on',
585 'mkdir mkdir','rmdir rmdir','echo echo',
582 'mkdir mkdir','rmdir rmdir','echo echo',
586 'ren ren','cls cls','copy copy')
583 'ren ren','cls cls','copy copy')
587 else:
584 else:
588 auto_alias = ()
585 auto_alias = ()
589 self.auto_alias = map(lambda s:s.split(None,1),auto_alias)
586 self.auto_alias = map(lambda s:s.split(None,1),auto_alias)
590 # Call the actual (public) initializer
587 # Call the actual (public) initializer
591 self.init_auto_alias()
588 self.init_auto_alias()
592 # end __init__
589 # end __init__
593
590
594 def set_hook(self,name,hook):
591 def set_hook(self,name,hook):
595 """set_hook(name,hook) -> sets an internal IPython hook.
592 """set_hook(name,hook) -> sets an internal IPython hook.
596
593
597 IPython exposes some of its internal API as user-modifiable hooks. By
594 IPython exposes some of its internal API as user-modifiable hooks. By
598 resetting one of these hooks, you can modify IPython's behavior to
595 resetting one of these hooks, you can modify IPython's behavior to
599 call at runtime your own routines."""
596 call at runtime your own routines."""
600
597
601 # At some point in the future, this should validate the hook before it
598 # At some point in the future, this should validate the hook before it
602 # accepts it. Probably at least check that the hook takes the number
599 # accepts it. Probably at least check that the hook takes the number
603 # of args it's supposed to.
600 # of args it's supposed to.
604 setattr(self.hooks,name,new.instancemethod(hook,self,self.__class__))
601 setattr(self.hooks,name,new.instancemethod(hook,self,self.__class__))
605
602
606 def set_custom_exc(self,exc_tuple,handler):
603 def set_custom_exc(self,exc_tuple,handler):
607 """set_custom_exc(exc_tuple,handler)
604 """set_custom_exc(exc_tuple,handler)
608
605
609 Set a custom exception handler, which will be called if any of the
606 Set a custom exception handler, which will be called if any of the
610 exceptions in exc_tuple occur in the mainloop (specifically, in the
607 exceptions in exc_tuple occur in the mainloop (specifically, in the
611 runcode() method.
608 runcode() method.
612
609
613 Inputs:
610 Inputs:
614
611
615 - exc_tuple: a *tuple* of valid exceptions to call the defined
612 - exc_tuple: a *tuple* of valid exceptions to call the defined
616 handler for. It is very important that you use a tuple, and NOT A
613 handler for. It is very important that you use a tuple, and NOT A
617 LIST here, because of the way Python's except statement works. If
614 LIST here, because of the way Python's except statement works. If
618 you only want to trap a single exception, use a singleton tuple:
615 you only want to trap a single exception, use a singleton tuple:
619
616
620 exc_tuple == (MyCustomException,)
617 exc_tuple == (MyCustomException,)
621
618
622 - handler: this must be defined as a function with the following
619 - handler: this must be defined as a function with the following
623 basic interface: def my_handler(self,etype,value,tb).
620 basic interface: def my_handler(self,etype,value,tb).
624
621
625 This will be made into an instance method (via new.instancemethod)
622 This will be made into an instance method (via new.instancemethod)
626 of IPython itself, and it will be called if any of the exceptions
623 of IPython itself, and it will be called if any of the exceptions
627 listed in the exc_tuple are caught. If the handler is None, an
624 listed in the exc_tuple are caught. If the handler is None, an
628 internal basic one is used, which just prints basic info.
625 internal basic one is used, which just prints basic info.
629
626
630 WARNING: by putting in your own exception handler into IPython's main
627 WARNING: by putting in your own exception handler into IPython's main
631 execution loop, you run a very good chance of nasty crashes. This
628 execution loop, you run a very good chance of nasty crashes. This
632 facility should only be used if you really know what you are doing."""
629 facility should only be used if you really know what you are doing."""
633
630
634 assert type(exc_tuple)==type(()) , \
631 assert type(exc_tuple)==type(()) , \
635 "The custom exceptions must be given AS A TUPLE."
632 "The custom exceptions must be given AS A TUPLE."
636
633
637 def dummy_handler(self,etype,value,tb):
634 def dummy_handler(self,etype,value,tb):
638 print '*** Simple custom exception handler ***'
635 print '*** Simple custom exception handler ***'
639 print 'Exception type :',etype
636 print 'Exception type :',etype
640 print 'Exception value:',value
637 print 'Exception value:',value
641 print 'Traceback :',tb
638 print 'Traceback :',tb
642 print 'Source code :','\n'.join(self.buffer)
639 print 'Source code :','\n'.join(self.buffer)
643
640
644 if handler is None: handler = dummy_handler
641 if handler is None: handler = dummy_handler
645
642
646 self.CustomTB = new.instancemethod(handler,self,self.__class__)
643 self.CustomTB = new.instancemethod(handler,self,self.__class__)
647 self.custom_exceptions = exc_tuple
644 self.custom_exceptions = exc_tuple
648
645
649 def set_custom_completer(self,completer,pos=0):
646 def set_custom_completer(self,completer,pos=0):
650 """set_custom_completer(completer,pos=0)
647 """set_custom_completer(completer,pos=0)
651
648
652 Adds a new custom completer function.
649 Adds a new custom completer function.
653
650
654 The position argument (defaults to 0) is the index in the completers
651 The position argument (defaults to 0) is the index in the completers
655 list where you want the completer to be inserted."""
652 list where you want the completer to be inserted."""
656
653
657 newcomp = new.instancemethod(completer,self.Completer,
654 newcomp = new.instancemethod(completer,self.Completer,
658 self.Completer.__class__)
655 self.Completer.__class__)
659 self.Completer.matchers.insert(pos,newcomp)
656 self.Completer.matchers.insert(pos,newcomp)
660
657
661 def complete(self,text):
658 def complete(self,text):
662 """Return a sorted list of all possible completions on text.
659 """Return a sorted list of all possible completions on text.
663
660
664 Inputs:
661 Inputs:
665
662
666 - text: a string of text to be completed on.
663 - text: a string of text to be completed on.
667
664
668 This is a wrapper around the completion mechanism, similar to what
665 This is a wrapper around the completion mechanism, similar to what
669 readline does at the command line when the TAB key is hit. By
666 readline does at the command line when the TAB key is hit. By
670 exposing it as a method, it can be used by other non-readline
667 exposing it as a method, it can be used by other non-readline
671 environments (such as GUIs) for text completion.
668 environments (such as GUIs) for text completion.
672
669
673 Simple usage example:
670 Simple usage example:
674
671
675 In [1]: x = 'hello'
672 In [1]: x = 'hello'
676
673
677 In [2]: __IP.complete('x.l')
674 In [2]: __IP.complete('x.l')
678 Out[2]: ['x.ljust', 'x.lower', 'x.lstrip']"""
675 Out[2]: ['x.ljust', 'x.lower', 'x.lstrip']"""
679
676
680 complete = self.Completer.complete
677 complete = self.Completer.complete
681 state = 0
678 state = 0
682 # use a dict so we get unique keys, since ipyhton's multiple
679 # use a dict so we get unique keys, since ipyhton's multiple
683 # completers can return duplicates.
680 # completers can return duplicates.
684 comps = {}
681 comps = {}
685 while True:
682 while True:
686 newcomp = complete(text,state)
683 newcomp = complete(text,state)
687 if newcomp is None:
684 if newcomp is None:
688 break
685 break
689 comps[newcomp] = 1
686 comps[newcomp] = 1
690 state += 1
687 state += 1
691 outcomps = comps.keys()
688 outcomps = comps.keys()
692 outcomps.sort()
689 outcomps.sort()
693 return outcomps
690 return outcomps
694
691
695 def set_completer_frame(self, frame):
692 def set_completer_frame(self, frame):
696 if frame:
693 if frame:
697 self.Completer.namespace = frame.f_locals
694 self.Completer.namespace = frame.f_locals
698 self.Completer.global_namespace = frame.f_globals
695 self.Completer.global_namespace = frame.f_globals
699 else:
696 else:
700 self.Completer.namespace = self.user_ns
697 self.Completer.namespace = self.user_ns
701 self.Completer.global_namespace = self.user_global_ns
698 self.Completer.global_namespace = self.user_global_ns
702
699
703 def post_config_initialization(self):
700 def post_config_initialization(self):
704 """Post configuration init method
701 """Post configuration init method
705
702
706 This is called after the configuration files have been processed to
703 This is called after the configuration files have been processed to
707 'finalize' the initialization."""
704 'finalize' the initialization."""
708
705
709 rc = self.rc
706 rc = self.rc
710
707
711 # Load readline proper
708 # Load readline proper
712 if rc.readline:
709 if rc.readline:
713 self.init_readline()
710 self.init_readline()
714
711
715 # Set user colors (don't do it in the constructor above so that it
712 # Set user colors (don't do it in the constructor above so that it
716 # doesn't crash if colors option is invalid)
713 # doesn't crash if colors option is invalid)
717 self.magic_colors(rc.colors)
714 self.magic_colors(rc.colors)
718
715
719 # Load user aliases
716 # Load user aliases
720 for alias in rc.alias:
717 for alias in rc.alias:
721 self.magic_alias(alias)
718 self.magic_alias(alias)
722
719
723 # dynamic data that survives through sessions
720 # dynamic data that survives through sessions
724 # XXX make the filename a config option?
721 # XXX make the filename a config option?
725 persist_base = 'persist'
722 persist_base = 'persist'
726 if rc.profile:
723 if rc.profile:
727 persist_base += '_%s' % rc.profile
724 persist_base += '_%s' % rc.profile
728 self.persist_fname = os.path.join(rc.ipythondir,persist_base)
725 self.persist_fname = os.path.join(rc.ipythondir,persist_base)
729
726
730 try:
727 try:
731 self.persist = pickle.load(file(self.persist_fname))
728 self.persist = pickle.load(file(self.persist_fname))
732 except:
729 except:
733 self.persist = {}
730 self.persist = {}
734
731
735 def init_auto_alias(self):
732 def init_auto_alias(self):
736 """Define some aliases automatically.
733 """Define some aliases automatically.
737
734
738 These are ALL parameter-less aliases"""
735 These are ALL parameter-less aliases"""
739 for alias,cmd in self.auto_alias:
736 for alias,cmd in self.auto_alias:
740 self.alias_table[alias] = (0,cmd)
737 self.alias_table[alias] = (0,cmd)
741
738
742 def alias_table_validate(self,verbose=0):
739 def alias_table_validate(self,verbose=0):
743 """Update information about the alias table.
740 """Update information about the alias table.
744
741
745 In particular, make sure no Python keywords/builtins are in it."""
742 In particular, make sure no Python keywords/builtins are in it."""
746
743
747 no_alias = self.no_alias
744 no_alias = self.no_alias
748 for k in self.alias_table.keys():
745 for k in self.alias_table.keys():
749 if k in no_alias:
746 if k in no_alias:
750 del self.alias_table[k]
747 del self.alias_table[k]
751 if verbose:
748 if verbose:
752 print ("Deleting alias <%s>, it's a Python "
749 print ("Deleting alias <%s>, it's a Python "
753 "keyword or builtin." % k)
750 "keyword or builtin." % k)
754
751
755 def set_autoindent(self,value=None):
752 def set_autoindent(self,value=None):
756 """Set the autoindent flag, checking for readline support.
753 """Set the autoindent flag, checking for readline support.
757
754
758 If called with no arguments, it acts as a toggle."""
755 If called with no arguments, it acts as a toggle."""
759
756
760 if not self.has_readline:
757 if not self.has_readline:
761 if os.name == 'posix':
758 if os.name == 'posix':
762 warn("The auto-indent feature requires the readline library")
759 warn("The auto-indent feature requires the readline library")
763 self.autoindent = 0
760 self.autoindent = 0
764 return
761 return
765 if value is None:
762 if value is None:
766 self.autoindent = not self.autoindent
763 self.autoindent = not self.autoindent
767 else:
764 else:
768 self.autoindent = value
765 self.autoindent = value
769
766
770 def rc_set_toggle(self,rc_field,value=None):
767 def rc_set_toggle(self,rc_field,value=None):
771 """Set or toggle a field in IPython's rc config. structure.
768 """Set or toggle a field in IPython's rc config. structure.
772
769
773 If called with no arguments, it acts as a toggle.
770 If called with no arguments, it acts as a toggle.
774
771
775 If called with a non-existent field, the resulting AttributeError
772 If called with a non-existent field, the resulting AttributeError
776 exception will propagate out."""
773 exception will propagate out."""
777
774
778 rc_val = getattr(self.rc,rc_field)
775 rc_val = getattr(self.rc,rc_field)
779 if value is None:
776 if value is None:
780 value = not rc_val
777 value = not rc_val
781 setattr(self.rc,rc_field,value)
778 setattr(self.rc,rc_field,value)
782
779
783 def user_setup(self,ipythondir,rc_suffix,mode='install'):
780 def user_setup(self,ipythondir,rc_suffix,mode='install'):
784 """Install the user configuration directory.
781 """Install the user configuration directory.
785
782
786 Can be called when running for the first time or to upgrade the user's
783 Can be called when running for the first time or to upgrade the user's
787 .ipython/ directory with the mode parameter. Valid modes are 'install'
784 .ipython/ directory with the mode parameter. Valid modes are 'install'
788 and 'upgrade'."""
785 and 'upgrade'."""
789
786
790 def wait():
787 def wait():
791 try:
788 try:
792 raw_input("Please press <RETURN> to start IPython.")
789 raw_input("Please press <RETURN> to start IPython.")
793 except EOFError:
790 except EOFError:
794 print >> Term.cout
791 print >> Term.cout
795 print '*'*70
792 print '*'*70
796
793
797 cwd = os.getcwd() # remember where we started
794 cwd = os.getcwd() # remember where we started
798 glb = glob.glob
795 glb = glob.glob
799 print '*'*70
796 print '*'*70
800 if mode == 'install':
797 if mode == 'install':
801 print \
798 print \
802 """Welcome to IPython. I will try to create a personal configuration directory
799 """Welcome to IPython. I will try to create a personal configuration directory
803 where you can customize many aspects of IPython's functionality in:\n"""
800 where you can customize many aspects of IPython's functionality in:\n"""
804 else:
801 else:
805 print 'I am going to upgrade your configuration in:'
802 print 'I am going to upgrade your configuration in:'
806
803
807 print ipythondir
804 print ipythondir
808
805
809 rcdirend = os.path.join('IPython','UserConfig')
806 rcdirend = os.path.join('IPython','UserConfig')
810 cfg = lambda d: os.path.join(d,rcdirend)
807 cfg = lambda d: os.path.join(d,rcdirend)
811 try:
808 try:
812 rcdir = filter(os.path.isdir,map(cfg,sys.path))[0]
809 rcdir = filter(os.path.isdir,map(cfg,sys.path))[0]
813 except IOError:
810 except IOError:
814 warning = """
811 warning = """
815 Installation error. IPython's directory was not found.
812 Installation error. IPython's directory was not found.
816
813
817 Check the following:
814 Check the following:
818
815
819 The ipython/IPython directory should be in a directory belonging to your
816 The ipython/IPython directory should be in a directory belonging to your
820 PYTHONPATH environment variable (that is, it should be in a directory
817 PYTHONPATH environment variable (that is, it should be in a directory
821 belonging to sys.path). You can copy it explicitly there or just link to it.
818 belonging to sys.path). You can copy it explicitly there or just link to it.
822
819
823 IPython will proceed with builtin defaults.
820 IPython will proceed with builtin defaults.
824 """
821 """
825 warn(warning)
822 warn(warning)
826 wait()
823 wait()
827 return
824 return
828
825
829 if mode == 'install':
826 if mode == 'install':
830 try:
827 try:
831 shutil.copytree(rcdir,ipythondir)
828 shutil.copytree(rcdir,ipythondir)
832 os.chdir(ipythondir)
829 os.chdir(ipythondir)
833 rc_files = glb("ipythonrc*")
830 rc_files = glb("ipythonrc*")
834 for rc_file in rc_files:
831 for rc_file in rc_files:
835 os.rename(rc_file,rc_file+rc_suffix)
832 os.rename(rc_file,rc_file+rc_suffix)
836 except:
833 except:
837 warning = """
834 warning = """
838
835
839 There was a problem with the installation:
836 There was a problem with the installation:
840 %s
837 %s
841 Try to correct it or contact the developers if you think it's a bug.
838 Try to correct it or contact the developers if you think it's a bug.
842 IPython will proceed with builtin defaults.""" % sys.exc_info()[1]
839 IPython will proceed with builtin defaults.""" % sys.exc_info()[1]
843 warn(warning)
840 warn(warning)
844 wait()
841 wait()
845 return
842 return
846
843
847 elif mode == 'upgrade':
844 elif mode == 'upgrade':
848 try:
845 try:
849 os.chdir(ipythondir)
846 os.chdir(ipythondir)
850 except:
847 except:
851 print """
848 print """
852 Can not upgrade: changing to directory %s failed. Details:
849 Can not upgrade: changing to directory %s failed. Details:
853 %s
850 %s
854 """ % (ipythondir,sys.exc_info()[1])
851 """ % (ipythondir,sys.exc_info()[1])
855 wait()
852 wait()
856 return
853 return
857 else:
854 else:
858 sources = glb(os.path.join(rcdir,'[A-Za-z]*'))
855 sources = glb(os.path.join(rcdir,'[A-Za-z]*'))
859 for new_full_path in sources:
856 for new_full_path in sources:
860 new_filename = os.path.basename(new_full_path)
857 new_filename = os.path.basename(new_full_path)
861 if new_filename.startswith('ipythonrc'):
858 if new_filename.startswith('ipythonrc'):
862 new_filename = new_filename + rc_suffix
859 new_filename = new_filename + rc_suffix
863 # The config directory should only contain files, skip any
860 # The config directory should only contain files, skip any
864 # directories which may be there (like CVS)
861 # directories which may be there (like CVS)
865 if os.path.isdir(new_full_path):
862 if os.path.isdir(new_full_path):
866 continue
863 continue
867 if os.path.exists(new_filename):
864 if os.path.exists(new_filename):
868 old_file = new_filename+'.old'
865 old_file = new_filename+'.old'
869 if os.path.exists(old_file):
866 if os.path.exists(old_file):
870 os.remove(old_file)
867 os.remove(old_file)
871 os.rename(new_filename,old_file)
868 os.rename(new_filename,old_file)
872 shutil.copy(new_full_path,new_filename)
869 shutil.copy(new_full_path,new_filename)
873 else:
870 else:
874 raise ValueError,'unrecognized mode for install:',`mode`
871 raise ValueError,'unrecognized mode for install:',`mode`
875
872
876 # Fix line-endings to those native to each platform in the config
873 # Fix line-endings to those native to each platform in the config
877 # directory.
874 # directory.
878 try:
875 try:
879 os.chdir(ipythondir)
876 os.chdir(ipythondir)
880 except:
877 except:
881 print """
878 print """
882 Problem: changing to directory %s failed.
879 Problem: changing to directory %s failed.
883 Details:
880 Details:
884 %s
881 %s
885
882
886 Some configuration files may have incorrect line endings. This should not
883 Some configuration files may have incorrect line endings. This should not
887 cause any problems during execution. """ % (ipythondir,sys.exc_info()[1])
884 cause any problems during execution. """ % (ipythondir,sys.exc_info()[1])
888 wait()
885 wait()
889 else:
886 else:
890 for fname in glb('ipythonrc*'):
887 for fname in glb('ipythonrc*'):
891 try:
888 try:
892 native_line_ends(fname,backup=0)
889 native_line_ends(fname,backup=0)
893 except IOError:
890 except IOError:
894 pass
891 pass
895
892
896 if mode == 'install':
893 if mode == 'install':
897 print """
894 print """
898 Successful installation!
895 Successful installation!
899
896
900 Please read the sections 'Initial Configuration' and 'Quick Tips' in the
897 Please read the sections 'Initial Configuration' and 'Quick Tips' in the
901 IPython manual (there are both HTML and PDF versions supplied with the
898 IPython manual (there are both HTML and PDF versions supplied with the
902 distribution) to make sure that your system environment is properly configured
899 distribution) to make sure that your system environment is properly configured
903 to take advantage of IPython's features."""
900 to take advantage of IPython's features."""
904 else:
901 else:
905 print """
902 print """
906 Successful upgrade!
903 Successful upgrade!
907
904
908 All files in your directory:
905 All files in your directory:
909 %(ipythondir)s
906 %(ipythondir)s
910 which would have been overwritten by the upgrade were backed up with a .old
907 which would have been overwritten by the upgrade were backed up with a .old
911 extension. If you had made particular customizations in those files you may
908 extension. If you had made particular customizations in those files you may
912 want to merge them back into the new files.""" % locals()
909 want to merge them back into the new files.""" % locals()
913 wait()
910 wait()
914 os.chdir(cwd)
911 os.chdir(cwd)
915 # end user_setup()
912 # end user_setup()
916
913
917 def atexit_operations(self):
914 def atexit_operations(self):
918 """This will be executed at the time of exit.
915 """This will be executed at the time of exit.
919
916
920 Saving of persistent data should be performed here. """
917 Saving of persistent data should be performed here. """
921
918
922 # input history
919 # input history
923 self.savehist()
920 self.savehist()
924
921
925 # Cleanup all tempfiles left around
922 # Cleanup all tempfiles left around
926 for tfile in self.tempfiles:
923 for tfile in self.tempfiles:
927 try:
924 try:
928 os.unlink(tfile)
925 os.unlink(tfile)
929 except OSError:
926 except OSError:
930 pass
927 pass
931
928
932 # save the "persistent data" catch-all dictionary
929 # save the "persistent data" catch-all dictionary
933 try:
930 try:
934 pickle.dump(self.persist, open(self.persist_fname,"w"))
931 pickle.dump(self.persist, open(self.persist_fname,"w"))
935 except:
932 except:
936 print "*** ERROR *** persistent data saving failed."
933 print "*** ERROR *** persistent data saving failed."
937
934
938 def savehist(self):
935 def savehist(self):
939 """Save input history to a file (via readline library)."""
936 """Save input history to a file (via readline library)."""
940 try:
937 try:
941 self.readline.write_history_file(self.histfile)
938 self.readline.write_history_file(self.histfile)
942 except:
939 except:
943 print 'Unable to save IPython command history to file: ' + \
940 print 'Unable to save IPython command history to file: ' + \
944 `self.histfile`
941 `self.histfile`
945
942
946 def pre_readline(self):
943 def pre_readline(self):
947 """readline hook to be used at the start of each line.
944 """readline hook to be used at the start of each line.
948
945
949 Currently it handles auto-indent only."""
946 Currently it handles auto-indent only."""
950
947
951 self.readline.insert_text(' '* self.readline_indent)
948 self.readline.insert_text(' '* self.readline_indent)
952
949
953 def init_readline(self):
950 def init_readline(self):
954 """Command history completion/saving/reloading."""
951 """Command history completion/saving/reloading."""
955 try:
952 try:
956 import readline
953 import readline
957 except ImportError:
954 except ImportError:
958 self.has_readline = 0
955 self.has_readline = 0
959 self.readline = None
956 self.readline = None
960 # no point in bugging windows users with this every time:
957 # no point in bugging windows users with this every time:
961 if os.name == 'posix':
958 if os.name == 'posix':
962 warn('Readline services not available on this platform.')
959 warn('Readline services not available on this platform.')
963 else:
960 else:
964 import atexit
961 import atexit
965 from IPython.completer import IPCompleter
962 from IPython.completer import IPCompleter
966 self.Completer = IPCompleter(self,
963 self.Completer = IPCompleter(self,
967 self.user_ns,
964 self.user_ns,
968 self.user_global_ns,
965 self.user_global_ns,
969 self.rc.readline_omit__names,
966 self.rc.readline_omit__names,
970 self.alias_table)
967 self.alias_table)
971
968
972 # Platform-specific configuration
969 # Platform-specific configuration
973 if os.name == 'nt':
970 if os.name == 'nt':
974 self.readline_startup_hook = readline.set_pre_input_hook
971 self.readline_startup_hook = readline.set_pre_input_hook
975 else:
972 else:
976 self.readline_startup_hook = readline.set_startup_hook
973 self.readline_startup_hook = readline.set_startup_hook
977
974
978 # Load user's initrc file (readline config)
975 # Load user's initrc file (readline config)
979 inputrc_name = os.environ.get('INPUTRC')
976 inputrc_name = os.environ.get('INPUTRC')
980 if inputrc_name is None:
977 if inputrc_name is None:
981 home_dir = get_home_dir()
978 home_dir = get_home_dir()
982 if home_dir is not None:
979 if home_dir is not None:
983 inputrc_name = os.path.join(home_dir,'.inputrc')
980 inputrc_name = os.path.join(home_dir,'.inputrc')
984 if os.path.isfile(inputrc_name):
981 if os.path.isfile(inputrc_name):
985 try:
982 try:
986 readline.read_init_file(inputrc_name)
983 readline.read_init_file(inputrc_name)
987 except:
984 except:
988 warn('Problems reading readline initialization file <%s>'
985 warn('Problems reading readline initialization file <%s>'
989 % inputrc_name)
986 % inputrc_name)
990
987
991 self.has_readline = 1
988 self.has_readline = 1
992 self.readline = readline
989 self.readline = readline
993 self.readline_indent = 0 # for auto-indenting via readline
990 self.readline_indent = 0 # for auto-indenting via readline
994 # save this in sys so embedded copies can restore it properly
991 # save this in sys so embedded copies can restore it properly
995 sys.ipcompleter = self.Completer.complete
992 sys.ipcompleter = self.Completer.complete
996 readline.set_completer(self.Completer.complete)
993 readline.set_completer(self.Completer.complete)
997
994
998 # Configure readline according to user's prefs
995 # Configure readline according to user's prefs
999 for rlcommand in self.rc.readline_parse_and_bind:
996 for rlcommand in self.rc.readline_parse_and_bind:
1000 readline.parse_and_bind(rlcommand)
997 readline.parse_and_bind(rlcommand)
1001
998
1002 # remove some chars from the delimiters list
999 # remove some chars from the delimiters list
1003 delims = readline.get_completer_delims()
1000 delims = readline.get_completer_delims()
1004 delims = delims.translate(string._idmap,
1001 delims = delims.translate(string._idmap,
1005 self.rc.readline_remove_delims)
1002 self.rc.readline_remove_delims)
1006 readline.set_completer_delims(delims)
1003 readline.set_completer_delims(delims)
1007 # otherwise we end up with a monster history after a while:
1004 # otherwise we end up with a monster history after a while:
1008 readline.set_history_length(1000)
1005 readline.set_history_length(1000)
1009 try:
1006 try:
1010 #print '*** Reading readline history' # dbg
1007 #print '*** Reading readline history' # dbg
1011 readline.read_history_file(self.histfile)
1008 readline.read_history_file(self.histfile)
1012 except IOError:
1009 except IOError:
1013 pass # It doesn't exist yet.
1010 pass # It doesn't exist yet.
1014
1011
1015 atexit.register(self.atexit_operations)
1012 atexit.register(self.atexit_operations)
1016 del atexit
1013 del atexit
1017
1014
1018 # Configure auto-indent for all platforms
1015 # Configure auto-indent for all platforms
1019 self.set_autoindent(self.rc.autoindent)
1016 self.set_autoindent(self.rc.autoindent)
1020
1017
1021 def showsyntaxerror(self, filename=None):
1018 def showsyntaxerror(self, filename=None):
1022 """Display the syntax error that just occurred.
1019 """Display the syntax error that just occurred.
1023
1020
1024 This doesn't display a stack trace because there isn't one.
1021 This doesn't display a stack trace because there isn't one.
1025
1022
1026 If a filename is given, it is stuffed in the exception instead
1023 If a filename is given, it is stuffed in the exception instead
1027 of what was there before (because Python's parser always uses
1024 of what was there before (because Python's parser always uses
1028 "<string>" when reading from a string).
1025 "<string>" when reading from a string).
1029 """
1026 """
1030 type, value, sys.last_traceback = sys.exc_info()
1027 type, value, sys.last_traceback = sys.exc_info()
1031 sys.last_type = type
1028 sys.last_type = type
1032 sys.last_value = value
1029 sys.last_value = value
1033 if filename and type is SyntaxError:
1030 if filename and type is SyntaxError:
1034 # Work hard to stuff the correct filename in the exception
1031 # Work hard to stuff the correct filename in the exception
1035 try:
1032 try:
1036 msg, (dummy_filename, lineno, offset, line) = value
1033 msg, (dummy_filename, lineno, offset, line) = value
1037 except:
1034 except:
1038 # Not the format we expect; leave it alone
1035 # Not the format we expect; leave it alone
1039 pass
1036 pass
1040 else:
1037 else:
1041 # Stuff in the right filename
1038 # Stuff in the right filename
1042 try:
1039 try:
1043 # Assume SyntaxError is a class exception
1040 # Assume SyntaxError is a class exception
1044 value = SyntaxError(msg, (filename, lineno, offset, line))
1041 value = SyntaxError(msg, (filename, lineno, offset, line))
1045 except:
1042 except:
1046 # If that failed, assume SyntaxError is a string
1043 # If that failed, assume SyntaxError is a string
1047 value = msg, (filename, lineno, offset, line)
1044 value = msg, (filename, lineno, offset, line)
1048 self.SyntaxTB(type,value,[])
1045 self.SyntaxTB(type,value,[])
1049
1046
1050 def debugger(self):
1047 def debugger(self):
1051 """Call the pdb debugger."""
1048 """Call the pdb debugger."""
1052
1049
1053 if not self.rc.pdb:
1050 if not self.rc.pdb:
1054 return
1051 return
1055 pdb.pm()
1052 pdb.pm()
1056
1053
1057 def showtraceback(self,exc_tuple = None,filename=None):
1054 def showtraceback(self,exc_tuple = None,filename=None):
1058 """Display the exception that just occurred."""
1055 """Display the exception that just occurred."""
1059
1056
1060 # Though this won't be called by syntax errors in the input line,
1057 # Though this won't be called by syntax errors in the input line,
1061 # there may be SyntaxError cases whith imported code.
1058 # there may be SyntaxError cases whith imported code.
1062 if exc_tuple is None:
1059 if exc_tuple is None:
1063 type, value, tb = sys.exc_info()
1060 type, value, tb = sys.exc_info()
1064 else:
1061 else:
1065 type, value, tb = exc_tuple
1062 type, value, tb = exc_tuple
1066 if type is SyntaxError:
1063 if type is SyntaxError:
1067 self.showsyntaxerror(filename)
1064 self.showsyntaxerror(filename)
1068 else:
1065 else:
1069 sys.last_type = type
1066 sys.last_type = type
1070 sys.last_value = value
1067 sys.last_value = value
1071 sys.last_traceback = tb
1068 sys.last_traceback = tb
1072 self.InteractiveTB()
1069 self.InteractiveTB()
1073 if self.InteractiveTB.call_pdb and self.has_readline:
1070 if self.InteractiveTB.call_pdb and self.has_readline:
1074 # pdb mucks up readline, fix it back
1071 # pdb mucks up readline, fix it back
1075 self.readline.set_completer(self.Completer.complete)
1072 self.readline.set_completer(self.Completer.complete)
1076
1073
1077 def update_cache(self, line):
1074 def update_cache(self, line):
1078 """puts line into cache"""
1075 """puts line into cache"""
1079 self.inputcache.insert(0, line) # This copies the cache every time ... :-(
1076 self.inputcache.insert(0, line) # This copies the cache every time ... :-(
1080 if len(self.inputcache) >= self.CACHELENGTH:
1077 if len(self.inputcache) >= self.CACHELENGTH:
1081 self.inputcache.pop() # This doesn't :-)
1078 self.inputcache.pop() # This doesn't :-)
1082
1079
1083 def mainloop(self,banner=None):
1080 def mainloop(self,banner=None):
1084 """Creates the local namespace and starts the mainloop.
1081 """Creates the local namespace and starts the mainloop.
1085
1082
1086 If an optional banner argument is given, it will override the
1083 If an optional banner argument is given, it will override the
1087 internally created default banner."""
1084 internally created default banner."""
1088
1085
1089 if self.rc.c: # Emulate Python's -c option
1086 if self.rc.c: # Emulate Python's -c option
1090 self.exec_init_cmd()
1087 self.exec_init_cmd()
1091 if banner is None:
1088 if banner is None:
1092 if self.rc.banner:
1089 if self.rc.banner:
1093 banner = self.BANNER+self.banner2
1090 banner = self.BANNER+self.banner2
1094 else:
1091 else:
1095 banner = ''
1092 banner = ''
1096 self.interact(banner)
1093 self.interact(banner)
1097
1094
1098 def exec_init_cmd(self):
1095 def exec_init_cmd(self):
1099 """Execute a command given at the command line.
1096 """Execute a command given at the command line.
1100
1097
1101 This emulates Python's -c option."""
1098 This emulates Python's -c option."""
1102
1099
1103 sys.argv = ['-c']
1100 sys.argv = ['-c']
1104 self.push(self.rc.c)
1101 self.push(self.rc.c)
1105
1102
1106 def embed_mainloop(self,header='',local_ns=None,global_ns=None,stack_depth=0):
1103 def embed_mainloop(self,header='',local_ns=None,global_ns=None,stack_depth=0):
1107 """Embeds IPython into a running python program.
1104 """Embeds IPython into a running python program.
1108
1105
1109 Input:
1106 Input:
1110
1107
1111 - header: An optional header message can be specified.
1108 - header: An optional header message can be specified.
1112
1109
1113 - local_ns, global_ns: working namespaces. If given as None, the
1110 - local_ns, global_ns: working namespaces. If given as None, the
1114 IPython-initialized one is updated with __main__.__dict__, so that
1111 IPython-initialized one is updated with __main__.__dict__, so that
1115 program variables become visible but user-specific configuration
1112 program variables become visible but user-specific configuration
1116 remains possible.
1113 remains possible.
1117
1114
1118 - stack_depth: specifies how many levels in the stack to go to
1115 - stack_depth: specifies how many levels in the stack to go to
1119 looking for namespaces (when local_ns and global_ns are None). This
1116 looking for namespaces (when local_ns and global_ns are None). This
1120 allows an intermediate caller to make sure that this function gets
1117 allows an intermediate caller to make sure that this function gets
1121 the namespace from the intended level in the stack. By default (0)
1118 the namespace from the intended level in the stack. By default (0)
1122 it will get its locals and globals from the immediate caller.
1119 it will get its locals and globals from the immediate caller.
1123
1120
1124 Warning: it's possible to use this in a program which is being run by
1121 Warning: it's possible to use this in a program which is being run by
1125 IPython itself (via %run), but some funny things will happen (a few
1122 IPython itself (via %run), but some funny things will happen (a few
1126 globals get overwritten). In the future this will be cleaned up, as
1123 globals get overwritten). In the future this will be cleaned up, as
1127 there is no fundamental reason why it can't work perfectly."""
1124 there is no fundamental reason why it can't work perfectly."""
1128
1125
1129 # Get locals and globals from caller
1126 # Get locals and globals from caller
1130 if local_ns is None or global_ns is None:
1127 if local_ns is None or global_ns is None:
1131 call_frame = sys._getframe(stack_depth).f_back
1128 call_frame = sys._getframe(stack_depth).f_back
1132
1129
1133 if local_ns is None:
1130 if local_ns is None:
1134 local_ns = call_frame.f_locals
1131 local_ns = call_frame.f_locals
1135 if global_ns is None:
1132 if global_ns is None:
1136 global_ns = call_frame.f_globals
1133 global_ns = call_frame.f_globals
1137
1134
1138 # Update namespaces and fire up interpreter
1135 # Update namespaces and fire up interpreter
1139 self.user_ns = local_ns
1136 self.user_ns = local_ns
1140 self.user_global_ns = global_ns
1137 self.user_global_ns = global_ns
1141
1138
1142 # Patch for global embedding to make sure that things don't overwrite
1139 # Patch for global embedding to make sure that things don't overwrite
1143 # user globals accidentally. Thanks to Richard <rxe@renre-europe.com>
1140 # user globals accidentally. Thanks to Richard <rxe@renre-europe.com>
1144 # FIXME. Test this a bit more carefully (the if.. is new)
1141 # FIXME. Test this a bit more carefully (the if.. is new)
1145 if local_ns is None and global_ns is None:
1142 if local_ns is None and global_ns is None:
1146 self.user_global_ns.update(__main__.__dict__)
1143 self.user_global_ns.update(__main__.__dict__)
1147
1144
1148 # make sure the tab-completer has the correct frame information, so it
1145 # make sure the tab-completer has the correct frame information, so it
1149 # actually completes using the frame's locals/globals
1146 # actually completes using the frame's locals/globals
1150 self.set_completer_frame(call_frame)
1147 self.set_completer_frame(call_frame)
1151
1148
1152 self.interact(header)
1149 self.interact(header)
1153
1150
1154 def interact(self, banner=None):
1151 def interact(self, banner=None):
1155 """Closely emulate the interactive Python console.
1152 """Closely emulate the interactive Python console.
1156
1153
1157 The optional banner argument specify the banner to print
1154 The optional banner argument specify the banner to print
1158 before the first interaction; by default it prints a banner
1155 before the first interaction; by default it prints a banner
1159 similar to the one printed by the real Python interpreter,
1156 similar to the one printed by the real Python interpreter,
1160 followed by the current class name in parentheses (so as not
1157 followed by the current class name in parentheses (so as not
1161 to confuse this with the real interpreter -- since it's so
1158 to confuse this with the real interpreter -- since it's so
1162 close!).
1159 close!).
1163
1160
1164 """
1161 """
1165 cprt = 'Type "copyright", "credits" or "license" for more information.'
1162 cprt = 'Type "copyright", "credits" or "license" for more information.'
1166 if banner is None:
1163 if banner is None:
1167 self.write("Python %s on %s\n%s\n(%s)\n" %
1164 self.write("Python %s on %s\n%s\n(%s)\n" %
1168 (sys.version, sys.platform, cprt,
1165 (sys.version, sys.platform, cprt,
1169 self.__class__.__name__))
1166 self.__class__.__name__))
1170 else:
1167 else:
1171 self.write(banner)
1168 self.write(banner)
1172
1169
1173 more = 0
1170 more = 0
1174
1171
1175 # Mark activity in the builtins
1172 # Mark activity in the builtins
1176 __builtin__.__dict__['__IPYTHON__active'] += 1
1173 __builtin__.__dict__['__IPYTHON__active'] += 1
1177
1174
1178 # compiled regexps for autoindent management
1175 # compiled regexps for autoindent management
1179 ini_spaces_re = re.compile(r'^(\s+)')
1176 ini_spaces_re = re.compile(r'^(\s+)')
1180 dedent_re = re.compile(r'^\s+raise|^\s+return')
1177 dedent_re = re.compile(r'^\s+raise|^\s+return')
1181
1178
1182 # exit_now is set by a call to %Exit or %Quit
1179 # exit_now is set by a call to %Exit or %Quit
1183 while not self.exit_now:
1180 while not self.exit_now:
1184 try:
1181 try:
1185 if more:
1182 if more:
1186 prompt = self.outputcache.prompt2
1183 prompt = self.outputcache.prompt2
1187 if self.autoindent:
1184 if self.autoindent:
1188 self.readline_startup_hook(self.pre_readline)
1185 self.readline_startup_hook(self.pre_readline)
1189 else:
1186 else:
1190 prompt = self.outputcache.prompt1
1187 prompt = self.outputcache.prompt1
1191 try:
1188 try:
1192 line = self.raw_input(prompt,more)
1189 line = self.raw_input(prompt,more)
1193 if self.autoindent:
1190 if self.autoindent:
1194 self.readline_startup_hook(None)
1191 self.readline_startup_hook(None)
1195 except EOFError:
1192 except EOFError:
1196 if self.autoindent:
1193 if self.autoindent:
1197 self.readline_startup_hook(None)
1194 self.readline_startup_hook(None)
1198 self.write("\n")
1195 self.write("\n")
1199 self.exit()
1196 self.exit()
1200 except IPythonExit:
1197 except IPythonExit:
1201 self.exit()
1198 self.exit()
1202 else:
1199 else:
1203 more = self.push(line)
1200 more = self.push(line)
1204 # Auto-indent management
1201 # Auto-indent management
1205 if self.autoindent:
1202 if self.autoindent:
1206 if line:
1203 if line:
1207 ini_spaces = ini_spaces_re.match(line)
1204 ini_spaces = ini_spaces_re.match(line)
1208 if ini_spaces:
1205 if ini_spaces:
1209 nspaces = ini_spaces.end()
1206 nspaces = ini_spaces.end()
1210 else:
1207 else:
1211 nspaces = 0
1208 nspaces = 0
1212 self.readline_indent = nspaces
1209 self.readline_indent = nspaces
1213
1210
1214 if line[-1] == ':':
1211 if line[-1] == ':':
1215 self.readline_indent += 4
1212 self.readline_indent += 4
1216 elif dedent_re.match(line):
1213 elif dedent_re.match(line):
1217 self.readline_indent -= 4
1214 self.readline_indent -= 4
1218 else:
1215 else:
1219 self.readline_indent = 0
1216 self.readline_indent = 0
1220
1217
1221 except KeyboardInterrupt:
1218 except KeyboardInterrupt:
1222 self.write("\nKeyboardInterrupt\n")
1219 self.write("\nKeyboardInterrupt\n")
1223 self.resetbuffer()
1220 self.resetbuffer()
1224 more = 0
1221 more = 0
1225 # keep cache in sync with the prompt counter:
1222 # keep cache in sync with the prompt counter:
1226 self.outputcache.prompt_count -= 1
1223 self.outputcache.prompt_count -= 1
1227
1224
1228 if self.autoindent:
1225 if self.autoindent:
1229 self.readline_indent = 0
1226 self.readline_indent = 0
1230
1227
1231 except bdb.BdbQuit:
1228 except bdb.BdbQuit:
1232 warn("The Python debugger has exited with a BdbQuit exception.\n"
1229 warn("The Python debugger has exited with a BdbQuit exception.\n"
1233 "Because of how pdb handles the stack, it is impossible\n"
1230 "Because of how pdb handles the stack, it is impossible\n"
1234 "for IPython to properly format this particular exception.\n"
1231 "for IPython to properly format this particular exception.\n"
1235 "IPython will resume normal operation.")
1232 "IPython will resume normal operation.")
1236
1233
1237 # We are off again...
1234 # We are off again...
1238 __builtin__.__dict__['__IPYTHON__active'] -= 1
1235 __builtin__.__dict__['__IPYTHON__active'] -= 1
1239
1236
1240 def excepthook(self, type, value, tb):
1237 def excepthook(self, type, value, tb):
1241 """One more defense for GUI apps that call sys.excepthook.
1238 """One more defense for GUI apps that call sys.excepthook.
1242
1239
1243 GUI frameworks like wxPython trap exceptions and call
1240 GUI frameworks like wxPython trap exceptions and call
1244 sys.excepthook themselves. I guess this is a feature that
1241 sys.excepthook themselves. I guess this is a feature that
1245 enables them to keep running after exceptions that would
1242 enables them to keep running after exceptions that would
1246 otherwise kill their mainloop. This is a bother for IPython
1243 otherwise kill their mainloop. This is a bother for IPython
1247 which excepts to catch all of the program exceptions with a try:
1244 which excepts to catch all of the program exceptions with a try:
1248 except: statement.
1245 except: statement.
1249
1246
1250 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
1247 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
1251 any app directly invokes sys.excepthook, it will look to the user like
1248 any app directly invokes sys.excepthook, it will look to the user like
1252 IPython crashed. In order to work around this, we can disable the
1249 IPython crashed. In order to work around this, we can disable the
1253 CrashHandler and replace it with this excepthook instead, which prints a
1250 CrashHandler and replace it with this excepthook instead, which prints a
1254 regular traceback using our InteractiveTB. In this fashion, apps which
1251 regular traceback using our InteractiveTB. In this fashion, apps which
1255 call sys.excepthook will generate a regular-looking exception from
1252 call sys.excepthook will generate a regular-looking exception from
1256 IPython, and the CrashHandler will only be triggered by real IPython
1253 IPython, and the CrashHandler will only be triggered by real IPython
1257 crashes.
1254 crashes.
1258
1255
1259 This hook should be used sparingly, only in places which are not likely
1256 This hook should be used sparingly, only in places which are not likely
1260 to be true IPython errors.
1257 to be true IPython errors.
1261 """
1258 """
1262
1259
1263 self.InteractiveTB(type, value, tb, tb_offset=0)
1260 self.InteractiveTB(type, value, tb, tb_offset=0)
1264 if self.InteractiveTB.call_pdb and self.has_readline:
1261 if self.InteractiveTB.call_pdb and self.has_readline:
1265 self.readline.set_completer(self.Completer.complete)
1262 self.readline.set_completer(self.Completer.complete)
1266
1263
1267 def call_alias(self,alias,rest=''):
1264 def call_alias(self,alias,rest=''):
1268 """Call an alias given its name and the rest of the line.
1265 """Call an alias given its name and the rest of the line.
1269
1266
1270 This function MUST be given a proper alias, because it doesn't make
1267 This function MUST be given a proper alias, because it doesn't make
1271 any checks when looking up into the alias table. The caller is
1268 any checks when looking up into the alias table. The caller is
1272 responsible for invoking it only with a valid alias."""
1269 responsible for invoking it only with a valid alias."""
1273
1270
1274 #print 'ALIAS: <%s>+<%s>' % (alias,rest) # dbg
1271 #print 'ALIAS: <%s>+<%s>' % (alias,rest) # dbg
1275 nargs,cmd = self.alias_table[alias]
1272 nargs,cmd = self.alias_table[alias]
1276 # Expand the %l special to be the user's input line
1273 # Expand the %l special to be the user's input line
1277 if cmd.find('%l') >= 0:
1274 if cmd.find('%l') >= 0:
1278 cmd = cmd.replace('%l',rest)
1275 cmd = cmd.replace('%l',rest)
1279 rest = ''
1276 rest = ''
1280 if nargs==0:
1277 if nargs==0:
1281 # Simple, argument-less aliases
1278 # Simple, argument-less aliases
1282 cmd = '%s %s' % (cmd,rest)
1279 cmd = '%s %s' % (cmd,rest)
1283 else:
1280 else:
1284 # Handle aliases with positional arguments
1281 # Handle aliases with positional arguments
1285 args = rest.split(None,nargs)
1282 args = rest.split(None,nargs)
1286 if len(args)< nargs:
1283 if len(args)< nargs:
1287 error('Alias <%s> requires %s arguments, %s given.' %
1284 error('Alias <%s> requires %s arguments, %s given.' %
1288 (alias,nargs,len(args)))
1285 (alias,nargs,len(args)))
1289 return
1286 return
1290 cmd = '%s %s' % (cmd % tuple(args[:nargs]),' '.join(args[nargs:]))
1287 cmd = '%s %s' % (cmd % tuple(args[:nargs]),' '.join(args[nargs:]))
1291 # Now call the macro, evaluating in the user's namespace
1288 # Now call the macro, evaluating in the user's namespace
1292 try:
1289 try:
1293 self.system(cmd)
1290 self.system(cmd)
1294 except:
1291 except:
1295 self.showtraceback()
1292 self.showtraceback()
1296
1293
1297 def runlines(self,lines):
1294 def runlines(self,lines):
1298 """Run a string of one or more lines of source.
1295 """Run a string of one or more lines of source.
1299
1296
1300 This method is capable of running a string containing multiple source
1297 This method is capable of running a string containing multiple source
1301 lines, as if they had been entered at the IPython prompt. Since it
1298 lines, as if they had been entered at the IPython prompt. Since it
1302 exposes IPython's processing machinery, the given strings can contain
1299 exposes IPython's processing machinery, the given strings can contain
1303 magic calls (%magic), special shell access (!cmd), etc."""
1300 magic calls (%magic), special shell access (!cmd), etc."""
1304
1301
1305 # We must start with a clean buffer, in case this is run from an
1302 # We must start with a clean buffer, in case this is run from an
1306 # interactive IPython session (via a magic, for example).
1303 # interactive IPython session (via a magic, for example).
1307 self.resetbuffer()
1304 self.resetbuffer()
1308 lines = lines.split('\n')
1305 lines = lines.split('\n')
1309 more = 0
1306 more = 0
1310 for line in lines:
1307 for line in lines:
1311 # skip blank lines so we don't mess up the prompt counter, but do
1308 # skip blank lines so we don't mess up the prompt counter, but do
1312 # NOT skip even a blank line if we are in a code block (more is
1309 # NOT skip even a blank line if we are in a code block (more is
1313 # true)
1310 # true)
1314 if line or more:
1311 if line or more:
1315 more = self.push((self.prefilter(line,more)))
1312 more = self.push((self.prefilter(line,more)))
1316 # IPython's runsource returns None if there was an error
1313 # IPython's runsource returns None if there was an error
1317 # compiling the code. This allows us to stop processing right
1314 # compiling the code. This allows us to stop processing right
1318 # away, so the user gets the error message at the right place.
1315 # away, so the user gets the error message at the right place.
1319 if more is None:
1316 if more is None:
1320 break
1317 break
1321 # final newline in case the input didn't have it, so that the code
1318 # final newline in case the input didn't have it, so that the code
1322 # actually does get executed
1319 # actually does get executed
1323 if more:
1320 if more:
1324 self.push('\n')
1321 self.push('\n')
1325
1322
1326 def runsource(self, source, filename="<input>", symbol="single"):
1323 def runsource(self, source, filename="<input>", symbol="single"):
1327 """Compile and run some source in the interpreter.
1324 """Compile and run some source in the interpreter.
1328
1325
1329 Arguments are as for compile_command().
1326 Arguments are as for compile_command().
1330
1327
1331 One several things can happen:
1328 One several things can happen:
1332
1329
1333 1) The input is incorrect; compile_command() raised an
1330 1) The input is incorrect; compile_command() raised an
1334 exception (SyntaxError or OverflowError). A syntax traceback
1331 exception (SyntaxError or OverflowError). A syntax traceback
1335 will be printed by calling the showsyntaxerror() method.
1332 will be printed by calling the showsyntaxerror() method.
1336
1333
1337 2) The input is incomplete, and more input is required;
1334 2) The input is incomplete, and more input is required;
1338 compile_command() returned None. Nothing happens.
1335 compile_command() returned None. Nothing happens.
1339
1336
1340 3) The input is complete; compile_command() returned a code
1337 3) The input is complete; compile_command() returned a code
1341 object. The code is executed by calling self.runcode() (which
1338 object. The code is executed by calling self.runcode() (which
1342 also handles run-time exceptions, except for SystemExit).
1339 also handles run-time exceptions, except for SystemExit).
1343
1340
1344 The return value is:
1341 The return value is:
1345
1342
1346 - True in case 2
1343 - True in case 2
1347
1344
1348 - False in the other cases, unless an exception is raised, where
1345 - False in the other cases, unless an exception is raised, where
1349 None is returned instead. This can be used by external callers to
1346 None is returned instead. This can be used by external callers to
1350 know whether to continue feeding input or not.
1347 know whether to continue feeding input or not.
1351
1348
1352 The return value can be used to decide whether to use sys.ps1 or
1349 The return value can be used to decide whether to use sys.ps1 or
1353 sys.ps2 to prompt the next line."""
1350 sys.ps2 to prompt the next line."""
1354
1351
1355 try:
1352 try:
1356 code = self.compile(source, filename, symbol)
1353 code = self.compile(source, filename, symbol)
1357 except (OverflowError, SyntaxError, ValueError):
1354 except (OverflowError, SyntaxError, ValueError):
1358 # Case 1
1355 # Case 1
1359 self.showsyntaxerror(filename)
1356 self.showsyntaxerror(filename)
1360 return None
1357 return None
1361
1358
1362 if code is None:
1359 if code is None:
1363 # Case 2
1360 # Case 2
1364 return True
1361 return True
1365
1362
1366 # Case 3
1363 # Case 3
1367 # We store the code object so that threaded shells and
1364 # We store the code object so that threaded shells and
1368 # custom exception handlers can access all this info if needed.
1365 # custom exception handlers can access all this info if needed.
1369 # The source corresponding to this can be obtained from the
1366 # The source corresponding to this can be obtained from the
1370 # buffer attribute as '\n'.join(self.buffer).
1367 # buffer attribute as '\n'.join(self.buffer).
1371 self.code_to_run = code
1368 self.code_to_run = code
1372 # now actually execute the code object
1369 # now actually execute the code object
1373 if self.runcode(code) == 0:
1370 if self.runcode(code) == 0:
1374 return False
1371 return False
1375 else:
1372 else:
1376 return None
1373 return None
1377
1374
1378 def runcode(self,code_obj):
1375 def runcode(self,code_obj):
1379 """Execute a code object.
1376 """Execute a code object.
1380
1377
1381 When an exception occurs, self.showtraceback() is called to display a
1378 When an exception occurs, self.showtraceback() is called to display a
1382 traceback.
1379 traceback.
1383
1380
1384 Return value: a flag indicating whether the code to be run completed
1381 Return value: a flag indicating whether the code to be run completed
1385 successfully:
1382 successfully:
1386
1383
1387 - 0: successful execution.
1384 - 0: successful execution.
1388 - 1: an error occurred.
1385 - 1: an error occurred.
1389 """
1386 """
1390
1387
1391 # Set our own excepthook in case the user code tries to call it
1388 # Set our own excepthook in case the user code tries to call it
1392 # directly, so that the IPython crash handler doesn't get triggered
1389 # directly, so that the IPython crash handler doesn't get triggered
1393 old_excepthook,sys.excepthook = sys.excepthook, self.excepthook
1390 old_excepthook,sys.excepthook = sys.excepthook, self.excepthook
1394 outflag = 1 # happens in more places, so it's easier as default
1391 outflag = 1 # happens in more places, so it's easier as default
1395 try:
1392 try:
1396 try:
1393 try:
1397 # Embedded instances require separate global/local namespaces
1394 # Embedded instances require separate global/local namespaces
1398 # so they can see both the surrounding (local) namespace and
1395 # so they can see both the surrounding (local) namespace and
1399 # the module-level globals when called inside another function.
1396 # the module-level globals when called inside another function.
1400 if self.embedded:
1397 if self.embedded:
1401 exec code_obj in self.user_global_ns, self.user_ns
1398 exec code_obj in self.user_global_ns, self.user_ns
1402 # Normal (non-embedded) instances should only have a single
1399 # Normal (non-embedded) instances should only have a single
1403 # namespace for user code execution, otherwise functions won't
1400 # namespace for user code execution, otherwise functions won't
1404 # see interactive top-level globals.
1401 # see interactive top-level globals.
1405 else:
1402 else:
1406 exec code_obj in self.user_ns
1403 exec code_obj in self.user_ns
1407 finally:
1404 finally:
1408 # Reset our crash handler in place
1405 # Reset our crash handler in place
1409 sys.excepthook = old_excepthook
1406 sys.excepthook = old_excepthook
1410 except SystemExit:
1407 except SystemExit:
1411 self.resetbuffer()
1408 self.resetbuffer()
1412 self.showtraceback()
1409 self.showtraceback()
1413 warn("Type exit or quit to exit IPython "
1410 warn("Type exit or quit to exit IPython "
1414 "(%Exit or %Quit do so unconditionally).",level=1)
1411 "(%Exit or %Quit do so unconditionally).",level=1)
1415 except self.custom_exceptions:
1412 except self.custom_exceptions:
1416 etype,value,tb = sys.exc_info()
1413 etype,value,tb = sys.exc_info()
1417 self.CustomTB(etype,value,tb)
1414 self.CustomTB(etype,value,tb)
1418 except:
1415 except:
1419 self.showtraceback()
1416 self.showtraceback()
1420 else:
1417 else:
1421 outflag = 0
1418 outflag = 0
1422 if softspace(sys.stdout, 0):
1419 if softspace(sys.stdout, 0):
1423 print
1420 print
1424 # Flush out code object which has been run (and source)
1421 # Flush out code object which has been run (and source)
1425 self.code_to_run = None
1422 self.code_to_run = None
1426 return outflag
1423 return outflag
1427
1424
1428 def push(self, line):
1425 def push(self, line):
1429 """Push a line to the interpreter.
1426 """Push a line to the interpreter.
1430
1427
1431 The line should not have a trailing newline; it may have
1428 The line should not have a trailing newline; it may have
1432 internal newlines. The line is appended to a buffer and the
1429 internal newlines. The line is appended to a buffer and the
1433 interpreter's runsource() method is called with the
1430 interpreter's runsource() method is called with the
1434 concatenated contents of the buffer as source. If this
1431 concatenated contents of the buffer as source. If this
1435 indicates that the command was executed or invalid, the buffer
1432 indicates that the command was executed or invalid, the buffer
1436 is reset; otherwise, the command is incomplete, and the buffer
1433 is reset; otherwise, the command is incomplete, and the buffer
1437 is left as it was after the line was appended. The return
1434 is left as it was after the line was appended. The return
1438 value is 1 if more input is required, 0 if the line was dealt
1435 value is 1 if more input is required, 0 if the line was dealt
1439 with in some way (this is the same as runsource()).
1436 with in some way (this is the same as runsource()).
1440
1437
1441 """
1438 """
1442 self.buffer.append(line)
1439 self.buffer.append(line)
1443 source = "\n".join(self.buffer)
1440 more = self.runsource('\n'.join(self.buffer), self.filename)
1444 more = self.runsource(source, self.filename)
1445 if not more:
1441 if not more:
1446 self.resetbuffer()
1442 self.resetbuffer()
1447 return more
1443 return more
1448
1444
1449 def resetbuffer(self):
1445 def resetbuffer(self):
1450 """Reset the input buffer."""
1446 """Reset the input buffer."""
1451 self.buffer[:] = []
1447 self.buffer[:] = []
1452
1448
1453 def raw_input(self,prompt='',continue_prompt=False):
1449 def raw_input(self,prompt='',continue_prompt=False):
1454 """Write a prompt and read a line.
1450 """Write a prompt and read a line.
1455
1451
1456 The returned line does not include the trailing newline.
1452 The returned line does not include the trailing newline.
1457 When the user enters the EOF key sequence, EOFError is raised.
1453 When the user enters the EOF key sequence, EOFError is raised.
1458
1454
1459 Optional inputs:
1455 Optional inputs:
1460
1456
1461 - prompt(''): a string to be printed to prompt the user.
1457 - prompt(''): a string to be printed to prompt the user.
1462
1458
1463 - continue_prompt(False): whether this line is the first one or a
1459 - continue_prompt(False): whether this line is the first one or a
1464 continuation in a sequence of inputs.
1460 continuation in a sequence of inputs.
1465 """
1461 """
1466
1462
1467 line = raw_input_original(prompt)
1463 line = raw_input_original(prompt)
1468 # Try to be reasonably smart about not re-indenting pasted input more
1464 # Try to be reasonably smart about not re-indenting pasted input more
1469 # than necessary. We do this by trimming out the auto-indent initial
1465 # than necessary. We do this by trimming out the auto-indent initial
1470 # spaces, if the user's actual input started itself with whitespace.
1466 # spaces, if the user's actual input started itself with whitespace.
1471 if self.autoindent:
1467 if self.autoindent:
1472 line2 = line[self.readline_indent:]
1468 line2 = line[self.readline_indent:]
1473 if line2[0:1] in (' ','\t'):
1469 if line2[0:1] in (' ','\t'):
1474 line = line2
1470 line = line2
1475 return self.prefilter(line,continue_prompt)
1471 return self.prefilter(line,continue_prompt)
1476
1472
1477 def split_user_input(self,line):
1473 def split_user_input(self,line):
1478 """Split user input into pre-char, function part and rest."""
1474 """Split user input into pre-char, function part and rest."""
1479
1475
1480 lsplit = self.line_split.match(line)
1476 lsplit = self.line_split.match(line)
1481 if lsplit is None: # no regexp match returns None
1477 if lsplit is None: # no regexp match returns None
1482 try:
1478 try:
1483 iFun,theRest = line.split(None,1)
1479 iFun,theRest = line.split(None,1)
1484 except ValueError:
1480 except ValueError:
1485 iFun,theRest = line,''
1481 iFun,theRest = line,''
1486 pre = re.match('^(\s*)(.*)',line).groups()[0]
1482 pre = re.match('^(\s*)(.*)',line).groups()[0]
1487 else:
1483 else:
1488 pre,iFun,theRest = lsplit.groups()
1484 pre,iFun,theRest = lsplit.groups()
1489
1485
1490 #print 'line:<%s>' % line # dbg
1486 #print 'line:<%s>' % line # dbg
1491 #print 'pre <%s> iFun <%s> rest <%s>' % (pre,iFun.strip(),theRest) # dbg
1487 #print 'pre <%s> iFun <%s> rest <%s>' % (pre,iFun.strip(),theRest) # dbg
1492 return pre,iFun.strip(),theRest
1488 return pre,iFun.strip(),theRest
1493
1489
1494 def _prefilter(self, line, continue_prompt):
1490 def _prefilter(self, line, continue_prompt):
1495 """Calls different preprocessors, depending on the form of line."""
1491 """Calls different preprocessors, depending on the form of line."""
1496
1492
1497 # All handlers *must* return a value, even if it's blank ('').
1493 # All handlers *must* return a value, even if it's blank ('').
1498
1494
1499 # Lines are NOT logged here. Handlers should process the line as
1495 # Lines are NOT logged here. Handlers should process the line as
1500 # needed, update the cache AND log it (so that the input cache array
1496 # needed, update the cache AND log it (so that the input cache array
1501 # stays synced).
1497 # stays synced).
1502
1498
1503 # This function is _very_ delicate, and since it's also the one which
1499 # This function is _very_ delicate, and since it's also the one which
1504 # determines IPython's response to user input, it must be as efficient
1500 # determines IPython's response to user input, it must be as efficient
1505 # as possible. For this reason it has _many_ returns in it, trying
1501 # as possible. For this reason it has _many_ returns in it, trying
1506 # always to exit as quickly as it can figure out what it needs to do.
1502 # always to exit as quickly as it can figure out what it needs to do.
1507
1503
1508 # This function is the main responsible for maintaining IPython's
1504 # This function is the main responsible for maintaining IPython's
1509 # behavior respectful of Python's semantics. So be _very_ careful if
1505 # behavior respectful of Python's semantics. So be _very_ careful if
1510 # making changes to anything here.
1506 # making changes to anything here.
1511
1507
1512 #.....................................................................
1508 #.....................................................................
1513 # Code begins
1509 # Code begins
1514
1510
1515 #if line.startswith('%crash'): raise RuntimeError,'Crash now!' # dbg
1511 #if line.startswith('%crash'): raise RuntimeError,'Crash now!' # dbg
1516
1512
1517 # save the line away in case we crash, so the post-mortem handler can
1513 # save the line away in case we crash, so the post-mortem handler can
1518 # record it
1514 # record it
1519 self._last_input_line = line
1515 self._last_input_line = line
1520
1516
1521 #print '***line: <%s>' % line # dbg
1517 #print '***line: <%s>' % line # dbg
1522
1518
1523 # the input history needs to track even empty lines
1519 # the input history needs to track even empty lines
1524 if not line.strip():
1520 if not line.strip():
1525 if not continue_prompt:
1521 if not continue_prompt:
1526 self.outputcache.prompt_count -= 1
1522 self.outputcache.prompt_count -= 1
1527 return self.handle_normal('',continue_prompt)
1523 return self.handle_normal('',continue_prompt)
1528
1524
1529 # print '***cont',continue_prompt # dbg
1525 # print '***cont',continue_prompt # dbg
1530 # special handlers are only allowed for single line statements
1526 # special handlers are only allowed for single line statements
1531 if continue_prompt and not self.rc.multi_line_specials:
1527 if continue_prompt and not self.rc.multi_line_specials:
1532 return self.handle_normal(line,continue_prompt)
1528 return self.handle_normal(line,continue_prompt)
1533
1529
1534 # For the rest, we need the structure of the input
1530 # For the rest, we need the structure of the input
1535 pre,iFun,theRest = self.split_user_input(line)
1531 pre,iFun,theRest = self.split_user_input(line)
1536 #print 'pre <%s> iFun <%s> rest <%s>' % (pre,iFun,theRest) # dbg
1532 #print 'pre <%s> iFun <%s> rest <%s>' % (pre,iFun,theRest) # dbg
1537
1533
1538 # First check for explicit escapes in the last/first character
1534 # First check for explicit escapes in the last/first character
1539 handler = None
1535 handler = None
1540 if line[-1] == self.ESC_HELP:
1536 if line[-1] == self.ESC_HELP:
1541 handler = self.esc_handlers.get(line[-1]) # the ? can be at the end
1537 handler = self.esc_handlers.get(line[-1]) # the ? can be at the end
1542 if handler is None:
1538 if handler is None:
1543 # look at the first character of iFun, NOT of line, so we skip
1539 # look at the first character of iFun, NOT of line, so we skip
1544 # leading whitespace in multiline input
1540 # leading whitespace in multiline input
1545 handler = self.esc_handlers.get(iFun[0:1])
1541 handler = self.esc_handlers.get(iFun[0:1])
1546 if handler is not None:
1542 if handler is not None:
1547 return handler(line,continue_prompt,pre,iFun,theRest)
1543 return handler(line,continue_prompt,pre,iFun,theRest)
1548 # Emacs ipython-mode tags certain input lines
1544 # Emacs ipython-mode tags certain input lines
1549 if line.endswith('# PYTHON-MODE'):
1545 if line.endswith('# PYTHON-MODE'):
1550 return self.handle_emacs(line,continue_prompt)
1546 return self.handle_emacs(line,continue_prompt)
1551
1547
1552 # Next, check if we can automatically execute this thing
1548 # Next, check if we can automatically execute this thing
1553
1549
1554 # Allow ! in multi-line statements if multi_line_specials is on:
1550 # Allow ! in multi-line statements if multi_line_specials is on:
1555 if continue_prompt and self.rc.multi_line_specials and \
1551 if continue_prompt and self.rc.multi_line_specials and \
1556 iFun.startswith(self.ESC_SHELL):
1552 iFun.startswith(self.ESC_SHELL):
1557 return self.handle_shell_escape(line,continue_prompt,
1553 return self.handle_shell_escape(line,continue_prompt,
1558 pre=pre,iFun=iFun,
1554 pre=pre,iFun=iFun,
1559 theRest=theRest)
1555 theRest=theRest)
1560
1556
1561 # Let's try to find if the input line is a magic fn
1557 # Let's try to find if the input line is a magic fn
1562 oinfo = None
1558 oinfo = None
1563 if hasattr(self,'magic_'+iFun):
1559 if hasattr(self,'magic_'+iFun):
1564 oinfo = self._ofind(iFun) # FIXME - _ofind is part of Magic
1560 oinfo = self._ofind(iFun) # FIXME - _ofind is part of Magic
1565 if oinfo['ismagic']:
1561 if oinfo['ismagic']:
1566 # Be careful not to call magics when a variable assignment is
1562 # Be careful not to call magics when a variable assignment is
1567 # being made (ls='hi', for example)
1563 # being made (ls='hi', for example)
1568 if self.rc.automagic and \
1564 if self.rc.automagic and \
1569 (len(theRest)==0 or theRest[0] not in '!=()<>,') and \
1565 (len(theRest)==0 or theRest[0] not in '!=()<>,') and \
1570 (self.rc.multi_line_specials or not continue_prompt):
1566 (self.rc.multi_line_specials or not continue_prompt):
1571 return self.handle_magic(line,continue_prompt,
1567 return self.handle_magic(line,continue_prompt,
1572 pre,iFun,theRest)
1568 pre,iFun,theRest)
1573 else:
1569 else:
1574 return self.handle_normal(line,continue_prompt)
1570 return self.handle_normal(line,continue_prompt)
1575
1571
1576 # If the rest of the line begins with an (in)equality, assginment or
1572 # If the rest of the line begins with an (in)equality, assginment or
1577 # function call, we should not call _ofind but simply execute it.
1573 # function call, we should not call _ofind but simply execute it.
1578 # This avoids spurious geattr() accesses on objects upon assignment.
1574 # This avoids spurious geattr() accesses on objects upon assignment.
1579 #
1575 #
1580 # It also allows users to assign to either alias or magic names true
1576 # It also allows users to assign to either alias or magic names true
1581 # python variables (the magic/alias systems always take second seat to
1577 # python variables (the magic/alias systems always take second seat to
1582 # true python code).
1578 # true python code).
1583 if theRest and theRest[0] in '!=()':
1579 if theRest and theRest[0] in '!=()':
1584 return self.handle_normal(line,continue_prompt)
1580 return self.handle_normal(line,continue_prompt)
1585
1581
1586 if oinfo is None:
1582 if oinfo is None:
1587 oinfo = self._ofind(iFun) # FIXME - _ofind is part of Magic
1583 oinfo = self._ofind(iFun) # FIXME - _ofind is part of Magic
1588
1584
1589 if not oinfo['found']:
1585 if not oinfo['found']:
1590 if iFun in ('quit','exit'):
1586 if iFun in ('quit','exit'):
1591 raise IPythonExit
1587 raise IPythonExit
1592 return self.handle_normal(line,continue_prompt)
1588 return self.handle_normal(line,continue_prompt)
1593 else:
1589 else:
1594 #print 'iFun <%s> rest <%s>' % (iFun,theRest) # dbg
1590 #print 'iFun <%s> rest <%s>' % (iFun,theRest) # dbg
1595 if oinfo['isalias']:
1591 if oinfo['isalias']:
1596 return self.handle_alias(line,continue_prompt,
1592 return self.handle_alias(line,continue_prompt,
1597 pre,iFun,theRest)
1593 pre,iFun,theRest)
1598
1594
1599 if self.rc.autocall and \
1595 if self.rc.autocall and \
1600 not self.re_exclude_auto.match(theRest) and \
1596 not self.re_exclude_auto.match(theRest) and \
1601 self.re_fun_name.match(iFun) and \
1597 self.re_fun_name.match(iFun) and \
1602 callable(oinfo['obj']) :
1598 callable(oinfo['obj']) :
1603 #print 'going auto' # dbg
1599 #print 'going auto' # dbg
1604 return self.handle_auto(line,continue_prompt,pre,iFun,theRest)
1600 return self.handle_auto(line,continue_prompt,pre,iFun,theRest)
1605 else:
1601 else:
1606 #print 'was callable?', callable(oinfo['obj']) # dbg
1602 #print 'was callable?', callable(oinfo['obj']) # dbg
1607 return self.handle_normal(line,continue_prompt)
1603 return self.handle_normal(line,continue_prompt)
1608
1604
1609 # If we get here, we have a normal Python line. Log and return.
1605 # If we get here, we have a normal Python line. Log and return.
1610 return self.handle_normal(line,continue_prompt)
1606 return self.handle_normal(line,continue_prompt)
1611
1607
1612 def _prefilter_dumb(self, line, continue_prompt):
1608 def _prefilter_dumb(self, line, continue_prompt):
1613 """simple prefilter function, for debugging"""
1609 """simple prefilter function, for debugging"""
1614 return self.handle_normal(line,continue_prompt)
1610 return self.handle_normal(line,continue_prompt)
1615
1611
1616 # Set the default prefilter() function (this can be user-overridden)
1612 # Set the default prefilter() function (this can be user-overridden)
1617 prefilter = _prefilter
1613 prefilter = _prefilter
1618
1614
1619 def handle_normal(self,line,continue_prompt=None,
1615 def handle_normal(self,line,continue_prompt=None,
1620 pre=None,iFun=None,theRest=None):
1616 pre=None,iFun=None,theRest=None):
1621 """Handle normal input lines. Use as a template for handlers."""
1617 """Handle normal input lines. Use as a template for handlers."""
1622
1618
1623 self.log(line,continue_prompt)
1619 self.log(line,continue_prompt)
1624 self.update_cache(line)
1620 self.update_cache(line)
1625 return line
1621 return line
1626
1622
1627 def handle_alias(self,line,continue_prompt=None,
1623 def handle_alias(self,line,continue_prompt=None,
1628 pre=None,iFun=None,theRest=None):
1624 pre=None,iFun=None,theRest=None):
1629 """Handle alias input lines. """
1625 """Handle alias input lines. """
1630
1626
1631 theRest = esc_quotes(theRest)
1627 theRest = esc_quotes(theRest)
1632 line_out = "%s%s.call_alias('%s','%s')" % (pre,self.name,iFun,theRest)
1628 line_out = "%s%s.call_alias('%s','%s')" % (pre,self.name,iFun,theRest)
1633 self.log(line_out,continue_prompt)
1629 self.log(line_out,continue_prompt)
1634 self.update_cache(line_out)
1630 self.update_cache(line_out)
1635 return line_out
1631 return line_out
1636
1632
1637 def handle_shell_escape(self, line, continue_prompt=None,
1633 def handle_shell_escape(self, line, continue_prompt=None,
1638 pre=None,iFun=None,theRest=None):
1634 pre=None,iFun=None,theRest=None):
1639 """Execute the line in a shell, empty return value"""
1635 """Execute the line in a shell, empty return value"""
1640
1636
1641 #print 'line in :', `line` # dbg
1637 #print 'line in :', `line` # dbg
1642 # Example of a special handler. Others follow a similar pattern.
1638 # Example of a special handler. Others follow a similar pattern.
1643 if continue_prompt: # multi-line statements
1639 if continue_prompt: # multi-line statements
1644 if iFun.startswith('!!'):
1640 if iFun.startswith('!!'):
1645 print 'SyntaxError: !! is not allowed in multiline statements'
1641 print 'SyntaxError: !! is not allowed in multiline statements'
1646 return pre
1642 return pre
1647 else:
1643 else:
1648 cmd = ("%s %s" % (iFun[1:],theRest)).replace('"','\\"')
1644 cmd = ("%s %s" % (iFun[1:],theRest)).replace('"','\\"')
1649 line_out = '%s%s.system("%s")' % (pre,self.name,cmd)
1645 line_out = '%s%s.system("%s")' % (pre,self.name,cmd)
1650 #line_out = ('%s%s.system(' % (pre,self.name)) + repr(cmd) + ')'
1646 #line_out = ('%s%s.system(' % (pre,self.name)) + repr(cmd) + ')'
1651 else: # single-line input
1647 else: # single-line input
1652 if line.startswith('!!'):
1648 if line.startswith('!!'):
1653 # rewrite iFun/theRest to properly hold the call to %sx and
1649 # rewrite iFun/theRest to properly hold the call to %sx and
1654 # the actual command to be executed, so handle_magic can work
1650 # the actual command to be executed, so handle_magic can work
1655 # correctly
1651 # correctly
1656 theRest = '%s %s' % (iFun[2:],theRest)
1652 theRest = '%s %s' % (iFun[2:],theRest)
1657 iFun = 'sx'
1653 iFun = 'sx'
1658 return self.handle_magic('%ssx %s' % (self.ESC_MAGIC,line[2:]),
1654 return self.handle_magic('%ssx %s' % (self.ESC_MAGIC,line[2:]),
1659 continue_prompt,pre,iFun,theRest)
1655 continue_prompt,pre,iFun,theRest)
1660 else:
1656 else:
1661 cmd = esc_quotes(line[1:])
1657 cmd = esc_quotes(line[1:])
1662 line_out = '%s.system("%s")' % (self.name,cmd)
1658 line_out = '%s.system("%s")' % (self.name,cmd)
1663 #line_out = ('%s.system(' % self.name) + repr(cmd)+ ')'
1659 #line_out = ('%s.system(' % self.name) + repr(cmd)+ ')'
1664 # update cache/log and return
1660 # update cache/log and return
1665 self.log(line_out,continue_prompt)
1661 self.log(line_out,continue_prompt)
1666 self.update_cache(line_out) # readline cache gets normal line
1662 self.update_cache(line_out) # readline cache gets normal line
1667 #print 'line out r:', `line_out` # dbg
1663 #print 'line out r:', `line_out` # dbg
1668 #print 'line out s:', line_out # dbg
1664 #print 'line out s:', line_out # dbg
1669 return line_out
1665 return line_out
1670
1666
1671 def handle_magic(self, line, continue_prompt=None,
1667 def handle_magic(self, line, continue_prompt=None,
1672 pre=None,iFun=None,theRest=None):
1668 pre=None,iFun=None,theRest=None):
1673 """Execute magic functions.
1669 """Execute magic functions.
1674
1670
1675 Also log them with a prepended # so the log is clean Python."""
1671 Also log them with a prepended # so the log is clean Python."""
1676
1672
1677 cmd = '%sipmagic("%s")' % (pre,esc_quotes('%s %s' % (iFun,theRest)))
1673 cmd = '%sipmagic("%s")' % (pre,esc_quotes('%s %s' % (iFun,theRest)))
1678 self.log(cmd,continue_prompt)
1674 self.log(cmd,continue_prompt)
1679 self.update_cache(line)
1675 self.update_cache(line)
1680 #print 'in handle_magic, cmd=<%s>' % cmd # dbg
1676 #print 'in handle_magic, cmd=<%s>' % cmd # dbg
1681 return cmd
1677 return cmd
1682
1678
1683 def handle_auto(self, line, continue_prompt=None,
1679 def handle_auto(self, line, continue_prompt=None,
1684 pre=None,iFun=None,theRest=None):
1680 pre=None,iFun=None,theRest=None):
1685 """Hande lines which can be auto-executed, quoting if requested."""
1681 """Hande lines which can be auto-executed, quoting if requested."""
1686
1682
1687 #print 'pre <%s> iFun <%s> rest <%s>' % (pre,iFun,theRest) # dbg
1683 #print 'pre <%s> iFun <%s> rest <%s>' % (pre,iFun,theRest) # dbg
1688
1684
1689 # This should only be active for single-line input!
1685 # This should only be active for single-line input!
1690 if continue_prompt:
1686 if continue_prompt:
1691 return line
1687 return line
1692
1688
1693 if pre == self.ESC_QUOTE:
1689 if pre == self.ESC_QUOTE:
1694 # Auto-quote splitting on whitespace
1690 # Auto-quote splitting on whitespace
1695 newcmd = '%s("%s")' % (iFun,'", "'.join(theRest.split()) )
1691 newcmd = '%s("%s")' % (iFun,'", "'.join(theRest.split()) )
1696 elif pre == self.ESC_QUOTE2:
1692 elif pre == self.ESC_QUOTE2:
1697 # Auto-quote whole string
1693 # Auto-quote whole string
1698 newcmd = '%s("%s")' % (iFun,theRest)
1694 newcmd = '%s("%s")' % (iFun,theRest)
1699 else:
1695 else:
1700 # Auto-paren
1696 # Auto-paren
1701 if theRest[0:1] in ('=','['):
1697 if theRest[0:1] in ('=','['):
1702 # Don't autocall in these cases. They can be either
1698 # Don't autocall in these cases. They can be either
1703 # rebindings of an existing callable's name, or item access
1699 # rebindings of an existing callable's name, or item access
1704 # for an object which is BOTH callable and implements
1700 # for an object which is BOTH callable and implements
1705 # __getitem__.
1701 # __getitem__.
1706 return '%s %s' % (iFun,theRest)
1702 return '%s %s' % (iFun,theRest)
1707 if theRest.endswith(';'):
1703 if theRest.endswith(';'):
1708 newcmd = '%s(%s);' % (iFun.rstrip(),theRest[:-1])
1704 newcmd = '%s(%s);' % (iFun.rstrip(),theRest[:-1])
1709 else:
1705 else:
1710 newcmd = '%s(%s)' % (iFun.rstrip(),theRest)
1706 newcmd = '%s(%s)' % (iFun.rstrip(),theRest)
1711
1707
1712 print >>Term.cout, self.outputcache.prompt1.auto_rewrite() + newcmd
1708 print >>Term.cout, self.outputcache.prompt1.auto_rewrite() + newcmd
1713 # log what is now valid Python, not the actual user input (without the
1709 # log what is now valid Python, not the actual user input (without the
1714 # final newline)
1710 # final newline)
1715 self.log(newcmd,continue_prompt)
1711 self.log(newcmd,continue_prompt)
1716 return newcmd
1712 return newcmd
1717
1713
1718 def handle_help(self, line, continue_prompt=None,
1714 def handle_help(self, line, continue_prompt=None,
1719 pre=None,iFun=None,theRest=None):
1715 pre=None,iFun=None,theRest=None):
1720 """Try to get some help for the object.
1716 """Try to get some help for the object.
1721
1717
1722 obj? or ?obj -> basic information.
1718 obj? or ?obj -> basic information.
1723 obj?? or ??obj -> more details.
1719 obj?? or ??obj -> more details.
1724 """
1720 """
1725
1721
1726 # We need to make sure that we don't process lines which would be
1722 # We need to make sure that we don't process lines which would be
1727 # otherwise valid python, such as "x=1 # what?"
1723 # otherwise valid python, such as "x=1 # what?"
1728 try:
1724 try:
1729 codeop.compile_command(line)
1725 codeop.compile_command(line)
1730 except SyntaxError:
1726 except SyntaxError:
1731 # We should only handle as help stuff which is NOT valid syntax
1727 # We should only handle as help stuff which is NOT valid syntax
1732 if line[0]==self.ESC_HELP:
1728 if line[0]==self.ESC_HELP:
1733 line = line[1:]
1729 line = line[1:]
1734 elif line[-1]==self.ESC_HELP:
1730 elif line[-1]==self.ESC_HELP:
1735 line = line[:-1]
1731 line = line[:-1]
1736 self.log('#?'+line)
1732 self.log('#?'+line)
1737 self.update_cache(line)
1733 self.update_cache(line)
1738 if line:
1734 if line:
1739 self.magic_pinfo(line)
1735 self.magic_pinfo(line)
1740 else:
1736 else:
1741 page(self.usage,screen_lines=self.rc.screen_length)
1737 page(self.usage,screen_lines=self.rc.screen_length)
1742 return '' # Empty string is needed here!
1738 return '' # Empty string is needed here!
1743 except:
1739 except:
1744 # Pass any other exceptions through to the normal handler
1740 # Pass any other exceptions through to the normal handler
1745 return self.handle_normal(line,continue_prompt)
1741 return self.handle_normal(line,continue_prompt)
1746 else:
1742 else:
1747 # If the code compiles ok, we should handle it normally
1743 # If the code compiles ok, we should handle it normally
1748 return self.handle_normal(line,continue_prompt)
1744 return self.handle_normal(line,continue_prompt)
1749
1745
1750 def handle_emacs(self,line,continue_prompt=None,
1746 def handle_emacs(self,line,continue_prompt=None,
1751 pre=None,iFun=None,theRest=None):
1747 pre=None,iFun=None,theRest=None):
1752 """Handle input lines marked by python-mode."""
1748 """Handle input lines marked by python-mode."""
1753
1749
1754 # Currently, nothing is done. Later more functionality can be added
1750 # Currently, nothing is done. Later more functionality can be added
1755 # here if needed.
1751 # here if needed.
1756
1752
1757 # The input cache shouldn't be updated
1753 # The input cache shouldn't be updated
1758
1754
1759 return line
1755 return line
1760
1756
1761 def write(self,data):
1757 def write(self,data):
1762 """Write a string to the default output"""
1758 """Write a string to the default output"""
1763 Term.cout.write(data)
1759 Term.cout.write(data)
1764
1760
1765 def write_err(self,data):
1761 def write_err(self,data):
1766 """Write a string to the default error output"""
1762 """Write a string to the default error output"""
1767 Term.cerr.write(data)
1763 Term.cerr.write(data)
1768
1764
1769 def exit(self):
1765 def exit(self):
1770 """Handle interactive exit.
1766 """Handle interactive exit.
1771
1767
1772 This method sets the exit_now attribute."""
1768 This method sets the exit_now attribute."""
1773
1769
1774 if self.rc.confirm_exit:
1770 if self.rc.confirm_exit:
1775 if ask_yes_no('Do you really want to exit ([y]/n)?','y'):
1771 if ask_yes_no('Do you really want to exit ([y]/n)?','y'):
1776 self.exit_now = True
1772 self.exit_now = True
1777 else:
1773 else:
1778 self.exit_now = True
1774 self.exit_now = True
1779 return self.exit_now
1775 return self.exit_now
1780
1776
1781 def safe_execfile(self,fname,*where,**kw):
1777 def safe_execfile(self,fname,*where,**kw):
1782 fname = os.path.expanduser(fname)
1778 fname = os.path.expanduser(fname)
1783
1779
1784 # find things also in current directory
1780 # find things also in current directory
1785 dname = os.path.dirname(fname)
1781 dname = os.path.dirname(fname)
1786 if not sys.path.count(dname):
1782 if not sys.path.count(dname):
1787 sys.path.append(dname)
1783 sys.path.append(dname)
1788
1784
1789 try:
1785 try:
1790 xfile = open(fname)
1786 xfile = open(fname)
1791 except:
1787 except:
1792 print >> Term.cerr, \
1788 print >> Term.cerr, \
1793 'Could not open file <%s> for safe execution.' % fname
1789 'Could not open file <%s> for safe execution.' % fname
1794 return None
1790 return None
1795
1791
1796 kw.setdefault('islog',0)
1792 kw.setdefault('islog',0)
1797 kw.setdefault('quiet',1)
1793 kw.setdefault('quiet',1)
1798 kw.setdefault('exit_ignore',0)
1794 kw.setdefault('exit_ignore',0)
1799 first = xfile.readline()
1795 first = xfile.readline()
1800 _LOGHEAD = str(self.LOGHEAD).split('\n',1)[0].strip()
1796 _LOGHEAD = str(self.LOGHEAD).split('\n',1)[0].strip()
1801 xfile.close()
1797 xfile.close()
1802 # line by line execution
1798 # line by line execution
1803 if first.startswith(_LOGHEAD) or kw['islog']:
1799 if first.startswith(_LOGHEAD) or kw['islog']:
1804 print 'Loading log file <%s> one line at a time...' % fname
1800 print 'Loading log file <%s> one line at a time...' % fname
1805 if kw['quiet']:
1801 if kw['quiet']:
1806 stdout_save = sys.stdout
1802 stdout_save = sys.stdout
1807 sys.stdout = StringIO.StringIO()
1803 sys.stdout = StringIO.StringIO()
1808 try:
1804 try:
1809 globs,locs = where[0:2]
1805 globs,locs = where[0:2]
1810 except:
1806 except:
1811 try:
1807 try:
1812 globs = locs = where[0]
1808 globs = locs = where[0]
1813 except:
1809 except:
1814 globs = locs = globals()
1810 globs = locs = globals()
1815 badblocks = []
1811 badblocks = []
1816
1812
1817 # we also need to identify indented blocks of code when replaying
1813 # we also need to identify indented blocks of code when replaying
1818 # logs and put them together before passing them to an exec
1814 # logs and put them together before passing them to an exec
1819 # statement. This takes a bit of regexp and look-ahead work in the
1815 # statement. This takes a bit of regexp and look-ahead work in the
1820 # file. It's easiest if we swallow the whole thing in memory
1816 # file. It's easiest if we swallow the whole thing in memory
1821 # first, and manually walk through the lines list moving the
1817 # first, and manually walk through the lines list moving the
1822 # counter ourselves.
1818 # counter ourselves.
1823 indent_re = re.compile('\s+\S')
1819 indent_re = re.compile('\s+\S')
1824 xfile = open(fname)
1820 xfile = open(fname)
1825 filelines = xfile.readlines()
1821 filelines = xfile.readlines()
1826 xfile.close()
1822 xfile.close()
1827 nlines = len(filelines)
1823 nlines = len(filelines)
1828 lnum = 0
1824 lnum = 0
1829 while lnum < nlines:
1825 while lnum < nlines:
1830 line = filelines[lnum]
1826 line = filelines[lnum]
1831 lnum += 1
1827 lnum += 1
1832 # don't re-insert logger status info into cache
1828 # don't re-insert logger status info into cache
1833 if line.startswith('#log#'):
1829 if line.startswith('#log#'):
1834 continue
1830 continue
1835 elif line.startswith('#%s'% self.ESC_MAGIC):
1831 elif line.startswith('#%s'% self.ESC_MAGIC):
1836 self.update_cache(line[1:])
1832 self.update_cache(line[1:])
1837 line = magic2python(line)
1833 line = magic2python(line)
1838 elif line.startswith('#!'):
1834 elif line.startswith('#!'):
1839 self.update_cache(line[1:])
1835 self.update_cache(line[1:])
1840 else:
1836 else:
1841 # build a block of code (maybe a single line) for execution
1837 # build a block of code (maybe a single line) for execution
1842 block = line
1838 block = line
1843 try:
1839 try:
1844 next = filelines[lnum] # lnum has already incremented
1840 next = filelines[lnum] # lnum has already incremented
1845 except:
1841 except:
1846 next = None
1842 next = None
1847 while next and indent_re.match(next):
1843 while next and indent_re.match(next):
1848 block += next
1844 block += next
1849 lnum += 1
1845 lnum += 1
1850 try:
1846 try:
1851 next = filelines[lnum]
1847 next = filelines[lnum]
1852 except:
1848 except:
1853 next = None
1849 next = None
1854 # now execute the block of one or more lines
1850 # now execute the block of one or more lines
1855 try:
1851 try:
1856 exec block in globs,locs
1852 exec block in globs,locs
1857 self.update_cache(block.rstrip())
1853 self.update_cache(block.rstrip())
1858 except SystemExit:
1854 except SystemExit:
1859 pass
1855 pass
1860 except:
1856 except:
1861 badblocks.append(block.rstrip())
1857 badblocks.append(block.rstrip())
1862 if kw['quiet']: # restore stdout
1858 if kw['quiet']: # restore stdout
1863 sys.stdout.close()
1859 sys.stdout.close()
1864 sys.stdout = stdout_save
1860 sys.stdout = stdout_save
1865 print 'Finished replaying log file <%s>' % fname
1861 print 'Finished replaying log file <%s>' % fname
1866 if badblocks:
1862 if badblocks:
1867 print >> sys.stderr, ('\nThe following lines/blocks in file '
1863 print >> sys.stderr, ('\nThe following lines/blocks in file '
1868 '<%s> reported errors:' % fname)
1864 '<%s> reported errors:' % fname)
1869
1865
1870 for badline in badblocks:
1866 for badline in badblocks:
1871 print >> sys.stderr, badline
1867 print >> sys.stderr, badline
1872 else: # regular file execution
1868 else: # regular file execution
1873 try:
1869 try:
1874 execfile(fname,*where)
1870 execfile(fname,*where)
1875 except SyntaxError:
1871 except SyntaxError:
1876 etype, evalue = sys.exc_info()[0:2]
1872 etype, evalue = sys.exc_info()[0:2]
1877 self.SyntaxTB(etype,evalue,[])
1873 self.SyntaxTB(etype,evalue,[])
1878 warn('Failure executing file: <%s>' % fname)
1874 warn('Failure executing file: <%s>' % fname)
1879 except SystemExit,status:
1875 except SystemExit,status:
1880 if not kw['exit_ignore']:
1876 if not kw['exit_ignore']:
1881 self.InteractiveTB()
1877 self.InteractiveTB()
1882 warn('Failure executing file: <%s>' % fname)
1878 warn('Failure executing file: <%s>' % fname)
1883 except:
1879 except:
1884 self.InteractiveTB()
1880 self.InteractiveTB()
1885 warn('Failure executing file: <%s>' % fname)
1881 warn('Failure executing file: <%s>' % fname)
1886
1882
1887 #************************* end of file <iplib.py> *****************************
1883 #************************* end of file <iplib.py> *****************************
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
General Comments 0
You need to be logged in to leave comments. Login now