##// END OF EJS Templates
remove all trailling spaces
Bernardo B. Marques -
Show More

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

@@ -109,10 +109,10 b' class Application(SingletonConfigurable):'
109 new = getattr(logging, new)
109 new = getattr(logging, new)
110 self.log_level = new
110 self.log_level = new
111 self.log.setLevel(new)
111 self.log.setLevel(new)
112
112
113 # the alias map for configurables
113 # the alias map for configurables
114 aliases = Dict({'log-level' : 'Application.log_level'})
114 aliases = Dict({'log-level' : 'Application.log_level'})
115
115
116 # flags for loading Configurables or store_const style flags
116 # flags for loading Configurables or store_const style flags
117 # flags are loaded from this dict by '--key' flags
117 # flags are loaded from this dict by '--key' flags
118 # this must be a dict of two-tuples, the first element being the Config/dict
118 # this must be a dict of two-tuples, the first element being the Config/dict
@@ -124,20 +124,20 b' class Application(SingletonConfigurable):'
124 assert len(value) == 2, "Bad flag: %r:%s"%(key,value)
124 assert len(value) == 2, "Bad flag: %r:%s"%(key,value)
125 assert isinstance(value[0], (dict, Config)), "Bad flag: %r:%s"%(key,value)
125 assert isinstance(value[0], (dict, Config)), "Bad flag: %r:%s"%(key,value)
126 assert isinstance(value[1], basestring), "Bad flag: %r:%s"%(key,value)
126 assert isinstance(value[1], basestring), "Bad flag: %r:%s"%(key,value)
127
127
128
128
129 # subcommands for launching other applications
129 # subcommands for launching other applications
130 # if this is not empty, this will be a parent Application
130 # if this is not empty, this will be a parent Application
131 # this must be a dict of two-tuples,
131 # this must be a dict of two-tuples,
132 # the first element being the application class/import string
132 # the first element being the application class/import string
133 # and the second being the help string for the subcommand
133 # and the second being the help string for the subcommand
134 subcommands = Dict()
134 subcommands = Dict()
135 # parse_command_line will initialize a subapp, if requested
135 # parse_command_line will initialize a subapp, if requested
136 subapp = Instance('IPython.config.application.Application', allow_none=True)
136 subapp = Instance('IPython.config.application.Application', allow_none=True)
137
137
138 # extra command-line arguments that don't set config values
138 # extra command-line arguments that don't set config values
139 extra_args = List(Unicode)
139 extra_args = List(Unicode)
140
140
141
141
142 def __init__(self, **kwargs):
142 def __init__(self, **kwargs):
143 SingletonConfigurable.__init__(self, **kwargs)
143 SingletonConfigurable.__init__(self, **kwargs)
@@ -145,7 +145,7 b' class Application(SingletonConfigurable):'
145 # options and config files.
145 # options and config files.
146 if self.__class__ not in self.classes:
146 if self.__class__ not in self.classes:
147 self.classes.insert(0, self.__class__)
147 self.classes.insert(0, self.__class__)
148
148
149 self.init_logging()
149 self.init_logging()
150
150
151 def _config_changed(self, name, old, new):
151 def _config_changed(self, name, old, new):
@@ -157,7 +157,7 b' class Application(SingletonConfigurable):'
157 """Start logging for this application.
157 """Start logging for this application.
158
158
159 The default is to log to stdout using a StreaHandler. The log level
159 The default is to log to stdout using a StreaHandler. The log level
160 starts at loggin.WARN, but this can be adjusted by setting the
160 starts at loggin.WARN, but this can be adjusted by setting the
161 ``log_level`` attribute.
161 ``log_level`` attribute.
162 """
162 """
163 self.log = logging.getLogger(self.__class__.__name__)
163 self.log = logging.getLogger(self.__class__.__name__)
@@ -174,36 +174,36 b' class Application(SingletonConfigurable):'
174
174
175 def initialize(self, argv=None):
175 def initialize(self, argv=None):
176 """Do the basic steps to configure me.
176 """Do the basic steps to configure me.
177
177
178 Override in subclasses.
178 Override in subclasses.
179 """
179 """
180 self.parse_command_line(argv)
180 self.parse_command_line(argv)
181
181
182
182
183 def start(self):
183 def start(self):
184 """Start the app mainloop.
184 """Start the app mainloop.
185
185
186 Override in subclasses.
186 Override in subclasses.
187 """
187 """
188 if self.subapp is not None:
188 if self.subapp is not None:
189 return self.subapp.start()
189 return self.subapp.start()
190
190
191 def print_alias_help(self):
191 def print_alias_help(self):
192 """Print the alias part of the help."""
192 """Print the alias part of the help."""
193 if not self.aliases:
193 if not self.aliases:
194 return
194 return
195
195
196 lines = []
196 lines = []
197 classdict = {}
197 classdict = {}
198 for cls in self.classes:
198 for cls in self.classes:
199 # include all parents (up to, but excluding Configurable) in available names
199 # include all parents (up to, but excluding Configurable) in available names
200 for c in cls.mro()[:-3]:
200 for c in cls.mro()[:-3]:
201 classdict[c.__name__] = c
201 classdict[c.__name__] = c
202
202
203 for alias, longname in self.aliases.iteritems():
203 for alias, longname in self.aliases.iteritems():
204 classname, traitname = longname.split('.',1)
204 classname, traitname = longname.split('.',1)
205 cls = classdict[classname]
205 cls = classdict[classname]
206
206
207 trait = cls.class_traits(config=True)[traitname]
207 trait = cls.class_traits(config=True)[traitname]
208 help = cls.class_get_trait_help(trait).splitlines()
208 help = cls.class_get_trait_help(trait).splitlines()
209 # reformat first line
209 # reformat first line
@@ -213,12 +213,12 b' class Application(SingletonConfigurable):'
213 lines.extend(help)
213 lines.extend(help)
214 # lines.append('')
214 # lines.append('')
215 print os.linesep.join(lines)
215 print os.linesep.join(lines)
216
216
217 def print_flag_help(self):
217 def print_flag_help(self):
218 """Print the flag part of the help."""
218 """Print the flag part of the help."""
219 if not self.flags:
219 if not self.flags:
220 return
220 return
221
221
222 lines = []
222 lines = []
223 for m, (cfg,help) in self.flags.iteritems():
223 for m, (cfg,help) in self.flags.iteritems():
224 prefix = '--' if len(m) > 1 else '-'
224 prefix = '--' if len(m) > 1 else '-'
@@ -226,7 +226,7 b' class Application(SingletonConfigurable):'
226 lines.append(indent(dedent(help.strip())))
226 lines.append(indent(dedent(help.strip())))
227 # lines.append('')
227 # lines.append('')
228 print os.linesep.join(lines)
228 print os.linesep.join(lines)
229
229
230 def print_options(self):
230 def print_options(self):
231 if not self.flags and not self.aliases:
231 if not self.flags and not self.aliases:
232 return
232 return
@@ -240,12 +240,12 b' class Application(SingletonConfigurable):'
240 self.print_flag_help()
240 self.print_flag_help()
241 self.print_alias_help()
241 self.print_alias_help()
242 print
242 print
243
243
244 def print_subcommands(self):
244 def print_subcommands(self):
245 """Print the subcommand part of the help."""
245 """Print the subcommand part of the help."""
246 if not self.subcommands:
246 if not self.subcommands:
247 return
247 return
248
248
249 lines = ["Subcommands"]
249 lines = ["Subcommands"]
250 lines.append('-'*len(lines[0]))
250 lines.append('-'*len(lines[0]))
251 lines.append('')
251 lines.append('')
@@ -258,15 +258,15 b' class Application(SingletonConfigurable):'
258 lines.append(indent(dedent(help.strip())))
258 lines.append(indent(dedent(help.strip())))
259 lines.append('')
259 lines.append('')
260 print os.linesep.join(lines)
260 print os.linesep.join(lines)
261
261
262 def print_help(self, classes=False):
262 def print_help(self, classes=False):
263 """Print the help for each Configurable class in self.classes.
263 """Print the help for each Configurable class in self.classes.
264
264
265 If classes=False (the default), only flags and aliases are printed.
265 If classes=False (the default), only flags and aliases are printed.
266 """
266 """
267 self.print_subcommands()
267 self.print_subcommands()
268 self.print_options()
268 self.print_options()
269
269
270 if classes:
270 if classes:
271 if self.classes:
271 if self.classes:
272 print "Class parameters"
272 print "Class parameters"
@@ -275,7 +275,7 b' class Application(SingletonConfigurable):'
275 for p in wrap_paragraphs(self.keyvalue_description):
275 for p in wrap_paragraphs(self.keyvalue_description):
276 print p
276 print p
277 print
277 print
278
278
279 for cls in self.classes:
279 for cls in self.classes:
280 cls.class_print_help()
280 cls.class_print_help()
281 print
281 print
@@ -315,21 +315,21 b' class Application(SingletonConfigurable):'
315 # Save the combined config as self.config, which triggers the traits
315 # Save the combined config as self.config, which triggers the traits
316 # events.
316 # events.
317 self.config = newconfig
317 self.config = newconfig
318
318
319 def initialize_subcommand(self, subc, argv=None):
319 def initialize_subcommand(self, subc, argv=None):
320 """Initialize a subcommand with argv."""
320 """Initialize a subcommand with argv."""
321 subapp,help = self.subcommands.get(subc)
321 subapp,help = self.subcommands.get(subc)
322
322
323 if isinstance(subapp, basestring):
323 if isinstance(subapp, basestring):
324 subapp = import_item(subapp)
324 subapp = import_item(subapp)
325
325
326 # clear existing instances
326 # clear existing instances
327 self.__class__.clear_instance()
327 self.__class__.clear_instance()
328 # instantiate
328 # instantiate
329 self.subapp = subapp.instance()
329 self.subapp = subapp.instance()
330 # and initialize subapp
330 # and initialize subapp
331 self.subapp.initialize(argv)
331 self.subapp.initialize(argv)
332
332
333 def parse_command_line(self, argv=None):
333 def parse_command_line(self, argv=None):
334 """Parse the command line arguments."""
334 """Parse the command line arguments."""
335 argv = sys.argv[1:] if argv is None else argv
335 argv = sys.argv[1:] if argv is None else argv
@@ -340,7 +340,7 b' class Application(SingletonConfigurable):'
340 if re.match(r'^\w(\-?\w)*$', subc) and subc in self.subcommands:
340 if re.match(r'^\w(\-?\w)*$', subc) and subc in self.subcommands:
341 # it's a subcommand, and *not* a flag or class parameter
341 # it's a subcommand, and *not* a flag or class parameter
342 return self.initialize_subcommand(subc, subargv)
342 return self.initialize_subcommand(subc, subargv)
343
343
344 if '-h' in argv or '--help' in argv or '--help-all' in argv:
344 if '-h' in argv or '--help' in argv or '--help-all' in argv:
345 self.print_description()
345 self.print_description()
346 self.print_help('--help-all' in argv)
346 self.print_help('--help-all' in argv)
@@ -350,7 +350,7 b' class Application(SingletonConfigurable):'
350 if '--version' in argv:
350 if '--version' in argv:
351 self.print_version()
351 self.print_version()
352 self.exit(0)
352 self.exit(0)
353
353
354 loader = KVArgParseConfigLoader(argv=argv, aliases=self.aliases,
354 loader = KVArgParseConfigLoader(argv=argv, aliases=self.aliases,
355 flags=self.flags)
355 flags=self.flags)
356 try:
356 try:
@@ -383,7 +383,7 b' class Application(SingletonConfigurable):'
383 else:
383 else:
384 self.log.debug("Loaded config file: %s", loader.full_filename)
384 self.log.debug("Loaded config file: %s", loader.full_filename)
385 self.update_config(config)
385 self.update_config(config)
386
386
387 def generate_config_file(self):
387 def generate_config_file(self):
388 """generate default config file from Configurables"""
388 """generate default config file from Configurables"""
389 lines = ["# Configuration file for %s."%self.name]
389 lines = ["# Configuration file for %s."%self.name]
@@ -404,10 +404,10 b' class Application(SingletonConfigurable):'
404
404
405 def boolean_flag(name, configurable, set_help='', unset_help=''):
405 def boolean_flag(name, configurable, set_help='', unset_help=''):
406 """Helper for building basic --trait, --no-trait flags.
406 """Helper for building basic --trait, --no-trait flags.
407
407
408 Parameters
408 Parameters
409 ----------
409 ----------
410
410
411 name : str
411 name : str
412 The name of the flag.
412 The name of the flag.
413 configurable : str
413 configurable : str
@@ -416,10 +416,10 b" def boolean_flag(name, configurable, set_help='', unset_help=''):"
416 help string for --name flag
416 help string for --name flag
417 unset_help : unicode
417 unset_help : unicode
418 help string for --no-name flag
418 help string for --no-name flag
419
419
420 Returns
420 Returns
421 -------
421 -------
422
422
423 cfg : dict
423 cfg : dict
424 A dict with two keys: 'name', and 'no-name', for setting and unsetting
424 A dict with two keys: 'name', and 'no-name', for setting and unsetting
425 the trait, respectively.
425 the trait, respectively.
@@ -427,9 +427,9 b" def boolean_flag(name, configurable, set_help='', unset_help=''):"
427 # default helpstrings
427 # default helpstrings
428 set_help = set_help or "set %s=True"%configurable
428 set_help = set_help or "set %s=True"%configurable
429 unset_help = unset_help or "set %s=False"%configurable
429 unset_help = unset_help or "set %s=False"%configurable
430
430
431 cls,trait = configurable.split('.')
431 cls,trait = configurable.split('.')
432
432
433 setter = {cls : {trait : True}}
433 setter = {cls : {trait : True}}
434 unsetter = {cls : {trait : False}}
434 unsetter = {cls : {trait : False}}
435 return {name : (setter, set_help), 'no-'+name : (unsetter, unset_help)}
435 return {name : (setter, set_help), 'no-'+name : (unsetter, unset_help)}
@@ -55,16 +55,16 b' class Configurable(HasTraits):'
55 Parameters
55 Parameters
56 ----------
56 ----------
57 config : Config
57 config : Config
58 If this is empty, default values are used. If config is a
58 If this is empty, default values are used. If config is a
59 :class:`Config` instance, it will be used to configure the
59 :class:`Config` instance, it will be used to configure the
60 instance.
60 instance.
61
61
62 Notes
62 Notes
63 -----
63 -----
64 Subclasses of Configurable must call the :meth:`__init__` method of
64 Subclasses of Configurable must call the :meth:`__init__` method of
65 :class:`Configurable` *before* doing anything else and using
65 :class:`Configurable` *before* doing anything else and using
66 :func:`super`::
66 :func:`super`::
67
67
68 class MyConfigurable(Configurable):
68 class MyConfigurable(Configurable):
69 def __init__(self, config=None):
69 def __init__(self, config=None):
70 super(MyConfigurable, self).__init__(config)
70 super(MyConfigurable, self).__init__(config)
@@ -82,7 +82,7 b' class Configurable(HasTraits):'
82 # making that a class attribute.
82 # making that a class attribute.
83 # self.config = deepcopy(config)
83 # self.config = deepcopy(config)
84 self.config = config
84 self.config = config
85 # This should go second so individual keyword arguments override
85 # This should go second so individual keyword arguments override
86 # the values in config.
86 # the values in config.
87 super(Configurable, self).__init__(**kwargs)
87 super(Configurable, self).__init__(**kwargs)
88 self.created = datetime.datetime.now()
88 self.created = datetime.datetime.now()
@@ -105,11 +105,11 b' class Configurable(HasTraits):'
105 # classes that are Configurable subclasses. This starts with Configurable
105 # classes that are Configurable subclasses. This starts with Configurable
106 # and works down the mro loading the config for each section.
106 # and works down the mro loading the config for each section.
107 section_names = [cls.__name__ for cls in \
107 section_names = [cls.__name__ for cls in \
108 reversed(self.__class__.__mro__) if
108 reversed(self.__class__.__mro__) if
109 issubclass(cls, Configurable) and issubclass(self.__class__, cls)]
109 issubclass(cls, Configurable) and issubclass(self.__class__, cls)]
110
110
111 for sname in section_names:
111 for sname in section_names:
112 # Don't do a blind getattr as that would cause the config to
112 # Don't do a blind getattr as that would cause the config to
113 # dynamically create the section with name self.__class__.__name__.
113 # dynamically create the section with name self.__class__.__name__.
114 if new._has_section(sname):
114 if new._has_section(sname):
115 my_config = new[sname]
115 my_config = new[sname]
@@ -149,7 +149,7 b' class Configurable(HasTraits):'
149 help = cls.class_get_trait_help(v)
149 help = cls.class_get_trait_help(v)
150 final_help.append(help)
150 final_help.append(help)
151 return '\n'.join(final_help)
151 return '\n'.join(final_help)
152
152
153 @classmethod
153 @classmethod
154 def class_get_trait_help(cls, trait):
154 def class_get_trait_help(cls, trait):
155 """Get the help string for a single trait."""
155 """Get the help string for a single trait."""
@@ -167,7 +167,7 b' class Configurable(HasTraits):'
167 if 'Enum' in trait.__class__.__name__:
167 if 'Enum' in trait.__class__.__name__:
168 # include Enum choices
168 # include Enum choices
169 lines.append(indent('Choices: %r'%(trait.values,)))
169 lines.append(indent('Choices: %r'%(trait.values,)))
170
170
171 help = trait.get_metadata('help')
171 help = trait.get_metadata('help')
172 if help is not None:
172 if help is not None:
173 help = '\n'.join(wrap_paragraphs(help, 76))
173 help = '\n'.join(wrap_paragraphs(help, 76))
@@ -185,9 +185,9 b' class Configurable(HasTraits):'
185 def c(s):
185 def c(s):
186 """return a commented, wrapped block."""
186 """return a commented, wrapped block."""
187 s = '\n\n'.join(wrap_paragraphs(s, 78))
187 s = '\n\n'.join(wrap_paragraphs(s, 78))
188
188
189 return '# ' + s.replace('\n', '\n# ')
189 return '# ' + s.replace('\n', '\n# ')
190
190
191 # section header
191 # section header
192 breaker = '#' + '-'*78
192 breaker = '#' + '-'*78
193 s = "# %s configuration"%cls.__name__
193 s = "# %s configuration"%cls.__name__
@@ -202,7 +202,7 b' class Configurable(HasTraits):'
202 if desc:
202 if desc:
203 lines.append(c(desc))
203 lines.append(c(desc))
204 lines.append('')
204 lines.append('')
205
205
206 parents = []
206 parents = []
207 for parent in cls.mro():
207 for parent in cls.mro():
208 # only include parents that are not base classes
208 # only include parents that are not base classes
@@ -211,20 +211,20 b' class Configurable(HasTraits):'
211 if parent is not cls and issubclass(parent, Configurable) and \
211 if parent is not cls and issubclass(parent, Configurable) and \
212 parent.class_traits(config=True):
212 parent.class_traits(config=True):
213 parents.append(parent)
213 parents.append(parent)
214
214
215 if parents:
215 if parents:
216 pstr = ', '.join([ p.__name__ for p in parents ])
216 pstr = ', '.join([ p.__name__ for p in parents ])
217 lines.append(c('%s will inherit config from: %s'%(cls.__name__, pstr)))
217 lines.append(c('%s will inherit config from: %s'%(cls.__name__, pstr)))
218 lines.append('')
218 lines.append('')
219
219
220 for name,trait in cls.class_traits(config=True).iteritems():
220 for name,trait in cls.class_traits(config=True).iteritems():
221 help = trait.get_metadata('help') or ''
221 help = trait.get_metadata('help') or ''
222 lines.append(c(help))
222 lines.append(c(help))
223 lines.append('# c.%s.%s = %r'%(cls.__name__, name, trait.get_default_value()))
223 lines.append('# c.%s.%s = %r'%(cls.__name__, name, trait.get_default_value()))
224 lines.append('')
224 lines.append('')
225 return '\n'.join(lines)
225 return '\n'.join(lines)
226
226
227
227
228
228
229 class SingletonConfigurable(Configurable):
229 class SingletonConfigurable(Configurable):
230 """A configurable that only allows one instance.
230 """A configurable that only allows one instance.
@@ -235,20 +235,20 b' class SingletonConfigurable(Configurable):'
235 """
235 """
236
236
237 _instance = None
237 _instance = None
238
238
239 @classmethod
239 @classmethod
240 def _walk_mro(cls):
240 def _walk_mro(cls):
241 """Walk the cls.mro() for parent classes that are also singletons
241 """Walk the cls.mro() for parent classes that are also singletons
242
242
243 For use in instance()
243 For use in instance()
244 """
244 """
245
245
246 for subclass in cls.mro():
246 for subclass in cls.mro():
247 if issubclass(cls, subclass) and \
247 if issubclass(cls, subclass) and \
248 issubclass(subclass, SingletonConfigurable) and \
248 issubclass(subclass, SingletonConfigurable) and \
249 subclass != SingletonConfigurable:
249 subclass != SingletonConfigurable:
250 yield subclass
250 yield subclass
251
251
252 @classmethod
252 @classmethod
253 def clear_instance(cls):
253 def clear_instance(cls):
254 """unset _instance for this class and singleton parents.
254 """unset _instance for this class and singleton parents.
@@ -260,7 +260,7 b' class SingletonConfigurable(Configurable):'
260 # only clear instances that are instances
260 # only clear instances that are instances
261 # of the calling class
261 # of the calling class
262 subclass._instance = None
262 subclass._instance = None
263
263
264 @classmethod
264 @classmethod
265 def instance(cls, *args, **kwargs):
265 def instance(cls, *args, **kwargs):
266 """Returns a global instance of this class.
266 """Returns a global instance of this class.
@@ -297,7 +297,7 b' class SingletonConfigurable(Configurable):'
297 # parent classes' _instance attribute.
297 # parent classes' _instance attribute.
298 for subclass in cls._walk_mro():
298 for subclass in cls._walk_mro():
299 subclass._instance = inst
299 subclass._instance = inst
300
300
301 if isinstance(cls._instance, cls):
301 if isinstance(cls._instance, cls):
302 return cls._instance
302 return cls._instance
303 else:
303 else:
@@ -314,15 +314,15 b' class SingletonConfigurable(Configurable):'
314
314
315 class LoggingConfigurable(Configurable):
315 class LoggingConfigurable(Configurable):
316 """A parent class for Configurables that log.
316 """A parent class for Configurables that log.
317
317
318 Subclasses have a log trait, and the default behavior
318 Subclasses have a log trait, and the default behavior
319 is to get the logger from the currently running Application
319 is to get the logger from the currently running Application
320 via Application.instance().log.
320 via Application.instance().log.
321 """
321 """
322
322
323 log = Instance('logging.Logger')
323 log = Instance('logging.Logger')
324 def _log_default(self):
324 def _log_default(self):
325 from IPython.config.application import Application
325 from IPython.config.application import Application
326 return Application.instance().log
326 return Application.instance().log
327
327
328
328
@@ -53,14 +53,14 b' class ArgumentError(ConfigLoaderError):'
53
53
54 class ArgumentParser(argparse.ArgumentParser):
54 class ArgumentParser(argparse.ArgumentParser):
55 """Simple argparse subclass that prints help to stdout by default."""
55 """Simple argparse subclass that prints help to stdout by default."""
56
56
57 def print_help(self, file=None):
57 def print_help(self, file=None):
58 if file is None:
58 if file is None:
59 file = sys.stdout
59 file = sys.stdout
60 return super(ArgumentParser, self).print_help(file)
60 return super(ArgumentParser, self).print_help(file)
61
61
62 print_help.__doc__ = argparse.ArgumentParser.print_help.__doc__
62 print_help.__doc__ = argparse.ArgumentParser.print_help.__doc__
63
63
64 #-----------------------------------------------------------------------------
64 #-----------------------------------------------------------------------------
65 # Config class for holding config information
65 # Config class for holding config information
66 #-----------------------------------------------------------------------------
66 #-----------------------------------------------------------------------------
@@ -125,10 +125,10 b' class Config(dict):'
125 # infinite recursion on top of PyPy. Instead, we manually fish the
125 # infinite recursion on top of PyPy. Instead, we manually fish the
126 # bound method.
126 # bound method.
127 is_section_key = self.__class__._is_section_key.__get__(self)
127 is_section_key = self.__class__._is_section_key.__get__(self)
128
128
129 # Because we use this for an exec namespace, we need to delegate
129 # Because we use this for an exec namespace, we need to delegate
130 # the lookup of names in __builtin__ to itself. This means
130 # the lookup of names in __builtin__ to itself. This means
131 # that you can't have section or attribute names that are
131 # that you can't have section or attribute names that are
132 # builtins.
132 # builtins.
133 try:
133 try:
134 return getattr(builtin_mod, key)
134 return getattr(builtin_mod, key)
@@ -182,25 +182,25 b' class Config(dict):'
182
182
183 class ConfigLoader(object):
183 class ConfigLoader(object):
184 """A object for loading configurations from just about anywhere.
184 """A object for loading configurations from just about anywhere.
185
185
186 The resulting configuration is packaged as a :class:`Struct`.
186 The resulting configuration is packaged as a :class:`Struct`.
187
187
188 Notes
188 Notes
189 -----
189 -----
190 A :class:`ConfigLoader` does one thing: load a config from a source
190 A :class:`ConfigLoader` does one thing: load a config from a source
191 (file, command line arguments) and returns the data as a :class:`Struct`.
191 (file, command line arguments) and returns the data as a :class:`Struct`.
192 There are lots of things that :class:`ConfigLoader` does not do. It does
192 There are lots of things that :class:`ConfigLoader` does not do. It does
193 not implement complex logic for finding config files. It does not handle
193 not implement complex logic for finding config files. It does not handle
194 default values or merge multiple configs. These things need to be
194 default values or merge multiple configs. These things need to be
195 handled elsewhere.
195 handled elsewhere.
196 """
196 """
197
197
198 def __init__(self):
198 def __init__(self):
199 """A base class for config loaders.
199 """A base class for config loaders.
200
200
201 Examples
201 Examples
202 --------
202 --------
203
203
204 >>> cl = ConfigLoader()
204 >>> cl = ConfigLoader()
205 >>> config = cl.load_config()
205 >>> config = cl.load_config()
206 >>> config
206 >>> config
@@ -213,7 +213,7 b' class ConfigLoader(object):'
213
213
214 def load_config(self):
214 def load_config(self):
215 """Load a config from somewhere, return a :class:`Config` instance.
215 """Load a config from somewhere, return a :class:`Config` instance.
216
216
217 Usually, this will cause self.config to be set and then returned.
217 Usually, this will cause self.config to be set and then returned.
218 However, in most cases, :meth:`ConfigLoader.clear` should be called
218 However, in most cases, :meth:`ConfigLoader.clear` should be called
219 to erase any previous state.
219 to erase any previous state.
@@ -233,7 +233,7 b' class FileConfigLoader(ConfigLoader):'
233
233
234 class PyFileConfigLoader(FileConfigLoader):
234 class PyFileConfigLoader(FileConfigLoader):
235 """A config loader for pure python files.
235 """A config loader for pure python files.
236
236
237 This calls execfile on a plain python file and looks for attributes
237 This calls execfile on a plain python file and looks for attributes
238 that are all caps. These attribute are added to the config Struct.
238 that are all caps. These attribute are added to the config Struct.
239 """
239 """
@@ -276,10 +276,10 b' class PyFileConfigLoader(FileConfigLoader):'
276 # and self.config. The sub-config is loaded with the same path
276 # and self.config. The sub-config is loaded with the same path
277 # as the parent, but it uses an empty config which is then merged
277 # as the parent, but it uses an empty config which is then merged
278 # with the parents.
278 # with the parents.
279
279
280 # If a profile is specified, the config file will be loaded
280 # If a profile is specified, the config file will be loaded
281 # from that profile
281 # from that profile
282
282
283 def load_subconfig(fname, profile=None):
283 def load_subconfig(fname, profile=None):
284 # import here to prevent circular imports
284 # import here to prevent circular imports
285 from IPython.core.profiledir import ProfileDir, ProfileDirError
285 from IPython.core.profiledir import ProfileDir, ProfileDirError
@@ -303,7 +303,7 b' class PyFileConfigLoader(FileConfigLoader):'
303 pass
303 pass
304 else:
304 else:
305 self.config._merge(sub_config)
305 self.config._merge(sub_config)
306
306
307 # Again, this needs to be a closure and should be used in config
307 # Again, this needs to be a closure and should be used in config
308 # files to get the config being loaded.
308 # files to get the config being loaded.
309 def get_config():
309 def get_config():
@@ -340,7 +340,7 b' class CommandLineConfigLoader(ConfigLoader):'
340 # it succeeds. If it still fails, we let it raise.
340 # it succeeds. If it still fails, we let it raise.
341 exec_str = u'self.config.' + lhs + '=' + repr(rhs)
341 exec_str = u'self.config.' + lhs + '=' + repr(rhs)
342 exec exec_str in locals(), globals()
342 exec exec_str in locals(), globals()
343
343
344 def _load_flag(self, cfg):
344 def _load_flag(self, cfg):
345 """update self.config from a flag, which can be a dict or Config"""
345 """update self.config from a flag, which can be a dict or Config"""
346 if isinstance(cfg, (dict, Config)):
346 if isinstance(cfg, (dict, Config)):
@@ -373,7 +373,7 b' class KeyValueConfigLoader(CommandLineConfigLoader):'
373 """A config loader that loads key value pairs from the command line.
373 """A config loader that loads key value pairs from the command line.
374
374
375 This allows command line options to be gives in the following form::
375 This allows command line options to be gives in the following form::
376
376
377 ipython --profile="foo" --InteractiveShell.autocall=False
377 ipython --profile="foo" --InteractiveShell.autocall=False
378 """
378 """
379
379
@@ -414,13 +414,13 b' class KeyValueConfigLoader(CommandLineConfigLoader):'
414 self.argv = argv
414 self.argv = argv
415 self.aliases = aliases or {}
415 self.aliases = aliases or {}
416 self.flags = flags or {}
416 self.flags = flags or {}
417
417
418
418
419 def clear(self):
419 def clear(self):
420 super(KeyValueConfigLoader, self).clear()
420 super(KeyValueConfigLoader, self).clear()
421 self.extra_args = []
421 self.extra_args = []
422
422
423
423
424 def _decode_argv(self, argv, enc=None):
424 def _decode_argv(self, argv, enc=None):
425 """decode argv if bytes, using stin.encoding, falling back on default enc"""
425 """decode argv if bytes, using stin.encoding, falling back on default enc"""
426 uargv = []
426 uargv = []
@@ -432,16 +432,16 b' class KeyValueConfigLoader(CommandLineConfigLoader):'
432 arg = arg.decode(enc)
432 arg = arg.decode(enc)
433 uargv.append(arg)
433 uargv.append(arg)
434 return uargv
434 return uargv
435
435
436
436
437 def load_config(self, argv=None, aliases=None, flags=None):
437 def load_config(self, argv=None, aliases=None, flags=None):
438 """Parse the configuration and generate the Config object.
438 """Parse the configuration and generate the Config object.
439
439
440 After loading, any arguments that are not key-value or
440 After loading, any arguments that are not key-value or
441 flags will be stored in self.extra_args - a list of
441 flags will be stored in self.extra_args - a list of
442 unparsed command-line arguments. This is used for
442 unparsed command-line arguments. This is used for
443 arguments such as input files or subcommands.
443 arguments such as input files or subcommands.
444
444
445 Parameters
445 Parameters
446 ----------
446 ----------
447 argv : list, optional
447 argv : list, optional
@@ -454,7 +454,7 b' class KeyValueConfigLoader(CommandLineConfigLoader):'
454 Of the form: `{'alias' : 'Configurable.trait'}`
454 Of the form: `{'alias' : 'Configurable.trait'}`
455 flags : dict
455 flags : dict
456 A dict of flags, keyed by str name. Values can be Config objects
456 A dict of flags, keyed by str name. Values can be Config objects
457 or dicts. When the flag is triggered, The config is loaded as
457 or dicts. When the flag is triggered, The config is loaded as
458 `self.config.update(cfg)`.
458 `self.config.update(cfg)`.
459 """
459 """
460 from IPython.config.configurable import Configurable
460 from IPython.config.configurable import Configurable
@@ -466,20 +466,20 b' class KeyValueConfigLoader(CommandLineConfigLoader):'
466 aliases = self.aliases
466 aliases = self.aliases
467 if flags is None:
467 if flags is None:
468 flags = self.flags
468 flags = self.flags
469
469
470 # ensure argv is a list of unicode strings:
470 # ensure argv is a list of unicode strings:
471 uargv = self._decode_argv(argv)
471 uargv = self._decode_argv(argv)
472 for idx,raw in enumerate(uargv):
472 for idx,raw in enumerate(uargv):
473 # strip leading '-'
473 # strip leading '-'
474 item = raw.lstrip('-')
474 item = raw.lstrip('-')
475
475
476 if raw == '--':
476 if raw == '--':
477 # don't parse arguments after '--'
477 # don't parse arguments after '--'
478 # this is useful for relaying arguments to scripts, e.g.
478 # this is useful for relaying arguments to scripts, e.g.
479 # ipython -i foo.py --pylab=qt -- args after '--' go-to-foo.py
479 # ipython -i foo.py --pylab=qt -- args after '--' go-to-foo.py
480 self.extra_args.extend(uargv[idx+1:])
480 self.extra_args.extend(uargv[idx+1:])
481 break
481 break
482
482
483 if kv_pattern.match(raw):
483 if kv_pattern.match(raw):
484 lhs,rhs = item.split('=',1)
484 lhs,rhs = item.split('=',1)
485 # Substitute longnames for aliases.
485 # Substitute longnames for aliases.
@@ -489,7 +489,7 b' class KeyValueConfigLoader(CommandLineConfigLoader):'
489 # probably a mistyped alias, but not technically illegal
489 # probably a mistyped alias, but not technically illegal
490 warn.warn("Unrecognized alias: '%s', it will probably have no effect."%lhs)
490 warn.warn("Unrecognized alias: '%s', it will probably have no effect."%lhs)
491 self._exec_config_str(lhs, rhs)
491 self._exec_config_str(lhs, rhs)
492
492
493 elif flag_pattern.match(raw):
493 elif flag_pattern.match(raw):
494 if item in flags:
494 if item in flags:
495 cfg,help = flags[item]
495 cfg,help = flags[item]
@@ -503,7 +503,7 b' class KeyValueConfigLoader(CommandLineConfigLoader):'
503 else:
503 else:
504 raise ArgumentError("Invalid argument: '%s'"%raw)
504 raise ArgumentError("Invalid argument: '%s'"%raw)
505 else:
505 else:
506 # keep all args that aren't valid in a list,
506 # keep all args that aren't valid in a list,
507 # in case our parent knows what to do with them.
507 # in case our parent knows what to do with them.
508 self.extra_args.append(item)
508 self.extra_args.append(item)
509 return self.config
509 return self.config
@@ -541,7 +541,7 b' class ArgParseConfigLoader(CommandLineConfigLoader):'
541 self.argv = argv
541 self.argv = argv
542 self.aliases = aliases or {}
542 self.aliases = aliases or {}
543 self.flags = flags or {}
543 self.flags = flags or {}
544
544
545 self.parser_args = parser_args
545 self.parser_args = parser_args
546 self.version = parser_kw.pop("version", None)
546 self.version = parser_kw.pop("version", None)
547 kwargs = dict(argument_default=argparse.SUPPRESS)
547 kwargs = dict(argument_default=argparse.SUPPRESS)
@@ -597,10 +597,10 b' class ArgParseConfigLoader(CommandLineConfigLoader):'
597
597
598 class KVArgParseConfigLoader(ArgParseConfigLoader):
598 class KVArgParseConfigLoader(ArgParseConfigLoader):
599 """A config loader that loads aliases and flags with argparse,
599 """A config loader that loads aliases and flags with argparse,
600 but will use KVLoader for the rest. This allows better parsing
600 but will use KVLoader for the rest. This allows better parsing
601 of common args, such as `ipython -c 'print 5'`, but still gets
601 of common args, such as `ipython -c 'print 5'`, but still gets
602 arbitrary config with `ipython --InteractiveShell.use_readline=False`"""
602 arbitrary config with `ipython --InteractiveShell.use_readline=False`"""
603
603
604 def _convert_to_config(self):
604 def _convert_to_config(self):
605 """self.parsed_data->self.config"""
605 """self.parsed_data->self.config"""
606 for k, v in vars(self.parsed_data).iteritems():
606 for k, v in vars(self.parsed_data).iteritems():
@@ -626,14 +626,14 b' class KVArgParseConfigLoader(ArgParseConfigLoader):'
626 paa('--'+key, type=unicode, dest=value, nargs=nargs)
626 paa('--'+key, type=unicode, dest=value, nargs=nargs)
627 for key, (value, help) in flags.iteritems():
627 for key, (value, help) in flags.iteritems():
628 if key in self.aliases:
628 if key in self.aliases:
629 #
629 #
630 self.alias_flags[self.aliases[key]] = value
630 self.alias_flags[self.aliases[key]] = value
631 continue
631 continue
632 if len(key) is 1:
632 if len(key) is 1:
633 paa('-'+key, '--'+key, action='append_const', dest='_flags', const=value)
633 paa('-'+key, '--'+key, action='append_const', dest='_flags', const=value)
634 else:
634 else:
635 paa('--'+key, action='append_const', dest='_flags', const=value)
635 paa('--'+key, action='append_const', dest='_flags', const=value)
636
636
637 def _convert_to_config(self):
637 def _convert_to_config(self):
638 """self.parsed_data->self.config, parse unrecognized extra args via KVLoader."""
638 """self.parsed_data->self.config, parse unrecognized extra args via KVLoader."""
639 # remove subconfigs list from namespace before transforming the Namespace
639 # remove subconfigs list from namespace before transforming the Namespace
@@ -642,7 +642,7 b' class KVArgParseConfigLoader(ArgParseConfigLoader):'
642 del self.parsed_data._flags
642 del self.parsed_data._flags
643 else:
643 else:
644 subcs = []
644 subcs = []
645
645
646 for k, v in vars(self.parsed_data).iteritems():
646 for k, v in vars(self.parsed_data).iteritems():
647 if v is None:
647 if v is None:
648 # it was a flag that shares the name of an alias
648 # it was a flag that shares the name of an alias
@@ -650,10 +650,10 b' class KVArgParseConfigLoader(ArgParseConfigLoader):'
650 else:
650 else:
651 # eval the KV assignment
651 # eval the KV assignment
652 self._exec_config_str(k, v)
652 self._exec_config_str(k, v)
653
653
654 for subc in subcs:
654 for subc in subcs:
655 self._load_flag(subc)
655 self._load_flag(subc)
656
656
657 if self.extra_args:
657 if self.extra_args:
658 sub_parser = KeyValueConfigLoader()
658 sub_parser = KeyValueConfigLoader()
659 sub_parser.load_config(self.extra_args)
659 sub_parser.load_config(self.extra_args)
@@ -49,7 +49,7 b' def default_aliases():'
49 # their case. For example, things like 'less' or 'clear' that manipulate
49 # their case. For example, things like 'less' or 'clear' that manipulate
50 # the terminal should NOT be declared here, as they will only work if the
50 # the terminal should NOT be declared here, as they will only work if the
51 # kernel is running inside a true terminal, and not over the network.
51 # kernel is running inside a true terminal, and not over the network.
52
52
53 if os.name == 'posix':
53 if os.name == 'posix':
54 default_aliases = [('mkdir', 'mkdir'), ('rmdir', 'rmdir'),
54 default_aliases = [('mkdir', 'mkdir'), ('rmdir', 'rmdir'),
55 ('mv', 'mv -i'), ('rm', 'rm -i'), ('cp', 'cp -i'),
55 ('mv', 'mv -i'), ('rm', 'rm -i'), ('cp', 'cp -i'),
@@ -94,7 +94,7 b' def default_aliases():'
94 ]
94 ]
95 else:
95 else:
96 default_aliases = []
96 default_aliases = []
97
97
98 return default_aliases
98 return default_aliases
99
99
100
100
@@ -213,33 +213,33 b' class AliasManager(Configurable):'
213 return cmd
213 return cmd
214
214
215 def expand_alias(self, line):
215 def expand_alias(self, line):
216 """ Expand an alias in the command line
216 """ Expand an alias in the command line
217
217
218 Returns the provided command line, possibly with the first word
218 Returns the provided command line, possibly with the first word
219 (command) translated according to alias expansion rules.
219 (command) translated according to alias expansion rules.
220
220
221 [ipython]|16> _ip.expand_aliases("np myfile.txt")
221 [ipython]|16> _ip.expand_aliases("np myfile.txt")
222 <16> 'q:/opt/np/notepad++.exe myfile.txt'
222 <16> 'q:/opt/np/notepad++.exe myfile.txt'
223 """
223 """
224
224
225 pre,_,fn,rest = split_user_input(line)
225 pre,_,fn,rest = split_user_input(line)
226 res = pre + self.expand_aliases(fn, rest)
226 res = pre + self.expand_aliases(fn, rest)
227 return res
227 return res
228
228
229 def expand_aliases(self, fn, rest):
229 def expand_aliases(self, fn, rest):
230 """Expand multiple levels of aliases:
230 """Expand multiple levels of aliases:
231
231
232 if:
232 if:
233
233
234 alias foo bar /tmp
234 alias foo bar /tmp
235 alias baz foo
235 alias baz foo
236
236
237 then:
237 then:
238
238
239 baz huhhahhei -> bar /tmp huhhahhei
239 baz huhhahhei -> bar /tmp huhhahhei
240 """
240 """
241 line = fn + " " + rest
241 line = fn + " " + rest
242
242
243 done = set()
243 done = set()
244 while 1:
244 while 1:
245 pre,_,fn,rest = split_user_input(line, shell_line_split)
245 pre,_,fn,rest = split_user_input(line, shell_line_split)
@@ -259,5 +259,5 b' class AliasManager(Configurable):'
259 line=l2
259 line=l2
260 else:
260 else:
261 break
261 break
262
262
263 return line
263 return line
@@ -5,7 +5,7 b' An application for IPython.'
5 All top-level applications should use the classes in this module for
5 All top-level applications should use the classes in this module for
6 handling configuration and creating componenets.
6 handling configuration and creating componenets.
7
7
8 The job of an :class:`Application` is to create the master configuration
8 The job of an :class:`Application` is to create the master configuration
9 object and then create the configurable objects, passing the config to them.
9 object and then create the configurable objects, passing the config to them.
10
10
11 Authors:
11 Authors:
@@ -78,15 +78,15 b' class BaseIPythonApplication(Application):'
78 name = Unicode(u'ipython')
78 name = Unicode(u'ipython')
79 description = Unicode(u'IPython: an enhanced interactive Python shell.')
79 description = Unicode(u'IPython: an enhanced interactive Python shell.')
80 version = Unicode(release.version)
80 version = Unicode(release.version)
81
81
82 aliases = Dict(base_aliases)
82 aliases = Dict(base_aliases)
83 flags = Dict(base_flags)
83 flags = Dict(base_flags)
84 classes = List([ProfileDir])
84 classes = List([ProfileDir])
85
85
86 # Track whether the config_file has changed,
86 # Track whether the config_file has changed,
87 # because some logic happens only if we aren't using the default.
87 # because some logic happens only if we aren't using the default.
88 config_file_specified = Bool(False)
88 config_file_specified = Bool(False)
89
89
90 config_file_name = Unicode(u'ipython_config.py')
90 config_file_name = Unicode(u'ipython_config.py')
91 def _config_file_name_default(self):
91 def _config_file_name_default(self):
92 return self.name.replace('-','_') + u'_config.py'
92 return self.name.replace('-','_') + u'_config.py'
@@ -108,13 +108,13 b' class BaseIPythonApplication(Application):'
108 )
108 )
109 def _profile_default(self):
109 def _profile_default(self):
110 return "python3" if py3compat.PY3 else "default"
110 return "python3" if py3compat.PY3 else "default"
111
111
112 def _profile_changed(self, name, old, new):
112 def _profile_changed(self, name, old, new):
113 self.builtin_profile_dir = os.path.join(
113 self.builtin_profile_dir = os.path.join(
114 get_ipython_package_dir(), u'config', u'profile', new
114 get_ipython_package_dir(), u'config', u'profile', new
115 )
115 )
116
116
117 ipython_dir = Unicode(get_ipython_dir(), config=True,
117 ipython_dir = Unicode(get_ipython_dir(), config=True,
118 help="""
118 help="""
119 The name of the IPython directory. This directory is used for logging
119 The name of the IPython directory. This directory is used for logging
120 configuration (through profiles), history storage, etc. The default
120 configuration (through profiles), history storage, etc. The default
@@ -122,16 +122,16 b' class BaseIPythonApplication(Application):'
122 the environment variable IPYTHON_DIR.
122 the environment variable IPYTHON_DIR.
123 """
123 """
124 )
124 )
125
125
126 overwrite = Bool(False, config=True,
126 overwrite = Bool(False, config=True,
127 help="""Whether to overwrite existing config files when copying""")
127 help="""Whether to overwrite existing config files when copying""")
128 auto_create = Bool(False, config=True,
128 auto_create = Bool(False, config=True,
129 help="""Whether to create profile dir if it doesn't exist""")
129 help="""Whether to create profile dir if it doesn't exist""")
130
130
131 config_files = List(Unicode)
131 config_files = List(Unicode)
132 def _config_files_default(self):
132 def _config_files_default(self):
133 return [u'ipython_config.py']
133 return [u'ipython_config.py']
134
134
135 copy_config_files = Bool(False, config=True,
135 copy_config_files = Bool(False, config=True,
136 help="""Whether to install the default config files into the profile dir.
136 help="""Whether to install the default config files into the profile dir.
137 If a new profile is being created, and IPython contains config files for that
137 If a new profile is being created, and IPython contains config files for that
@@ -147,7 +147,7 b' class BaseIPythonApplication(Application):'
147 # ensure even default IPYTHON_DIR exists
147 # ensure even default IPYTHON_DIR exists
148 if not os.path.exists(self.ipython_dir):
148 if not os.path.exists(self.ipython_dir):
149 self._ipython_dir_changed('ipython_dir', self.ipython_dir, self.ipython_dir)
149 self._ipython_dir_changed('ipython_dir', self.ipython_dir, self.ipython_dir)
150
150
151 #-------------------------------------------------------------------------
151 #-------------------------------------------------------------------------
152 # Various stages of Application creation
152 # Various stages of Application creation
153 #-------------------------------------------------------------------------
153 #-------------------------------------------------------------------------
@@ -183,7 +183,7 b' class BaseIPythonApplication(Application):'
183 try:
183 try:
184 Application.load_config_file(
184 Application.load_config_file(
185 self,
185 self,
186 base_config,
186 base_config,
187 path=self.config_file_paths
187 path=self.config_file_paths
188 )
188 )
189 except IOError:
189 except IOError:
@@ -198,7 +198,7 b' class BaseIPythonApplication(Application):'
198 try:
198 try:
199 Application.load_config_file(
199 Application.load_config_file(
200 self,
200 self,
201 self.config_file_name,
201 self.config_file_name,
202 path=self.config_file_paths
202 path=self.config_file_paths
203 )
203 )
204 except IOError:
204 except IOError:
@@ -258,17 +258,17 b' class BaseIPythonApplication(Application):'
258 self.exit(1)
258 self.exit(1)
259 else:
259 else:
260 self.log.info("Using existing profile dir: %r"%location)
260 self.log.info("Using existing profile dir: %r"%location)
261
261
262 self.profile_dir = p
262 self.profile_dir = p
263 self.config_file_paths.append(p.location)
263 self.config_file_paths.append(p.location)
264
264
265 def init_config_files(self):
265 def init_config_files(self):
266 """[optionally] copy default config files into profile dir."""
266 """[optionally] copy default config files into profile dir."""
267 # copy config files
267 # copy config files
268 path = self.builtin_profile_dir
268 path = self.builtin_profile_dir
269 if self.copy_config_files:
269 if self.copy_config_files:
270 src = self.profile
270 src = self.profile
271
271
272 cfg = self.config_file_name
272 cfg = self.config_file_name
273 if path and os.path.exists(os.path.join(path, cfg)):
273 if path and os.path.exists(os.path.join(path, cfg)):
274 self.log.warn("Staging %r from %s into %r [overwrite=%s]"%(
274 self.log.warn("Staging %r from %s into %r [overwrite=%s]"%(
@@ -289,8 +289,8 b' class BaseIPythonApplication(Application):'
289 self.log.warn("Staging bundled %s from %s into %r"%(
289 self.log.warn("Staging bundled %s from %s into %r"%(
290 cfg, self.profile, self.profile_dir.location)
290 cfg, self.profile, self.profile_dir.location)
291 )
291 )
292
292
293
293
294 def stage_default_config_file(self):
294 def stage_default_config_file(self):
295 """auto generate default config file, and stage it into the profile."""
295 """auto generate default config file, and stage it into the profile."""
296 s = self.generate_config_file()
296 s = self.generate_config_file()
@@ -299,8 +299,8 b' class BaseIPythonApplication(Application):'
299 self.log.warn("Generating default config file: %r"%(fname))
299 self.log.warn("Generating default config file: %r"%(fname))
300 with open(fname, 'w') as f:
300 with open(fname, 'w') as f:
301 f.write(s)
301 f.write(s)
302
302
303
303
304 def initialize(self, argv=None):
304 def initialize(self, argv=None):
305 # don't hook up crash handler before parsing command-line
305 # don't hook up crash handler before parsing command-line
306 self.parse_command_line(argv)
306 self.parse_command_line(argv)
@@ -126,7 +126,7 b' def has_open_quotes(s):'
126
126
127 def protect_filename(s):
127 def protect_filename(s):
128 """Escape a string to protect certain characters."""
128 """Escape a string to protect certain characters."""
129
129
130 return "".join([(ch in PROTECTABLES and '\\' + ch or ch)
130 return "".join([(ch in PROTECTABLES and '\\' + ch or ch)
131 for ch in s])
131 for ch in s])
132
132
@@ -156,7 +156,7 b' def expand_user(path):'
156 path : str
156 path : str
157 String to be expanded. If no ~ is present, the output is the same as the
157 String to be expanded. If no ~ is present, the output is the same as the
158 input.
158 input.
159
159
160 Returns
160 Returns
161 -------
161 -------
162 newpath : str
162 newpath : str
@@ -170,7 +170,7 b' def expand_user(path):'
170 tilde_expand = False
170 tilde_expand = False
171 tilde_val = ''
171 tilde_val = ''
172 newpath = path
172 newpath = path
173
173
174 if path.startswith('~'):
174 if path.startswith('~'):
175 tilde_expand = True
175 tilde_expand = True
176 rest = path[1:]
176 rest = path[1:]
@@ -229,7 +229,7 b' class CompletionSplitter(object):'
229 automatically builds the necessary """
229 automatically builds the necessary """
230
230
231 # Private interface
231 # Private interface
232
232
233 # A string of delimiter characters. The default value makes sense for
233 # A string of delimiter characters. The default value makes sense for
234 # IPython's most typical usage patterns.
234 # IPython's most typical usage patterns.
235 _delims = DELIMS
235 _delims = DELIMS
@@ -265,15 +265,15 b' class CompletionSplitter(object):'
265
265
266
266
267 class Completer(Configurable):
267 class Completer(Configurable):
268
268
269 greedy = CBool(False, config=True,
269 greedy = CBool(False, config=True,
270 help="""Activate greedy completion
270 help="""Activate greedy completion
271
271
272 This will enable completion on elements of lists, results of function calls, etc.,
272 This will enable completion on elements of lists, results of function calls, etc.,
273 but can be unsafe because the code is actually evaluated on TAB.
273 but can be unsafe because the code is actually evaluated on TAB.
274 """
274 """
275 )
275 )
276
276
277 def __init__(self, namespace=None, global_namespace=None, config=None):
277 def __init__(self, namespace=None, global_namespace=None, config=None):
278 """Create a new completer for the command line.
278 """Create a new completer for the command line.
279
279
@@ -307,7 +307,7 b' class Completer(Configurable):'
307 self.global_namespace = {}
307 self.global_namespace = {}
308 else:
308 else:
309 self.global_namespace = global_namespace
309 self.global_namespace = global_namespace
310
310
311 super(Completer, self).__init__(config=config)
311 super(Completer, self).__init__(config=config)
312
312
313 def complete(self, text, state):
313 def complete(self, text, state):
@@ -319,7 +319,7 b' class Completer(Configurable):'
319 """
319 """
320 if self.use_main_ns:
320 if self.use_main_ns:
321 self.namespace = __main__.__dict__
321 self.namespace = __main__.__dict__
322
322
323 if state == 0:
323 if state == 0:
324 if "." in text:
324 if "." in text:
325 self.matches = self.attr_matches(text)
325 self.matches = self.attr_matches(text)
@@ -369,7 +369,7 b' class Completer(Configurable):'
369 m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text)
369 m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text)
370
370
371 if m:
371 if m:
372 expr, attr = m.group(1, 3)
372 expr, attr = m.group(1, 3)
373 elif self.greedy:
373 elif self.greedy:
374 m2 = re.match(r"(.+)\.(\w*)$", self.line_buffer)
374 m2 = re.match(r"(.+)\.(\w*)$", self.line_buffer)
375 if not m2:
375 if not m2:
@@ -377,7 +377,7 b' class Completer(Configurable):'
377 expr, attr = m2.group(1,2)
377 expr, attr = m2.group(1,2)
378 else:
378 else:
379 return []
379 return []
380
380
381 try:
381 try:
382 obj = eval(expr, self.namespace)
382 obj = eval(expr, self.namespace)
383 except:
383 except:
@@ -387,7 +387,7 b' class Completer(Configurable):'
387 return []
387 return []
388
388
389 words = dir2(obj)
389 words = dir2(obj)
390
390
391 try:
391 try:
392 words = generics.complete_object(obj, words)
392 words = generics.complete_object(obj, words)
393 except TryNext:
393 except TryNext:
@@ -407,10 +407,10 b' class IPCompleter(Completer):'
407 self.splitter.set_delims(GREEDY_DELIMS)
407 self.splitter.set_delims(GREEDY_DELIMS)
408 else:
408 else:
409 self.splitter.set_delims(DELIMS)
409 self.splitter.set_delims(DELIMS)
410
410
411 if self.readline:
411 if self.readline:
412 self.readline.set_completer_delims(self.splitter.get_delims())
412 self.readline.set_completer_delims(self.splitter.get_delims())
413
413
414 def __init__(self, shell=None, namespace=None, global_namespace=None,
414 def __init__(self, shell=None, namespace=None, global_namespace=None,
415 omit__names=True, alias_table=None, use_readline=True,
415 omit__names=True, alias_table=None, use_readline=True,
416 config=None):
416 config=None):
@@ -448,7 +448,7 b' class IPCompleter(Completer):'
448
448
449 # Readline configuration, only used by the rlcompleter method.
449 # Readline configuration, only used by the rlcompleter method.
450 if use_readline:
450 if use_readline:
451 # We store the right version of readline so that later code
451 # We store the right version of readline so that later code
452 import IPython.utils.rlineimpl as readline
452 import IPython.utils.rlineimpl as readline
453 self.readline = readline
453 self.readline = readline
454 else:
454 else:
@@ -475,7 +475,7 b' class IPCompleter(Completer):'
475 # buffers, to avoid completion problems.
475 # buffers, to avoid completion problems.
476 term = os.environ.get('TERM','xterm')
476 term = os.environ.get('TERM','xterm')
477 self.dumb_terminal = term in ['dumb','emacs']
477 self.dumb_terminal = term in ['dumb','emacs']
478
478
479 # Special handling of backslashes needed in win32 platforms
479 # Special handling of backslashes needed in win32 platforms
480 if sys.platform == "win32":
480 if sys.platform == "win32":
481 self.clean_glob = self._clean_glob_win32
481 self.clean_glob = self._clean_glob_win32
@@ -489,7 +489,7 b' class IPCompleter(Completer):'
489 self.alias_matches,
489 self.alias_matches,
490 self.python_func_kw_matches,
490 self.python_func_kw_matches,
491 ]
491 ]
492
492
493 def all_completions(self, text):
493 def all_completions(self, text):
494 """
494 """
495 Wrapper around the complete method for the benefit of emacs
495 Wrapper around the complete method for the benefit of emacs
@@ -502,7 +502,7 b' class IPCompleter(Completer):'
502
502
503 def _clean_glob_win32(self,text):
503 def _clean_glob_win32(self,text):
504 return [f.replace("\\","/")
504 return [f.replace("\\","/")
505 for f in self.glob("%s*" % text)]
505 for f in self.glob("%s*" % text)]
506
506
507 def file_matches(self, text):
507 def file_matches(self, text):
508 """Match filenames, expanding ~USER type strings.
508 """Match filenames, expanding ~USER type strings.
@@ -569,7 +569,7 b' class IPCompleter(Completer):'
569 # beginning of filename so that we don't double-write the part
569 # beginning of filename so that we don't double-write the part
570 # of the filename we have so far
570 # of the filename we have so far
571 len_lsplit = len(lsplit)
571 len_lsplit = len(lsplit)
572 matches = [text_prefix + text0 +
572 matches = [text_prefix + text0 +
573 protect_filename(f[len_lsplit:]) for f in m0]
573 protect_filename(f[len_lsplit:]) for f in m0]
574 else:
574 else:
575 if open_quotes:
575 if open_quotes:
@@ -578,7 +578,7 b' class IPCompleter(Completer):'
578 # would cause bugs when the filesystem call is made).
578 # would cause bugs when the filesystem call is made).
579 matches = m0
579 matches = m0
580 else:
580 else:
581 matches = [text_prefix +
581 matches = [text_prefix +
582 protect_filename(f) for f in m0]
582 protect_filename(f) for f in m0]
583
583
584 #io.rprint('mm', matches) # dbg
584 #io.rprint('mm', matches) # dbg
@@ -595,7 +595,7 b' class IPCompleter(Completer):'
595 return [ pre+m for m in magics if m.startswith(baretext)]
595 return [ pre+m for m in magics if m.startswith(baretext)]
596
596
597 def alias_matches(self, text):
597 def alias_matches(self, text):
598 """Match internal system aliases"""
598 """Match internal system aliases"""
599 #print 'Completer->alias_matches:',text,'lb',self.text_until_cursor # dbg
599 #print 'Completer->alias_matches:',text,'lb',self.text_until_cursor # dbg
600
600
601 # if we are not in the first 'item', alias matching
601 # if we are not in the first 'item', alias matching
@@ -715,10 +715,10 b' class IPCompleter(Completer):'
715
715
716 def dispatch_custom_completer(self, text):
716 def dispatch_custom_completer(self, text):
717 #io.rprint("Custom! '%s' %s" % (text, self.custom_completers)) # dbg
717 #io.rprint("Custom! '%s' %s" % (text, self.custom_completers)) # dbg
718 line = self.line_buffer
718 line = self.line_buffer
719 if not line.strip():
719 if not line.strip():
720 return None
720 return None
721
721
722 # Create a little structure to pass all the relevant information about
722 # Create a little structure to pass all the relevant information about
723 # the current completion to any custom completer.
723 # the current completion to any custom completer.
724 event = Bunch()
724 event = Bunch()
@@ -727,16 +727,16 b' class IPCompleter(Completer):'
727 cmd = line.split(None,1)[0]
727 cmd = line.split(None,1)[0]
728 event.command = cmd
728 event.command = cmd
729 event.text_until_cursor = self.text_until_cursor
729 event.text_until_cursor = self.text_until_cursor
730
730
731 #print "\ncustom:{%s]\n" % event # dbg
731 #print "\ncustom:{%s]\n" % event # dbg
732
732
733 # for foo etc, try also to find completer for %foo
733 # for foo etc, try also to find completer for %foo
734 if not cmd.startswith(self.magic_escape):
734 if not cmd.startswith(self.magic_escape):
735 try_magic = self.custom_completers.s_matches(
735 try_magic = self.custom_completers.s_matches(
736 self.magic_escape + cmd)
736 self.magic_escape + cmd)
737 else:
737 else:
738 try_magic = []
738 try_magic = []
739
739
740 for c in itertools.chain(self.custom_completers.s_matches(cmd),
740 for c in itertools.chain(self.custom_completers.s_matches(cmd),
741 try_magic,
741 try_magic,
742 self.custom_completers.flat_matches(self.text_until_cursor)):
742 self.custom_completers.flat_matches(self.text_until_cursor)):
@@ -753,9 +753,9 b' class IPCompleter(Completer):'
753 return [r for r in res if r.lower().startswith(text_low)]
753 return [r for r in res if r.lower().startswith(text_low)]
754 except TryNext:
754 except TryNext:
755 pass
755 pass
756
756
757 return None
757 return None
758
758
759 def complete(self, text=None, line_buffer=None, cursor_pos=None):
759 def complete(self, text=None, line_buffer=None, cursor_pos=None):
760 """Find completions for the given text and line context.
760 """Find completions for the given text and line context.
761
761
@@ -785,7 +785,7 b' class IPCompleter(Completer):'
785 -------
785 -------
786 text : str
786 text : str
787 Text that was actually used in the completion.
787 Text that was actually used in the completion.
788
788
789 matches : list
789 matches : list
790 A list of completion matches.
790 A list of completion matches.
791 """
791 """
@@ -803,7 +803,7 b' class IPCompleter(Completer):'
803 # If no line buffer is given, assume the input text is all there was
803 # If no line buffer is given, assume the input text is all there was
804 if line_buffer is None:
804 if line_buffer is None:
805 line_buffer = text
805 line_buffer = text
806
806
807 self.line_buffer = line_buffer
807 self.line_buffer = line_buffer
808 self.text_until_cursor = self.line_buffer[:cursor_pos]
808 self.text_until_cursor = self.line_buffer[:cursor_pos]
809 #io.rprint('\nCOMP2 %r %r %r' % (text, line_buffer, cursor_pos)) # dbg
809 #io.rprint('\nCOMP2 %r %r %r' % (text, line_buffer, cursor_pos)) # dbg
@@ -893,7 +893,7 b' class IPCompleter(Completer):'
893 import traceback; traceback.print_exc()
893 import traceback; traceback.print_exc()
894 else:
894 else:
895 # The normal production version is here
895 # The normal production version is here
896
896
897 # This method computes the self.matches array
897 # This method computes the self.matches array
898 self.complete(text, line_buffer, cursor_pos)
898 self.complete(text, line_buffer, cursor_pos)
899
899
@@ -78,7 +78,7 b' def shlex_split(x):'
78 if len(endofline) >= 1:
78 if len(endofline) >= 1:
79 comps.append(''.join(endofline))
79 comps.append(''.join(endofline))
80 return comps
80 return comps
81
81
82 except ValueError:
82 except ValueError:
83 endofline = [x[-1:]]+endofline
83 endofline = [x[-1:]]+endofline
84 x = x[:-1]
84 x = x[:-1]
@@ -108,7 +108,7 b' def module_list(path):'
108 isfile = os.path.isfile
108 isfile = os.path.isfile
109 pjoin = os.path.join
109 pjoin = os.path.join
110 basename = os.path.basename
110 basename = os.path.basename
111
111
112 # Now find actual path matches for packages or modules
112 # Now find actual path matches for packages or modules
113 folder_list = [p for p in folder_list
113 folder_list = [p for p in folder_list
114 if isfile(pjoin(path, p,'__init__.py'))
114 if isfile(pjoin(path, p,'__init__.py'))
@@ -125,12 +125,12 b' def get_root_modules():'
125
125
126 if 'rootmodules' in ip.db:
126 if 'rootmodules' in ip.db:
127 return ip.db['rootmodules']
127 return ip.db['rootmodules']
128
128
129 t = time()
129 t = time()
130 store = False
130 store = False
131 modules = list(sys.builtin_module_names)
131 modules = list(sys.builtin_module_names)
132 for path in sys.path:
132 for path in sys.path:
133 modules += module_list(path)
133 modules += module_list(path)
134 if time() - t >= TIMEOUT_STORAGE and not store:
134 if time() - t >= TIMEOUT_STORAGE and not store:
135 store = True
135 store = True
136 print("\nCaching the list of root modules, please wait!")
136 print("\nCaching the list of root modules, please wait!")
@@ -141,7 +141,7 b' def get_root_modules():'
141 print("This is taking too long, we give up.\n")
141 print("This is taking too long, we give up.\n")
142 ip.db['rootmodules'] = []
142 ip.db['rootmodules'] = []
143 return []
143 return []
144
144
145 modules = set(modules)
145 modules = set(modules)
146 if '__init__' in modules:
146 if '__init__' in modules:
147 modules.remove('__init__')
147 modules.remove('__init__')
@@ -173,7 +173,7 b' def try_import(mod, only_modules=False):'
173 if (not hasattr(m, '__file__')) or (not only_modules) or m_is_init:
173 if (not hasattr(m, '__file__')) or (not only_modules) or m_is_init:
174 completions.extend( [attr for attr in dir(m) if
174 completions.extend( [attr for attr in dir(m) if
175 is_importable(m, attr, only_modules)])
175 is_importable(m, attr, only_modules)])
176
176
177 completions.extend(getattr(m, '__all__', []))
177 completions.extend(getattr(m, '__all__', []))
178 if m_is_init:
178 if m_is_init:
179 completions.extend(module_list(os.path.dirname(m.__file__)))
179 completions.extend(module_list(os.path.dirname(m.__file__)))
@@ -192,22 +192,22 b' def quick_completer(cmd, completions):'
192
192
193 Takes either a list of completions, or all completions in string (that will
193 Takes either a list of completions, or all completions in string (that will
194 be split on whitespace).
194 be split on whitespace).
195
195
196 Example::
196 Example::
197
197
198 [d:\ipython]|1> import ipy_completers
198 [d:\ipython]|1> import ipy_completers
199 [d:\ipython]|2> ipy_completers.quick_completer('foo', ['bar','baz'])
199 [d:\ipython]|2> ipy_completers.quick_completer('foo', ['bar','baz'])
200 [d:\ipython]|3> foo b<TAB>
200 [d:\ipython]|3> foo b<TAB>
201 bar baz
201 bar baz
202 [d:\ipython]|3> foo ba
202 [d:\ipython]|3> foo ba
203 """
203 """
204
204
205 if isinstance(completions, basestring):
205 if isinstance(completions, basestring):
206 completions = completions.split()
206 completions = completions.split()
207
207
208 def do_complete(self, event):
208 def do_complete(self, event):
209 return completions
209 return completions
210
210
211 get_ipython().set_hook('complete_command',do_complete, str_key = cmd)
211 get_ipython().set_hook('complete_command',do_complete, str_key = cmd)
212
212
213
213
@@ -226,7 +226,7 b' def module_completion(line):'
226 # from whatever <tab> -> 'import '
226 # from whatever <tab> -> 'import '
227 if nwords == 3 and words[0] == 'from':
227 if nwords == 3 and words[0] == 'from':
228 return ['import ']
228 return ['import ']
229
229
230 # 'from xy<tab>' or 'import xy<tab>'
230 # 'from xy<tab>' or 'import xy<tab>'
231 if nwords < 3 and (words[0] in ['import','from']) :
231 if nwords < 3 and (words[0] in ['import','from']) :
232 if nwords == 1:
232 if nwords == 1:
@@ -236,7 +236,7 b' def module_completion(line):'
236 return get_root_modules()
236 return get_root_modules()
237 completion_list = try_import('.'.join(mod[:-1]), True)
237 completion_list = try_import('.'.join(mod[:-1]), True)
238 return ['.'.join(mod[:-1] + [el]) for el in completion_list]
238 return ['.'.join(mod[:-1] + [el]) for el in completion_list]
239
239
240 # 'from xyz import abc<tab>'
240 # 'from xyz import abc<tab>'
241 if nwords >= 3 and words[0] == 'from':
241 if nwords >= 3 and words[0] == 'from':
242 mod = words[1]
242 mod = words[1]
@@ -275,7 +275,7 b' def magic_run_completer(self, event):'
275 lglob = glob.glob
275 lglob = glob.glob
276 isdir = os.path.isdir
276 isdir = os.path.isdir
277 relpath, tilde_expand, tilde_val = expand_user(relpath)
277 relpath, tilde_expand, tilde_val = expand_user(relpath)
278
278
279 dirs = [f.replace('\\','/') + "/" for f in lglob(relpath+'*') if isdir(f)]
279 dirs = [f.replace('\\','/') + "/" for f in lglob(relpath+'*') if isdir(f)]
280
280
281 # Find if the user has already typed the first filename, after which we
281 # Find if the user has already typed the first filename, after which we
@@ -305,7 +305,7 b' def cd_completer(self, event):'
305 return bkms.keys()
305 return bkms.keys()
306 else:
306 else:
307 return []
307 return []
308
308
309 if event.symbol == '-':
309 if event.symbol == '-':
310 width_dh = str(len(str(len(ip.user_ns['_dh']) + 1)))
310 width_dh = str(len(str(len(ip.user_ns['_dh']) + 1)))
311 # jump in directory history by number
311 # jump in directory history by number
@@ -329,7 +329,7 b' def cd_completer(self, event):'
329 # we don't want to deal with any of that, complex code
329 # we don't want to deal with any of that, complex code
330 # for this is elsewhere
330 # for this is elsewhere
331 raise TryNext
331 raise TryNext
332
332
333 found.append(d)
333 found.append(d)
334
334
335 if not found:
335 if not found:
@@ -341,7 +341,7 b' def cd_completer(self, event):'
341 bkmatches = [s for s in bks if s.startswith(event.symbol)]
341 bkmatches = [s for s in bks if s.startswith(event.symbol)]
342 if bkmatches:
342 if bkmatches:
343 return bkmatches
343 return bkmatches
344
344
345 raise TryNext
345 raise TryNext
346
346
347 return [compress_user(p, tilde_expand, tilde_val) for p in found]
347 return [compress_user(p, tilde_expand, tilde_val) for p in found]
@@ -67,14 +67,14 b' class CrashHandler(object):'
67 message_template = _default_message_template
67 message_template = _default_message_template
68 section_sep = '\n\n'+'*'*75+'\n\n'
68 section_sep = '\n\n'+'*'*75+'\n\n'
69
69
70 def __init__(self, app, contact_name=None, contact_email=None,
70 def __init__(self, app, contact_name=None, contact_email=None,
71 bug_tracker=None, show_crash_traceback=True, call_pdb=False):
71 bug_tracker=None, show_crash_traceback=True, call_pdb=False):
72 """Create a new crash handler
72 """Create a new crash handler
73
73
74 Parameters
74 Parameters
75 ----------
75 ----------
76 app : Application
76 app : Application
77 A running :class:`Application` instance, which will be queried at
77 A running :class:`Application` instance, which will be queried at
78 crash time for internal information.
78 crash time for internal information.
79
79
80 contact_name : str
80 contact_name : str
@@ -106,7 +106,7 b' class CrashHandler(object):'
106 contact_email = contact_email,
106 contact_email = contact_email,
107 bug_tracker = bug_tracker,
107 bug_tracker = bug_tracker,
108 crash_report_fname = self.crash_report_fname)
108 crash_report_fname = self.crash_report_fname)
109
109
110
110
111 def __call__(self, etype, evalue, etb):
111 def __call__(self, etype, evalue, etb):
112 """Handle an exception, call for compatible with sys.excepthook"""
112 """Handle an exception, call for compatible with sys.excepthook"""
@@ -160,13 +160,13 b' class CrashHandler(object):'
160
160
161 def make_report(self,traceback):
161 def make_report(self,traceback):
162 """Return a string containing a crash report."""
162 """Return a string containing a crash report."""
163
163
164 sec_sep = self.section_sep
164 sec_sep = self.section_sep
165
165
166 report = ['*'*75+'\n\n'+'IPython post-mortem report\n\n']
166 report = ['*'*75+'\n\n'+'IPython post-mortem report\n\n']
167 rpt_add = report.append
167 rpt_add = report.append
168 rpt_add(sys_info())
168 rpt_add(sys_info())
169
169
170 try:
170 try:
171 config = pformat(self.app.config)
171 config = pformat(self.app.config)
172 rpt_add(sec_sep)
172 rpt_add(sec_sep)
@@ -39,7 +39,7 b' has_pydb = False'
39 prompt = 'ipdb> '
39 prompt = 'ipdb> '
40 #We have to check this directly from sys.argv, config struct not yet available
40 #We have to check this directly from sys.argv, config struct not yet available
41 if '-pydb' in sys.argv:
41 if '-pydb' in sys.argv:
42 try:
42 try:
43 import pydb
43 import pydb
44 if hasattr(pydb.pydb, "runl") and pydb.version>'1.17':
44 if hasattr(pydb.pydb, "runl") and pydb.version>'1.17':
45 # Version 1.17 is broken, and that's what ships with Ubuntu Edgy, so we
45 # Version 1.17 is broken, and that's what ships with Ubuntu Edgy, so we
@@ -130,7 +130,7 b' class Tracer(object):'
130
130
131 This is similar to the pdb.set_trace() function from the std lib, but
131 This is similar to the pdb.set_trace() function from the std lib, but
132 using IPython's enhanced debugger."""
132 using IPython's enhanced debugger."""
133
133
134 self.debugger.set_trace(sys._getframe().f_back)
134 self.debugger.set_trace(sys._getframe().f_back)
135
135
136
136
@@ -173,9 +173,9 b' class Pdb(OldPdb):'
173 OldPdb.__init__(self,stdin=stdin,stdout=io.stdout)
173 OldPdb.__init__(self,stdin=stdin,stdout=io.stdout)
174 else:
174 else:
175 OldPdb.__init__(self,completekey,stdin,stdout)
175 OldPdb.__init__(self,completekey,stdin,stdout)
176
176
177 self.prompt = prompt # The default prompt is '(Pdb)'
177 self.prompt = prompt # The default prompt is '(Pdb)'
178
178
179 # IPython changes...
179 # IPython changes...
180 self.is_pydb = has_pydb
180 self.is_pydb = has_pydb
181
181
@@ -207,7 +207,7 b' class Pdb(OldPdb):'
207 # module and add a few attributes needed for debugging
207 # module and add a few attributes needed for debugging
208 self.color_scheme_table = exception_colors()
208 self.color_scheme_table = exception_colors()
209
209
210 # shorthands
210 # shorthands
211 C = coloransi.TermColors
211 C = coloransi.TermColors
212 cst = self.color_scheme_table
212 cst = self.color_scheme_table
213
213
@@ -250,11 +250,11 b' class Pdb(OldPdb):'
250 self.shell.set_completer_frame(self.curframe)
250 self.shell.set_completer_frame(self.curframe)
251
251
252 def new_do_quit(self, arg):
252 def new_do_quit(self, arg):
253
253
254 if hasattr(self, 'old_all_completions'):
254 if hasattr(self, 'old_all_completions'):
255 self.shell.Completer.all_completions=self.old_all_completions
255 self.shell.Completer.all_completions=self.old_all_completions
256
256
257
257
258 return OldPdb.do_quit(self, arg)
258 return OldPdb.do_quit(self, arg)
259
259
260 do_q = do_quit = decorate_fn_with_doc(new_do_quit, OldPdb.do_quit)
260 do_q = do_quit = decorate_fn_with_doc(new_do_quit, OldPdb.do_quit)
@@ -288,9 +288,9 b' class Pdb(OldPdb):'
288
288
289 def format_stack_entry(self, frame_lineno, lprefix=': ', context = 3):
289 def format_stack_entry(self, frame_lineno, lprefix=': ', context = 3):
290 import linecache, repr
290 import linecache, repr
291
291
292 ret = []
292 ret = []
293
293
294 Colors = self.color_scheme_table.active_colors
294 Colors = self.color_scheme_table.active_colors
295 ColorsNormal = Colors.Normal
295 ColorsNormal = Colors.Normal
296 tpl_link = '%s%%s%s' % (Colors.filenameEm, ColorsNormal)
296 tpl_link = '%s%%s%s' % (Colors.filenameEm, ColorsNormal)
@@ -298,9 +298,9 b' class Pdb(OldPdb):'
298 tpl_line = '%%s%s%%s %s%%s' % (Colors.lineno, ColorsNormal)
298 tpl_line = '%%s%s%%s %s%%s' % (Colors.lineno, ColorsNormal)
299 tpl_line_em = '%%s%s%%s %s%%s%s' % (Colors.linenoEm, Colors.line,
299 tpl_line_em = '%%s%s%%s %s%%s%s' % (Colors.linenoEm, Colors.line,
300 ColorsNormal)
300 ColorsNormal)
301
301
302 frame, lineno = frame_lineno
302 frame, lineno = frame_lineno
303
303
304 return_value = ''
304 return_value = ''
305 if '__return__' in frame.f_locals:
305 if '__return__' in frame.f_locals:
306 rv = frame.f_locals['__return__']
306 rv = frame.f_locals['__return__']
@@ -311,14 +311,14 b' class Pdb(OldPdb):'
311 #s = filename + '(' + `lineno` + ')'
311 #s = filename + '(' + `lineno` + ')'
312 filename = self.canonic(frame.f_code.co_filename)
312 filename = self.canonic(frame.f_code.co_filename)
313 link = tpl_link % filename
313 link = tpl_link % filename
314
314
315 if frame.f_code.co_name:
315 if frame.f_code.co_name:
316 func = frame.f_code.co_name
316 func = frame.f_code.co_name
317 else:
317 else:
318 func = "<lambda>"
318 func = "<lambda>"
319
319
320 call = ''
320 call = ''
321 if func != '?':
321 if func != '?':
322 if '__args__' in frame.f_locals:
322 if '__args__' in frame.f_locals:
323 args = repr.repr(frame.f_locals['__args__'])
323 args = repr.repr(frame.f_locals['__args__'])
324 else:
324 else:
@@ -332,13 +332,13 b' class Pdb(OldPdb):'
332 else:
332 else:
333 ret.append(' ')
333 ret.append(' ')
334 ret.append('%s(%s)%s\n' % (link,lineno,call))
334 ret.append('%s(%s)%s\n' % (link,lineno,call))
335
335
336 start = lineno - 1 - context//2
336 start = lineno - 1 - context//2
337 lines = linecache.getlines(filename)
337 lines = linecache.getlines(filename)
338 start = max(start, 0)
338 start = max(start, 0)
339 start = min(start, len(lines) - context)
339 start = min(start, len(lines) - context)
340 lines = lines[start : start + context]
340 lines = lines[start : start + context]
341
341
342 for i,line in enumerate(lines):
342 for i,line in enumerate(lines):
343 show_arrow = (start + 1 + i == lineno)
343 show_arrow = (start + 1 + i == lineno)
344 linetpl = (frame is self.curframe or show_arrow) \
344 linetpl = (frame is self.curframe or show_arrow) \
@@ -362,7 +362,7 b' class Pdb(OldPdb):'
362 if lineno in self.get_file_breaks(filename):
362 if lineno in self.get_file_breaks(filename):
363 bps = self.get_breaks(filename, lineno)
363 bps = self.get_breaks(filename, lineno)
364 bp = bps[-1]
364 bp = bps[-1]
365
365
366 if bp:
366 if bp:
367 Colors = self.color_scheme_table.active_colors
367 Colors = self.color_scheme_table.active_colors
368 bp_mark = str(bp.number)
368 bp_mark = str(bp.number)
@@ -387,7 +387,7 b' class Pdb(OldPdb):'
387 else:
387 else:
388 num = '%*s' % (numbers_width - len(bp_mark), str(lineno))
388 num = '%*s' % (numbers_width - len(bp_mark), str(lineno))
389 line = tpl_line % (bp_mark_color + bp_mark, num, line)
389 line = tpl_line % (bp_mark_color + bp_mark, num, line)
390
390
391 return line
391 return line
392
392
393 def list_command_pydb(self, arg):
393 def list_command_pydb(self, arg):
@@ -395,7 +395,7 b' class Pdb(OldPdb):'
395 filename, first, last = OldPdb.parse_list_cmd(self, arg)
395 filename, first, last = OldPdb.parse_list_cmd(self, arg)
396 if filename is not None:
396 if filename is not None:
397 self.print_list_lines(filename, first, last)
397 self.print_list_lines(filename, first, last)
398
398
399 def print_list_lines(self, filename, first, last):
399 def print_list_lines(self, filename, first, last):
400 """The printing (as opposed to the parsing part of a 'list'
400 """The printing (as opposed to the parsing part of a 'list'
401 command."""
401 command."""
@@ -496,7 +496,7 b' class Pdb(OldPdb):'
496 #
496 #
497 # End hack. The rest of this method is copied verbatim from 2.6 pdb.py
497 # End hack. The rest of this method is copied verbatim from 2.6 pdb.py
498 #######################################################################
498 #######################################################################
499
499
500 if not line:
500 if not line:
501 print >>self.stdout, 'End of file'
501 print >>self.stdout, 'End of file'
502 return 0
502 return 0
@@ -49,7 +49,7 b' def display(*objs, **kwargs):'
49 """
49 """
50 include = kwargs.get('include')
50 include = kwargs.get('include')
51 exclude = kwargs.get('exclude')
51 exclude = kwargs.get('exclude')
52
52
53 from IPython.core.interactiveshell import InteractiveShell
53 from IPython.core.interactiveshell import InteractiveShell
54 inst = InteractiveShell.instance()
54 inst = InteractiveShell.instance()
55 format = inst.display_formatter.format
55 format = inst.display_formatter.format
@@ -237,7 +237,7 b' class DisplayObject(object):'
237 in the frontend. The MIME type of the data should match the
237 in the frontend. The MIME type of the data should match the
238 subclasses used, so the Png subclass should be used for 'image/png'
238 subclasses used, so the Png subclass should be used for 'image/png'
239 data. If the data is a URL, the data will first be downloaded
239 data. If the data is a URL, the data will first be downloaded
240 and then displayed. If
240 and then displayed. If
241
241
242 Parameters
242 Parameters
243 ----------
243 ----------
@@ -123,7 +123,7 b' class DisplayHook(Configurable):'
123 return no_cache_def
123 return no_cache_def
124 else:
124 else:
125 return p_str
125 return p_str
126
126
127 def set_colors(self, colors):
127 def set_colors(self, colors):
128 """Set the active color scheme and configure colors for the three
128 """Set the active color scheme and configure colors for the three
129 prompt subsystems."""
129 prompt subsystems."""
@@ -135,7 +135,7 b' class DisplayHook(Configurable):'
135 prompts.prompt_specials = prompts.prompt_specials_nocolor
135 prompts.prompt_specials = prompts.prompt_specials_nocolor
136 else:
136 else:
137 prompts.prompt_specials = prompts.prompt_specials_color
137 prompts.prompt_specials = prompts.prompt_specials_color
138
138
139 self.color_table.set_active_scheme(colors)
139 self.color_table.set_active_scheme(colors)
140 self.prompt1.set_colors()
140 self.prompt1.set_colors()
141 self.prompt2.set_colors()
141 self.prompt2.set_colors()
@@ -227,7 +227,7 b' class DisplayHook(Configurable):'
227 format_dict : dict
227 format_dict : dict
228 The format dict for the object passed to `sys.displayhook`.
228 The format dict for the object passed to `sys.displayhook`.
229 """
229 """
230 # We want to print because we want to always make sure we have a
230 # We want to print because we want to always make sure we have a
231 # newline, even if all the prompt separators are ''. This is the
231 # newline, even if all the prompt separators are ''. This is the
232 # standard IPython behavior.
232 # standard IPython behavior.
233 result_repr = format_dict['text/plain']
233 result_repr = format_dict['text/plain']
@@ -291,7 +291,7 b' class DisplayHook(Configurable):'
291
291
292 def __call__(self, result=None):
292 def __call__(self, result=None):
293 """Printing with history cache management.
293 """Printing with history cache management.
294
294
295 This is invoked everytime the interpreter needs to print, and is
295 This is invoked everytime the interpreter needs to print, and is
296 activated by setting the variable sys.displayhook to it.
296 activated by setting the variable sys.displayhook to it.
297 """
297 """
@@ -310,17 +310,17 b' class DisplayHook(Configurable):'
310 raise ValueError,"You shouldn't have reached the cache flush "\
310 raise ValueError,"You shouldn't have reached the cache flush "\
311 "if full caching is not enabled!"
311 "if full caching is not enabled!"
312 # delete auto-generated vars from global namespace
312 # delete auto-generated vars from global namespace
313
313
314 for n in range(1,self.prompt_count + 1):
314 for n in range(1,self.prompt_count + 1):
315 key = '_'+`n`
315 key = '_'+`n`
316 try:
316 try:
317 del self.shell.user_ns[key]
317 del self.shell.user_ns[key]
318 except: pass
318 except: pass
319 self.shell.user_ns['_oh'].clear()
319 self.shell.user_ns['_oh'].clear()
320
320
321 # Release our own references to objects:
321 # Release our own references to objects:
322 self._, self.__, self.___ = '', '', ''
322 self._, self.__, self.___ = '', '', ''
323
323
324 if '_' not in __builtin__.__dict__:
324 if '_' not in __builtin__.__dict__:
325 self.shell.user_ns.update({'_':None,'__':None, '___':None})
325 self.shell.user_ns.update({'_':None,'__':None, '___':None})
326 import gc
326 import gc
@@ -87,7 +87,7 b' class DisplayPublisher(Configurable):'
87 A string that give the function or method that created the data,
87 A string that give the function or method that created the data,
88 such as 'IPython.core.page'.
88 such as 'IPython.core.page'.
89 data : dict
89 data : dict
90 A dictionary having keys that are valid MIME types (like
90 A dictionary having keys that are valid MIME types (like
91 'text/plain' or 'image/svg+xml') and values that are the data for
91 'text/plain' or 'image/svg+xml') and values that are the data for
92 that MIME type. The data itself must be a JSON'able data
92 that MIME type. The data itself must be a JSON'able data
93 structure. Minimally all data should have the 'text/plain' data,
93 structure. Minimally all data should have the 'text/plain' data,
@@ -128,7 +128,7 b' def publish_display_data(source, data, metadata=None):'
128 A string that give the function or method that created the data,
128 A string that give the function or method that created the data,
129 such as 'IPython.core.page'.
129 such as 'IPython.core.page'.
130 data : dict
130 data : dict
131 A dictionary having keys that are valid MIME types (like
131 A dictionary having keys that are valid MIME types (like
132 'text/plain' or 'image/svg+xml') and values that are the data for
132 'text/plain' or 'image/svg+xml') and values that are the data for
133 that MIME type. The data itself must be a JSON'able data
133 that MIME type. The data itself must be a JSON'able data
134 structure. Minimally all data should have the 'text/plain' data,
134 structure. Minimally all data should have the 'text/plain' data,
@@ -32,7 +32,7 b' class IPythonCoreError(Exception):'
32
32
33 class TryNext(IPythonCoreError):
33 class TryNext(IPythonCoreError):
34 """Try next hook exception.
34 """Try next hook exception.
35
35
36 Raise this in your hook function to indicate that the next hook handler
36 Raise this in your hook function to indicate that the next hook handler
37 should be used to handle the operation. If you pass arguments to the
37 should be used to handle the operation. If you pass arguments to the
38 constructor those arguments will be used by the next hook instead of the
38 constructor those arguments will be used by the next hook instead of the
@@ -45,7 +45,7 b' class TryNext(IPythonCoreError):'
45
45
46 class UsageError(IPythonCoreError):
46 class UsageError(IPythonCoreError):
47 """Error in magic function arguments, etc.
47 """Error in magic function arguments, etc.
48
48
49 Something that probably won't warrant a full traceback, but should
49 Something that probably won't warrant a full traceback, but should
50 nevertheless interrupt a macro / batch file.
50 nevertheless interrupt a macro / batch file.
51 """
51 """
@@ -27,16 +27,16 b' def exception_colors():'
27 >>> print ec.active_colors
27 >>> print ec.active_colors
28 None
28 None
29
29
30 Now we activate a color scheme:
30 Now we activate a color scheme:
31 >>> ec.set_active_scheme('NoColor')
31 >>> ec.set_active_scheme('NoColor')
32 >>> ec.active_scheme_name
32 >>> ec.active_scheme_name
33 'NoColor'
33 'NoColor'
34 >>> ec.active_colors.keys()
34 >>> ec.active_colors.keys()
35 ['em', 'filenameEm', 'excName', 'valEm', 'nameEm', 'line', 'topline',
35 ['em', 'filenameEm', 'excName', 'valEm', 'nameEm', 'line', 'topline',
36 'name', 'caret', 'val', 'vName', 'Normal', 'filename', 'linenoEm',
36 'name', 'caret', 'val', 'vName', 'Normal', 'filename', 'linenoEm',
37 'lineno', 'normalEm']
37 'lineno', 'normalEm']
38 """
38 """
39
39
40 ex_colors = ColorSchemeTable()
40 ex_colors = ColorSchemeTable()
41
41
42 # Populate it with color schemes
42 # Populate it with color schemes
@@ -36,13 +36,13 b' class ExtensionManager(Configurable):'
36 def load_ipython_extension(ipython):
36 def load_ipython_extension(ipython):
37 # Do things with ipython
37 # Do things with ipython
38
38
39 This function is called after your extension is imported and the
39 This function is called after your extension is imported and the
40 currently active :class:`InteractiveShell` instance is passed as
40 currently active :class:`InteractiveShell` instance is passed as
41 the only argument. You can do anything you want with IPython at
41 the only argument. You can do anything you want with IPython at
42 that point, including defining new magic and aliases, adding new
42 that point, including defining new magic and aliases, adding new
43 components, etc.
43 components, etc.
44
44
45 The :func:`load_ipython_extension` will be called again is you
45 The :func:`load_ipython_extension` will be called again is you
46 load or reload the extension again. It is up to the extension
46 load or reload the extension again. It is up to the extension
47 author to add code to manage that.
47 author to add code to manage that.
48
48
@@ -361,26 +361,26 b' class PlainTextFormatter(BaseFormatter):'
361
361
362 # The newline character.
362 # The newline character.
363 newline = Unicode('\n', config=True)
363 newline = Unicode('\n', config=True)
364
364
365 # format-string for pprinting floats
365 # format-string for pprinting floats
366 float_format = Unicode('%r')
366 float_format = Unicode('%r')
367 # setter for float precision, either int or direct format-string
367 # setter for float precision, either int or direct format-string
368 float_precision = CUnicode('', config=True)
368 float_precision = CUnicode('', config=True)
369
369
370 def _float_precision_changed(self, name, old, new):
370 def _float_precision_changed(self, name, old, new):
371 """float_precision changed, set float_format accordingly.
371 """float_precision changed, set float_format accordingly.
372
372
373 float_precision can be set by int or str.
373 float_precision can be set by int or str.
374 This will set float_format, after interpreting input.
374 This will set float_format, after interpreting input.
375 If numpy has been imported, numpy print precision will also be set.
375 If numpy has been imported, numpy print precision will also be set.
376
376
377 integer `n` sets format to '%.nf', otherwise, format set directly.
377 integer `n` sets format to '%.nf', otherwise, format set directly.
378
378
379 An empty string returns to defaults (repr for float, 8 for numpy).
379 An empty string returns to defaults (repr for float, 8 for numpy).
380
380
381 This parameter can be set via the '%precision' magic.
381 This parameter can be set via the '%precision' magic.
382 """
382 """
383
383
384 if '%' in new:
384 if '%' in new:
385 # got explicit format string
385 # got explicit format string
386 fmt = new
386 fmt = new
@@ -397,7 +397,7 b' class PlainTextFormatter(BaseFormatter):'
397 raise ValueError("Precision must be int or format string, not %r"%new)
397 raise ValueError("Precision must be int or format string, not %r"%new)
398 except AssertionError:
398 except AssertionError:
399 raise ValueError("int precision must be non-negative, not %r"%i)
399 raise ValueError("int precision must be non-negative, not %r"%i)
400
400
401 fmt = '%%.%if'%i
401 fmt = '%%.%if'%i
402 if 'numpy' in sys.modules:
402 if 'numpy' in sys.modules:
403 # set numpy precision if it has been imported
403 # set numpy precision if it has been imported
@@ -458,7 +458,7 b' class HTMLFormatter(BaseFormatter):'
458 this.
458 this.
459
459
460 The return value of this formatter should be a valid HTML snippet that
460 The return value of this formatter should be a valid HTML snippet that
461 could be injected into an existing DOM. It should *not* include the
461 could be injected into an existing DOM. It should *not* include the
462 ```<html>`` or ```<body>`` tags.
462 ```<html>`` or ```<body>`` tags.
463 """
463 """
464 format_type = Unicode('text/html')
464 format_type = Unicode('text/html')
@@ -550,7 +550,7 b' class JavascriptFormatter(BaseFormatter):'
550 """A Javascript formatter.
550 """A Javascript formatter.
551
551
552 To define the callables that compute the Javascript representation of
552 To define the callables that compute the Javascript representation of
553 your objects, define a :meth:`_repr_javascript_` method or use the
553 your objects, define a :meth:`_repr_javascript_` method or use the
554 :meth:`for_type` or :meth:`for_type_by_name` methods to register functions
554 :meth:`for_type` or :meth:`for_type_by_name` methods to register functions
555 that handle this.
555 that handle this.
556
556
@@ -67,19 +67,19 b' class HistoryManager(Configurable):'
67 # Should we log output to the database? (default no)
67 # Should we log output to the database? (default no)
68 db_log_output = Bool(False, config=True)
68 db_log_output = Bool(False, config=True)
69 # Write to database every x commands (higher values save disk access & power)
69 # Write to database every x commands (higher values save disk access & power)
70 # Values of 1 or less effectively disable caching.
70 # Values of 1 or less effectively disable caching.
71 db_cache_size = Int(0, config=True)
71 db_cache_size = Int(0, config=True)
72 # The input and output caches
72 # The input and output caches
73 db_input_cache = List()
73 db_input_cache = List()
74 db_output_cache = List()
74 db_output_cache = List()
75
75
76 # History saving in separate thread
76 # History saving in separate thread
77 save_thread = Instance('IPython.core.history.HistorySavingThread')
77 save_thread = Instance('IPython.core.history.HistorySavingThread')
78 try: # Event is a function returning an instance of _Event...
78 try: # Event is a function returning an instance of _Event...
79 save_flag = Instance(threading._Event)
79 save_flag = Instance(threading._Event)
80 except AttributeError: # ...until Python 3.3, when it's a class.
80 except AttributeError: # ...until Python 3.3, when it's a class.
81 save_flag = Instance(threading.Event)
81 save_flag = Instance(threading.Event)
82
82
83 # Private interface
83 # Private interface
84 # Variables used to store the three last inputs from the user. On each new
84 # Variables used to store the three last inputs from the user. On each new
85 # history update, we populate the user's namespace with these, shifted as
85 # history update, we populate the user's namespace with these, shifted as
@@ -119,7 +119,7 b' class HistoryManager(Configurable):'
119 else:
119 else:
120 # The hist_file is probably :memory: or something else.
120 # The hist_file is probably :memory: or something else.
121 raise
121 raise
122
122
123 self.save_flag = threading.Event()
123 self.save_flag = threading.Event()
124 self.db_input_cache_lock = threading.Lock()
124 self.db_input_cache_lock = threading.Lock()
125 self.db_output_cache_lock = threading.Lock()
125 self.db_output_cache_lock = threading.Lock()
@@ -128,7 +128,7 b' class HistoryManager(Configurable):'
128
128
129 self.new_session()
129 self.new_session()
130
130
131
131
132 def init_db(self):
132 def init_db(self):
133 """Connect to the database, and create tables if necessary."""
133 """Connect to the database, and create tables if necessary."""
134 # use detect_types so that timestamps return datetime objects
134 # use detect_types so that timestamps return datetime objects
@@ -136,7 +136,7 b' class HistoryManager(Configurable):'
136 self.db.execute("""CREATE TABLE IF NOT EXISTS sessions (session integer
136 self.db.execute("""CREATE TABLE IF NOT EXISTS sessions (session integer
137 primary key autoincrement, start timestamp,
137 primary key autoincrement, start timestamp,
138 end timestamp, num_cmds integer, remark text)""")
138 end timestamp, num_cmds integer, remark text)""")
139 self.db.execute("""CREATE TABLE IF NOT EXISTS history
139 self.db.execute("""CREATE TABLE IF NOT EXISTS history
140 (session integer, line integer, source text, source_raw text,
140 (session integer, line integer, source text, source_raw text,
141 PRIMARY KEY (session, line))""")
141 PRIMARY KEY (session, line))""")
142 # Output history is optional, but ensure the table's there so it can be
142 # Output history is optional, but ensure the table's there so it can be
@@ -145,17 +145,17 b' class HistoryManager(Configurable):'
145 (session integer, line integer, output text,
145 (session integer, line integer, output text,
146 PRIMARY KEY (session, line))""")
146 PRIMARY KEY (session, line))""")
147 self.db.commit()
147 self.db.commit()
148
148
149 def new_session(self, conn=None):
149 def new_session(self, conn=None):
150 """Get a new session number."""
150 """Get a new session number."""
151 if conn is None:
151 if conn is None:
152 conn = self.db
152 conn = self.db
153
153
154 with conn:
154 with conn:
155 cur = conn.execute("""INSERT INTO sessions VALUES (NULL, ?, NULL,
155 cur = conn.execute("""INSERT INTO sessions VALUES (NULL, ?, NULL,
156 NULL, "") """, (datetime.datetime.now(),))
156 NULL, "") """, (datetime.datetime.now(),))
157 self.session_number = cur.lastrowid
157 self.session_number = cur.lastrowid
158
158
159 def end_session(self):
159 def end_session(self):
160 """Close the database session, filling in the end time and line count."""
160 """Close the database session, filling in the end time and line count."""
161 self.writeout_cache()
161 self.writeout_cache()
@@ -164,33 +164,33 b' class HistoryManager(Configurable):'
164 session==?""", (datetime.datetime.now(),
164 session==?""", (datetime.datetime.now(),
165 len(self.input_hist_parsed)-1, self.session_number))
165 len(self.input_hist_parsed)-1, self.session_number))
166 self.session_number = 0
166 self.session_number = 0
167
167
168 def name_session(self, name):
168 def name_session(self, name):
169 """Give the current session a name in the history database."""
169 """Give the current session a name in the history database."""
170 with self.db:
170 with self.db:
171 self.db.execute("UPDATE sessions SET remark=? WHERE session==?",
171 self.db.execute("UPDATE sessions SET remark=? WHERE session==?",
172 (name, self.session_number))
172 (name, self.session_number))
173
173
174 def reset(self, new_session=True):
174 def reset(self, new_session=True):
175 """Clear the session history, releasing all object references, and
175 """Clear the session history, releasing all object references, and
176 optionally open a new session."""
176 optionally open a new session."""
177 self.output_hist.clear()
177 self.output_hist.clear()
178 # The directory history can't be completely empty
178 # The directory history can't be completely empty
179 self.dir_hist[:] = [os.getcwdu()]
179 self.dir_hist[:] = [os.getcwdu()]
180
180
181 if new_session:
181 if new_session:
182 if self.session_number:
182 if self.session_number:
183 self.end_session()
183 self.end_session()
184 self.input_hist_parsed[:] = [""]
184 self.input_hist_parsed[:] = [""]
185 self.input_hist_raw[:] = [""]
185 self.input_hist_raw[:] = [""]
186 self.new_session()
186 self.new_session()
187
187
188 ## -------------------------------
188 ## -------------------------------
189 ## Methods for retrieving history:
189 ## Methods for retrieving history:
190 ## -------------------------------
190 ## -------------------------------
191 def _run_sql(self, sql, params, raw=True, output=False):
191 def _run_sql(self, sql, params, raw=True, output=False):
192 """Prepares and runs an SQL query for the history database.
192 """Prepares and runs an SQL query for the history database.
193
193
194 Parameters
194 Parameters
195 ----------
195 ----------
196 sql : str
196 sql : str
@@ -199,7 +199,7 b' class HistoryManager(Configurable):'
199 Parameters passed to the SQL query (to replace "?")
199 Parameters passed to the SQL query (to replace "?")
200 raw, output : bool
200 raw, output : bool
201 See :meth:`get_range`
201 See :meth:`get_range`
202
202
203 Returns
203 Returns
204 -------
204 -------
205 Tuples as :meth:`get_range`
205 Tuples as :meth:`get_range`
@@ -214,38 +214,38 b' class HistoryManager(Configurable):'
214 if output: # Regroup into 3-tuples, and parse JSON
214 if output: # Regroup into 3-tuples, and parse JSON
215 return ((ses, lin, (inp, out)) for ses, lin, inp, out in cur)
215 return ((ses, lin, (inp, out)) for ses, lin, inp, out in cur)
216 return cur
216 return cur
217
217
218
218
219 def get_session_info(self, session=0):
219 def get_session_info(self, session=0):
220 """get info about a session
220 """get info about a session
221
221
222 Parameters
222 Parameters
223 ----------
223 ----------
224
224
225 session : int
225 session : int
226 Session number to retrieve. The current session is 0, and negative
226 Session number to retrieve. The current session is 0, and negative
227 numbers count back from current session, so -1 is previous session.
227 numbers count back from current session, so -1 is previous session.
228
228
229 Returns
229 Returns
230 -------
230 -------
231
231
232 (session_id [int], start [datetime], end [datetime], num_cmds [int], remark [unicode])
232 (session_id [int], start [datetime], end [datetime], num_cmds [int], remark [unicode])
233
233
234 Sessions that are running or did not exit cleanly will have `end=None`
234 Sessions that are running or did not exit cleanly will have `end=None`
235 and `num_cmds=None`.
235 and `num_cmds=None`.
236
236
237 """
237 """
238
238
239 if session <= 0:
239 if session <= 0:
240 session += self.session_number
240 session += self.session_number
241
241
242 query = "SELECT * from sessions where session == ?"
242 query = "SELECT * from sessions where session == ?"
243 return self.db.execute(query, (session,)).fetchone()
243 return self.db.execute(query, (session,)).fetchone()
244
244
245
245
246 def get_tail(self, n=10, raw=True, output=False, include_latest=False):
246 def get_tail(self, n=10, raw=True, output=False, include_latest=False):
247 """Get the last n lines from the history database.
247 """Get the last n lines from the history database.
248
248
249 Parameters
249 Parameters
250 ----------
250 ----------
251 n : int
251 n : int
@@ -256,7 +256,7 b' class HistoryManager(Configurable):'
256 If False (default), n+1 lines are fetched, and the latest one
256 If False (default), n+1 lines are fetched, and the latest one
257 is discarded. This is intended to be used where the function
257 is discarded. This is intended to be used where the function
258 is called by a user command, which it should not return.
258 is called by a user command, which it should not return.
259
259
260 Returns
260 Returns
261 -------
261 -------
262 Tuples as :meth:`get_range`
262 Tuples as :meth:`get_range`
@@ -269,12 +269,12 b' class HistoryManager(Configurable):'
269 if not include_latest:
269 if not include_latest:
270 return reversed(list(cur)[1:])
270 return reversed(list(cur)[1:])
271 return reversed(list(cur))
271 return reversed(list(cur))
272
272
273 def search(self, pattern="*", raw=True, search_raw=True,
273 def search(self, pattern="*", raw=True, search_raw=True,
274 output=False):
274 output=False):
275 """Search the database using unix glob-style matching (wildcards
275 """Search the database using unix glob-style matching (wildcards
276 * and ?).
276 * and ?).
277
277
278 Parameters
278 Parameters
279 ----------
279 ----------
280 pattern : str
280 pattern : str
@@ -283,7 +283,7 b' class HistoryManager(Configurable):'
283 If True, search the raw input, otherwise, the parsed input
283 If True, search the raw input, otherwise, the parsed input
284 raw, output : bool
284 raw, output : bool
285 See :meth:`get_range`
285 See :meth:`get_range`
286
286
287 Returns
287 Returns
288 -------
288 -------
289 Tuples as :meth:`get_range`
289 Tuples as :meth:`get_range`
@@ -294,12 +294,12 b' class HistoryManager(Configurable):'
294 self.writeout_cache()
294 self.writeout_cache()
295 return self._run_sql("WHERE %s GLOB ?" % tosearch, (pattern,),
295 return self._run_sql("WHERE %s GLOB ?" % tosearch, (pattern,),
296 raw=raw, output=output)
296 raw=raw, output=output)
297
297
298 def _get_range_session(self, start=1, stop=None, raw=True, output=False):
298 def _get_range_session(self, start=1, stop=None, raw=True, output=False):
299 """Get input and output history from the current session. Called by
299 """Get input and output history from the current session. Called by
300 get_range, and takes similar parameters."""
300 get_range, and takes similar parameters."""
301 input_hist = self.input_hist_raw if raw else self.input_hist_parsed
301 input_hist = self.input_hist_raw if raw else self.input_hist_parsed
302
302
303 n = len(input_hist)
303 n = len(input_hist)
304 if start < 0:
304 if start < 0:
305 start += n
305 start += n
@@ -307,17 +307,17 b' class HistoryManager(Configurable):'
307 stop = n
307 stop = n
308 elif stop < 0:
308 elif stop < 0:
309 stop += n
309 stop += n
310
310
311 for i in range(start, stop):
311 for i in range(start, stop):
312 if output:
312 if output:
313 line = (input_hist[i], self.output_hist_reprs.get(i))
313 line = (input_hist[i], self.output_hist_reprs.get(i))
314 else:
314 else:
315 line = input_hist[i]
315 line = input_hist[i]
316 yield (0, i, line)
316 yield (0, i, line)
317
317
318 def get_range(self, session=0, start=1, stop=None, raw=True,output=False):
318 def get_range(self, session=0, start=1, stop=None, raw=True,output=False):
319 """Retrieve input by session.
319 """Retrieve input by session.
320
320
321 Parameters
321 Parameters
322 ----------
322 ----------
323 session : int
323 session : int
@@ -335,7 +335,7 b' class HistoryManager(Configurable):'
335 objects for the current session, or text reprs from previous
335 objects for the current session, or text reprs from previous
336 sessions if db_log_output was enabled at the time. Where no output
336 sessions if db_log_output was enabled at the time. Where no output
337 is found, None is used.
337 is found, None is used.
338
338
339 Returns
339 Returns
340 -------
340 -------
341 An iterator over the desired lines. Each line is a 3-tuple, either
341 An iterator over the desired lines. Each line is a 3-tuple, either
@@ -346,21 +346,21 b' class HistoryManager(Configurable):'
346 return self._get_range_session(start, stop, raw, output)
346 return self._get_range_session(start, stop, raw, output)
347 if session < 0:
347 if session < 0:
348 session += self.session_number
348 session += self.session_number
349
349
350 if stop:
350 if stop:
351 lineclause = "line >= ? AND line < ?"
351 lineclause = "line >= ? AND line < ?"
352 params = (session, start, stop)
352 params = (session, start, stop)
353 else:
353 else:
354 lineclause = "line>=?"
354 lineclause = "line>=?"
355 params = (session, start)
355 params = (session, start)
356
356
357 return self._run_sql("WHERE session==? AND %s""" % lineclause,
357 return self._run_sql("WHERE session==? AND %s""" % lineclause,
358 params, raw=raw, output=output)
358 params, raw=raw, output=output)
359
359
360 def get_range_by_str(self, rangestr, raw=True, output=False):
360 def get_range_by_str(self, rangestr, raw=True, output=False):
361 """Get lines of history from a string of ranges, as used by magic
361 """Get lines of history from a string of ranges, as used by magic
362 commands %hist, %save, %macro, etc.
362 commands %hist, %save, %macro, etc.
363
363
364 Parameters
364 Parameters
365 ----------
365 ----------
366 rangestr : str
366 rangestr : str
@@ -368,7 +368,7 b' class HistoryManager(Configurable):'
368 :func:`magic_history` for full details.
368 :func:`magic_history` for full details.
369 raw, output : bool
369 raw, output : bool
370 As :meth:`get_range`
370 As :meth:`get_range`
371
371
372 Returns
372 Returns
373 -------
373 -------
374 Tuples as :meth:`get_range`
374 Tuples as :meth:`get_range`
@@ -376,19 +376,19 b' class HistoryManager(Configurable):'
376 for sess, s, e in extract_hist_ranges(rangestr):
376 for sess, s, e in extract_hist_ranges(rangestr):
377 for line in self.get_range(sess, s, e, raw=raw, output=output):
377 for line in self.get_range(sess, s, e, raw=raw, output=output):
378 yield line
378 yield line
379
379
380 ## ----------------------------
380 ## ----------------------------
381 ## Methods for storing history:
381 ## Methods for storing history:
382 ## ----------------------------
382 ## ----------------------------
383 def store_inputs(self, line_num, source, source_raw=None):
383 def store_inputs(self, line_num, source, source_raw=None):
384 """Store source and raw input in history and create input cache
384 """Store source and raw input in history and create input cache
385 variables _i*.
385 variables _i*.
386
386
387 Parameters
387 Parameters
388 ----------
388 ----------
389 line_num : int
389 line_num : int
390 The prompt number of this input.
390 The prompt number of this input.
391
391
392 source : str
392 source : str
393 Python input.
393 Python input.
394
394
@@ -400,14 +400,14 b' class HistoryManager(Configurable):'
400 source_raw = source
400 source_raw = source
401 source = source.rstrip('\n')
401 source = source.rstrip('\n')
402 source_raw = source_raw.rstrip('\n')
402 source_raw = source_raw.rstrip('\n')
403
403
404 # do not store exit/quit commands
404 # do not store exit/quit commands
405 if self._exit_re.match(source_raw.strip()):
405 if self._exit_re.match(source_raw.strip()):
406 return
406 return
407
407
408 self.input_hist_parsed.append(source)
408 self.input_hist_parsed.append(source)
409 self.input_hist_raw.append(source_raw)
409 self.input_hist_raw.append(source_raw)
410
410
411 with self.db_input_cache_lock:
411 with self.db_input_cache_lock:
412 self.db_input_cache.append((line_num, source, source_raw))
412 self.db_input_cache.append((line_num, source, source_raw))
413 # Trigger to flush cache and write to DB.
413 # Trigger to flush cache and write to DB.
@@ -427,12 +427,12 b' class HistoryManager(Configurable):'
427 '_iii': self._iii,
427 '_iii': self._iii,
428 new_i : self._i00 }
428 new_i : self._i00 }
429 self.shell.user_ns.update(to_main)
429 self.shell.user_ns.update(to_main)
430
430
431 def store_output(self, line_num):
431 def store_output(self, line_num):
432 """If database output logging is enabled, this saves all the
432 """If database output logging is enabled, this saves all the
433 outputs from the indicated prompt number to the database. It's
433 outputs from the indicated prompt number to the database. It's
434 called by run_cell after code has been executed.
434 called by run_cell after code has been executed.
435
435
436 Parameters
436 Parameters
437 ----------
437 ----------
438 line_num : int
438 line_num : int
@@ -441,29 +441,29 b' class HistoryManager(Configurable):'
441 if (not self.db_log_output) or (line_num not in self.output_hist_reprs):
441 if (not self.db_log_output) or (line_num not in self.output_hist_reprs):
442 return
442 return
443 output = self.output_hist_reprs[line_num]
443 output = self.output_hist_reprs[line_num]
444
444
445 with self.db_output_cache_lock:
445 with self.db_output_cache_lock:
446 self.db_output_cache.append((line_num, output))
446 self.db_output_cache.append((line_num, output))
447 if self.db_cache_size <= 1:
447 if self.db_cache_size <= 1:
448 self.save_flag.set()
448 self.save_flag.set()
449
449
450 def _writeout_input_cache(self, conn):
450 def _writeout_input_cache(self, conn):
451 with conn:
451 with conn:
452 for line in self.db_input_cache:
452 for line in self.db_input_cache:
453 conn.execute("INSERT INTO history VALUES (?, ?, ?, ?)",
453 conn.execute("INSERT INTO history VALUES (?, ?, ?, ?)",
454 (self.session_number,)+line)
454 (self.session_number,)+line)
455
455
456 def _writeout_output_cache(self, conn):
456 def _writeout_output_cache(self, conn):
457 with conn:
457 with conn:
458 for line in self.db_output_cache:
458 for line in self.db_output_cache:
459 conn.execute("INSERT INTO output_history VALUES (?, ?, ?)",
459 conn.execute("INSERT INTO output_history VALUES (?, ?, ?)",
460 (self.session_number,)+line)
460 (self.session_number,)+line)
461
461
462 def writeout_cache(self, conn=None):
462 def writeout_cache(self, conn=None):
463 """Write any entries in the cache to the database."""
463 """Write any entries in the cache to the database."""
464 if conn is None:
464 if conn is None:
465 conn = self.db
465 conn = self.db
466
466
467 with self.db_input_cache_lock:
467 with self.db_input_cache_lock:
468 try:
468 try:
469 self._writeout_input_cache(conn)
469 self._writeout_input_cache(conn)
@@ -492,7 +492,7 b' class HistoryManager(Configurable):'
492 class HistorySavingThread(threading.Thread):
492 class HistorySavingThread(threading.Thread):
493 """This thread takes care of writing history to the database, so that
493 """This thread takes care of writing history to the database, so that
494 the UI isn't held up while that happens.
494 the UI isn't held up while that happens.
495
495
496 It waits for the HistoryManager's save_flag to be set, then writes out
496 It waits for the HistoryManager's save_flag to be set, then writes out
497 the history cache. The main thread is responsible for setting the flag when
497 the history cache. The main thread is responsible for setting the flag when
498 the cache size reaches a defined threshold."""
498 the cache size reaches a defined threshold."""
@@ -502,7 +502,7 b' class HistorySavingThread(threading.Thread):'
502 super(HistorySavingThread, self).__init__()
502 super(HistorySavingThread, self).__init__()
503 self.history_manager = history_manager
503 self.history_manager = history_manager
504 atexit.register(self.stop)
504 atexit.register(self.stop)
505
505
506 def run(self):
506 def run(self):
507 # We need a separate db connection per thread:
507 # We need a separate db connection per thread:
508 try:
508 try:
@@ -516,10 +516,10 b' class HistorySavingThread(threading.Thread):'
516 except Exception as e:
516 except Exception as e:
517 print(("The history saving thread hit an unexpected error (%s)."
517 print(("The history saving thread hit an unexpected error (%s)."
518 "History will not be written to the database.") % repr(e))
518 "History will not be written to the database.") % repr(e))
519
519
520 def stop(self):
520 def stop(self):
521 """This can be called from the main thread to safely stop this thread.
521 """This can be called from the main thread to safely stop this thread.
522
522
523 Note that it does not attempt to write out remaining history before
523 Note that it does not attempt to write out remaining history before
524 exiting. That should be done by calling the HistoryManager's
524 exiting. That should be done by calling the HistoryManager's
525 end_session method."""
525 end_session method."""
@@ -527,7 +527,7 b' class HistorySavingThread(threading.Thread):'
527 self.history_manager.save_flag.set()
527 self.history_manager.save_flag.set()
528 self.join()
528 self.join()
529
529
530
530
531 # To match, e.g. ~5/8-~2/3
531 # To match, e.g. ~5/8-~2/3
532 range_re = re.compile(r"""
532 range_re = re.compile(r"""
533 ((?P<startsess>~?\d+)/)?
533 ((?P<startsess>~?\d+)/)?
@@ -539,7 +539,7 b' $""", re.VERBOSE)'
539
539
540 def extract_hist_ranges(ranges_str):
540 def extract_hist_ranges(ranges_str):
541 """Turn a string of history ranges into 3-tuples of (session, start, stop).
541 """Turn a string of history ranges into 3-tuples of (session, start, stop).
542
542
543 Examples
543 Examples
544 --------
544 --------
545 list(extract_input_ranges("~8/5-~7/4 2"))
545 list(extract_input_ranges("~8/5-~7/4 2"))
@@ -578,7 +578,7 b' def _format_lineno(session, line):'
578 @skip_doctest
578 @skip_doctest
579 def magic_history(self, parameter_s = ''):
579 def magic_history(self, parameter_s = ''):
580 """Print input history (_i<n> variables), with most recent last.
580 """Print input history (_i<n> variables), with most recent last.
581
581
582 %history -> print at most 40 inputs (some may be multi-line)\\
582 %history -> print at most 40 inputs (some may be multi-line)\\
583 %history n -> print at most n inputs\\
583 %history n -> print at most n inputs\\
584 %history n1 n2 -> print inputs between n1 and n2 (n2 not included)\\
584 %history n1 n2 -> print inputs between n1 and n2 (n2 not included)\\
@@ -594,7 +594,7 b" def magic_history(self, parameter_s = ''):"
594 ~8/1-~6/5 : From the first line of 8 sessions ago, to the fifth line
594 ~8/1-~6/5 : From the first line of 8 sessions ago, to the fifth line
595 of 6 sessions ago.
595 of 6 sessions ago.
596 Multiple ranges can be entered, separated by spaces
596 Multiple ranges can be entered, separated by spaces
597
597
598 The same syntax is used by %macro, %save, %edit, %rerun
598 The same syntax is used by %macro, %save, %edit, %rerun
599
599
600 Options:
600 Options:
@@ -609,29 +609,29 b" def magic_history(self, parameter_s = ''):"
609 doctest-ready output.
609 doctest-ready output.
610
610
611 -r: (default) print the 'raw' history, i.e. the actual commands you typed.
611 -r: (default) print the 'raw' history, i.e. the actual commands you typed.
612
612
613 -t: print the 'translated' history, as IPython understands it. IPython
613 -t: print the 'translated' history, as IPython understands it. IPython
614 filters your input and converts it all into valid Python source before
614 filters your input and converts it all into valid Python source before
615 executing it (things like magics or aliases are turned into function
615 executing it (things like magics or aliases are turned into function
616 calls, for example). With this option, you'll see the native history
616 calls, for example). With this option, you'll see the native history
617 instead of the user-entered version: '%cd /' will be seen as
617 instead of the user-entered version: '%cd /' will be seen as
618 'get_ipython().magic("%cd /")' instead of '%cd /'.
618 'get_ipython().magic("%cd /")' instead of '%cd /'.
619
619
620 -g: treat the arg as a pattern to grep for in (full) history.
620 -g: treat the arg as a pattern to grep for in (full) history.
621 This includes the saved history (almost all commands ever written).
621 This includes the saved history (almost all commands ever written).
622 Use '%hist -g' to show full saved history (may be very long).
622 Use '%hist -g' to show full saved history (may be very long).
623
623
624 -l: get the last n lines from all sessions. Specify n as a single arg, or
624 -l: get the last n lines from all sessions. Specify n as a single arg, or
625 the default is the last 10 lines.
625 the default is the last 10 lines.
626
626
627 -f FILENAME: instead of printing the output to the screen, redirect it to
627 -f FILENAME: instead of printing the output to the screen, redirect it to
628 the given file. The file is always overwritten, though IPython asks for
628 the given file. The file is always overwritten, though IPython asks for
629 confirmation first if it already exists.
629 confirmation first if it already exists.
630
630
631 Examples
631 Examples
632 --------
632 --------
633 ::
633 ::
634
634
635 In [6]: %hist -n 4 6
635 In [6]: %hist -n 4 6
636 4:a = 12
636 4:a = 12
637 5:print a**2
637 5:print a**2
@@ -642,10 +642,10 b" def magic_history(self, parameter_s = ''):"
642 print('This feature is only available if numbered prompts are in use.')
642 print('This feature is only available if numbered prompts are in use.')
643 return
643 return
644 opts,args = self.parse_options(parameter_s,'noprtglf:',mode='string')
644 opts,args = self.parse_options(parameter_s,'noprtglf:',mode='string')
645
645
646 # For brevity
646 # For brevity
647 history_manager = self.shell.history_manager
647 history_manager = self.shell.history_manager
648
648
649 def _format_lineno(session, line):
649 def _format_lineno(session, line):
650 """Helper function to format line numbers properly."""
650 """Helper function to format line numbers properly."""
651 if session in (0, history_manager.session_number):
651 if session in (0, history_manager.session_number):
@@ -661,22 +661,22 b" def magic_history(self, parameter_s = ''):"
661 close_at_end = False
661 close_at_end = False
662 else:
662 else:
663 if os.path.exists(outfname):
663 if os.path.exists(outfname):
664 if not io.ask_yes_no("File %r exists. Overwrite?" % outfname):
664 if not io.ask_yes_no("File %r exists. Overwrite?" % outfname):
665 print('Aborting.')
665 print('Aborting.')
666 return
666 return
667
667
668 outfile = open(outfname,'w')
668 outfile = open(outfname,'w')
669 close_at_end = True
669 close_at_end = True
670
670
671 print_nums = 'n' in opts
671 print_nums = 'n' in opts
672 get_output = 'o' in opts
672 get_output = 'o' in opts
673 pyprompts = 'p' in opts
673 pyprompts = 'p' in opts
674 # Raw history is the default
674 # Raw history is the default
675 raw = not('t' in opts)
675 raw = not('t' in opts)
676
676
677 default_length = 40
677 default_length = 40
678 pattern = None
678 pattern = None
679
679
680 if 'g' in opts: # Glob search
680 if 'g' in opts: # Glob search
681 pattern = "*" + args + "*" if args else "*"
681 pattern = "*" + args + "*" if args else "*"
682 hist = history_manager.search(pattern, raw=raw, output=get_output)
682 hist = history_manager.search(pattern, raw=raw, output=get_output)
@@ -692,11 +692,11 b" def magic_history(self, parameter_s = ''):"
692 hist = history_manager.get_range_by_str(args, raw, get_output)
692 hist = history_manager.get_range_by_str(args, raw, get_output)
693 else: # Just get history for the current session
693 else: # Just get history for the current session
694 hist = history_manager.get_range(raw=raw, output=get_output)
694 hist = history_manager.get_range(raw=raw, output=get_output)
695
695
696 # We could be displaying the entire history, so let's not try to pull it
696 # We could be displaying the entire history, so let's not try to pull it
697 # into a list in memory. Anything that needs more space will just misalign.
697 # into a list in memory. Anything that needs more space will just misalign.
698 width = 4
698 width = 4
699
699
700 for session, lineno, inline in hist:
700 for session, lineno, inline in hist:
701 # Print user history with tabs expanded to 4 spaces. The GUI clients
701 # Print user history with tabs expanded to 4 spaces. The GUI clients
702 # use hard tabs for easier usability in auto-indented code, but we want
702 # use hard tabs for easier usability in auto-indented code, but we want
@@ -704,7 +704,7 b" def magic_history(self, parameter_s = ''):"
704 if get_output:
704 if get_output:
705 inline, output = inline
705 inline, output = inline
706 inline = inline.expandtabs(4).rstrip()
706 inline = inline.expandtabs(4).rstrip()
707
707
708 multiline = "\n" in inline
708 multiline = "\n" in inline
709 line_sep = '\n' if multiline else ' '
709 line_sep = '\n' if multiline else ' '
710 if print_nums:
710 if print_nums:
@@ -727,29 +727,29 b' def magic_rep(self, arg):'
727 %rep are equivalent.
727 %rep are equivalent.
728
728
729 - %recall (no arguments):
729 - %recall (no arguments):
730
730
731 Place a string version of last computation result (stored in the special '_'
731 Place a string version of last computation result (stored in the special '_'
732 variable) to the next input prompt. Allows you to create elaborate command
732 variable) to the next input prompt. Allows you to create elaborate command
733 lines without using copy-paste::
733 lines without using copy-paste::
734
734
735 In[1]: l = ["hei", "vaan"]
735 In[1]: l = ["hei", "vaan"]
736 In[2]: "".join(l)
736 In[2]: "".join(l)
737 Out[2]: heivaan
737 Out[2]: heivaan
738 In[3]: %rep
738 In[3]: %rep
739 In[4]: heivaan_ <== cursor blinking
739 In[4]: heivaan_ <== cursor blinking
740
740
741 %recall 45
741 %recall 45
742
742
743 Place history line 45 on the next input prompt. Use %hist to find
743 Place history line 45 on the next input prompt. Use %hist to find
744 out the number.
744 out the number.
745
745
746 %recall 1-4
746 %recall 1-4
747
747
748 Combine the specified lines into one cell, and place it on the next
748 Combine the specified lines into one cell, and place it on the next
749 input prompt. See %history for the slice syntax.
749 input prompt. See %history for the slice syntax.
750
750
751 %recall foo+bar
751 %recall foo+bar
752
752
753 If foo+bar can be evaluated in the user namespace, the result is
753 If foo+bar can be evaluated in the user namespace, the result is
754 placed at the next input prompt. Otherwise, the history is searched
754 placed at the next input prompt. Otherwise, the history is searched
755 for lines which contain that substring, and the most recent one is
755 for lines which contain that substring, and the most recent one is
@@ -777,18 +777,18 b' def magic_rep(self, arg):'
777 else:
777 else:
778 self.set_next_input(cmd.rstrip())
778 self.set_next_input(cmd.rstrip())
779 print("Couldn't evaluate or find in history:", arg)
779 print("Couldn't evaluate or find in history:", arg)
780
780
781 def magic_rerun(self, parameter_s=''):
781 def magic_rerun(self, parameter_s=''):
782 """Re-run previous input
782 """Re-run previous input
783
783
784 By default, you can specify ranges of input history to be repeated
784 By default, you can specify ranges of input history to be repeated
785 (as with %history). With no arguments, it will repeat the last line.
785 (as with %history). With no arguments, it will repeat the last line.
786
786
787 Options:
787 Options:
788
788
789 -l <n> : Repeat the last n lines of input, not including the
789 -l <n> : Repeat the last n lines of input, not including the
790 current command.
790 current command.
791
791
792 -g foo : Repeat the most recent line which contains foo
792 -g foo : Repeat the most recent line which contains foo
793 """
793 """
794 opts, args = self.parse_options(parameter_s, 'l:g:', mode='string')
794 opts, args = self.parse_options(parameter_s, 'l:g:', mode='string')
@@ -820,7 +820,7 b" def magic_rerun(self, parameter_s=''):"
820
820
821
821
822 def init_ipython(ip):
822 def init_ipython(ip):
823 ip.define_magic("rep", magic_rep)
823 ip.define_magic("rep", magic_rep)
824 ip.define_magic("recall", magic_rep)
824 ip.define_magic("recall", magic_rep)
825 ip.define_magic("rerun", magic_rerun)
825 ip.define_magic("rerun", magic_rerun)
826 ip.define_magic("hist",magic_history) # Alternative name
826 ip.define_magic("hist",magic_history) # Alternative name
@@ -64,24 +64,24 b' def editor(self,filename, linenum=None):'
64 # IPython configures a default editor at startup by reading $EDITOR from
64 # IPython configures a default editor at startup by reading $EDITOR from
65 # the environment, and falling back on vi (unix) or notepad (win32).
65 # the environment, and falling back on vi (unix) or notepad (win32).
66 editor = self.editor
66 editor = self.editor
67
67
68 # marker for at which line to open the file (for existing objects)
68 # marker for at which line to open the file (for existing objects)
69 if linenum is None or editor=='notepad':
69 if linenum is None or editor=='notepad':
70 linemark = ''
70 linemark = ''
71 else:
71 else:
72 linemark = '+%d' % int(linenum)
72 linemark = '+%d' % int(linenum)
73
73
74 # Enclose in quotes if necessary and legal
74 # Enclose in quotes if necessary and legal
75 if ' ' in editor and os.path.isfile(editor) and editor[0] != '"':
75 if ' ' in editor and os.path.isfile(editor) and editor[0] != '"':
76 editor = '"%s"' % editor
76 editor = '"%s"' % editor
77
77
78 # Call the actual editor
78 # Call the actual editor
79 if os.system('%s %s %s' % (editor,linemark,filename)) != 0:
79 if os.system('%s %s %s' % (editor,linemark,filename)) != 0:
80 raise TryNext()
80 raise TryNext()
81
81
82 import tempfile
82 import tempfile
83 def fix_error_editor(self,filename,linenum,column,msg):
83 def fix_error_editor(self,filename,linenum,column,msg):
84 """Open the editor at the given filename, linenumber, column and
84 """Open the editor at the given filename, linenumber, column and
85 show an error message. This is used for correcting syntax errors.
85 show an error message. This is used for correcting syntax errors.
86 The current implementation only has special support for the VIM editor,
86 The current implementation only has special support for the VIM editor,
87 and falls back on the 'editor' hook if VIM is not used.
87 and falls back on the 'editor' hook if VIM is not used.
@@ -110,25 +110,25 b' def synchronize_with_editor(self, filename, linenum, column):'
110
110
111 class CommandChainDispatcher:
111 class CommandChainDispatcher:
112 """ Dispatch calls to a chain of commands until some func can handle it
112 """ Dispatch calls to a chain of commands until some func can handle it
113
113
114 Usage: instantiate, execute "add" to add commands (with optional
114 Usage: instantiate, execute "add" to add commands (with optional
115 priority), execute normally via f() calling mechanism.
115 priority), execute normally via f() calling mechanism.
116
116
117 """
117 """
118 def __init__(self,commands=None):
118 def __init__(self,commands=None):
119 if commands is None:
119 if commands is None:
120 self.chain = []
120 self.chain = []
121 else:
121 else:
122 self.chain = commands
122 self.chain = commands
123
123
124
124
125 def __call__(self,*args, **kw):
125 def __call__(self,*args, **kw):
126 """ Command chain is called just like normal func.
126 """ Command chain is called just like normal func.
127
127
128 This will call all funcs in chain with the same args as were given to this
128 This will call all funcs in chain with the same args as were given to this
129 function, and return the result of first func that didn't raise
129 function, and return the result of first func that didn't raise
130 TryNext """
130 TryNext """
131
131
132 for prio,cmd in self.chain:
132 for prio,cmd in self.chain:
133 #print "prio",prio,"cmd",cmd #dbg
133 #print "prio",prio,"cmd",cmd #dbg
134 try:
134 try:
@@ -139,32 +139,32 b' class CommandChainDispatcher:'
139 kw = exc.kwargs
139 kw = exc.kwargs
140 # if no function will accept it, raise TryNext up to the caller
140 # if no function will accept it, raise TryNext up to the caller
141 raise TryNext
141 raise TryNext
142
142
143 def __str__(self):
143 def __str__(self):
144 return str(self.chain)
144 return str(self.chain)
145
145
146 def add(self, func, priority=0):
146 def add(self, func, priority=0):
147 """ Add a func to the cmd chain with given priority """
147 """ Add a func to the cmd chain with given priority """
148 bisect.insort(self.chain,(priority,func))
148 bisect.insort(self.chain,(priority,func))
149
149
150 def __iter__(self):
150 def __iter__(self):
151 """ Return all objects in chain.
151 """ Return all objects in chain.
152
152
153 Handy if the objects are not callable.
153 Handy if the objects are not callable.
154 """
154 """
155 return iter(self.chain)
155 return iter(self.chain)
156
156
157
157
158 def input_prefilter(self,line):
158 def input_prefilter(self,line):
159 """ Default input prefilter
159 """ Default input prefilter
160
160
161 This returns the line as unchanged, so that the interpreter
161 This returns the line as unchanged, so that the interpreter
162 knows that nothing was done and proceeds with "classic" prefiltering
162 knows that nothing was done and proceeds with "classic" prefiltering
163 (%magics, !shell commands etc.).
163 (%magics, !shell commands etc.).
164
164
165 Note that leading whitespace is not passed to this hook. Prefilter
165 Note that leading whitespace is not passed to this hook. Prefilter
166 can't alter indentation.
166 can't alter indentation.
167
167
168 """
168 """
169 #print "attempt to rewrite",line #dbg
169 #print "attempt to rewrite",line #dbg
170 return line
170 return line
@@ -172,17 +172,17 b' def input_prefilter(self,line):'
172
172
173 def shutdown_hook(self):
173 def shutdown_hook(self):
174 """ default shutdown hook
174 """ default shutdown hook
175
175
176 Typically, shotdown hooks should raise TryNext so all shutdown ops are done
176 Typically, shotdown hooks should raise TryNext so all shutdown ops are done
177 """
177 """
178
178
179 #print "default shutdown hook ok" # dbg
179 #print "default shutdown hook ok" # dbg
180 return
180 return
181
181
182
182
183 def late_startup_hook(self):
183 def late_startup_hook(self):
184 """ Executed after ipython has been constructed and configured
184 """ Executed after ipython has been constructed and configured
185
185
186 """
186 """
187 #print "default startup hook ok" # dbg
187 #print "default startup hook ok" # dbg
188
188
@@ -202,11 +202,11 b' def show_in_pager(self,s):'
202
202
203 def pre_prompt_hook(self):
203 def pre_prompt_hook(self):
204 """ Run before displaying the next prompt
204 """ Run before displaying the next prompt
205
205
206 Use this e.g. to display output from asynchronous operations (in order
206 Use this e.g. to display output from asynchronous operations (in order
207 to not mess up text entry)
207 to not mess up text entry)
208 """
208 """
209
209
210 return None
210 return None
211
211
212
212
@@ -219,7 +219,7 b' def clipboard_get(self):'
219 """ Get text from the clipboard.
219 """ Get text from the clipboard.
220 """
220 """
221 from IPython.lib.clipboard import (
221 from IPython.lib.clipboard import (
222 osx_clipboard_get, tkinter_clipboard_get,
222 osx_clipboard_get, tkinter_clipboard_get,
223 win32_clipboard_get
223 win32_clipboard_get
224 )
224 )
225 if sys.platform == 'win32':
225 if sys.platform == 'win32':
@@ -145,7 +145,7 b' class ReadlineNoRecord(object):'
145 def __init__(self, shell):
145 def __init__(self, shell):
146 self.shell = shell
146 self.shell = shell
147 self._nested_level = 0
147 self._nested_level = 0
148
148
149 def __enter__(self):
149 def __enter__(self):
150 if self._nested_level == 0:
150 if self._nested_level == 0:
151 try:
151 try:
@@ -154,7 +154,7 b' class ReadlineNoRecord(object):'
154 except (AttributeError, IndexError): # Can fail with pyreadline
154 except (AttributeError, IndexError): # Can fail with pyreadline
155 self.orig_length, self.readline_tail = 999999, []
155 self.orig_length, self.readline_tail = 999999, []
156 self._nested_level += 1
156 self._nested_level += 1
157
157
158 def __exit__(self, type, value, traceback):
158 def __exit__(self, type, value, traceback):
159 self._nested_level -= 1
159 self._nested_level -= 1
160 if self._nested_level == 0:
160 if self._nested_level == 0:
@@ -164,7 +164,7 b' class ReadlineNoRecord(object):'
164 if e > 0:
164 if e > 0:
165 for _ in range(e):
165 for _ in range(e):
166 self.shell.readline.remove_history_item(self.orig_length)
166 self.shell.readline.remove_history_item(self.orig_length)
167
167
168 # If it still doesn't match, just reload readline history.
168 # If it still doesn't match, just reload readline history.
169 if self.current_length() != self.orig_length \
169 if self.current_length() != self.orig_length \
170 or self.get_readline_tail() != self.readline_tail:
170 or self.get_readline_tail() != self.readline_tail:
@@ -173,10 +173,10 b' class ReadlineNoRecord(object):'
173 pass
173 pass
174 # Returning False will cause exceptions to propagate
174 # Returning False will cause exceptions to propagate
175 return False
175 return False
176
176
177 def current_length(self):
177 def current_length(self):
178 return self.shell.readline.get_current_history_length()
178 return self.shell.readline.get_current_history_length()
179
179
180 def get_readline_tail(self, n=10):
180 def get_readline_tail(self, n=10):
181 """Get the last n items in readline history."""
181 """Get the last n items in readline history."""
182 end = self.shell.readline.get_current_history_length() + 1
182 end = self.shell.readline.get_current_history_length() + 1
@@ -243,7 +243,7 b' class InteractiveShell(SingletonConfigurable, Magic):'
243 get confused with color codes, this capability can be turned off.
243 get confused with color codes, this capability can be turned off.
244 """
244 """
245 )
245 )
246 colors = CaselessStrEnum(('NoColor','LightBG','Linux'),
246 colors = CaselessStrEnum(('NoColor','LightBG','Linux'),
247 default_value=get_default_colors(), config=True,
247 default_value=get_default_colors(), config=True,
248 help="Set the color scheme (NoColor, Linux, or LightBG)."
248 help="Set the color scheme (NoColor, Linux, or LightBG)."
249 )
249 )
@@ -315,7 +315,7 b' class InteractiveShell(SingletonConfigurable, Magic):'
315 quiet = CBool(False, config=True)
315 quiet = CBool(False, config=True)
316
316
317 history_length = Int(10000, config=True)
317 history_length = Int(10000, config=True)
318
318
319 # The readline stuff will eventually be moved to the terminal subclass
319 # The readline stuff will eventually be moved to the terminal subclass
320 # but for now, we can't do that as readline is welded in everywhere.
320 # but for now, we can't do that as readline is welded in everywhere.
321 readline_use = CBool(True, config=True)
321 readline_use = CBool(True, config=True)
@@ -345,7 +345,7 b' class InteractiveShell(SingletonConfigurable, Magic):'
345 separate_out = SeparateUnicode('', config=True)
345 separate_out = SeparateUnicode('', config=True)
346 separate_out2 = SeparateUnicode('', config=True)
346 separate_out2 = SeparateUnicode('', config=True)
347 wildcards_case_sensitive = CBool(True, config=True)
347 wildcards_case_sensitive = CBool(True, config=True)
348 xmode = CaselessStrEnum(('Context','Plain', 'Verbose'),
348 xmode = CaselessStrEnum(('Context','Plain', 'Verbose'),
349 default_value='Context', config=True)
349 default_value='Context', config=True)
350
350
351 # Subcomponents of InteractiveShell
351 # Subcomponents of InteractiveShell
@@ -393,7 +393,7 b' class InteractiveShell(SingletonConfigurable, Magic):'
393 # is what we want to do.
393 # is what we want to do.
394 self.save_sys_module_state()
394 self.save_sys_module_state()
395 self.init_sys_modules()
395 self.init_sys_modules()
396
396
397 # While we're trying to have each part of the code directly access what
397 # While we're trying to have each part of the code directly access what
398 # it needs without keeping redundant references to objects, we have too
398 # it needs without keeping redundant references to objects, we have too
399 # much legacy code that expects ip.db to exist.
399 # much legacy code that expects ip.db to exist.
@@ -583,7 +583,7 b' class InteractiveShell(SingletonConfigurable, Magic):'
583 def init_io(self):
583 def init_io(self):
584 # This will just use sys.stdout and sys.stderr. If you want to
584 # This will just use sys.stdout and sys.stderr. If you want to
585 # override sys.stdout and sys.stderr themselves, you need to do that
585 # override sys.stdout and sys.stderr themselves, you need to do that
586 # *before* instantiating this class, because io holds onto
586 # *before* instantiating this class, because io holds onto
587 # references to the underlying streams.
587 # references to the underlying streams.
588 if sys.platform == 'win32' and self.has_readline:
588 if sys.platform == 'win32' and self.has_readline:
589 io.stdout = io.stderr = io.IOStream(self.readline._outputfile)
589 io.stdout = io.stderr = io.IOStream(self.readline._outputfile)
@@ -593,7 +593,7 b' class InteractiveShell(SingletonConfigurable, Magic):'
593
593
594 def init_prompts(self):
594 def init_prompts(self):
595 # TODO: This is a pass for now because the prompts are managed inside
595 # TODO: This is a pass for now because the prompts are managed inside
596 # the DisplayHook. Once there is a separate prompt manager, this
596 # the DisplayHook. Once there is a separate prompt manager, this
597 # will initialize that object and all prompt related information.
597 # will initialize that object and all prompt related information.
598 pass
598 pass
599
599
@@ -682,13 +682,13 b' class InteractiveShell(SingletonConfigurable, Magic):'
682 """set_hook(name,hook) -> sets an internal IPython hook.
682 """set_hook(name,hook) -> sets an internal IPython hook.
683
683
684 IPython exposes some of its internal API as user-modifiable hooks. By
684 IPython exposes some of its internal API as user-modifiable hooks. By
685 adding your function to one of these hooks, you can modify IPython's
685 adding your function to one of these hooks, you can modify IPython's
686 behavior to call at runtime your own routines."""
686 behavior to call at runtime your own routines."""
687
687
688 # At some point in the future, this should validate the hook before it
688 # At some point in the future, this should validate the hook before it
689 # accepts it. Probably at least check that the hook takes the number
689 # accepts it. Probably at least check that the hook takes the number
690 # of args it's supposed to.
690 # of args it's supposed to.
691
691
692 f = types.MethodType(hook,self)
692 f = types.MethodType(hook,self)
693
693
694 # check if the hook is for strdispatcher first
694 # check if the hook is for strdispatcher first
@@ -702,14 +702,14 b' class InteractiveShell(SingletonConfigurable, Magic):'
702 sdp.add_re(re.compile(re_key), f, priority )
702 sdp.add_re(re.compile(re_key), f, priority )
703 self.strdispatchers[name] = sdp
703 self.strdispatchers[name] = sdp
704 return
704 return
705
705
706 dp = getattr(self.hooks, name, None)
706 dp = getattr(self.hooks, name, None)
707 if name not in IPython.core.hooks.__all__:
707 if name not in IPython.core.hooks.__all__:
708 print "Warning! Hook '%s' is not one of %s" % \
708 print "Warning! Hook '%s' is not one of %s" % \
709 (name, IPython.core.hooks.__all__ )
709 (name, IPython.core.hooks.__all__ )
710 if not dp:
710 if not dp:
711 dp = IPython.core.hooks.CommandChainDispatcher()
711 dp = IPython.core.hooks.CommandChainDispatcher()
712
712
713 try:
713 try:
714 dp.add(f,priority)
714 dp.add(f,priority)
715 except AttributeError:
715 except AttributeError:
@@ -757,7 +757,7 b' class InteractiveShell(SingletonConfigurable, Magic):'
757 must therefore make a *copy* of the given namespace, to allow the
757 must therefore make a *copy* of the given namespace, to allow the
758 original module's __dict__ to be cleared and reused.
758 original module's __dict__ to be cleared and reused.
759
759
760
760
761 Parameters
761 Parameters
762 ----------
762 ----------
763 ns : a namespace (a dict, typically)
763 ns : a namespace (a dict, typically)
@@ -849,7 +849,7 b' class InteractiveShell(SingletonConfigurable, Magic):'
849 else:
849 else:
850 # fallback to our internal debugger
850 # fallback to our internal debugger
851 pm = lambda : self.InteractiveTB.debugger(force=True)
851 pm = lambda : self.InteractiveTB.debugger(force=True)
852
852
853 with self.readline_no_record:
853 with self.readline_no_record:
854 pm()
854 pm()
855
855
@@ -923,7 +923,7 b' class InteractiveShell(SingletonConfigurable, Magic):'
923 # the script will fail, because the function's closure had references
923 # the script will fail, because the function's closure had references
924 # to the original objects, which are now all None. So we must protect
924 # to the original objects, which are now all None. So we must protect
925 # these modules from deletion by keeping a cache.
925 # these modules from deletion by keeping a cache.
926 #
926 #
927 # To avoid keeping stale modules around (we only need the one from the
927 # To avoid keeping stale modules around (we only need the one from the
928 # last run), we use a dict keyed with the full path to the script, so
928 # last run), we use a dict keyed with the full path to the script, so
929 # only the last version of the module is held in the cache. Note,
929 # only the last version of the module is held in the cache. Note,
@@ -931,7 +931,7 b' class InteractiveShell(SingletonConfigurable, Magic):'
931 # __dict__). Because if we try to cache the actual modules, old ones
931 # __dict__). Because if we try to cache the actual modules, old ones
932 # (uncached) could be destroyed while still holding references (such as
932 # (uncached) could be destroyed while still holding references (such as
933 # those held by GUI objects that tend to be long-lived)>
933 # those held by GUI objects that tend to be long-lived)>
934 #
934 #
935 # The %reset command will flush this cache. See the cache_main_mod()
935 # The %reset command will flush this cache. See the cache_main_mod()
936 # and clear_main_mod_cache() methods for details on use.
936 # and clear_main_mod_cache() methods for details on use.
937
937
@@ -1067,11 +1067,11 b' class InteractiveShell(SingletonConfigurable, Magic):'
1067 # module, and can even mutate at runtime, depending on the context
1067 # module, and can even mutate at runtime, depending on the context
1068 # (Python makes no guarantees on it). In contrast, __builtin__ is
1068 # (Python makes no guarantees on it). In contrast, __builtin__ is
1069 # always a module object, though it must be explicitly imported.
1069 # always a module object, though it must be explicitly imported.
1070
1070
1071 # For more details:
1071 # For more details:
1072 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1072 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1073 ns = dict(__builtin__ = builtin_mod)
1073 ns = dict(__builtin__ = builtin_mod)
1074
1074
1075 # Put 'help' in the user namespace
1075 # Put 'help' in the user namespace
1076 try:
1076 try:
1077 from site import _Helper
1077 from site import _Helper
@@ -1093,7 +1093,7 b' class InteractiveShell(SingletonConfigurable, Magic):'
1093
1093
1094 # Store myself as the public api!!!
1094 # Store myself as the public api!!!
1095 ns['get_ipython'] = self.get_ipython
1095 ns['get_ipython'] = self.get_ipython
1096
1096
1097 ns['exit'] = self.exiter
1097 ns['exit'] = self.exiter
1098 ns['quit'] = self.exiter
1098 ns['quit'] = self.exiter
1099
1099
@@ -1104,14 +1104,14 b' class InteractiveShell(SingletonConfigurable, Magic):'
1104 # Anything put into ns now would show up in %who. Think twice before
1104 # Anything put into ns now would show up in %who. Think twice before
1105 # putting anything here, as we really want %who to show the user their
1105 # putting anything here, as we really want %who to show the user their
1106 # stuff, not our variables.
1106 # stuff, not our variables.
1107
1107
1108 # Finally, update the real user's namespace
1108 # Finally, update the real user's namespace
1109 self.user_ns.update(ns)
1109 self.user_ns.update(ns)
1110
1110
1111 def reset(self, new_session=True):
1111 def reset(self, new_session=True):
1112 """Clear all internal namespaces, and attempt to release references to
1112 """Clear all internal namespaces, and attempt to release references to
1113 user objects.
1113 user objects.
1114
1114
1115 If new_session is True, a new history session will be opened.
1115 If new_session is True, a new history session will be opened.
1116 """
1116 """
1117 # Clear histories
1117 # Clear histories
@@ -1119,11 +1119,11 b' class InteractiveShell(SingletonConfigurable, Magic):'
1119 # Reset counter used to index all histories
1119 # Reset counter used to index all histories
1120 if new_session:
1120 if new_session:
1121 self.execution_count = 1
1121 self.execution_count = 1
1122
1122
1123 # Flush cached output items
1123 # Flush cached output items
1124 if self.displayhook.do_full_cache:
1124 if self.displayhook.do_full_cache:
1125 self.displayhook.flush()
1125 self.displayhook.flush()
1126
1126
1127 # Restore the user namespaces to minimal usability
1127 # Restore the user namespaces to minimal usability
1128 for ns in self.ns_refs_table:
1128 for ns in self.ns_refs_table:
1129 ns.clear()
1129 ns.clear()
@@ -1137,25 +1137,25 b' class InteractiveShell(SingletonConfigurable, Magic):'
1137 drop_keys.discard('__builtins__')
1137 drop_keys.discard('__builtins__')
1138 for k in drop_keys:
1138 for k in drop_keys:
1139 del ns[k]
1139 del ns[k]
1140
1140
1141 # Restore the user namespaces to minimal usability
1141 # Restore the user namespaces to minimal usability
1142 self.init_user_ns()
1142 self.init_user_ns()
1143
1143
1144 # Restore the default and user aliases
1144 # Restore the default and user aliases
1145 self.alias_manager.clear_aliases()
1145 self.alias_manager.clear_aliases()
1146 self.alias_manager.init_aliases()
1146 self.alias_manager.init_aliases()
1147
1147
1148 # Flush the private list of module references kept for script
1148 # Flush the private list of module references kept for script
1149 # execution protection
1149 # execution protection
1150 self.clear_main_mod_cache()
1150 self.clear_main_mod_cache()
1151
1151
1152 # Clear out the namespace from the last %run
1152 # Clear out the namespace from the last %run
1153 self.new_main_mod()
1153 self.new_main_mod()
1154
1154
1155 def del_var(self, varname, by_name=False):
1155 def del_var(self, varname, by_name=False):
1156 """Delete a variable from the various namespaces, so that, as
1156 """Delete a variable from the various namespaces, so that, as
1157 far as possible, we're not keeping any hidden references to it.
1157 far as possible, we're not keeping any hidden references to it.
1158
1158
1159 Parameters
1159 Parameters
1160 ----------
1160 ----------
1161 varname : str
1161 varname : str
@@ -1170,7 +1170,7 b' class InteractiveShell(SingletonConfigurable, Magic):'
1170 ns_refs = self.ns_refs_table + [self.user_ns,
1170 ns_refs = self.ns_refs_table + [self.user_ns,
1171 self.user_global_ns, self._user_main_module.__dict__] +\
1171 self.user_global_ns, self._user_main_module.__dict__] +\
1172 self._main_ns_cache.values()
1172 self._main_ns_cache.values()
1173
1173
1174 if by_name: # Delete by name
1174 if by_name: # Delete by name
1175 for ns in ns_refs:
1175 for ns in ns_refs:
1176 try:
1176 try:
@@ -1188,12 +1188,12 b' class InteractiveShell(SingletonConfigurable, Magic):'
1188 to_delete = [n for n, o in ns.iteritems() if o is obj]
1188 to_delete = [n for n, o in ns.iteritems() if o is obj]
1189 for name in to_delete:
1189 for name in to_delete:
1190 del ns[name]
1190 del ns[name]
1191
1191
1192 # displayhook keeps extra references, but not in a dictionary
1192 # displayhook keeps extra references, but not in a dictionary
1193 for name in ('_', '__', '___'):
1193 for name in ('_', '__', '___'):
1194 if getattr(self.displayhook, name) is obj:
1194 if getattr(self.displayhook, name) is obj:
1195 setattr(self.displayhook, name, None)
1195 setattr(self.displayhook, name, None)
1196
1196
1197 def reset_selective(self, regex=None):
1197 def reset_selective(self, regex=None):
1198 """Clear selective variables from internal namespaces based on a
1198 """Clear selective variables from internal namespaces based on a
1199 specified regular expression.
1199 specified regular expression.
@@ -1214,8 +1214,8 b' class InteractiveShell(SingletonConfigurable, Magic):'
1214 for ns in self.ns_refs_table:
1214 for ns in self.ns_refs_table:
1215 for var in ns:
1215 for var in ns:
1216 if m.search(var):
1216 if m.search(var):
1217 del ns[var]
1217 del ns[var]
1218
1218
1219 def push(self, variables, interactive=True):
1219 def push(self, variables, interactive=True):
1220 """Inject a group of variables into the IPython user namespace.
1220 """Inject a group of variables into the IPython user namespace.
1221
1221
@@ -1252,7 +1252,7 b' class InteractiveShell(SingletonConfigurable, Magic):'
1252 (name,cf.f_code.co_name))
1252 (name,cf.f_code.co_name))
1253 else:
1253 else:
1254 raise ValueError('variables must be a dict/str/list/tuple')
1254 raise ValueError('variables must be a dict/str/list/tuple')
1255
1255
1256 # Propagate variables to user namespace
1256 # Propagate variables to user namespace
1257 self.user_ns.update(vdict)
1257 self.user_ns.update(vdict)
1258
1258
@@ -1361,11 +1361,11 b' class InteractiveShell(SingletonConfigurable, Magic):'
1361 root = '.'.join(path[:-1])
1361 root = '.'.join(path[:-1])
1362 if info.parent is not None:
1362 if info.parent is not None:
1363 try:
1363 try:
1364 target = getattr(info.parent, '__class__')
1364 target = getattr(info.parent, '__class__')
1365 # The object belongs to a class instance.
1365 # The object belongs to a class instance.
1366 try:
1366 try:
1367 target = getattr(target, path[-1])
1367 target = getattr(target, path[-1])
1368 # The class defines the object.
1368 # The class defines the object.
1369 if isinstance(target, property):
1369 if isinstance(target, property):
1370 oname = root + '.__class__.' + path[-1]
1370 oname = root + '.__class__.' + path[-1]
1371 info = Struct(self._ofind(oname))
1371 info = Struct(self._ofind(oname))
@@ -1380,7 +1380,7 b' class InteractiveShell(SingletonConfigurable, Magic):'
1380 """Find an object and return a struct with info about it."""
1380 """Find an object and return a struct with info about it."""
1381 inf = Struct(self._ofind(oname, namespaces))
1381 inf = Struct(self._ofind(oname, namespaces))
1382 return Struct(self._ofind_property(oname, inf))
1382 return Struct(self._ofind_property(oname, inf))
1383
1383
1384 def _inspect(self, meth, oname, namespaces=None, **kw):
1384 def _inspect(self, meth, oname, namespaces=None, **kw):
1385 """Generic interface to the inspector system.
1385 """Generic interface to the inspector system.
1386
1386
@@ -1422,7 +1422,7 b' class InteractiveShell(SingletonConfigurable, Magic):'
1422 def init_traceback_handlers(self, custom_exceptions):
1422 def init_traceback_handlers(self, custom_exceptions):
1423 # Syntax error handler.
1423 # Syntax error handler.
1424 self.SyntaxTB = ultratb.SyntaxTB(color_scheme='NoColor')
1424 self.SyntaxTB = ultratb.SyntaxTB(color_scheme='NoColor')
1425
1425
1426 # The interactive one is initialized with an offset, meaning we always
1426 # The interactive one is initialized with an offset, meaning we always
1427 # want to remove the topmost item in the traceback, which is our own
1427 # want to remove the topmost item in the traceback, which is our own
1428 # internal code. Valid modes: ['Plain','Context','Verbose']
1428 # internal code. Valid modes: ['Plain','Context','Verbose']
@@ -1526,7 +1526,7 b' class InteractiveShell(SingletonConfigurable, Magic):'
1526 care of calling it if needed, so unless you are explicitly catching a
1526 care of calling it if needed, so unless you are explicitly catching a
1527 SyntaxError exception, don't try to analyze the stack manually and
1527 SyntaxError exception, don't try to analyze the stack manually and
1528 simply call this method."""
1528 simply call this method."""
1529
1529
1530 try:
1530 try:
1531 if exc_tuple is None:
1531 if exc_tuple is None:
1532 etype, value, tb = sys.exc_info()
1532 etype, value, tb = sys.exc_info()
@@ -1540,7 +1540,7 b' class InteractiveShell(SingletonConfigurable, Magic):'
1540 else:
1540 else:
1541 self.write_err('No traceback available to show.\n')
1541 self.write_err('No traceback available to show.\n')
1542 return
1542 return
1543
1543
1544 if etype is SyntaxError:
1544 if etype is SyntaxError:
1545 # Though this won't be called by syntax errors in the input
1545 # Though this won't be called by syntax errors in the input
1546 # line, there may be SyntaxError cases with imported code.
1546 # line, there may be SyntaxError cases with imported code.
@@ -1570,14 +1570,14 b' class InteractiveShell(SingletonConfigurable, Magic):'
1570 else:
1570 else:
1571 stb = self.InteractiveTB.structured_traceback(etype,
1571 stb = self.InteractiveTB.structured_traceback(etype,
1572 value, tb, tb_offset=tb_offset)
1572 value, tb, tb_offset=tb_offset)
1573
1573
1574 if self.call_pdb:
1574 if self.call_pdb:
1575 # drop into debugger
1575 # drop into debugger
1576 self.debugger(force=True)
1576 self.debugger(force=True)
1577
1577
1578 # Actually show the traceback
1578 # Actually show the traceback
1579 self._showtraceback(etype, value, stb)
1579 self._showtraceback(etype, value, stb)
1580
1580
1581 except KeyboardInterrupt:
1581 except KeyboardInterrupt:
1582 self.write_err("\nKeyboardInterrupt\n")
1582 self.write_err("\nKeyboardInterrupt\n")
1583
1583
@@ -1604,7 +1604,7 b' class InteractiveShell(SingletonConfigurable, Magic):'
1604 sys.last_type = etype
1604 sys.last_type = etype
1605 sys.last_value = value
1605 sys.last_value = value
1606 sys.last_traceback = last_traceback
1606 sys.last_traceback = last_traceback
1607
1607
1608 if filename and etype is SyntaxError:
1608 if filename and etype is SyntaxError:
1609 # Work hard to stuff the correct filename in the exception
1609 # Work hard to stuff the correct filename in the exception
1610 try:
1610 try:
@@ -1622,13 +1622,13 b' class InteractiveShell(SingletonConfigurable, Magic):'
1622 value = msg, (filename, lineno, offset, line)
1622 value = msg, (filename, lineno, offset, line)
1623 stb = self.SyntaxTB.structured_traceback(etype, value, [])
1623 stb = self.SyntaxTB.structured_traceback(etype, value, [])
1624 self._showtraceback(etype, value, stb)
1624 self._showtraceback(etype, value, stb)
1625
1625
1626 # This is overridden in TerminalInteractiveShell to show a message about
1626 # This is overridden in TerminalInteractiveShell to show a message about
1627 # the %paste magic.
1627 # the %paste magic.
1628 def showindentationerror(self):
1628 def showindentationerror(self):
1629 """Called by run_cell when there's an IndentationError in code entered
1629 """Called by run_cell when there's an IndentationError in code entered
1630 at the prompt.
1630 at the prompt.
1631
1631
1632 This is overridden in TerminalInteractiveShell to show a message about
1632 This is overridden in TerminalInteractiveShell to show a message about
1633 the %paste magic."""
1633 the %paste magic."""
1634 self.showsyntaxerror()
1634 self.showsyntaxerror()
@@ -1660,7 +1660,7 b' class InteractiveShell(SingletonConfigurable, Magic):'
1660 self.has_readline = True
1660 self.has_readline = True
1661 self.readline = readline
1661 self.readline = readline
1662 sys.modules['readline'] = readline
1662 sys.modules['readline'] = readline
1663
1663
1664 # Platform-specific configuration
1664 # Platform-specific configuration
1665 if os.name == 'nt':
1665 if os.name == 'nt':
1666 # FIXME - check with Frederick to see if we can harmonize
1666 # FIXME - check with Frederick to see if we can harmonize
@@ -1686,7 +1686,7 b' class InteractiveShell(SingletonConfigurable, Magic):'
1686 except:
1686 except:
1687 warn('Problems reading readline initialization file <%s>'
1687 warn('Problems reading readline initialization file <%s>'
1688 % inputrc_name)
1688 % inputrc_name)
1689
1689
1690 # Configure readline according to user's prefs
1690 # Configure readline according to user's prefs
1691 # This is only done if GNU readline is being used. If libedit
1691 # This is only done if GNU readline is being used. If libedit
1692 # is being used (as on Leopard) the readline config is
1692 # is being used (as on Leopard) the readline config is
@@ -1707,13 +1707,13 b' class InteractiveShell(SingletonConfigurable, Magic):'
1707 readline.set_completer_delims(delims)
1707 readline.set_completer_delims(delims)
1708 # otherwise we end up with a monster history after a while:
1708 # otherwise we end up with a monster history after a while:
1709 readline.set_history_length(self.history_length)
1709 readline.set_history_length(self.history_length)
1710
1710
1711 self.refill_readline_hist()
1711 self.refill_readline_hist()
1712 self.readline_no_record = ReadlineNoRecord(self)
1712 self.readline_no_record = ReadlineNoRecord(self)
1713
1713
1714 # Configure auto-indent for all platforms
1714 # Configure auto-indent for all platforms
1715 self.set_autoindent(self.autoindent)
1715 self.set_autoindent(self.autoindent)
1716
1716
1717 def refill_readline_hist(self):
1717 def refill_readline_hist(self):
1718 # Load the last 1000 lines from history
1718 # Load the last 1000 lines from history
1719 self.readline.clear_history()
1719 self.readline.clear_history()
@@ -1727,13 +1727,13 b' class InteractiveShell(SingletonConfigurable, Magic):'
1727
1727
1728 def set_next_input(self, s):
1728 def set_next_input(self, s):
1729 """ Sets the 'default' input string for the next command line.
1729 """ Sets the 'default' input string for the next command line.
1730
1730
1731 Requires readline.
1731 Requires readline.
1732
1732
1733 Example:
1733 Example:
1734
1734
1735 [D:\ipython]|1> _ip.set_next_input("Hello Word")
1735 [D:\ipython]|1> _ip.set_next_input("Hello Word")
1736 [D:\ipython]|2> Hello Word_ # cursor is here
1736 [D:\ipython]|2> Hello Word_ # cursor is here
1737 """
1737 """
1738 if isinstance(s, unicode):
1738 if isinstance(s, unicode):
1739 s = s.encode(self.stdin_encoding, 'replace')
1739 s = s.encode(self.stdin_encoding, 'replace')
@@ -1770,7 +1770,7 b' class InteractiveShell(SingletonConfigurable, Magic):'
1770 from IPython.core.completer import IPCompleter
1770 from IPython.core.completer import IPCompleter
1771 from IPython.core.completerlib import (module_completer,
1771 from IPython.core.completerlib import (module_completer,
1772 magic_run_completer, cd_completer)
1772 magic_run_completer, cd_completer)
1773
1773
1774 self.Completer = IPCompleter(shell=self,
1774 self.Completer = IPCompleter(shell=self,
1775 namespace=self.user_ns,
1775 namespace=self.user_ns,
1776 global_namespace=self.user_global_ns,
1776 global_namespace=self.user_global_ns,
@@ -1779,7 +1779,7 b' class InteractiveShell(SingletonConfigurable, Magic):'
1779 use_readline=self.has_readline,
1779 use_readline=self.has_readline,
1780 config=self.config,
1780 config=self.config,
1781 )
1781 )
1782
1782
1783 # Add custom completers to the basic ones built into IPCompleter
1783 # Add custom completers to the basic ones built into IPCompleter
1784 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
1784 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
1785 self.strdispatchers['complete_command'] = sdisp
1785 self.strdispatchers['complete_command'] = sdisp
@@ -1823,7 +1823,7 b' class InteractiveShell(SingletonConfigurable, Magic):'
1823
1823
1824 The optional arguments allow the completion to take more context into
1824 The optional arguments allow the completion to take more context into
1825 account, and are part of the low-level completion API.
1825 account, and are part of the low-level completion API.
1826
1826
1827 This is a wrapper around the completion mechanism, similar to what
1827 This is a wrapper around the completion mechanism, similar to what
1828 readline does at the command line when the TAB key is hit. By
1828 readline does at the command line when the TAB key is hit. By
1829 exposing it as a method, it can be used by other non-readline
1829 exposing it as a method, it can be used by other non-readline
@@ -1897,11 +1897,11 b' class InteractiveShell(SingletonConfigurable, Magic):'
1897 # We do this first so that magic functions can override it.
1897 # We do this first so that magic functions can override it.
1898 if next_input:
1898 if next_input:
1899 self.set_next_input(next_input)
1899 self.set_next_input(next_input)
1900
1900
1901 args = arg_s.split(' ',1)
1901 args = arg_s.split(' ',1)
1902 magic_name = args[0]
1902 magic_name = args[0]
1903 magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
1903 magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
1904
1904
1905 try:
1905 try:
1906 magic_args = args[1]
1906 magic_args = args[1]
1907 except IndexError:
1907 except IndexError:
@@ -1921,14 +1921,14 b' class InteractiveShell(SingletonConfigurable, Magic):'
1921 return result
1921 return result
1922
1922
1923 def define_magic(self, magicname, func):
1923 def define_magic(self, magicname, func):
1924 """Expose own function as magic function for ipython
1924 """Expose own function as magic function for ipython
1925
1925
1926 def foo_impl(self,parameter_s=''):
1926 def foo_impl(self,parameter_s=''):
1927 'My very own magic!. (Use docstrings, IPython reads them).'
1927 'My very own magic!. (Use docstrings, IPython reads them).'
1928 print 'Magic function. Passed parameter is between < >:'
1928 print 'Magic function. Passed parameter is between < >:'
1929 print '<%s>' % parameter_s
1929 print '<%s>' % parameter_s
1930 print 'The self object is:',self
1930 print 'The self object is:',self
1931
1931
1932 self.define_magic('foo',foo_impl)
1932 self.define_magic('foo',foo_impl)
1933 """
1933 """
1934 im = types.MethodType(func,self)
1934 im = types.MethodType(func,self)
@@ -1948,10 +1948,10 b' class InteractiveShell(SingletonConfigurable, Magic):'
1948 name : str
1948 name : str
1949 The name of the macro.
1949 The name of the macro.
1950 themacro : str or Macro
1950 themacro : str or Macro
1951 The action to do upon invoking the macro. If a string, a new
1951 The action to do upon invoking the macro. If a string, a new
1952 Macro object is created by passing the string to it.
1952 Macro object is created by passing the string to it.
1953 """
1953 """
1954
1954
1955 from IPython.core import macro
1955 from IPython.core import macro
1956
1956
1957 if isinstance(themacro, basestring):
1957 if isinstance(themacro, basestring):
@@ -1981,15 +1981,15 b' class InteractiveShell(SingletonConfigurable, Magic):'
1981 # os.system() or use ip.system=ip.system_raw
1981 # os.system() or use ip.system=ip.system_raw
1982 # if they really want a background process.
1982 # if they really want a background process.
1983 raise OSError("Background processes not supported.")
1983 raise OSError("Background processes not supported.")
1984
1984
1985 # we explicitly do NOT return the subprocess status code, because
1985 # we explicitly do NOT return the subprocess status code, because
1986 # a non-None value would trigger :func:`sys.displayhook` calls.
1986 # a non-None value would trigger :func:`sys.displayhook` calls.
1987 # Instead, we store the exit_code in user_ns.
1987 # Instead, we store the exit_code in user_ns.
1988 self.user_ns['_exit_code'] = system(self.var_expand(cmd, depth=2))
1988 self.user_ns['_exit_code'] = system(self.var_expand(cmd, depth=2))
1989
1989
1990 def system_raw(self, cmd):
1990 def system_raw(self, cmd):
1991 """Call the given cmd in a subprocess using os.system
1991 """Call the given cmd in a subprocess using os.system
1992
1992
1993 Parameters
1993 Parameters
1994 ----------
1994 ----------
1995 cmd : str
1995 cmd : str
@@ -1999,7 +1999,7 b' class InteractiveShell(SingletonConfigurable, Magic):'
1999 # a non-None value would trigger :func:`sys.displayhook` calls.
1999 # a non-None value would trigger :func:`sys.displayhook` calls.
2000 # Instead, we store the exit_code in user_ns.
2000 # Instead, we store the exit_code in user_ns.
2001 self.user_ns['_exit_code'] = os.system(self.var_expand(cmd, depth=2))
2001 self.user_ns['_exit_code'] = os.system(self.var_expand(cmd, depth=2))
2002
2002
2003 # use piped system by default, because it is better behaved
2003 # use piped system by default, because it is better behaved
2004 system = system_piped
2004 system = system_piped
2005
2005
@@ -2012,7 +2012,7 b' class InteractiveShell(SingletonConfigurable, Magic):'
2012 Command to execute (can not end in '&', as background processes are
2012 Command to execute (can not end in '&', as background processes are
2013 not supported.
2013 not supported.
2014 split : bool, optional
2014 split : bool, optional
2015
2015
2016 If True, split the output into an IPython SList. Otherwise, an
2016 If True, split the output into an IPython SList. Otherwise, an
2017 IPython LSString is returned. These are objects similar to normal
2017 IPython LSString is returned. These are objects similar to normal
2018 lists and strings, with a few convenience attributes for easier
2018 lists and strings, with a few convenience attributes for easier
@@ -2076,7 +2076,7 b' class InteractiveShell(SingletonConfigurable, Magic):'
2076 into::
2076 into::
2077
2077
2078 ------> f(x)
2078 ------> f(x)
2079
2079
2080 after the user's input prompt. This helps the user understand that the
2080 after the user's input prompt. This helps the user understand that the
2081 input line was transformed automatically by IPython.
2081 input line was transformed automatically by IPython.
2082 """
2082 """
@@ -2089,7 +2089,7 b' class InteractiveShell(SingletonConfigurable, Magic):'
2089 print >> io.stdout, rw
2089 print >> io.stdout, rw
2090 except UnicodeEncodeError:
2090 except UnicodeEncodeError:
2091 print "------> " + cmd
2091 print "------> " + cmd
2092
2092
2093 #-------------------------------------------------------------------------
2093 #-------------------------------------------------------------------------
2094 # Things related to extracting values/expressions from kernel and user_ns
2094 # Things related to extracting values/expressions from kernel and user_ns
2095 #-------------------------------------------------------------------------
2095 #-------------------------------------------------------------------------
@@ -2119,7 +2119,7 b' class InteractiveShell(SingletonConfigurable, Magic):'
2119 value = self._simple_error()
2119 value = self._simple_error()
2120 out[varname] = value
2120 out[varname] = value
2121 return out
2121 return out
2122
2122
2123 def user_expressions(self, expressions):
2123 def user_expressions(self, expressions):
2124 """Evaluate a dict of expressions in the user's namespace.
2124 """Evaluate a dict of expressions in the user's namespace.
2125
2125
@@ -2129,7 +2129,7 b' class InteractiveShell(SingletonConfigurable, Magic):'
2129 A dict with string keys and string values. The expression values
2129 A dict with string keys and string values. The expression values
2130 should be valid Python expressions, each of which will be evaluated
2130 should be valid Python expressions, each of which will be evaluated
2131 in the user namespace.
2131 in the user namespace.
2132
2132
2133 Returns
2133 Returns
2134 -------
2134 -------
2135 A dict, keyed like the input expressions dict, with the repr() of each
2135 A dict, keyed like the input expressions dict, with the repr() of each
@@ -2251,10 +2251,10 b' class InteractiveShell(SingletonConfigurable, Magic):'
2251 except:
2251 except:
2252 self.showtraceback()
2252 self.showtraceback()
2253 warn('Unknown failure executing file: <%s>' % fname)
2253 warn('Unknown failure executing file: <%s>' % fname)
2254
2254
2255 def run_cell(self, raw_cell, store_history=True):
2255 def run_cell(self, raw_cell, store_history=True):
2256 """Run a complete IPython cell.
2256 """Run a complete IPython cell.
2257
2257
2258 Parameters
2258 Parameters
2259 ----------
2259 ----------
2260 raw_cell : str
2260 raw_cell : str
@@ -2266,11 +2266,11 b' class InteractiveShell(SingletonConfigurable, Magic):'
2266 """
2266 """
2267 if (not raw_cell) or raw_cell.isspace():
2267 if (not raw_cell) or raw_cell.isspace():
2268 return
2268 return
2269
2269
2270 for line in raw_cell.splitlines():
2270 for line in raw_cell.splitlines():
2271 self.input_splitter.push(line)
2271 self.input_splitter.push(line)
2272 cell = self.input_splitter.source_reset()
2272 cell = self.input_splitter.source_reset()
2273
2273
2274 with self.builtin_trap:
2274 with self.builtin_trap:
2275 prefilter_failed = False
2275 prefilter_failed = False
2276 if len(cell.splitlines()) == 1:
2276 if len(cell.splitlines()) == 1:
@@ -2285,18 +2285,18 b' class InteractiveShell(SingletonConfigurable, Magic):'
2285 # don't allow prefilter errors to crash IPython
2285 # don't allow prefilter errors to crash IPython
2286 self.showtraceback()
2286 self.showtraceback()
2287 prefilter_failed = True
2287 prefilter_failed = True
2288
2288
2289 # Store raw and processed history
2289 # Store raw and processed history
2290 if store_history:
2290 if store_history:
2291 self.history_manager.store_inputs(self.execution_count,
2291 self.history_manager.store_inputs(self.execution_count,
2292 cell, raw_cell)
2292 cell, raw_cell)
2293
2293
2294 self.logger.log(cell, raw_cell)
2294 self.logger.log(cell, raw_cell)
2295
2295
2296 if not prefilter_failed:
2296 if not prefilter_failed:
2297 # don't run if prefilter failed
2297 # don't run if prefilter failed
2298 cell_name = self.compile.cache(cell, self.execution_count)
2298 cell_name = self.compile.cache(cell, self.execution_count)
2299
2299
2300 with self.display_trap:
2300 with self.display_trap:
2301 try:
2301 try:
2302 code_ast = self.compile.ast_parse(cell, filename=cell_name)
2302 code_ast = self.compile.ast_parse(cell, filename=cell_name)
@@ -2309,10 +2309,10 b' class InteractiveShell(SingletonConfigurable, Magic):'
2309 self.showsyntaxerror()
2309 self.showsyntaxerror()
2310 self.execution_count += 1
2310 self.execution_count += 1
2311 return None
2311 return None
2312
2312
2313 self.run_ast_nodes(code_ast.body, cell_name,
2313 self.run_ast_nodes(code_ast.body, cell_name,
2314 interactivity="last_expr")
2314 interactivity="last_expr")
2315
2315
2316 # Execute any registered post-execution functions.
2316 # Execute any registered post-execution functions.
2317 for func, status in self._post_execute.iteritems():
2317 for func, status in self._post_execute.iteritems():
2318 if not status:
2318 if not status:
@@ -2323,18 +2323,18 b' class InteractiveShell(SingletonConfigurable, Magic):'
2323 self.showtraceback()
2323 self.showtraceback()
2324 # Deactivate failing function
2324 # Deactivate failing function
2325 self._post_execute[func] = False
2325 self._post_execute[func] = False
2326
2326
2327 if store_history:
2327 if store_history:
2328 # Write output to the database. Does nothing unless
2328 # Write output to the database. Does nothing unless
2329 # history output logging is enabled.
2329 # history output logging is enabled.
2330 self.history_manager.store_output(self.execution_count)
2330 self.history_manager.store_output(self.execution_count)
2331 # Each cell is a *single* input, regardless of how many lines it has
2331 # Each cell is a *single* input, regardless of how many lines it has
2332 self.execution_count += 1
2332 self.execution_count += 1
2333
2333
2334 def run_ast_nodes(self, nodelist, cell_name, interactivity='last_expr'):
2334 def run_ast_nodes(self, nodelist, cell_name, interactivity='last_expr'):
2335 """Run a sequence of AST nodes. The execution mode depends on the
2335 """Run a sequence of AST nodes. The execution mode depends on the
2336 interactivity parameter.
2336 interactivity parameter.
2337
2337
2338 Parameters
2338 Parameters
2339 ----------
2339 ----------
2340 nodelist : list
2340 nodelist : list
@@ -2351,13 +2351,13 b' class InteractiveShell(SingletonConfigurable, Magic):'
2351 """
2351 """
2352 if not nodelist:
2352 if not nodelist:
2353 return
2353 return
2354
2354
2355 if interactivity == 'last_expr':
2355 if interactivity == 'last_expr':
2356 if isinstance(nodelist[-1], ast.Expr):
2356 if isinstance(nodelist[-1], ast.Expr):
2357 interactivity = "last"
2357 interactivity = "last"
2358 else:
2358 else:
2359 interactivity = "none"
2359 interactivity = "none"
2360
2360
2361 if interactivity == 'none':
2361 if interactivity == 'none':
2362 to_run_exec, to_run_interactive = nodelist, []
2362 to_run_exec, to_run_interactive = nodelist, []
2363 elif interactivity == 'last':
2363 elif interactivity == 'last':
@@ -2366,7 +2366,7 b' class InteractiveShell(SingletonConfigurable, Magic):'
2366 to_run_exec, to_run_interactive = [], nodelist
2366 to_run_exec, to_run_interactive = [], nodelist
2367 else:
2367 else:
2368 raise ValueError("Interactivity was %r" % interactivity)
2368 raise ValueError("Interactivity was %r" % interactivity)
2369
2369
2370 exec_count = self.execution_count
2370 exec_count = self.execution_count
2371
2371
2372 try:
2372 try:
@@ -2394,7 +2394,7 b' class InteractiveShell(SingletonConfigurable, Magic):'
2394 self.showtraceback()
2394 self.showtraceback()
2395
2395
2396 return False
2396 return False
2397
2397
2398 def run_code(self, code_obj):
2398 def run_code(self, code_obj):
2399 """Execute a code object.
2399 """Execute a code object.
2400
2400
@@ -2444,7 +2444,7 b' class InteractiveShell(SingletonConfigurable, Magic):'
2444 print
2444 print
2445
2445
2446 return outflag
2446 return outflag
2447
2447
2448 # For backwards compatibility
2448 # For backwards compatibility
2449 runcode = run_code
2449 runcode = run_code
2450
2450
@@ -2487,7 +2487,7 b' class InteractiveShell(SingletonConfigurable, Magic):'
2487
2487
2488 filename = tempfile.mktemp('.py', prefix)
2488 filename = tempfile.mktemp('.py', prefix)
2489 self.tempfiles.append(filename)
2489 self.tempfiles.append(filename)
2490
2490
2491 if data:
2491 if data:
2492 tmp_file = open(filename,'w')
2492 tmp_file = open(filename,'w')
2493 tmp_file.write(data)
2493 tmp_file.write(data)
@@ -2508,16 +2508,16 b' class InteractiveShell(SingletonConfigurable, Magic):'
2508 if self.quiet:
2508 if self.quiet:
2509 return True
2509 return True
2510 return ask_yes_no(prompt,default)
2510 return ask_yes_no(prompt,default)
2511
2511
2512 def show_usage(self):
2512 def show_usage(self):
2513 """Show a usage message"""
2513 """Show a usage message"""
2514 page.page(IPython.core.usage.interactive_usage)
2514 page.page(IPython.core.usage.interactive_usage)
2515
2515
2516 def find_user_code(self, target, raw=True):
2516 def find_user_code(self, target, raw=True):
2517 """Get a code string from history, file, or a string or macro.
2517 """Get a code string from history, file, or a string or macro.
2518
2518
2519 This is mainly used by magic functions.
2519 This is mainly used by magic functions.
2520
2520
2521 Parameters
2521 Parameters
2522 ----------
2522 ----------
2523 target : str
2523 target : str
@@ -2527,21 +2527,21 b' class InteractiveShell(SingletonConfigurable, Magic):'
2527 raw : bool
2527 raw : bool
2528 If true (default), retrieve raw history. Has no effect on the other
2528 If true (default), retrieve raw history. Has no effect on the other
2529 retrieval mechanisms.
2529 retrieval mechanisms.
2530
2530
2531 Returns
2531 Returns
2532 -------
2532 -------
2533 A string of code.
2533 A string of code.
2534
2534
2535 ValueError is raised if nothing is found, and TypeError if it evaluates
2535 ValueError is raised if nothing is found, and TypeError if it evaluates
2536 to an object of another type. In each case, .args[0] is a printable
2536 to an object of another type. In each case, .args[0] is a printable
2537 message.
2537 message.
2538 """
2538 """
2539 code = self.extract_input_lines(target, raw=raw) # Grab history
2539 code = self.extract_input_lines(target, raw=raw) # Grab history
2540 if code:
2540 if code:
2541 return code
2541 return code
2542 if os.path.isfile(target): # Read file
2542 if os.path.isfile(target): # Read file
2543 return open(target, "r").read()
2543 return open(target, "r").read()
2544
2544
2545 try: # User namespace
2545 try: # User namespace
2546 codeobj = eval(target, self.user_ns)
2546 codeobj = eval(target, self.user_ns)
2547 except Exception:
2547 except Exception:
@@ -2551,7 +2551,7 b' class InteractiveShell(SingletonConfigurable, Magic):'
2551 return codeobj
2551 return codeobj
2552 elif isinstance(codeobj, Macro):
2552 elif isinstance(codeobj, Macro):
2553 return codeobj.value
2553 return codeobj.value
2554
2554
2555 raise TypeError("%s is neither a string nor a macro." % target,
2555 raise TypeError("%s is neither a string nor a macro." % target,
2556 codeobj)
2556 codeobj)
2557
2557
@@ -2567,20 +2567,20 b' class InteractiveShell(SingletonConfigurable, Magic):'
2567 For things that may depend on startup flags or platform specifics (such
2567 For things that may depend on startup flags or platform specifics (such
2568 as having readline or not), register a separate atexit function in the
2568 as having readline or not), register a separate atexit function in the
2569 code that has the appropriate information, rather than trying to
2569 code that has the appropriate information, rather than trying to
2570 clutter
2570 clutter
2571 """
2571 """
2572 # Close the history session (this stores the end time and line count)
2572 # Close the history session (this stores the end time and line count)
2573 # this must be *before* the tempfile cleanup, in case of temporary
2573 # this must be *before* the tempfile cleanup, in case of temporary
2574 # history db
2574 # history db
2575 self.history_manager.end_session()
2575 self.history_manager.end_session()
2576
2576
2577 # Cleanup all tempfiles left around
2577 # Cleanup all tempfiles left around
2578 for tfile in self.tempfiles:
2578 for tfile in self.tempfiles:
2579 try:
2579 try:
2580 os.unlink(tfile)
2580 os.unlink(tfile)
2581 except OSError:
2581 except OSError:
2582 pass
2582 pass
2583
2583
2584 # Clear all user namespaces to release all references cleanly.
2584 # Clear all user namespaces to release all references cleanly.
2585 self.reset(new_session=False)
2585 self.reset(new_session=False)
2586
2586
@@ -58,7 +58,7 b' class Logger(object):'
58 return self._logmode
58 return self._logmode
59
59
60 logmode = property(_get_mode,_set_mode)
60 logmode = property(_get_mode,_set_mode)
61
61
62 def logstart(self,logfname=None,loghead=None,logmode=None,
62 def logstart(self,logfname=None,loghead=None,logmode=None,
63 log_output=False,timestamp=False,log_raw_input=False):
63 log_output=False,timestamp=False,log_raw_input=False):
64 """Generate a new log-file with a default header.
64 """Generate a new log-file with a default header.
@@ -68,7 +68,7 b' class Logger(object):'
68 if self.logfile is not None:
68 if self.logfile is not None:
69 raise RuntimeError('Log file is already active: %s' %
69 raise RuntimeError('Log file is already active: %s' %
70 self.logfname)
70 self.logfname)
71
71
72 # The parameters can override constructor defaults
72 # The parameters can override constructor defaults
73 if logfname is not None: self.logfname = logfname
73 if logfname is not None: self.logfname = logfname
74 if loghead is not None: self.loghead = loghead
74 if loghead is not None: self.loghead = loghead
@@ -78,7 +78,7 b' class Logger(object):'
78 self.timestamp = timestamp
78 self.timestamp = timestamp
79 self.log_output = log_output
79 self.log_output = log_output
80 self.log_raw_input = log_raw_input
80 self.log_raw_input = log_raw_input
81
81
82 # init depending on the log mode requested
82 # init depending on the log mode requested
83 isfile = os.path.isfile
83 isfile = os.path.isfile
84 logmode = self.logmode
84 logmode = self.logmode
@@ -102,12 +102,12 b' class Logger(object):'
102
102
103 elif logmode == 'over':
103 elif logmode == 'over':
104 if isfile(self.logfname):
104 if isfile(self.logfname):
105 os.remove(self.logfname)
105 os.remove(self.logfname)
106 self.logfile = open(self.logfname,'w')
106 self.logfile = open(self.logfname,'w')
107
107
108 elif logmode == 'rotate':
108 elif logmode == 'rotate':
109 if isfile(self.logfname):
109 if isfile(self.logfname):
110 if isfile(self.logfname+'.001~'):
110 if isfile(self.logfname+'.001~'):
111 old = glob.glob(self.logfname+'.*~')
111 old = glob.glob(self.logfname+'.*~')
112 old.sort()
112 old.sort()
113 old.reverse()
113 old.reverse()
@@ -117,7 +117,7 b' class Logger(object):'
117 os.rename(f, root+'.'+`num`.zfill(3)+'~')
117 os.rename(f, root+'.'+`num`.zfill(3)+'~')
118 os.rename(self.logfname, self.logfname+'.001~')
118 os.rename(self.logfname, self.logfname+'.001~')
119 self.logfile = open(self.logfname,'w')
119 self.logfile = open(self.logfname,'w')
120
120
121 if logmode != 'append':
121 if logmode != 'append':
122 self.logfile.write(self.loghead)
122 self.logfile.write(self.loghead)
123
123
@@ -130,7 +130,7 b' class Logger(object):'
130 if val not in [False,True,0,1]:
130 if val not in [False,True,0,1]:
131 raise ValueError, \
131 raise ValueError, \
132 'Call switch_log ONLY with a boolean argument, not with:',val
132 'Call switch_log ONLY with a boolean argument, not with:',val
133
133
134 label = {0:'OFF',1:'ON',False:'OFF',True:'ON'}
134 label = {0:'OFF',1:'ON',False:'OFF',True:'ON'}
135
135
136 if self.logfile is None:
136 if self.logfile is None:
@@ -140,7 +140,7 b" Logging hasn't been started yet (use logstart for that)."
140 %logon/%logoff are for temporarily starting and stopping logging for a logfile
140 %logon/%logoff are for temporarily starting and stopping logging for a logfile
141 which already exists. But you must first start the logging process with
141 which already exists. But you must first start the logging process with
142 %logstart (optionally giving a logfile name)."""
142 %logstart (optionally giving a logfile name)."""
143
143
144 else:
144 else:
145 if self.log_active == val:
145 if self.log_active == val:
146 print 'Logging is already',label[val]
146 print 'Logging is already',label[val]
@@ -205,7 +205,7 b' which already exists. But you must first start the logging process with'
205 In order to start logging again, a new logstart() call needs to be
205 In order to start logging again, a new logstart() call needs to be
206 made, possibly (though not necessarily) with a new filename, mode and
206 made, possibly (though not necessarily) with a new filename, mode and
207 other options."""
207 other options."""
208
208
209 if self.logfile is not None:
209 if self.logfile is not None:
210 self.logfile.close()
210 self.logfile.close()
211 self.logfile = None
211 self.logfile = None
@@ -84,13 +84,13 b' def compress_dhist(dh):'
84 newhead.append(h)
84 newhead.append(h)
85 done.add(h)
85 done.add(h)
86
86
87 return newhead + tail
87 return newhead + tail
88
88
89 def needs_local_scope(func):
89 def needs_local_scope(func):
90 """Decorator to mark magic functions which need to local scope to run."""
90 """Decorator to mark magic functions which need to local scope to run."""
91 func.needs_local_scope = True
91 func.needs_local_scope = True
92 return func
92 return func
93
93
94 # Used for exception handling in magic_edit
94 # Used for exception handling in magic_edit
95 class MacroToEdit(ValueError): pass
95 class MacroToEdit(ValueError): pass
96
96
@@ -101,7 +101,7 b' class MacroToEdit(ValueError): pass'
101 # on construction of the main InteractiveShell object. Something odd is going
101 # on construction of the main InteractiveShell object. Something odd is going
102 # on with super() calls, Configurable and the MRO... For now leave it as-is, but
102 # on with super() calls, Configurable and the MRO... For now leave it as-is, but
103 # eventually this needs to be clarified.
103 # eventually this needs to be clarified.
104 # BG: This is because InteractiveShell inherits from this, but is itself a
104 # BG: This is because InteractiveShell inherits from this, but is itself a
105 # Configurable. This messes up the MRO in some way. The fix is that we need to
105 # Configurable. This messes up the MRO in some way. The fix is that we need to
106 # make Magic a configurable that InteractiveShell does not subclass.
106 # make Magic a configurable that InteractiveShell does not subclass.
107
107
@@ -124,7 +124,7 b' class Magic:'
124 # some utility functions
124 # some utility functions
125
125
126 def __init__(self,shell):
126 def __init__(self,shell):
127
127
128 self.options_table = {}
128 self.options_table = {}
129 if profile is None:
129 if profile is None:
130 self.magic_prun = self.profile_missing_notice
130 self.magic_prun = self.profile_missing_notice
@@ -153,7 +153,7 b' python-profiler package from non-free.""")'
153 ['magic_ls','magic_cd',...]"""
153 ['magic_ls','magic_cd',...]"""
154
154
155 # FIXME. This needs a cleanup, in the way the magics list is built.
155 # FIXME. This needs a cleanup, in the way the magics list is built.
156
156
157 # magics in class definition
157 # magics in class definition
158 class_magic = lambda fn: fn.startswith('magic_') and \
158 class_magic = lambda fn: fn.startswith('magic_') and \
159 callable(Magic.__dict__[fn])
159 callable(Magic.__dict__[fn])
@@ -171,13 +171,13 b' python-profiler package from non-free.""")'
171 out.append(fn.replace('magic_','',1))
171 out.append(fn.replace('magic_','',1))
172 out.sort()
172 out.sort()
173 return out
173 return out
174
174
175 def extract_input_lines(self, range_str, raw=False):
175 def extract_input_lines(self, range_str, raw=False):
176 """Return as a string a set of input history slices.
176 """Return as a string a set of input history slices.
177
177
178 Inputs:
178 Inputs:
179
179
180 - range_str: the set of slices is given as a string, like
180 - range_str: the set of slices is given as a string, like
181 "~5/6-~4/2 4:8 9", since this function is for use by magic functions
181 "~5/6-~4/2 4:8 9", since this function is for use by magic functions
182 which get their arguments as strings. The number before the / is the
182 which get their arguments as strings. The number before the / is the
183 session number: ~n goes n back from the current session.
183 session number: ~n goes n back from the current session.
@@ -195,7 +195,7 b' python-profiler package from non-free.""")'
195 lines = self.shell.history_manager.\
195 lines = self.shell.history_manager.\
196 get_range_by_str(range_str, raw=raw)
196 get_range_by_str(range_str, raw=raw)
197 return "\n".join(x for _, _, x in lines)
197 return "\n".join(x for _, _, x in lines)
198
198
199 def arg_err(self,func):
199 def arg_err(self,func):
200 """Print docstring if incorrect arguments were passed"""
200 """Print docstring if incorrect arguments were passed"""
201 print 'Error in arguments:'
201 print 'Error in arguments:'
@@ -209,7 +209,7 b' python-profiler package from non-free.""")'
209 # Magic command names as headers:
209 # Magic command names as headers:
210 cmd_name_re = re.compile(r'^(%s.*?):' % ESC_MAGIC,
210 cmd_name_re = re.compile(r'^(%s.*?):' % ESC_MAGIC,
211 re.MULTILINE)
211 re.MULTILINE)
212 # Magic commands
212 # Magic commands
213 cmd_re = re.compile(r'(?P<cmd>%s.+?\b)(?!\}\}:)' % ESC_MAGIC,
213 cmd_re = re.compile(r'(?P<cmd>%s.+?\b)(?!\}\}:)' % ESC_MAGIC,
214 re.MULTILINE)
214 re.MULTILINE)
215 # Paragraph continue
215 # Paragraph continue
@@ -249,11 +249,11 b' python-profiler package from non-free.""")'
249 -posix (True): whether to split the input line in POSIX mode or not,
249 -posix (True): whether to split the input line in POSIX mode or not,
250 as per the conventions outlined in the shlex module from the
250 as per the conventions outlined in the shlex module from the
251 standard library."""
251 standard library."""
252
252
253 # inject default options at the beginning of the input line
253 # inject default options at the beginning of the input line
254 caller = sys._getframe(1).f_code.co_name.replace('magic_','')
254 caller = sys._getframe(1).f_code.co_name.replace('magic_','')
255 arg_str = '%s %s' % (self.options_table.get(caller,''),arg_str)
255 arg_str = '%s %s' % (self.options_table.get(caller,''),arg_str)
256
256
257 mode = kw.get('mode','string')
257 mode = kw.get('mode','string')
258 if mode not in ['string','list']:
258 if mode not in ['string','list']:
259 raise ValueError,'incorrect mode given: %s' % mode
259 raise ValueError,'incorrect mode given: %s' % mode
@@ -272,7 +272,7 b' python-profiler package from non-free.""")'
272 try:
272 try:
273 opts,args = getopt(argv,opt_str,*long_opts)
273 opts,args = getopt(argv,opt_str,*long_opts)
274 except GetoptError,e:
274 except GetoptError,e:
275 raise UsageError('%s ( allowed: "%s" %s)' % (e.msg,opt_str,
275 raise UsageError('%s ( allowed: "%s" %s)' % (e.msg,opt_str,
276 " ".join(long_opts)))
276 " ".join(long_opts)))
277 for o,a in opts:
277 for o,a in opts:
278 if o.startswith('--'):
278 if o.startswith('--'):
@@ -295,7 +295,7 b' python-profiler package from non-free.""")'
295 args = ' '.join(args)
295 args = ' '.join(args)
296
296
297 return opts,args
297 return opts,args
298
298
299 #......................................................................
299 #......................................................................
300 # And now the actual magic functions
300 # And now the actual magic functions
301
301
@@ -307,11 +307,11 b' python-profiler package from non-free.""")'
307 (' '+mesc).join(self.lsmagic())
307 (' '+mesc).join(self.lsmagic())
308 print '\n' + Magic.auto_status[self.shell.automagic]
308 print '\n' + Magic.auto_status[self.shell.automagic]
309 return None
309 return None
310
310
311 def magic_magic(self, parameter_s = ''):
311 def magic_magic(self, parameter_s = ''):
312 """Print information about the magic function system.
312 """Print information about the magic function system.
313
313
314 Supported formats: -latex, -brief, -rest
314 Supported formats: -latex, -brief, -rest
315 """
315 """
316
316
317 mode = ''
317 mode = ''
@@ -338,30 +338,30 b' python-profiler package from non-free.""")'
338 break
338 break
339 if mode == 'brief':
339 if mode == 'brief':
340 # only first line
340 # only first line
341 if fn.__doc__:
341 if fn.__doc__:
342 fndoc = fn.__doc__.split('\n',1)[0]
342 fndoc = fn.__doc__.split('\n',1)[0]
343 else:
343 else:
344 fndoc = 'No documentation'
344 fndoc = 'No documentation'
345 else:
345 else:
346 if fn.__doc__:
346 if fn.__doc__:
347 fndoc = fn.__doc__.rstrip()
347 fndoc = fn.__doc__.rstrip()
348 else:
348 else:
349 fndoc = 'No documentation'
349 fndoc = 'No documentation'
350
350
351
351
352 if mode == 'rest':
352 if mode == 'rest':
353 rest_docs.append('**%s%s**::\n\n\t%s\n\n' %(ESC_MAGIC,
353 rest_docs.append('**%s%s**::\n\n\t%s\n\n' %(ESC_MAGIC,
354 fname,fndoc))
354 fname,fndoc))
355
355
356 else:
356 else:
357 magic_docs.append('%s%s:\n\t%s\n' %(ESC_MAGIC,
357 magic_docs.append('%s%s:\n\t%s\n' %(ESC_MAGIC,
358 fname,fndoc))
358 fname,fndoc))
359
359
360 magic_docs = ''.join(magic_docs)
360 magic_docs = ''.join(magic_docs)
361
361
362 if mode == 'rest':
362 if mode == 'rest':
363 return "".join(rest_docs)
363 return "".join(rest_docs)
364
364
365 if mode == 'latex':
365 if mode == 'latex':
366 print self.format_latex(magic_docs)
366 print self.format_latex(magic_docs)
367 return
367 return
@@ -369,7 +369,7 b' python-profiler package from non-free.""")'
369 magic_docs = format_screen(magic_docs)
369 magic_docs = format_screen(magic_docs)
370 if mode == 'brief':
370 if mode == 'brief':
371 return magic_docs
371 return magic_docs
372
372
373 outmsg = """
373 outmsg = """
374 IPython's 'magic' functions
374 IPython's 'magic' functions
375 ===========================
375 ===========================
@@ -495,11 +495,11 b' Currently the magic system has the following functions:\\n"""'
495
495
496 def magic_page(self, parameter_s=''):
496 def magic_page(self, parameter_s=''):
497 """Pretty print the object and display it through a pager.
497 """Pretty print the object and display it through a pager.
498
498
499 %page [options] OBJECT
499 %page [options] OBJECT
500
500
501 If no object is given, use _ (last output).
501 If no object is given, use _ (last output).
502
502
503 Options:
503 Options:
504
504
505 -r: page str(object), don't pretty-print it."""
505 -r: page str(object), don't pretty-print it."""
@@ -524,12 +524,12 b' Currently the magic system has the following functions:\\n"""'
524
524
525 def magic_pinfo(self, parameter_s='', namespaces=None):
525 def magic_pinfo(self, parameter_s='', namespaces=None):
526 """Provide detailed information about an object.
526 """Provide detailed information about an object.
527
527
528 '%pinfo object' is just a synonym for object? or ?object."""
528 '%pinfo object' is just a synonym for object? or ?object."""
529
529
530 #print 'pinfo par: <%s>' % parameter_s # dbg
530 #print 'pinfo par: <%s>' % parameter_s # dbg
531
531
532
532
533 # detail_level: 0 -> obj? , 1 -> obj??
533 # detail_level: 0 -> obj? , 1 -> obj??
534 detail_level = 0
534 detail_level = 0
535 # We need to detect if we got called as 'pinfo pinfo foo', which can
535 # We need to detect if we got called as 'pinfo pinfo foo', which can
@@ -546,7 +546,7 b' Currently the magic system has the following functions:\\n"""'
546
546
547 def magic_pinfo2(self, parameter_s='', namespaces=None):
547 def magic_pinfo2(self, parameter_s='', namespaces=None):
548 """Provide extra detailed information about an object.
548 """Provide extra detailed information about an object.
549
549
550 '%pinfo2 object' is just a synonym for object?? or ??object."""
550 '%pinfo2 object' is just a synonym for object?? or ??object."""
551 self.shell._inspect('pinfo', parameter_s, detail_level=1,
551 self.shell._inspect('pinfo', parameter_s, detail_level=1,
552 namespaces=namespaces)
552 namespaces=namespaces)
@@ -556,11 +556,11 b' Currently the magic system has the following functions:\\n"""'
556 """Print the definition header for any callable object.
556 """Print the definition header for any callable object.
557
557
558 If the object is a class, print the constructor information.
558 If the object is a class, print the constructor information.
559
559
560 Examples
560 Examples
561 --------
561 --------
562 ::
562 ::
563
563
564 In [3]: %pdef urllib.urlopen
564 In [3]: %pdef urllib.urlopen
565 urllib.urlopen(url, data=None, proxies=None)
565 urllib.urlopen(url, data=None, proxies=None)
566 """
566 """
@@ -615,7 +615,7 b' Currently the magic system has the following functions:\\n"""'
615 ?-i a* function
615 ?-i a* function
616
616
617 Arguments:
617 Arguments:
618
618
619 PATTERN
619 PATTERN
620
620
621 where PATTERN is a string containing * as a wildcard similar to its
621 where PATTERN is a string containing * as a wildcard similar to its
@@ -642,8 +642,8 b' Currently the magic system has the following functions:\\n"""'
642
642
643 -i/-c: make the pattern case insensitive/sensitive. If neither of
643 -i/-c: make the pattern case insensitive/sensitive. If neither of
644 these options are given, the default is read from your configuration
644 these options are given, the default is read from your configuration
645 file, with the option ``InteractiveShell.wildcards_case_sensitive``.
645 file, with the option ``InteractiveShell.wildcards_case_sensitive``.
646 If this option is not specified in your configuration file, IPython's
646 If this option is not specified in your configuration file, IPython's
647 internal default is to do a case sensitive search.
647 internal default is to do a case sensitive search.
648
648
649 -e/-s NAMESPACE: exclude/search a given namespace. The pattern you
649 -e/-s NAMESPACE: exclude/search a given namespace. The pattern you
@@ -659,9 +659,9 b' Currently the magic system has the following functions:\\n"""'
659 and it contains module-level globals. You can add namespaces to the
659 and it contains module-level globals. You can add namespaces to the
660 search with -s or exclude them with -e (these options can be given
660 search with -s or exclude them with -e (these options can be given
661 more than once).
661 more than once).
662
662
663 Examples:
663 Examples:
664
664
665 %psearch a* -> objects beginning with an a
665 %psearch a* -> objects beginning with an a
666 %psearch -e builtin a* -> objects NOT in the builtin space starting in a
666 %psearch -e builtin a* -> objects NOT in the builtin space starting in a
667 %psearch a* function -> all functions beginning with an a
667 %psearch a* function -> all functions beginning with an a
@@ -670,11 +670,11 b' Currently the magic system has the following functions:\\n"""'
670 %psearch r*.* string -> all strings in modules beginning with r
670 %psearch r*.* string -> all strings in modules beginning with r
671
671
672 Case sensitve search:
672 Case sensitve search:
673
673
674 %psearch -c a* list all object beginning with lower case a
674 %psearch -c a* list all object beginning with lower case a
675
675
676 Show objects beginning with a single _:
676 Show objects beginning with a single _:
677
677
678 %psearch -a _* list objects beginning with a single underscore"""
678 %psearch -a _* list objects beginning with a single underscore"""
679 try:
679 try:
680 parameter_s.encode('ascii')
680 parameter_s.encode('ascii')
@@ -703,14 +703,14 b' Currently the magic system has the following functions:\\n"""'
703 def_search.extend(opt('s',[]))
703 def_search.extend(opt('s',[]))
704 ns_exclude = ns_exclude=opt('e',[])
704 ns_exclude = ns_exclude=opt('e',[])
705 ns_search = [nm for nm in def_search if nm not in ns_exclude]
705 ns_search = [nm for nm in def_search if nm not in ns_exclude]
706
706
707 # Call the actual search
707 # Call the actual search
708 try:
708 try:
709 psearch(args,shell.ns_table,ns_search,
709 psearch(args,shell.ns_table,ns_search,
710 show_all=opt('a'),ignore_case=ignore_case)
710 show_all=opt('a'),ignore_case=ignore_case)
711 except:
711 except:
712 shell.showtraceback()
712 shell.showtraceback()
713
713
714 @skip_doctest
714 @skip_doctest
715 def magic_who_ls(self, parameter_s=''):
715 def magic_who_ls(self, parameter_s=''):
716 """Return a sorted list of all interactive variables.
716 """Return a sorted list of all interactive variables.
@@ -751,7 +751,7 b' Currently the magic system has the following functions:\\n"""'
751
751
752 out.sort()
752 out.sort()
753 return out
753 return out
754
754
755 @skip_doctest
755 @skip_doctest
756 def magic_who(self, parameter_s=''):
756 def magic_who(self, parameter_s=''):
757 """Print all interactive variables, with some minimal formatting.
757 """Print all interactive variables, with some minimal formatting.
@@ -820,7 +820,7 b' Currently the magic system has the following functions:\\n"""'
820 The same type filtering of %who can be applied here.
820 The same type filtering of %who can be applied here.
821
821
822 For all variables, the type is printed. Additionally it prints:
822 For all variables, the type is printed. Additionally it prints:
823
823
824 - For {},[],(): their length.
824 - For {},[],(): their length.
825
825
826 - For numpy arrays, a summary with shape, number of
826 - For numpy arrays, a summary with shape, number of
@@ -844,7 +844,7 b' Currently the magic system has the following functions:\\n"""'
844 alpha int 123
844 alpha int 123
845 beta str test
845 beta str test
846 """
846 """
847
847
848 varnames = self.magic_who_ls(parameter_s)
848 varnames = self.magic_who_ls(parameter_s)
849 if not varnames:
849 if not varnames:
850 if parameter_s:
850 if parameter_s:
@@ -875,13 +875,13 b' Currently the magic system has the following functions:\\n"""'
875 # Find all variable names and types so we can figure out column sizes
875 # Find all variable names and types so we can figure out column sizes
876 def get_vars(i):
876 def get_vars(i):
877 return self.shell.user_ns[i]
877 return self.shell.user_ns[i]
878
878
879 # some types are well known and can be shorter
879 # some types are well known and can be shorter
880 abbrevs = {'IPython.core.macro.Macro' : 'Macro'}
880 abbrevs = {'IPython.core.macro.Macro' : 'Macro'}
881 def type_name(v):
881 def type_name(v):
882 tn = type(v).__name__
882 tn = type(v).__name__
883 return abbrevs.get(tn,tn)
883 return abbrevs.get(tn,tn)
884
884
885 varlist = map(get_vars,varnames)
885 varlist = map(get_vars,varnames)
886
886
887 typelist = []
887 typelist = []
@@ -927,7 +927,7 b' Currently the magic system has the following functions:\\n"""'
927 vsize = Numeric.size(var)
927 vsize = Numeric.size(var)
928 vbytes = vsize*var.itemsize()
928 vbytes = vsize*var.itemsize()
929 vdtype = var.typecode()
929 vdtype = var.typecode()
930
930
931 if vbytes < 100000:
931 if vbytes < 100000:
932 print aformat % (vshape,vsize,vdtype,vbytes)
932 print aformat % (vshape,vsize,vdtype,vbytes)
933 else:
933 else:
@@ -947,19 +947,19 b' Currently the magic system has the following functions:\\n"""'
947 print vstr
947 print vstr
948 else:
948 else:
949 print vstr[:25] + "<...>" + vstr[-25:]
949 print vstr[:25] + "<...>" + vstr[-25:]
950
950
951 def magic_reset(self, parameter_s=''):
951 def magic_reset(self, parameter_s=''):
952 """Resets the namespace by removing all names defined by the user.
952 """Resets the namespace by removing all names defined by the user.
953
953
954 Parameters
954 Parameters
955 ----------
955 ----------
956 -f : force reset without asking for confirmation.
956 -f : force reset without asking for confirmation.
957
957
958 -s : 'Soft' reset: Only clears your namespace, leaving history intact.
958 -s : 'Soft' reset: Only clears your namespace, leaving history intact.
959 References to objects may be kept. By default (without this option),
959 References to objects may be kept. By default (without this option),
960 we do a 'hard' reset, giving you a new session and removing all
960 we do a 'hard' reset, giving you a new session and removing all
961 references to objects from the current session.
961 references to objects from the current session.
962
962
963 Examples
963 Examples
964 --------
964 --------
965 In [6]: a = 1
965 In [6]: a = 1
@@ -984,16 +984,16 b' Currently the magic system has the following functions:\\n"""'
984 if not ans:
984 if not ans:
985 print 'Nothing done.'
985 print 'Nothing done.'
986 return
986 return
987
987
988 if 's' in opts: # Soft reset
988 if 's' in opts: # Soft reset
989 user_ns = self.shell.user_ns
989 user_ns = self.shell.user_ns
990 for i in self.magic_who_ls():
990 for i in self.magic_who_ls():
991 del(user_ns[i])
991 del(user_ns[i])
992
992
993 else: # Hard reset
993 else: # Hard reset
994 self.shell.reset(new_session = False)
994 self.shell.reset(new_session = False)
995
995
996
996
997
997
998 def magic_reset_selective(self, parameter_s=''):
998 def magic_reset_selective(self, parameter_s=''):
999 """Resets the namespace by removing names defined by the user.
999 """Resets the namespace by removing names defined by the user.
@@ -1003,7 +1003,7 b' Currently the magic system has the following functions:\\n"""'
1003 %reset_selective [-f] regex
1003 %reset_selective [-f] regex
1004
1004
1005 No action is taken if regex is not included
1005 No action is taken if regex is not included
1006
1006
1007 Options
1007 Options
1008 -f : force reset without asking for confirmation.
1008 -f : force reset without asking for confirmation.
1009
1009
@@ -1013,7 +1013,7 b' Currently the magic system has the following functions:\\n"""'
1013 We first fully reset the namespace so your output looks identical to
1013 We first fully reset the namespace so your output looks identical to
1014 this example for pedagogical reasons; in practice you do not need a
1014 this example for pedagogical reasons; in practice you do not need a
1015 full reset.
1015 full reset.
1016
1016
1017 In [1]: %reset -f
1017 In [1]: %reset -f
1018
1018
1019 Now, with a clean namespace we can make a few variables and use
1019 Now, with a clean namespace we can make a few variables and use
@@ -1044,9 +1044,9 b' Currently the magic system has the following functions:\\n"""'
1044 In [11]: who_ls
1044 In [11]: who_ls
1045 Out[11]: ['a']
1045 Out[11]: ['a']
1046 """
1046 """
1047
1047
1048 opts, regex = self.parse_options(parameter_s,'f')
1048 opts, regex = self.parse_options(parameter_s,'f')
1049
1049
1050 if opts.has_key('f'):
1050 if opts.has_key('f'):
1051 ans = True
1051 ans = True
1052 else:
1052 else:
@@ -1065,16 +1065,16 b' Currently the magic system has the following functions:\\n"""'
1065 except TypeError:
1065 except TypeError:
1066 raise TypeError('regex must be a string or compiled pattern')
1066 raise TypeError('regex must be a string or compiled pattern')
1067 for i in self.magic_who_ls():
1067 for i in self.magic_who_ls():
1068 if m.search(i):
1068 if m.search(i):
1069 del(user_ns[i])
1069 del(user_ns[i])
1070
1070
1071 def magic_xdel(self, parameter_s=''):
1071 def magic_xdel(self, parameter_s=''):
1072 """Delete a variable, trying to clear it from anywhere that
1072 """Delete a variable, trying to clear it from anywhere that
1073 IPython's machinery has references to it. By default, this uses
1073 IPython's machinery has references to it. By default, this uses
1074 the identity of the named object in the user namespace to remove
1074 the identity of the named object in the user namespace to remove
1075 references held under other names. The object is also removed
1075 references held under other names. The object is also removed
1076 from the output history.
1076 from the output history.
1077
1077
1078 Options
1078 Options
1079 -n : Delete the specified name from all namespaces, without
1079 -n : Delete the specified name from all namespaces, without
1080 checking their identity.
1080 checking their identity.
@@ -1084,7 +1084,7 b' Currently the magic system has the following functions:\\n"""'
1084 self.shell.del_var(varname, ('n' in opts))
1084 self.shell.del_var(varname, ('n' in opts))
1085 except (NameError, ValueError) as e:
1085 except (NameError, ValueError) as e:
1086 print type(e).__name__ +": "+ str(e)
1086 print type(e).__name__ +": "+ str(e)
1087
1087
1088 def magic_logstart(self,parameter_s=''):
1088 def magic_logstart(self,parameter_s=''):
1089 """Start logging anywhere in a session.
1089 """Start logging anywhere in a session.
1090
1090
@@ -1125,7 +1125,7 b' Currently the magic system has the following functions:\\n"""'
1125
1125
1126 -t: put timestamps before each input line logged (these are put in
1126 -t: put timestamps before each input line logged (these are put in
1127 comments)."""
1127 comments)."""
1128
1128
1129 opts,par = self.parse_options(parameter_s,'ort')
1129 opts,par = self.parse_options(parameter_s,'ort')
1130 log_output = 'o' in opts
1130 log_output = 'o' in opts
1131 log_raw_input = 'r' in opts
1131 log_raw_input = 'r' in opts
@@ -1172,7 +1172,7 b' Currently the magic system has the following functions:\\n"""'
1172 input_hist = self.shell.history_manager.input_hist_raw
1172 input_hist = self.shell.history_manager.input_hist_raw
1173 else:
1173 else:
1174 input_hist = self.shell.history_manager.input_hist_parsed
1174 input_hist = self.shell.history_manager.input_hist_parsed
1175
1175
1176 if log_output:
1176 if log_output:
1177 log_write = logger.log_write
1177 log_write = logger.log_write
1178 output_hist = self.shell.history_manager.output_hist
1178 output_hist = self.shell.history_manager.output_hist
@@ -1186,7 +1186,7 b' Currently the magic system has the following functions:\\n"""'
1186 if timestamp:
1186 if timestamp:
1187 # re-enable timestamping
1187 # re-enable timestamping
1188 logger.timestamp = True
1188 logger.timestamp = True
1189
1189
1190 print ('Activating auto-logging. '
1190 print ('Activating auto-logging. '
1191 'Current session state plus future input saved.')
1191 'Current session state plus future input saved.')
1192 logger.logstate()
1192 logger.logstate()
@@ -1204,7 +1204,7 b' Currently the magic system has the following functions:\\n"""'
1204
1204
1205 You must have previously started logging."""
1205 You must have previously started logging."""
1206 self.shell.logger.switch_log(0)
1206 self.shell.logger.switch_log(0)
1207
1207
1208 def magic_logon(self,parameter_s=''):
1208 def magic_logon(self,parameter_s=''):
1209 """Restart logging.
1209 """Restart logging.
1210
1210
@@ -1212,14 +1212,14 b' Currently the magic system has the following functions:\\n"""'
1212 stopped with %logoff. For starting logging for the first time, you
1212 stopped with %logoff. For starting logging for the first time, you
1213 must use the %logstart function, which allows you to specify an
1213 must use the %logstart function, which allows you to specify an
1214 optional log filename."""
1214 optional log filename."""
1215
1215
1216 self.shell.logger.switch_log(1)
1216 self.shell.logger.switch_log(1)
1217
1217
1218 def magic_logstate(self,parameter_s=''):
1218 def magic_logstate(self,parameter_s=''):
1219 """Print the status of the logging system."""
1219 """Print the status of the logging system."""
1220
1220
1221 self.shell.logger.logstate()
1221 self.shell.logger.logstate()
1222
1222
1223 def magic_pdb(self, parameter_s=''):
1223 def magic_pdb(self, parameter_s=''):
1224 """Control the automatic calling of the pdb interactive debugger.
1224 """Control the automatic calling of the pdb interactive debugger.
1225
1225
@@ -1314,7 +1314,7 b' Currently the magic system has the following functions:\\n"""'
1314 When more than one key is provided, additional keys are used as
1314 When more than one key is provided, additional keys are used as
1315 secondary criteria when the there is equality in all keys selected
1315 secondary criteria when the there is equality in all keys selected
1316 before them.
1316 before them.
1317
1317
1318 Abbreviations can be used for any key names, as long as the
1318 Abbreviations can be used for any key names, as long as the
1319 abbreviation is unambiguous. The following are the keys currently
1319 abbreviation is unambiguous. The following are the keys currently
1320 defined:
1320 defined:
@@ -1353,16 +1353,16 b' Currently the magic system has the following functions:\\n"""'
1353 If you want to run complete programs under the profiler's control, use
1353 If you want to run complete programs under the profiler's control, use
1354 '%run -p [prof_opts] filename.py [args to program]' where prof_opts
1354 '%run -p [prof_opts] filename.py [args to program]' where prof_opts
1355 contains profiler specific options as described here.
1355 contains profiler specific options as described here.
1356
1356
1357 You can read the complete documentation for the profile module with::
1357 You can read the complete documentation for the profile module with::
1358
1358
1359 In [1]: import profile; profile.help()
1359 In [1]: import profile; profile.help()
1360 """
1360 """
1361
1361
1362 opts_def = Struct(D=[''],l=[],s=['time'],T=[''])
1362 opts_def = Struct(D=[''],l=[],s=['time'],T=[''])
1363 # protect user quote marks
1363 # protect user quote marks
1364 parameter_s = parameter_s.replace('"',r'\"').replace("'",r"\'")
1364 parameter_s = parameter_s.replace('"',r'\"').replace("'",r"\'")
1365
1365
1366 if user_mode: # regular user call
1366 if user_mode: # regular user call
1367 opts,arg_str = self.parse_options(parameter_s,'D:l:rs:T:',
1367 opts,arg_str = self.parse_options(parameter_s,'D:l:rs:T:',
1368 list_all=1)
1368 list_all=1)
@@ -1382,7 +1382,7 b' Currently the magic system has the following functions:\\n"""'
1382 namespace = locals()
1382 namespace = locals()
1383
1383
1384 opts.merge(opts_def)
1384 opts.merge(opts_def)
1385
1385
1386 prof = profile.Profile()
1386 prof = profile.Profile()
1387 try:
1387 try:
1388 prof = prof.runctx(arg_str,namespace,namespace)
1388 prof = prof.runctx(arg_str,namespace,namespace)
@@ -1403,7 +1403,7 b' Currently the magic system has the following functions:\\n"""'
1403 lims.append(float(lim))
1403 lims.append(float(lim))
1404 except ValueError:
1404 except ValueError:
1405 lims.append(lim)
1405 lims.append(lim)
1406
1406
1407 # Trap output.
1407 # Trap output.
1408 stdout_trap = StringIO()
1408 stdout_trap = StringIO()
1409
1409
@@ -1420,7 +1420,7 b' Currently the magic system has the following functions:\\n"""'
1420 stats.print_stats(*lims)
1420 stats.print_stats(*lims)
1421 finally:
1421 finally:
1422 sys.stdout = sys_stdout
1422 sys.stdout = sys_stdout
1423
1423
1424 output = stdout_trap.getvalue()
1424 output = stdout_trap.getvalue()
1425 output = output.rstrip()
1425 output = output.rstrip()
1426
1426
@@ -1454,7 +1454,7 b' Currently the magic system has the following functions:\\n"""'
1454
1454
1455 Usage:\\
1455 Usage:\\
1456 %run [-n -i -t [-N<N>] -d [-b<N>] -p [profile options]] file [args]
1456 %run [-n -i -t [-N<N>] -d [-b<N>] -p [profile options]] file [args]
1457
1457
1458 Parameters after the filename are passed as command-line arguments to
1458 Parameters after the filename are passed as command-line arguments to
1459 the program (put in sys.argv). Then, control returns to IPython's
1459 the program (put in sys.argv). Then, control returns to IPython's
1460 prompt.
1460 prompt.
@@ -1475,7 +1475,7 b' Currently the magic system has the following functions:\\n"""'
1475 interactive work, while giving each program a 'clean sheet' to run in.
1475 interactive work, while giving each program a 'clean sheet' to run in.
1476
1476
1477 Options:
1477 Options:
1478
1478
1479 -n: __name__ is NOT set to '__main__', but to the running file's name
1479 -n: __name__ is NOT set to '__main__', but to the running file's name
1480 without extension (as python does under import). This allows running
1480 without extension (as python does under import). This allows running
1481 scripts and reloading the definitions in them without calling code
1481 scripts and reloading the definitions in them without calling code
@@ -1520,7 +1520,7 b' Currently the magic system has the following functions:\\n"""'
1520 -d: run your program under the control of pdb, the Python debugger.
1520 -d: run your program under the control of pdb, the Python debugger.
1521 This allows you to execute your program step by step, watch variables,
1521 This allows you to execute your program step by step, watch variables,
1522 etc. Internally, what IPython does is similar to calling:
1522 etc. Internally, what IPython does is similar to calling:
1523
1523
1524 pdb.run('execfile("YOURFILENAME")')
1524 pdb.run('execfile("YOURFILENAME")')
1525
1525
1526 with a breakpoint set on line 1 of your file. You can change the line
1526 with a breakpoint set on line 1 of your file. You can change the line
@@ -1580,10 +1580,10 b' Currently the magic system has the following functions:\\n"""'
1580 if filename.lower().endswith('.ipy'):
1580 if filename.lower().endswith('.ipy'):
1581 self.shell.safe_execfile_ipy(filename)
1581 self.shell.safe_execfile_ipy(filename)
1582 return
1582 return
1583
1583
1584 # Control the response to exit() calls made by the script being run
1584 # Control the response to exit() calls made by the script being run
1585 exit_ignore = opts.has_key('e')
1585 exit_ignore = opts.has_key('e')
1586
1586
1587 # Make sure that the running script gets a proper sys.argv as if it
1587 # Make sure that the running script gets a proper sys.argv as if it
1588 # were run from a system shell.
1588 # were run from a system shell.
1589 save_argv = sys.argv # save it for later restoring
1589 save_argv = sys.argv # save it for later restoring
@@ -1626,7 +1626,7 b' Currently the magic system has the following functions:\\n"""'
1626 # This needs to be undone at the end to prevent holding references to
1626 # This needs to be undone at the end to prevent holding references to
1627 # every single object ever created.
1627 # every single object ever created.
1628 sys.modules[main_mod_name] = main_mod
1628 sys.modules[main_mod_name] = main_mod
1629
1629
1630 try:
1630 try:
1631 stats = None
1631 stats = None
1632 with self.readline_no_record:
1632 with self.readline_no_record:
@@ -1663,7 +1663,7 b' Currently the magic system has the following functions:\\n"""'
1663 print "%s prompt to start your script." % deb.prompt
1663 print "%s prompt to start your script." % deb.prompt
1664 try:
1664 try:
1665 deb.run('execfile("%s")' % filename,prog_ns)
1665 deb.run('execfile("%s")' % filename,prog_ns)
1666
1666
1667 except:
1667 except:
1668 etype, value, tb = sys.exc_info()
1668 etype, value, tb = sys.exc_info()
1669 # Skip three frames in the traceback: the %run one,
1669 # Skip three frames in the traceback: the %run one,
@@ -1739,7 +1739,7 b' Currently the magic system has the following functions:\\n"""'
1739 # we can do is to at least restore __builtins__ for the user on
1739 # we can do is to at least restore __builtins__ for the user on
1740 # exit.
1740 # exit.
1741 self.shell.user_ns['__builtins__'] = builtin_mod
1741 self.shell.user_ns['__builtins__'] = builtin_mod
1742
1742
1743 # Ensure key global structures are restored
1743 # Ensure key global structures are restored
1744 sys.argv = save_argv
1744 sys.argv = save_argv
1745 if restore_main:
1745 if restore_main:
@@ -1749,7 +1749,7 b' Currently the magic system has the following functions:\\n"""'
1749 # added. Otherwise it will trap references to objects
1749 # added. Otherwise it will trap references to objects
1750 # contained therein.
1750 # contained therein.
1751 del sys.modules[main_mod_name]
1751 del sys.modules[main_mod_name]
1752
1752
1753 return stats
1753 return stats
1754
1754
1755 @skip_doctest
1755 @skip_doctest
@@ -1764,14 +1764,14 b' Currently the magic system has the following functions:\\n"""'
1764
1764
1765 Options:
1765 Options:
1766 -n<N>: execute the given statement <N> times in a loop. If this value
1766 -n<N>: execute the given statement <N> times in a loop. If this value
1767 is not given, a fitting value is chosen.
1767 is not given, a fitting value is chosen.
1768
1768
1769 -r<R>: repeat the loop iteration <R> times and take the best result.
1769 -r<R>: repeat the loop iteration <R> times and take the best result.
1770 Default: 3
1770 Default: 3
1771
1771
1772 -t: use time.time to measure the time, which is the default on Unix.
1772 -t: use time.time to measure the time, which is the default on Unix.
1773 This function measures wall time.
1773 This function measures wall time.
1774
1774
1775 -c: use time.clock to measure the time, which is the default on
1775 -c: use time.clock to measure the time, which is the default on
1776 Windows and measures wall time. On Unix, resource.getrusage is used
1776 Windows and measures wall time. On Unix, resource.getrusage is used
1777 instead and returns the CPU user time.
1777 instead and returns the CPU user time.
@@ -1779,7 +1779,7 b' Currently the magic system has the following functions:\\n"""'
1779 -p<P>: use a precision of <P> digits to display the timing result.
1779 -p<P>: use a precision of <P> digits to display the timing result.
1780 Default: 3
1780 Default: 3
1781
1781
1782
1782
1783 Examples:
1783 Examples:
1784
1784
1785 In [1]: %timeit pass
1785 In [1]: %timeit pass
@@ -1797,7 +1797,7 b' Currently the magic system has the following functions:\\n"""'
1797
1797
1798 In [6]: %timeit -n1 time.sleep(2)
1798 In [6]: %timeit -n1 time.sleep(2)
1799 1 loops, best of 3: 2 s per loop
1799 1 loops, best of 3: 2 s per loop
1800
1800
1801
1801
1802 The times reported by %timeit will be slightly higher than those
1802 The times reported by %timeit will be slightly higher than those
1803 reported by the timeit.py script when variables are accessed. This is
1803 reported by the timeit.py script when variables are accessed. This is
@@ -1828,10 +1828,10 b' Currently the magic system has the following functions:\\n"""'
1828 # succeeds
1828 # succeeds
1829 #
1829 #
1830 # See bug: https://bugs.launchpad.net/ipython/+bug/348466
1830 # See bug: https://bugs.launchpad.net/ipython/+bug/348466
1831
1831
1832 #units = [u"s", u"ms",u'\xb5',"ns"]
1832 #units = [u"s", u"ms",u'\xb5',"ns"]
1833 units = [u"s", u"ms",u'us',"ns"]
1833 units = [u"s", u"ms",u'us',"ns"]
1834
1834
1835 scaling = [1, 1e3, 1e6, 1e9]
1835 scaling = [1, 1e3, 1e6, 1e9]
1836
1836
1837 opts, stmt = self.parse_options(parameter_s,'n:r:tcp:',
1837 opts, stmt = self.parse_options(parameter_s,'n:r:tcp:',
@@ -1857,15 +1857,15 b' Currently the magic system has the following functions:\\n"""'
1857 # Track compilation time so it can be reported if too long
1857 # Track compilation time so it can be reported if too long
1858 # Minimum time above which compilation time will be reported
1858 # Minimum time above which compilation time will be reported
1859 tc_min = 0.1
1859 tc_min = 0.1
1860
1860
1861 t0 = clock()
1861 t0 = clock()
1862 code = compile(src, "<magic-timeit>", "exec")
1862 code = compile(src, "<magic-timeit>", "exec")
1863 tc = clock()-t0
1863 tc = clock()-t0
1864
1864
1865 ns = {}
1865 ns = {}
1866 exec code in self.shell.user_ns, ns
1866 exec code in self.shell.user_ns, ns
1867 timer.inner = ns["inner"]
1867 timer.inner = ns["inner"]
1868
1868
1869 if number == 0:
1869 if number == 0:
1870 # determine number so that 0.2 <= total time < 2.0
1870 # determine number so that 0.2 <= total time < 2.0
1871 number = 1
1871 number = 1
@@ -1873,7 +1873,7 b' Currently the magic system has the following functions:\\n"""'
1873 if timer.timeit(number) >= 0.2:
1873 if timer.timeit(number) >= 0.2:
1874 break
1874 break
1875 number *= 10
1875 number *= 10
1876
1876
1877 best = min(timer.repeat(repeat, number)) / number
1877 best = min(timer.repeat(repeat, number)) / number
1878
1878
1879 if best > 0.0 and best < 1000.0:
1879 if best > 0.0 and best < 1000.0:
@@ -1901,7 +1901,7 b' Currently the magic system has the following functions:\\n"""'
1901 This function provides very basic timing functionality. In Python
1901 This function provides very basic timing functionality. In Python
1902 2.3, the timeit module offers more control and sophistication, so this
1902 2.3, the timeit module offers more control and sophistication, so this
1903 could be rewritten to use it (patches welcome).
1903 could be rewritten to use it (patches welcome).
1904
1904
1905 Some examples:
1905 Some examples:
1906
1906
1907 In [1]: time 2**128
1907 In [1]: time 2**128
@@ -1936,14 +1936,14 b' Currently the magic system has the following functions:\\n"""'
1936 Wall time: 0.00 s
1936 Wall time: 0.00 s
1937 Compiler : 0.78 s
1937 Compiler : 0.78 s
1938 """
1938 """
1939
1939
1940 # fail immediately if the given expression can't be compiled
1940 # fail immediately if the given expression can't be compiled
1941
1941
1942 expr = self.shell.prefilter(parameter_s,False)
1942 expr = self.shell.prefilter(parameter_s,False)
1943
1943
1944 # Minimum time above which compilation time will be reported
1944 # Minimum time above which compilation time will be reported
1945 tc_min = 0.1
1945 tc_min = 0.1
1946
1946
1947 try:
1947 try:
1948 mode = 'eval'
1948 mode = 'eval'
1949 t0 = clock()
1949 t0 = clock()
@@ -1992,7 +1992,7 b' Currently the magic system has the following functions:\\n"""'
1992 %macro [options] name n1-n2 n3-n4 ... n5 .. n6 ...
1992 %macro [options] name n1-n2 n3-n4 ... n5 .. n6 ...
1993
1993
1994 Options:
1994 Options:
1995
1995
1996 -r: use 'raw' input. By default, the 'processed' history is used,
1996 -r: use 'raw' input. By default, the 'processed' history is used,
1997 so that magics are loaded in their transformed version to valid
1997 so that magics are loaded in their transformed version to valid
1998 Python. If this option is given, the raw input as typed as the
1998 Python. If this option is given, the raw input as typed as the
@@ -2011,7 +2011,7 b' Currently the magic system has the following functions:\\n"""'
2011 notation, where N:M means numbers N through M-1.
2011 notation, where N:M means numbers N through M-1.
2012
2012
2013 For example, if your history contains (%hist prints it):
2013 For example, if your history contains (%hist prints it):
2014
2014
2015 44: x=1
2015 44: x=1
2016 45: y=3
2016 45: y=3
2017 46: z=x+y
2017 46: z=x+y
@@ -2036,9 +2036,9 b' Currently the magic system has the following functions:\\n"""'
2036 code instead of printing them when you type their name.
2036 code instead of printing them when you type their name.
2037
2037
2038 You can view a macro's contents by explicitly printing it with:
2038 You can view a macro's contents by explicitly printing it with:
2039
2039
2040 'print macro_name'.
2040 'print macro_name'.
2041
2041
2042 """
2042 """
2043 opts,args = self.parse_options(parameter_s,'r',mode='list')
2043 opts,args = self.parse_options(parameter_s,'r',mode='list')
2044 if not args: # List existing macros
2044 if not args: # List existing macros
@@ -2048,7 +2048,7 b' Currently the magic system has the following functions:\\n"""'
2048 raise UsageError(
2048 raise UsageError(
2049 "%macro insufficient args; usage '%macro name n1-n2 n3-4...")
2049 "%macro insufficient args; usage '%macro name n1-n2 n3-4...")
2050 name, codefrom = args[0], " ".join(args[1:])
2050 name, codefrom = args[0], " ".join(args[1:])
2051
2051
2052 #print 'rng',ranges # dbg
2052 #print 'rng',ranges # dbg
2053 try:
2053 try:
2054 lines = self.shell.find_user_code(codefrom, 'r' in opts)
2054 lines = self.shell.find_user_code(codefrom, 'r' in opts)
@@ -2068,13 +2068,13 b' Currently the magic system has the following functions:\\n"""'
2068 %save [options] filename n1-n2 n3-n4 ... n5 .. n6 ...
2068 %save [options] filename n1-n2 n3-n4 ... n5 .. n6 ...
2069
2069
2070 Options:
2070 Options:
2071
2071
2072 -r: use 'raw' input. By default, the 'processed' history is used,
2072 -r: use 'raw' input. By default, the 'processed' history is used,
2073 so that magics are loaded in their transformed version to valid
2073 so that magics are loaded in their transformed version to valid
2074 Python. If this option is given, the raw input as typed as the
2074 Python. If this option is given, the raw input as typed as the
2075 command line is used instead.
2075 command line is used instead.
2076
2076
2077 This function uses the same syntax as %history for input ranges,
2077 This function uses the same syntax as %history for input ranges,
2078 then saves the lines to the filename you specify.
2078 then saves the lines to the filename you specify.
2079
2079
2080 It adds a '.py' extension to the file if you don't do so yourself, and
2080 It adds a '.py' extension to the file if you don't do so yourself, and
@@ -2099,7 +2099,7 b' Currently the magic system has the following functions:\\n"""'
2099 f.write(py3compat.cast_unicode(cmds))
2099 f.write(py3compat.cast_unicode(cmds))
2100 print 'The following commands were written to file `%s`:' % fname
2100 print 'The following commands were written to file `%s`:' % fname
2101 print cmds
2101 print cmds
2102
2102
2103 def magic_pastebin(self, parameter_s = ''):
2103 def magic_pastebin(self, parameter_s = ''):
2104 """Upload code to the 'Lodge it' paste bin, returning the URL."""
2104 """Upload code to the 'Lodge it' paste bin, returning the URL."""
2105 try:
2105 try:
@@ -2110,7 +2110,7 b' Currently the magic system has the following functions:\\n"""'
2110 pbserver = ServerProxy('http://paste.pocoo.org/xmlrpc/')
2110 pbserver = ServerProxy('http://paste.pocoo.org/xmlrpc/')
2111 id = pbserver.pastes.newPaste("python", code)
2111 id = pbserver.pastes.newPaste("python", code)
2112 return "http://paste.pocoo.org/show/" + id
2112 return "http://paste.pocoo.org/show/" + id
2113
2113
2114 def magic_loadpy(self, arg_s):
2114 def magic_loadpy(self, arg_s):
2115 """Load a .py python script into the GUI console.
2115 """Load a .py python script into the GUI console.
2116
2116
@@ -2130,10 +2130,10 b' Currently the magic system has the following functions:\\n"""'
2130 with open(arg_s) as f:
2130 with open(arg_s) as f:
2131 content = f.read()
2131 content = f.read()
2132 self.set_next_input(content)
2132 self.set_next_input(content)
2133
2133
2134 def _find_edit_target(self, args, opts, last_call):
2134 def _find_edit_target(self, args, opts, last_call):
2135 """Utility method used by magic_edit to find what to edit."""
2135 """Utility method used by magic_edit to find what to edit."""
2136
2136
2137 def make_filename(arg):
2137 def make_filename(arg):
2138 "Make a filename from the given args"
2138 "Make a filename from the given args"
2139 arg = unquote_filename(arg)
2139 arg = unquote_filename(arg)
@@ -2141,20 +2141,20 b' Currently the magic system has the following functions:\\n"""'
2141 filename = get_py_filename(arg)
2141 filename = get_py_filename(arg)
2142 except IOError:
2142 except IOError:
2143 # If it ends with .py but doesn't already exist, assume we want
2143 # If it ends with .py but doesn't already exist, assume we want
2144 # a new file.
2144 # a new file.
2145 if arg.endswith('.py'):
2145 if arg.endswith('.py'):
2146 filename = arg
2146 filename = arg
2147 else:
2147 else:
2148 filename = None
2148 filename = None
2149 return filename
2149 return filename
2150
2150
2151 # Set a few locals from the options for convenience:
2151 # Set a few locals from the options for convenience:
2152 opts_prev = 'p' in opts
2152 opts_prev = 'p' in opts
2153 opts_raw = 'r' in opts
2153 opts_raw = 'r' in opts
2154
2154
2155 # custom exceptions
2155 # custom exceptions
2156 class DataIsObject(Exception): pass
2156 class DataIsObject(Exception): pass
2157
2157
2158 # Default line number value
2158 # Default line number value
2159 lineno = opts.get('n',None)
2159 lineno = opts.get('n',None)
2160
2160
@@ -2162,7 +2162,7 b' Currently the magic system has the following functions:\\n"""'
2162 args = '_%s' % last_call[0]
2162 args = '_%s' % last_call[0]
2163 if not self.shell.user_ns.has_key(args):
2163 if not self.shell.user_ns.has_key(args):
2164 args = last_call[1]
2164 args = last_call[1]
2165
2165
2166 # use last_call to remember the state of the previous call, but don't
2166 # use last_call to remember the state of the previous call, but don't
2167 # let it be clobbered by successive '-p' calls.
2167 # let it be clobbered by successive '-p' calls.
2168 try:
2168 try:
@@ -2177,7 +2177,7 b' Currently the magic system has the following functions:\\n"""'
2177 use_temp = True
2177 use_temp = True
2178
2178
2179 data = ''
2179 data = ''
2180
2180
2181 # First, see if the arguments should be a filename.
2181 # First, see if the arguments should be a filename.
2182 filename = make_filename(args)
2182 filename = make_filename(args)
2183 if filename:
2183 if filename:
@@ -2203,16 +2203,16 b' Currently the magic system has the following functions:\\n"""'
2203 "or as a filename." % args)
2203 "or as a filename." % args)
2204 return
2204 return
2205 use_temp = False
2205 use_temp = False
2206
2206
2207 except DataIsObject:
2207 except DataIsObject:
2208 # macros have a special edit function
2208 # macros have a special edit function
2209 if isinstance(data, Macro):
2209 if isinstance(data, Macro):
2210 raise MacroToEdit(data)
2210 raise MacroToEdit(data)
2211
2211
2212 # For objects, try to edit the file where they are defined
2212 # For objects, try to edit the file where they are defined
2213 try:
2213 try:
2214 filename = inspect.getabsfile(data)
2214 filename = inspect.getabsfile(data)
2215 if 'fakemodule' in filename.lower() and inspect.isclass(data):
2215 if 'fakemodule' in filename.lower() and inspect.isclass(data):
2216 # class created by %edit? Try to find source
2216 # class created by %edit? Try to find source
2217 # by looking for method definitions instead, the
2217 # by looking for method definitions instead, the
2218 # __module__ in those classes is FakeModule.
2218 # __module__ in those classes is FakeModule.
@@ -2223,9 +2223,9 b' Currently the magic system has the following functions:\\n"""'
2223 filename = inspect.getabsfile(attr)
2223 filename = inspect.getabsfile(attr)
2224 if filename and 'fakemodule' not in filename.lower():
2224 if filename and 'fakemodule' not in filename.lower():
2225 # change the attribute to be the edit target instead
2225 # change the attribute to be the edit target instead
2226 data = attr
2226 data = attr
2227 break
2227 break
2228
2228
2229 datafile = 1
2229 datafile = 1
2230 except TypeError:
2230 except TypeError:
2231 filename = make_filename(args)
2231 filename = make_filename(args)
@@ -2249,7 +2249,7 b' Currently the magic system has the following functions:\\n"""'
2249 if use_temp:
2249 if use_temp:
2250 filename = self.shell.mktempfile(data)
2250 filename = self.shell.mktempfile(data)
2251 print 'IPython will make a temporary file named:',filename
2251 print 'IPython will make a temporary file named:',filename
2252
2252
2253 return filename, lineno, use_temp
2253 return filename, lineno, use_temp
2254
2254
2255 def _edit_macro(self,mname,macro):
2255 def _edit_macro(self,mname,macro):
@@ -2266,7 +2266,7 b' Currently the magic system has the following functions:\\n"""'
2266 def magic_ed(self,parameter_s=''):
2266 def magic_ed(self,parameter_s=''):
2267 """Alias to %edit."""
2267 """Alias to %edit."""
2268 return self.magic_edit(parameter_s)
2268 return self.magic_edit(parameter_s)
2269
2269
2270 @skip_doctest
2270 @skip_doctest
2271 def magic_edit(self,parameter_s='',last_call=['','']):
2271 def magic_edit(self,parameter_s='',last_call=['','']):
2272 """Bring up an editor and execute the resulting code.
2272 """Bring up an editor and execute the resulting code.
@@ -2280,15 +2280,15 b' Currently the magic system has the following functions:\\n"""'
2280 notepad under Windows. See the end of this docstring for how to change
2280 notepad under Windows. See the end of this docstring for how to change
2281 the editor hook.
2281 the editor hook.
2282
2282
2283 You can also set the value of this editor via the
2283 You can also set the value of this editor via the
2284 ``TerminalInteractiveShell.editor`` option in your configuration file.
2284 ``TerminalInteractiveShell.editor`` option in your configuration file.
2285 This is useful if you wish to use a different editor from your typical
2285 This is useful if you wish to use a different editor from your typical
2286 default with IPython (and for Windows users who typically don't set
2286 default with IPython (and for Windows users who typically don't set
2287 environment variables).
2287 environment variables).
2288
2288
2289 This command allows you to conveniently edit multi-line code right in
2289 This command allows you to conveniently edit multi-line code right in
2290 your IPython session.
2290 your IPython session.
2291
2291
2292 If called without arguments, %edit opens up an empty editor with a
2292 If called without arguments, %edit opens up an empty editor with a
2293 temporary file and will execute the contents of this file when you
2293 temporary file and will execute the contents of this file when you
2294 close it (don't forget to save it!).
2294 close it (don't forget to save it!).
@@ -2301,7 +2301,7 b' Currently the magic system has the following functions:\\n"""'
2301 you can configure this by providing your own modified hook if your
2301 you can configure this by providing your own modified hook if your
2302 favorite editor supports line-number specifications with a different
2302 favorite editor supports line-number specifications with a different
2303 syntax.
2303 syntax.
2304
2304
2305 -p: this will call the editor with the same data as the previous time
2305 -p: this will call the editor with the same data as the previous time
2306 it was used, regardless of how long ago (in your current session) it
2306 it was used, regardless of how long ago (in your current session) it
2307 was.
2307 was.
@@ -2312,7 +2312,7 b' Currently the magic system has the following functions:\\n"""'
2312 this option is given, the raw input as typed as the command line is
2312 this option is given, the raw input as typed as the command line is
2313 used instead. When you exit the editor, it will be executed by
2313 used instead. When you exit the editor, it will be executed by
2314 IPython's own processor.
2314 IPython's own processor.
2315
2315
2316 -x: do not execute the edited code immediately upon exit. This is
2316 -x: do not execute the edited code immediately upon exit. This is
2317 mainly useful if you are editing programs which need to be called with
2317 mainly useful if you are editing programs which need to be called with
2318 command line arguments, which you can then do using %run.
2318 command line arguments, which you can then do using %run.
@@ -2321,7 +2321,7 b' Currently the magic system has the following functions:\\n"""'
2321 Arguments:
2321 Arguments:
2322
2322
2323 If arguments are given, the following possibilites exist:
2323 If arguments are given, the following possibilites exist:
2324
2324
2325 - If the argument is a filename, IPython will load that into the
2325 - If the argument is a filename, IPython will load that into the
2326 editor. It will execute its contents with execfile() when you exit,
2326 editor. It will execute its contents with execfile() when you exit,
2327 loading any code in the file into your interactive namespace.
2327 loading any code in the file into your interactive namespace.
@@ -2364,18 +2364,18 b' Currently the magic system has the following functions:\\n"""'
2364 Out[1]: 'def foo():n print "foo() was defined in an editing session"n'
2364 Out[1]: 'def foo():n print "foo() was defined in an editing session"n'
2365
2365
2366 We can then call the function foo():
2366 We can then call the function foo():
2367
2367
2368 In [2]: foo()
2368 In [2]: foo()
2369 foo() was defined in an editing session
2369 foo() was defined in an editing session
2370
2370
2371 Now we edit foo. IPython automatically loads the editor with the
2371 Now we edit foo. IPython automatically loads the editor with the
2372 (temporary) file where foo() was previously defined:
2372 (temporary) file where foo() was previously defined:
2373
2373
2374 In [3]: ed foo
2374 In [3]: ed foo
2375 Editing... done. Executing edited code...
2375 Editing... done. Executing edited code...
2376
2376
2377 And if we call foo() again we get the modified version:
2377 And if we call foo() again we get the modified version:
2378
2378
2379 In [4]: foo()
2379 In [4]: foo()
2380 foo() has now been changed!
2380 foo() has now been changed!
2381
2381
@@ -2411,7 +2411,7 b' Currently the magic system has the following functions:\\n"""'
2411 general instructions on how to set a new hook for use once you've
2411 general instructions on how to set a new hook for use once you've
2412 defined it."""
2412 defined it."""
2413 opts,args = self.parse_options(parameter_s,'prxn:')
2413 opts,args = self.parse_options(parameter_s,'prxn:')
2414
2414
2415 try:
2415 try:
2416 filename, lineno, is_temp = self._find_edit_target(args, opts, last_call)
2416 filename, lineno, is_temp = self._find_edit_target(args, opts, last_call)
2417 except MacroToEdit as e:
2417 except MacroToEdit as e:
@@ -2429,12 +2429,12 b' Currently the magic system has the following functions:\\n"""'
2429 except TryNext:
2429 except TryNext:
2430 warn('Could not open editor')
2430 warn('Could not open editor')
2431 return
2431 return
2432
2432
2433 # XXX TODO: should this be generalized for all string vars?
2433 # XXX TODO: should this be generalized for all string vars?
2434 # For now, this is special-cased to blocks created by cpaste
2434 # For now, this is special-cased to blocks created by cpaste
2435 if args.strip() == 'pasted_block':
2435 if args.strip() == 'pasted_block':
2436 self.shell.user_ns['pasted_block'] = file_read(filename)
2436 self.shell.user_ns['pasted_block'] = file_read(filename)
2437
2437
2438 if 'x' in opts: # -x prevents actual execution
2438 if 'x' in opts: # -x prevents actual execution
2439 print
2439 print
2440 else:
2440 else:
@@ -2445,7 +2445,7 b' Currently the magic system has the following functions:\\n"""'
2445 else:
2445 else:
2446 self.shell.safe_execfile(filename,self.shell.user_ns,
2446 self.shell.safe_execfile(filename,self.shell.user_ns,
2447 self.shell.user_ns)
2447 self.shell.user_ns)
2448
2448
2449 if is_temp:
2449 if is_temp:
2450 try:
2450 try:
2451 return open(filename).read()
2451 return open(filename).read()
@@ -2481,19 +2481,19 b' Currently the magic system has the following functions:\\n"""'
2481 Currently implemented schemes: NoColor, Linux, LightBG.
2481 Currently implemented schemes: NoColor, Linux, LightBG.
2482
2482
2483 Color scheme names are not case-sensitive.
2483 Color scheme names are not case-sensitive.
2484
2484
2485 Examples
2485 Examples
2486 --------
2486 --------
2487 To get a plain black and white terminal::
2487 To get a plain black and white terminal::
2488
2488
2489 %colors nocolor
2489 %colors nocolor
2490 """
2490 """
2491
2491
2492 def color_switch_err(name):
2492 def color_switch_err(name):
2493 warn('Error changing %s color schemes.\n%s' %
2493 warn('Error changing %s color schemes.\n%s' %
2494 (name,sys.exc_info()[1]))
2494 (name,sys.exc_info()[1]))
2495
2495
2496
2496
2497 new_scheme = parameter_s.strip()
2497 new_scheme = parameter_s.strip()
2498 if not new_scheme:
2498 if not new_scheme:
2499 raise UsageError(
2499 raise UsageError(
@@ -2517,11 +2517,11 b' http://starship.python.net/crew/theller/ctypes'
2517 Defaulting color scheme to 'NoColor'"""
2517 Defaulting color scheme to 'NoColor'"""
2518 new_scheme = 'NoColor'
2518 new_scheme = 'NoColor'
2519 warn(msg)
2519 warn(msg)
2520
2520
2521 # readline option is 0
2521 # readline option is 0
2522 if not shell.colors_force and not shell.has_readline:
2522 if not shell.colors_force and not shell.has_readline:
2523 new_scheme = 'NoColor'
2523 new_scheme = 'NoColor'
2524
2524
2525 # Set prompt colors
2525 # Set prompt colors
2526 try:
2526 try:
2527 shell.displayhook.set_colors(new_scheme)
2527 shell.displayhook.set_colors(new_scheme)
@@ -2545,7 +2545,7 b' Defaulting color scheme to \'NoColor\'"""'
2545 color_switch_err('object inspector')
2545 color_switch_err('object inspector')
2546 else:
2546 else:
2547 shell.inspector.set_active_scheme('NoColor')
2547 shell.inspector.set_active_scheme('NoColor')
2548
2548
2549 def magic_pprint(self, parameter_s=''):
2549 def magic_pprint(self, parameter_s=''):
2550 """Toggle pretty printing on/off."""
2550 """Toggle pretty printing on/off."""
2551 ptformatter = self.shell.display_formatter.formatters['text/plain']
2551 ptformatter = self.shell.display_formatter.formatters['text/plain']
@@ -2578,7 +2578,7 b' Defaulting color scheme to \'NoColor\'"""'
2578
2578
2579 You can also define aliases with parameters using %s specifiers (one
2579 You can also define aliases with parameters using %s specifiers (one
2580 per parameter):
2580 per parameter):
2581
2581
2582 In [1]: alias parts echo first %s second %s
2582 In [1]: alias parts echo first %s second %s
2583 In [2]: %parts A B
2583 In [2]: %parts A B
2584 first A second B
2584 first A second B
@@ -2589,7 +2589,7 b' Defaulting color scheme to \'NoColor\'"""'
2589 Note that %l and %s are mutually exclusive. You can only use one or
2589 Note that %l and %s are mutually exclusive. You can only use one or
2590 the other in your aliases.
2590 the other in your aliases.
2591
2591
2592 Aliases expand Python variables just like system calls using ! or !!
2592 Aliases expand Python variables just like system calls using ! or !!
2593 do: all expressions prefixed with '$' get expanded. For details of
2593 do: all expressions prefixed with '$' get expanded. For details of
2594 the semantic rules, see PEP-215:
2594 the semantic rules, see PEP-215:
2595 http://www.python.org/peps/pep-0215.html. This is the library used by
2595 http://www.python.org/peps/pep-0215.html. This is the library used by
@@ -2619,7 +2619,7 b' Defaulting color scheme to \'NoColor\'"""'
2619 print "Total number of aliases:", len(aliases)
2619 print "Total number of aliases:", len(aliases)
2620 sys.stdout.flush()
2620 sys.stdout.flush()
2621 return aliases
2621 return aliases
2622
2622
2623 # Now try to define a new one
2623 # Now try to define a new one
2624 try:
2624 try:
2625 alias,cmd = par.split(None, 1)
2625 alias,cmd = par.split(None, 1)
@@ -2649,7 +2649,7 b' Defaulting color scheme to \'NoColor\'"""'
2649 Under Windows, it checks executability as a match agains a
2649 Under Windows, it checks executability as a match agains a
2650 '|'-separated string of extensions, stored in the IPython config
2650 '|'-separated string of extensions, stored in the IPython config
2651 variable win_exec_ext. This defaults to 'exe|com|bat'.
2651 variable win_exec_ext. This defaults to 'exe|com|bat'.
2652
2652
2653 This function also resets the root module cache of module completer,
2653 This function also resets the root module cache of module completer,
2654 used on slow filesystems.
2654 used on slow filesystems.
2655 """
2655 """
@@ -2657,8 +2657,8 b' Defaulting color scheme to \'NoColor\'"""'
2657
2657
2658 # for the benefit of module completer in ipy_completers.py
2658 # for the benefit of module completer in ipy_completers.py
2659 del self.db['rootmodules']
2659 del self.db['rootmodules']
2660
2660
2661 path = [os.path.abspath(os.path.expanduser(p)) for p in
2661 path = [os.path.abspath(os.path.expanduser(p)) for p in
2662 os.environ.get('PATH','').split(os.pathsep)]
2662 os.environ.get('PATH','').split(os.pathsep)]
2663 path = filter(os.path.isdir,path)
2663 path = filter(os.path.isdir,path)
2664
2664
@@ -2717,20 +2717,20 b' Defaulting color scheme to \'NoColor\'"""'
2717 db['syscmdlist'] = syscmdlist
2717 db['syscmdlist'] = syscmdlist
2718 finally:
2718 finally:
2719 os.chdir(savedir)
2719 os.chdir(savedir)
2720
2720
2721 @skip_doctest
2721 @skip_doctest
2722 def magic_pwd(self, parameter_s = ''):
2722 def magic_pwd(self, parameter_s = ''):
2723 """Return the current working directory path.
2723 """Return the current working directory path.
2724
2724
2725 Examples
2725 Examples
2726 --------
2726 --------
2727 ::
2727 ::
2728
2728
2729 In [9]: pwd
2729 In [9]: pwd
2730 Out[9]: '/home/tsuser/sprint/ipython'
2730 Out[9]: '/home/tsuser/sprint/ipython'
2731 """
2731 """
2732 return os.getcwdu()
2732 return os.getcwdu()
2733
2733
2734 @skip_doctest
2734 @skip_doctest
2735 def magic_cd(self, parameter_s=''):
2735 def magic_cd(self, parameter_s=''):
2736 """Change the current working directory.
2736 """Change the current working directory.
@@ -2749,25 +2749,25 b' Defaulting color scheme to \'NoColor\'"""'
2749 cd -<n>: changes to the n-th directory in the directory history.
2749 cd -<n>: changes to the n-th directory in the directory history.
2750
2750
2751 cd --foo: change to directory that matches 'foo' in history
2751 cd --foo: change to directory that matches 'foo' in history
2752
2752
2753 cd -b <bookmark_name>: jump to a bookmark set by %bookmark
2753 cd -b <bookmark_name>: jump to a bookmark set by %bookmark
2754 (note: cd <bookmark_name> is enough if there is no
2754 (note: cd <bookmark_name> is enough if there is no
2755 directory <bookmark_name>, but a bookmark with the name exists.)
2755 directory <bookmark_name>, but a bookmark with the name exists.)
2756 'cd -b <tab>' allows you to tab-complete bookmark names.
2756 'cd -b <tab>' allows you to tab-complete bookmark names.
2757
2757
2758 Options:
2758 Options:
2759
2759
2760 -q: quiet. Do not print the working directory after the cd command is
2760 -q: quiet. Do not print the working directory after the cd command is
2761 executed. By default IPython's cd command does print this directory,
2761 executed. By default IPython's cd command does print this directory,
2762 since the default prompts do not display path information.
2762 since the default prompts do not display path information.
2763
2763
2764 Note that !cd doesn't work for this purpose because the shell where
2764 Note that !cd doesn't work for this purpose because the shell where
2765 !command runs is immediately discarded after executing 'command'.
2765 !command runs is immediately discarded after executing 'command'.
2766
2766
2767 Examples
2767 Examples
2768 --------
2768 --------
2769 ::
2769 ::
2770
2770
2771 In [10]: cd parent/child
2771 In [10]: cd parent/child
2772 /home/tsuser/parent/child
2772 /home/tsuser/parent/child
2773 """
2773 """
@@ -2797,25 +2797,25 b' Defaulting color scheme to \'NoColor\'"""'
2797 if pat in os.path.basename(ent) and os.path.isdir(ent):
2797 if pat in os.path.basename(ent) and os.path.isdir(ent):
2798 ps = ent
2798 ps = ent
2799 break
2799 break
2800
2800
2801 if fallback is None and pat in ent and os.path.isdir(ent):
2801 if fallback is None and pat in ent and os.path.isdir(ent):
2802 fallback = ent
2802 fallback = ent
2803
2803
2804 # if we have no last part match, pick the first full path match
2804 # if we have no last part match, pick the first full path match
2805 if ps is None:
2805 if ps is None:
2806 ps = fallback
2806 ps = fallback
2807
2807
2808 if ps is None:
2808 if ps is None:
2809 print "No matching entry in directory history"
2809 print "No matching entry in directory history"
2810 return
2810 return
2811 else:
2811 else:
2812 opts = {}
2812 opts = {}
2813
2813
2814
2814
2815 else:
2815 else:
2816 #turn all non-space-escaping backslashes to slashes,
2816 #turn all non-space-escaping backslashes to slashes,
2817 # for c:\windows\directory\names\
2817 # for c:\windows\directory\names\
2818 parameter_s = re.sub(r'\\(?! )','/', parameter_s)
2818 parameter_s = re.sub(r'\\(?! )','/', parameter_s)
2819 opts,ps = self.parse_options(parameter_s,'qb',mode='string')
2819 opts,ps = self.parse_options(parameter_s,'qb',mode='string')
2820 # jump to previous
2820 # jump to previous
2821 if ps == '-':
2821 if ps == '-':
@@ -2827,7 +2827,7 b' Defaulting color scheme to \'NoColor\'"""'
2827 else:
2827 else:
2828 if not os.path.isdir(ps) or opts.has_key('b'):
2828 if not os.path.isdir(ps) or opts.has_key('b'):
2829 bkms = self.db.get('bookmarks', {})
2829 bkms = self.db.get('bookmarks', {})
2830
2830
2831 if bkms.has_key(ps):
2831 if bkms.has_key(ps):
2832 target = bkms[ps]
2832 target = bkms[ps]
2833 print '(bookmark:%s) -> %s' % (ps,target)
2833 print '(bookmark:%s) -> %s' % (ps,target)
@@ -2853,14 +2853,14 b' Defaulting color scheme to \'NoColor\'"""'
2853 if oldcwd != cwd:
2853 if oldcwd != cwd:
2854 dhist.append(cwd)
2854 dhist.append(cwd)
2855 self.db['dhist'] = compress_dhist(dhist)[-100:]
2855 self.db['dhist'] = compress_dhist(dhist)[-100:]
2856
2856
2857 else:
2857 else:
2858 os.chdir(self.shell.home_dir)
2858 os.chdir(self.shell.home_dir)
2859 if hasattr(self.shell, 'term_title') and self.shell.term_title:
2859 if hasattr(self.shell, 'term_title') and self.shell.term_title:
2860 set_term_title('IPython: ' + '~')
2860 set_term_title('IPython: ' + '~')
2861 cwd = os.getcwdu()
2861 cwd = os.getcwdu()
2862 dhist = self.shell.user_ns['_dh']
2862 dhist = self.shell.user_ns['_dh']
2863
2863
2864 if oldcwd != cwd:
2864 if oldcwd != cwd:
2865 dhist.append(cwd)
2865 dhist.append(cwd)
2866 self.db['dhist'] = compress_dhist(dhist)[-100:]
2866 self.db['dhist'] = compress_dhist(dhist)[-100:]
@@ -2870,16 +2870,16 b' Defaulting color scheme to \'NoColor\'"""'
2870
2870
2871 def magic_env(self, parameter_s=''):
2871 def magic_env(self, parameter_s=''):
2872 """List environment variables."""
2872 """List environment variables."""
2873
2873
2874 return os.environ.data
2874 return os.environ.data
2875
2875
2876 def magic_pushd(self, parameter_s=''):
2876 def magic_pushd(self, parameter_s=''):
2877 """Place the current dir on stack and change directory.
2877 """Place the current dir on stack and change directory.
2878
2878
2879 Usage:\\
2879 Usage:\\
2880 %pushd ['dirname']
2880 %pushd ['dirname']
2881 """
2881 """
2882
2882
2883 dir_s = self.shell.dir_stack
2883 dir_s = self.shell.dir_stack
2884 tgt = os.path.expanduser(unquote_filename(parameter_s))
2884 tgt = os.path.expanduser(unquote_filename(parameter_s))
2885 cwd = os.getcwdu().replace(self.home_dir,'~')
2885 cwd = os.getcwdu().replace(self.home_dir,'~')
@@ -2912,10 +2912,10 b' Defaulting color scheme to \'NoColor\'"""'
2912 This history is automatically maintained by the %cd command, and
2912 This history is automatically maintained by the %cd command, and
2913 always available as the global list variable _dh. You can use %cd -<n>
2913 always available as the global list variable _dh. You can use %cd -<n>
2914 to go to directory number <n>.
2914 to go to directory number <n>.
2915
2915
2916 Note that most of time, you should view directory history by entering
2916 Note that most of time, you should view directory history by entering
2917 cd -<TAB>.
2917 cd -<TAB>.
2918
2918
2919 """
2919 """
2920
2920
2921 dh = self.shell.user_ns['_dh']
2921 dh = self.shell.user_ns['_dh']
@@ -2943,13 +2943,13 b' Defaulting color scheme to \'NoColor\'"""'
2943 """Shell capture - execute a shell command and capture its output.
2943 """Shell capture - execute a shell command and capture its output.
2944
2944
2945 DEPRECATED. Suboptimal, retained for backwards compatibility.
2945 DEPRECATED. Suboptimal, retained for backwards compatibility.
2946
2946
2947 You should use the form 'var = !command' instead. Example:
2947 You should use the form 'var = !command' instead. Example:
2948
2948
2949 "%sc -l myfiles = ls ~" should now be written as
2949 "%sc -l myfiles = ls ~" should now be written as
2950
2950
2951 "myfiles = !ls ~"
2951 "myfiles = !ls ~"
2952
2952
2953 myfiles.s, myfiles.l and myfiles.n still apply as documented
2953 myfiles.s, myfiles.l and myfiles.n still apply as documented
2954 below.
2954 below.
2955
2955
@@ -2963,7 +2963,7 b' Defaulting color scheme to \'NoColor\'"""'
2963
2963
2964 The '=' sign in the syntax is mandatory, and the variable name you
2964 The '=' sign in the syntax is mandatory, and the variable name you
2965 supply must follow Python's standard conventions for valid names.
2965 supply must follow Python's standard conventions for valid names.
2966
2966
2967 (A special format without variable name exists for internal use)
2967 (A special format without variable name exists for internal use)
2968
2968
2969 Options:
2969 Options:
@@ -2983,7 +2983,7 b' Defaulting color scheme to \'NoColor\'"""'
2983 For example:
2983 For example:
2984
2984
2985 # all-random
2985 # all-random
2986
2986
2987 # Capture into variable a
2987 # Capture into variable a
2988 In [1]: sc a=ls *py
2988 In [1]: sc a=ls *py
2989
2989
@@ -3074,7 +3074,7 b' Defaulting color scheme to \'NoColor\'"""'
3074 !!ls
3074 !!ls
3075 is a shorthand equivalent to:
3075 is a shorthand equivalent to:
3076 %sx ls
3076 %sx ls
3077
3077
3078 2) %sx differs from %sc in that %sx automatically splits into a list,
3078 2) %sx differs from %sc in that %sx automatically splits into a list,
3079 like '%sc -l'. The reason for this is to make it as easy as possible
3079 like '%sc -l'. The reason for this is to make it as easy as possible
3080 to process line-oriented shell output via further python commands.
3080 to process line-oriented shell output via further python commands.
@@ -3093,7 +3093,7 b' Defaulting color scheme to \'NoColor\'"""'
3093 if parameter_s:
3093 if parameter_s:
3094 return self.shell.getoutput(parameter_s)
3094 return self.shell.getoutput(parameter_s)
3095
3095
3096
3096
3097 def magic_bookmark(self, parameter_s=''):
3097 def magic_bookmark(self, parameter_s=''):
3098 """Manage IPython's bookmark system.
3098 """Manage IPython's bookmark system.
3099
3099
@@ -3116,7 +3116,7 b' Defaulting color scheme to \'NoColor\'"""'
3116 raise UsageError("%bookmark: too many arguments")
3116 raise UsageError("%bookmark: too many arguments")
3117
3117
3118 bkms = self.db.get('bookmarks',{})
3118 bkms = self.db.get('bookmarks',{})
3119
3119
3120 if opts.has_key('d'):
3120 if opts.has_key('d'):
3121 try:
3121 try:
3122 todel = args[0]
3122 todel = args[0]
@@ -3157,7 +3157,7 b' Defaulting color scheme to \'NoColor\'"""'
3157
3157
3158 This magic is similar to the cat utility, but it will assume the file
3158 This magic is similar to the cat utility, but it will assume the file
3159 to be Python source and will show it with syntax highlighting. """
3159 to be Python source and will show it with syntax highlighting. """
3160
3160
3161 try:
3161 try:
3162 filename = get_py_filename(parameter_s)
3162 filename = get_py_filename(parameter_s)
3163 cont = file_read(filename)
3163 cont = file_read(filename)
@@ -3205,13 +3205,13 b' Defaulting color scheme to \'NoColor\'"""'
3205 ]
3205 ]
3206
3206
3207 strip_from_start = map(re.compile,strip_re)
3207 strip_from_start = map(re.compile,strip_re)
3208
3208
3209 lines = []
3209 lines = []
3210 for l in raw_lines:
3210 for l in raw_lines:
3211 for pat in strip_from_start:
3211 for pat in strip_from_start:
3212 l = pat.sub('',l)
3212 l = pat.sub('',l)
3213 lines.append(l)
3213 lines.append(l)
3214
3214
3215 block = "\n".join(lines) + '\n'
3215 block = "\n".join(lines) + '\n'
3216 #print "block:\n",block
3216 #print "block:\n",block
3217 return block
3217 return block
@@ -3231,7 +3231,7 b' Defaulting color scheme to \'NoColor\'"""'
3231 """ Show a quick reference sheet """
3231 """ Show a quick reference sheet """
3232 import IPython.core.usage
3232 import IPython.core.usage
3233 qr = IPython.core.usage.quick_reference + self.magic_magic('-brief')
3233 qr = IPython.core.usage.quick_reference + self.magic_magic('-brief')
3234
3234
3235 page.page(qr)
3235 page.page(qr)
3236
3236
3237 def magic_doctest_mode(self,parameter_s=''):
3237 def magic_doctest_mode(self,parameter_s=''):
@@ -3298,7 +3298,7 b' Defaulting color scheme to \'NoColor\'"""'
3298
3298
3299 ptformatter.pprint = False
3299 ptformatter.pprint = False
3300 disp_formatter.plain_text_only = True
3300 disp_formatter.plain_text_only = True
3301
3301
3302 shell.magic_xmode('Plain')
3302 shell.magic_xmode('Plain')
3303 else:
3303 else:
3304 # turn off
3304 # turn off
@@ -3385,7 +3385,7 b' Defaulting color scheme to \'NoColor\'"""'
3385 name = src.replace('profile_', '')
3385 name = src.replace('profile_', '')
3386 print " %s"%name
3386 print " %s"%name
3387 pd = ProfileDir.create_profile_dir_by_name(ipython_dir, name)
3387 pd = ProfileDir.create_profile_dir_by_name(ipython_dir, name)
3388 pd.copy_config_file('ipython_config.py', path=src,
3388 pd.copy_config_file('ipython_config.py', path=src,
3389 overwrite=overwrite)
3389 overwrite=overwrite)
3390
3390
3391 @skip_doctest
3391 @skip_doctest
@@ -3452,16 +3452,16 b' Defaulting color scheme to \'NoColor\'"""'
3452 Backend in use: Qt4Agg
3452 Backend in use: Qt4Agg
3453 For more information, type 'help(pylab)'.
3453 For more information, type 'help(pylab)'.
3454 """
3454 """
3455
3455
3456 if Application.initialized():
3456 if Application.initialized():
3457 app = Application.instance()
3457 app = Application.instance()
3458 try:
3458 try:
3459 import_all_status = app.pylab_import_all
3459 import_all_status = app.pylab_import_all
3460 except AttributeError:
3460 except AttributeError:
3461 import_all_status = True
3461 import_all_status = True
3462 else:
3462 else:
3463 import_all_status = True
3463 import_all_status = True
3464
3464
3465 self.shell.enable_pylab(s,import_all=import_all_status)
3465 self.shell.enable_pylab(s,import_all=import_all_status)
3466
3466
3467 def magic_tb(self, s):
3467 def magic_tb(self, s):
@@ -3469,50 +3469,50 b' Defaulting color scheme to \'NoColor\'"""'
3469
3469
3470 See %xmode for changing exception reporting modes."""
3470 See %xmode for changing exception reporting modes."""
3471 self.shell.showtraceback()
3471 self.shell.showtraceback()
3472
3472
3473 @skip_doctest
3473 @skip_doctest
3474 def magic_precision(self, s=''):
3474 def magic_precision(self, s=''):
3475 """Set floating point precision for pretty printing.
3475 """Set floating point precision for pretty printing.
3476
3476
3477 Can set either integer precision or a format string.
3477 Can set either integer precision or a format string.
3478
3478
3479 If numpy has been imported and precision is an int,
3479 If numpy has been imported and precision is an int,
3480 numpy display precision will also be set, via ``numpy.set_printoptions``.
3480 numpy display precision will also be set, via ``numpy.set_printoptions``.
3481
3481
3482 If no argument is given, defaults will be restored.
3482 If no argument is given, defaults will be restored.
3483
3483
3484 Examples
3484 Examples
3485 --------
3485 --------
3486 ::
3486 ::
3487
3487
3488 In [1]: from math import pi
3488 In [1]: from math import pi
3489
3489
3490 In [2]: %precision 3
3490 In [2]: %precision 3
3491 Out[2]: u'%.3f'
3491 Out[2]: u'%.3f'
3492
3492
3493 In [3]: pi
3493 In [3]: pi
3494 Out[3]: 3.142
3494 Out[3]: 3.142
3495
3495
3496 In [4]: %precision %i
3496 In [4]: %precision %i
3497 Out[4]: u'%i'
3497 Out[4]: u'%i'
3498
3498
3499 In [5]: pi
3499 In [5]: pi
3500 Out[5]: 3
3500 Out[5]: 3
3501
3501
3502 In [6]: %precision %e
3502 In [6]: %precision %e
3503 Out[6]: u'%e'
3503 Out[6]: u'%e'
3504
3504
3505 In [7]: pi**10
3505 In [7]: pi**10
3506 Out[7]: 9.364805e+04
3506 Out[7]: 9.364805e+04
3507
3507
3508 In [8]: %precision
3508 In [8]: %precision
3509 Out[8]: u'%r'
3509 Out[8]: u'%r'
3510
3510
3511 In [9]: pi**10
3511 In [9]: pi**10
3512 Out[9]: 93648.047476082982
3512 Out[9]: 93648.047476082982
3513
3513
3514 """
3514 """
3515
3515
3516 ptformatter = self.shell.display_formatter.formatters['text/plain']
3516 ptformatter = self.shell.display_formatter.formatters['text/plain']
3517 ptformatter.float_precision = s
3517 ptformatter.float_precision = s
3518 return ptformatter.float_format
3518 return ptformatter.float_format
@@ -3583,6 +3583,6 b' Defaulting color scheme to \'NoColor\'"""'
3583 nb = current.reads(s, u'xml')
3583 nb = current.reads(s, u'xml')
3584 with open(new_fname, 'w') as f:
3584 with open(new_fname, 'w') as f:
3585 current.write(nb, f, new_format)
3585 current.write(nb, f, new_format)
3586
3586
3587
3587
3588 # end Magic
3588 # end Magic
@@ -197,7 +197,7 b' def call_tip(oinfo, format_call=True):'
197 When format_call is True, the whole call information is formattted as a
197 When format_call is True, the whole call information is formattted as a
198 single string. Otherwise, the object's name and its argspec dict are
198 single string. Otherwise, the object's name and its argspec dict are
199 returned. If no call information is available, None is returned.
199 returned. If no call information is available, None is returned.
200
200
201 docstring : str or None
201 docstring : str or None
202 The most relevant docstring for calling purposes is returned, if
202 The most relevant docstring for calling purposes is returned, if
203 available. The priority is: call docstring for callable instances, then
203 available. The priority is: call docstring for callable instances, then
@@ -219,7 +219,7 b' def call_tip(oinfo, format_call=True):'
219 else:
219 else:
220 if has_self:
220 if has_self:
221 argspec['args'] = argspec['args'][1:]
221 argspec['args'] = argspec['args'][1:]
222
222
223 call_line = oinfo['name']+format_argspec(argspec)
223 call_line = oinfo['name']+format_argspec(argspec)
224
224
225 # Now get docstring.
225 # Now get docstring.
@@ -249,14 +249,14 b' class Inspector:'
249
249
250 If any exception is generated, None is returned instead and the
250 If any exception is generated, None is returned instead and the
251 exception is suppressed."""
251 exception is suppressed."""
252
252
253 try:
253 try:
254 # We need a plain string here, NOT unicode!
254 # We need a plain string here, NOT unicode!
255 hdef = oname + inspect.formatargspec(*getargspec(obj))
255 hdef = oname + inspect.formatargspec(*getargspec(obj))
256 return py3compat.unicode_to_str(hdef, 'ascii')
256 return py3compat.unicode_to_str(hdef, 'ascii')
257 except:
257 except:
258 return None
258 return None
259
259
260 def __head(self,h):
260 def __head(self,h):
261 """Return a header string with proper colors."""
261 """Return a header string with proper colors."""
262 return '%s%s%s' % (self.color_table.active_colors.header,h,
262 return '%s%s%s' % (self.color_table.active_colors.header,h,
@@ -265,7 +265,7 b' class Inspector:'
265 def set_active_scheme(self,scheme):
265 def set_active_scheme(self,scheme):
266 self.color_table.set_active_scheme(scheme)
266 self.color_table.set_active_scheme(scheme)
267 self.parser.color_table.set_active_scheme(scheme)
267 self.parser.color_table.set_active_scheme(scheme)
268
268
269 def noinfo(self,msg,oname):
269 def noinfo(self,msg,oname):
270 """Generic message when no information is found."""
270 """Generic message when no information is found."""
271 print 'No %s found' % msg,
271 print 'No %s found' % msg,
@@ -273,7 +273,7 b' class Inspector:'
273 print 'for %s' % oname
273 print 'for %s' % oname
274 else:
274 else:
275 print
275 print
276
276
277 def pdef(self,obj,oname=''):
277 def pdef(self,obj,oname=''):
278 """Print the definition header for any callable object.
278 """Print the definition header for any callable object.
279
279
@@ -303,30 +303,30 b' class Inspector:'
303 Optional:
303 Optional:
304 -formatter: a function to run the docstring through for specially
304 -formatter: a function to run the docstring through for specially
305 formatted docstrings.
305 formatted docstrings.
306
306
307 Examples
307 Examples
308 --------
308 --------
309
309
310 In [1]: class NoInit:
310 In [1]: class NoInit:
311 ...: pass
311 ...: pass
312
312
313 In [2]: class NoDoc:
313 In [2]: class NoDoc:
314 ...: def __init__(self):
314 ...: def __init__(self):
315 ...: pass
315 ...: pass
316
316
317 In [3]: %pdoc NoDoc
317 In [3]: %pdoc NoDoc
318 No documentation found for NoDoc
318 No documentation found for NoDoc
319
319
320 In [4]: %pdoc NoInit
320 In [4]: %pdoc NoInit
321 No documentation found for NoInit
321 No documentation found for NoInit
322
322
323 In [5]: obj = NoInit()
323 In [5]: obj = NoInit()
324
324
325 In [6]: %pdoc obj
325 In [6]: %pdoc obj
326 No documentation found for obj
326 No documentation found for obj
327
327
328 In [5]: obj2 = NoDoc()
328 In [5]: obj2 = NoDoc()
329
329
330 In [6]: %pdoc obj2
330 In [6]: %pdoc obj2
331 No documentation found for obj2
331 No documentation found for obj2
332 """
332 """
@@ -355,14 +355,14 b' class Inspector:'
355 self.noinfo('documentation',oname)
355 self.noinfo('documentation',oname)
356 else:
356 else:
357 page.page('\n'.join(lines))
357 page.page('\n'.join(lines))
358
358
359 def psource(self,obj,oname=''):
359 def psource(self,obj,oname=''):
360 """Print the source code for an object."""
360 """Print the source code for an object."""
361
361
362 # Flush the source cache because inspect can return out-of-date source
362 # Flush the source cache because inspect can return out-of-date source
363 linecache.checkcache()
363 linecache.checkcache()
364 try:
364 try:
365 src = getsource(obj)
365 src = getsource(obj)
366 except:
366 except:
367 self.noinfo('source',oname)
367 self.noinfo('source',oname)
368 else:
368 else:
@@ -385,7 +385,7 b' class Inspector:'
385 return
385 return
386
386
387 # We only reach this point if object was successfully queried
387 # We only reach this point if object was successfully queried
388
388
389 # run contents of file through pager starting at line
389 # run contents of file through pager starting at line
390 # where the object is defined
390 # where the object is defined
391 ofile = inspect.getabsfile(obj)
391 ofile = inspect.getabsfile(obj)
@@ -399,10 +399,10 b' class Inspector:'
399 # getsourcelines returns lineno with 1-offset and page() uses
399 # getsourcelines returns lineno with 1-offset and page() uses
400 # 0-offset, so we must adjust.
400 # 0-offset, so we must adjust.
401 page.page(self.format(open(ofile).read()),lineno-1)
401 page.page(self.format(open(ofile).read()),lineno-1)
402
402
403 def _format_fields(self, fields, title_width=12):
403 def _format_fields(self, fields, title_width=12):
404 """Formats a list of fields for display.
404 """Formats a list of fields for display.
405
405
406 Parameters
406 Parameters
407 ----------
407 ----------
408 fields : list
408 fields : list
@@ -428,17 +428,17 b' class Inspector:'
428 ("Length", "length"),
428 ("Length", "length"),
429 ("File", "file"),
429 ("File", "file"),
430 ("Definition", "definition")]
430 ("Definition", "definition")]
431
431
432 pinfo_fields_obj = [("Class Docstring", "class_docstring"),
432 pinfo_fields_obj = [("Class Docstring", "class_docstring"),
433 ("Constructor Docstring","init_docstring"),
433 ("Constructor Docstring","init_docstring"),
434 ("Call def", "call_def"),
434 ("Call def", "call_def"),
435 ("Call docstring", "call_docstring")]
435 ("Call docstring", "call_docstring")]
436
436
437 def pinfo(self,obj,oname='',formatter=None,info=None,detail_level=0):
437 def pinfo(self,obj,oname='',formatter=None,info=None,detail_level=0):
438 """Show detailed information about an object.
438 """Show detailed information about an object.
439
439
440 Optional arguments:
440 Optional arguments:
441
441
442 - oname: name of the variable pointing to the object.
442 - oname: name of the variable pointing to the object.
443
443
444 - formatter: special formatter for docstrings (see pdoc)
444 - formatter: special formatter for docstrings (see pdoc)
@@ -455,14 +455,14 b' class Inspector:'
455 field = info[key]
455 field = info[key]
456 if field is not None:
456 if field is not None:
457 displayfields.append((title, field.rstrip()))
457 displayfields.append((title, field.rstrip()))
458
458
459 # Source or docstring, depending on detail level and whether
459 # Source or docstring, depending on detail level and whether
460 # source found.
460 # source found.
461 if detail_level > 0 and info['source'] is not None:
461 if detail_level > 0 and info['source'] is not None:
462 displayfields.append(("Source", self.format(py3compat.unicode_to_str(info['source']))))
462 displayfields.append(("Source", self.format(py3compat.unicode_to_str(info['source']))))
463 elif info['docstring'] is not None:
463 elif info['docstring'] is not None:
464 displayfields.append(("Docstring", info["docstring"]))
464 displayfields.append(("Docstring", info["docstring"]))
465
465
466 # Constructor info for classes
466 # Constructor info for classes
467 if info['isclass']:
467 if info['isclass']:
468 if info['init_definition'] or info['init_docstring']:
468 if info['init_definition'] or info['init_docstring']:
@@ -473,14 +473,14 b' class Inspector:'
473 if info['init_docstring'] is not None:
473 if info['init_docstring'] is not None:
474 displayfields.append((" Docstring",
474 displayfields.append((" Docstring",
475 indent(info['init_docstring'])))
475 indent(info['init_docstring'])))
476
476
477 # Info for objects:
477 # Info for objects:
478 else:
478 else:
479 for title, key in self.pinfo_fields_obj:
479 for title, key in self.pinfo_fields_obj:
480 field = info[key]
480 field = info[key]
481 if field is not None:
481 if field is not None:
482 displayfields.append((title, field.rstrip()))
482 displayfields.append((title, field.rstrip()))
483
483
484 # Finally send to printer/pager:
484 # Finally send to printer/pager:
485 if displayfields:
485 if displayfields:
486 page.page(self._format_fields(displayfields))
486 page.page(self._format_fields(displayfields))
@@ -489,7 +489,7 b' class Inspector:'
489 """Compute a dict with detailed information about an object.
489 """Compute a dict with detailed information about an object.
490
490
491 Optional arguments:
491 Optional arguments:
492
492
493 - oname: name of the variable pointing to the object.
493 - oname: name of the variable pointing to the object.
494
494
495 - formatter: special formatter for docstrings (see pdoc)
495 - formatter: special formatter for docstrings (see pdoc)
@@ -532,7 +532,7 b' class Inspector:'
532
532
533 # store output in a dict, we initialize it here and fill it as we go
533 # store output in a dict, we initialize it here and fill it as we go
534 out = dict(name=oname, found=True, isalias=isalias, ismagic=ismagic)
534 out = dict(name=oname, found=True, isalias=isalias, ismagic=ismagic)
535
535
536 string_max = 200 # max size of strings to show (snipped if longer)
536 string_max = 200 # max size of strings to show (snipped if longer)
537 shalf = int((string_max -5)/2)
537 shalf = int((string_max -5)/2)
538
538
@@ -599,7 +599,7 b' class Inspector:'
599 # avoid repetitions). If source fails, we add them back, see below.
599 # avoid repetitions). If source fails, we add them back, see below.
600 if ds and detail_level == 0:
600 if ds and detail_level == 0:
601 out['docstring'] = ds
601 out['docstring'] = ds
602
602
603 # Original source code for any callable
603 # Original source code for any callable
604 if detail_level:
604 if detail_level:
605 # Flush the source cache because inspect can return out-of-date
605 # Flush the source cache because inspect can return out-of-date
@@ -616,10 +616,10 b' class Inspector:'
616 out['source'] = source.rstrip()
616 out['source'] = source.rstrip()
617 except Exception:
617 except Exception:
618 pass
618 pass
619
619
620 if ds and source is None:
620 if ds and source is None:
621 out['docstring'] = ds
621 out['docstring'] = ds
622
622
623
623
624 # Constructor docstring for classes
624 # Constructor docstring for classes
625 if inspect.isclass(obj):
625 if inspect.isclass(obj):
@@ -692,7 +692,7 b' class Inspector:'
692 # Compute the object's argspec as a callable. The key is to decide
692 # Compute the object's argspec as a callable. The key is to decide
693 # whether to pull it from the object itself, from its __init__ or
693 # whether to pull it from the object itself, from its __init__ or
694 # from its __call__ method.
694 # from its __call__ method.
695
695
696 if inspect.isclass(obj):
696 if inspect.isclass(obj):
697 # Old-style classes need not have an __init__
697 # Old-style classes need not have an __init__
698 callable_obj = getattr(obj, "__init__", None)
698 callable_obj = getattr(obj, "__init__", None)
@@ -727,7 +727,7 b' class Inspector:'
727 - ns_table: dict of name->namespaces for search.
727 - ns_table: dict of name->namespaces for search.
728
728
729 Optional arguments:
729 Optional arguments:
730
730
731 - ns_search: list of namespace names to include in search.
731 - ns_search: list of namespace names to include in search.
732
732
733 - ignore_case(False): make the search case-insensitive.
733 - ignore_case(False): make the search case-insensitive.
@@ -736,7 +736,7 b' class Inspector:'
736 underscores.
736 underscores.
737 """
737 """
738 #print 'ps pattern:<%r>' % pattern # dbg
738 #print 'ps pattern:<%r>' % pattern # dbg
739
739
740 # defaults
740 # defaults
741 type_pattern = 'all'
741 type_pattern = 'all'
742 filter = ''
742 filter = ''
@@ -100,7 +100,7 b' class PrefilterManager(Configurable):'
100 """Main prefilter component.
100 """Main prefilter component.
101
101
102 The IPython prefilter is run on all user input before it is run. The
102 The IPython prefilter is run on all user input before it is run. The
103 prefilter consumes lines of input and produces transformed lines of
103 prefilter consumes lines of input and produces transformed lines of
104 input.
104 input.
105
105
106 The iplementation consists of two phases:
106 The iplementation consists of two phases:
@@ -119,12 +119,12 b' class PrefilterManager(Configurable):'
119
119
120 After all the transformers have been run, the line is fed to the checkers,
120 After all the transformers have been run, the line is fed to the checkers,
121 which are instances of :class:`PrefilterChecker`. The line is passed to
121 which are instances of :class:`PrefilterChecker`. The line is passed to
122 the :meth:`check` method, which either returns `None` or a
122 the :meth:`check` method, which either returns `None` or a
123 :class:`PrefilterHandler` instance. If `None` is returned, the other
123 :class:`PrefilterHandler` instance. If `None` is returned, the other
124 checkers are tried. If an :class:`PrefilterHandler` instance is returned,
124 checkers are tried. If an :class:`PrefilterHandler` instance is returned,
125 the line is passed to the :meth:`handle` method of the returned
125 the line is passed to the :meth:`handle` method of the returned
126 handler and no further checkers are tried.
126 handler and no further checkers are tried.
127
127
128 Both transformers and checkers have a `priority` attribute, that determines
128 Both transformers and checkers have a `priority` attribute, that determines
129 the order in which they are called. Smaller priorities are tried first.
129 the order in which they are called. Smaller priorities are tried first.
130
130
@@ -317,7 +317,7 b' class PrefilterManager(Configurable):'
317
317
318 # Now we compute line_info for the checkers and handlers
318 # Now we compute line_info for the checkers and handlers
319 line_info = LineInfo(line, continue_prompt)
319 line_info = LineInfo(line, continue_prompt)
320
320
321 # the input history needs to track even empty lines
321 # the input history needs to track even empty lines
322 stripped = line.strip()
322 stripped = line.strip()
323
323
@@ -358,7 +358,7 b' class PrefilterManager(Configurable):'
358 for lnum, line in enumerate(llines) ])
358 for lnum, line in enumerate(llines) ])
359 else:
359 else:
360 out = self.prefilter_line(llines[0], continue_prompt)
360 out = self.prefilter_line(llines[0], continue_prompt)
361
361
362 return out
362 return out
363
363
364 #-----------------------------------------------------------------------------
364 #-----------------------------------------------------------------------------
@@ -522,9 +522,9 b' class ShellEscapeChecker(PrefilterChecker):'
522
522
523
523
524 class MacroChecker(PrefilterChecker):
524 class MacroChecker(PrefilterChecker):
525
525
526 priority = Int(250, config=True)
526 priority = Int(250, config=True)
527
527
528 def check(self, line_info):
528 def check(self, line_info):
529 obj = self.shell.user_ns.get(line_info.ifun)
529 obj = self.shell.user_ns.get(line_info.ifun)
530 if isinstance(obj, Macro):
530 if isinstance(obj, Macro):
@@ -555,7 +555,7 b' class MultiLineMagicChecker(PrefilterChecker):'
555 "Allow ! and !! in multi-line statements if multi_line_specials is on"
555 "Allow ! and !! in multi-line statements if multi_line_specials is on"
556 # Note that this one of the only places we check the first character of
556 # Note that this one of the only places we check the first character of
557 # ifun and *not* the pre_char. Also note that the below test matches
557 # ifun and *not* the pre_char. Also note that the below test matches
558 # both ! and !!.
558 # both ! and !!.
559 if line_info.continue_prompt \
559 if line_info.continue_prompt \
560 and self.prefilter_manager.multi_line_specials:
560 and self.prefilter_manager.multi_line_specials:
561 if line_info.esc == ESC_MAGIC:
561 if line_info.esc == ESC_MAGIC:
@@ -591,7 +591,7 b' class AssignmentChecker(PrefilterChecker):'
591 def check(self, line_info):
591 def check(self, line_info):
592 """Check to see if user is assigning to a var for the first time, in
592 """Check to see if user is assigning to a var for the first time, in
593 which case we want to avoid any sort of automagic / autocall games.
593 which case we want to avoid any sort of automagic / autocall games.
594
594
595 This allows users to assign to either alias or magic names true python
595 This allows users to assign to either alias or magic names true python
596 variables (the magic/alias systems always take second seat to true
596 variables (the magic/alias systems always take second seat to true
597 python code). E.g. ls='hi', or ls,that=1,2"""
597 python code). E.g. ls='hi', or ls,that=1,2"""
@@ -669,7 +669,7 b' class AutocallChecker(PrefilterChecker):'
669 oinfo = line_info.ofind(self.shell) # This can mutate state via getattr
669 oinfo = line_info.ofind(self.shell) # This can mutate state via getattr
670 if not oinfo['found']:
670 if not oinfo['found']:
671 return None
671 return None
672
672
673 if callable(oinfo['obj']) \
673 if callable(oinfo['obj']) \
674 and (not re_exclude_auto.match(line_info.the_rest)) \
674 and (not re_exclude_auto.match(line_info.the_rest)) \
675 and re_fun_name.match(line_info.ifun):
675 and re_fun_name.match(line_info.ifun):
@@ -735,7 +735,7 b' class AliasHandler(PrefilterHandler):'
735 # aliases won't work in indented sections.
735 # aliases won't work in indented sections.
736 line_out = '%sget_ipython().system(%s)' % (line_info.pre_whitespace,
736 line_out = '%sget_ipython().system(%s)' % (line_info.pre_whitespace,
737 make_quoted_expr(transformed))
737 make_quoted_expr(transformed))
738
738
739 return line_out
739 return line_out
740
740
741
741
@@ -769,7 +769,7 b' class ShellEscapeHandler(PrefilterHandler):'
769
769
770 class MacroHandler(PrefilterHandler):
770 class MacroHandler(PrefilterHandler):
771 handler_name = Unicode("macro")
771 handler_name = Unicode("macro")
772
772
773 def handle(self, line_info):
773 def handle(self, line_info):
774 obj = self.shell.user_ns.get(line_info.ifun)
774 obj = self.shell.user_ns.get(line_info.ifun)
775 pre_space = line_info.pre_whitespace
775 pre_space = line_info.pre_whitespace
@@ -813,7 +813,7 b' class AutoHandler(PrefilterHandler):'
813
813
814 force_auto = isinstance(obj, IPyAutocall)
814 force_auto = isinstance(obj, IPyAutocall)
815 auto_rewrite = getattr(obj, 'rewrite', True)
815 auto_rewrite = getattr(obj, 'rewrite', True)
816
816
817 if esc == ESC_QUOTE:
817 if esc == ESC_QUOTE:
818 # Auto-quote splitting on whitespace
818 # Auto-quote splitting on whitespace
819 newcmd = '%s("%s")' % (ifun,'", "'.join(the_rest.split()) )
819 newcmd = '%s("%s")' % (ifun,'", "'.join(the_rest.split()) )
@@ -848,7 +848,7 b' class AutoHandler(PrefilterHandler):'
848
848
849 if auto_rewrite:
849 if auto_rewrite:
850 self.shell.auto_rewrite_input(newcmd)
850 self.shell.auto_rewrite_input(newcmd)
851
851
852 return newcmd
852 return newcmd
853
853
854
854
@@ -107,7 +107,7 b' class ProfileList(Application):'
107 )
107 )
108 ))
108 ))
109
109
110 ipython_dir = Unicode(get_ipython_dir(), config=True,
110 ipython_dir = Unicode(get_ipython_dir(), config=True,
111 help="""
111 help="""
112 The name of the IPython directory. This directory is used for logging
112 The name of the IPython directory. This directory is used for logging
113 configuration (through profiles), history storage, etc. The default
113 configuration (through profiles), history storage, etc. The default
@@ -115,7 +115,7 b' class ProfileList(Application):'
115 the environment variable IPYTHON_DIR.
115 the environment variable IPYTHON_DIR.
116 """
116 """
117 )
117 )
118
118
119 def list_profile_dirs(self):
119 def list_profile_dirs(self):
120 # Find the search paths
120 # Find the search paths
121 paths = [os.getcwdu(), self.ipython_dir]
121 paths = [os.getcwdu(), self.ipython_dir]
@@ -129,7 +129,7 b' class ProfileList(Application):'
129 profile = f.split('_',1)[-1]
129 profile = f.split('_',1)[-1]
130 start_cmd = 'ipython profile=%s' % profile
130 start_cmd = 'ipython profile=%s' % profile
131 print start_cmd + " ==> " + full_path
131 print start_cmd + " ==> " + full_path
132
132
133 def start(self):
133 def start(self):
134 self.list_profile_dirs()
134 self.list_profile_dirs()
135
135
@@ -150,15 +150,15 b' class ProfileCreate(BaseIPythonApplication):'
150 description = create_help
150 description = create_help
151 examples = _create_examples
151 examples = _create_examples
152 auto_create = Bool(True, config=False)
152 auto_create = Bool(True, config=False)
153
153
154 def _copy_config_files_default(self):
154 def _copy_config_files_default(self):
155 return True
155 return True
156
156
157 parallel = Bool(False, config=True,
157 parallel = Bool(False, config=True,
158 help="whether to include parallel computing config files")
158 help="whether to include parallel computing config files")
159 def _parallel_changed(self, name, old, new):
159 def _parallel_changed(self, name, old, new):
160 parallel_files = [ 'ipcontroller_config.py',
160 parallel_files = [ 'ipcontroller_config.py',
161 'ipengine_config.py',
161 'ipengine_config.py',
162 'ipcluster_config.py'
162 'ipcluster_config.py'
163 ]
163 ]
164 if new:
164 if new:
@@ -168,17 +168,17 b' class ProfileCreate(BaseIPythonApplication):'
168 for cf in parallel_files:
168 for cf in parallel_files:
169 if cf in self.config_files:
169 if cf in self.config_files:
170 self.config_files.remove(cf)
170 self.config_files.remove(cf)
171
171
172 def parse_command_line(self, argv):
172 def parse_command_line(self, argv):
173 super(ProfileCreate, self).parse_command_line(argv)
173 super(ProfileCreate, self).parse_command_line(argv)
174 # accept positional arg as profile name
174 # accept positional arg as profile name
175 if self.extra_args:
175 if self.extra_args:
176 self.profile = self.extra_args[0]
176 self.profile = self.extra_args[0]
177
177
178 flags = Dict(create_flags)
178 flags = Dict(create_flags)
179
179
180 classes = [ProfileDir]
180 classes = [ProfileDir]
181
181
182 def init_config_files(self):
182 def init_config_files(self):
183 super(ProfileCreate, self).init_config_files()
183 super(ProfileCreate, self).init_config_files()
184 # use local imports, since these classes may import from here
184 # use local imports, since these classes may import from here
@@ -223,7 +223,7 b' class ProfileCreate(BaseIPythonApplication):'
223 app.profile = self.profile
223 app.profile = self.profile
224 app.init_profile_dir()
224 app.init_profile_dir()
225 app.init_config_files()
225 app.init_config_files()
226
226
227 def stage_default_config_file(self):
227 def stage_default_config_file(self):
228 pass
228 pass
229
229
@@ -237,7 +237,7 b' class ProfileApp(Application):'
237 create = (ProfileCreate, "Create a new profile dir with default config files"),
237 create = (ProfileCreate, "Create a new profile dir with default config files"),
238 list = (ProfileList, "List existing profiles")
238 list = (ProfileList, "List existing profiles")
239 ))
239 ))
240
240
241 def start(self):
241 def start(self):
242 if self.subapp is None:
242 if self.subapp is None:
243 print "No subcommand specified. Must specify one of: %s"%(self.subcommands.keys())
243 print "No subcommand specified. Must specify one of: %s"%(self.subcommands.keys())
@@ -42,7 +42,7 b' PromptColors.add_scheme(coloransi.ColorScheme('
42 in_number = InputColors.NoColor, # Input prompt number
42 in_number = InputColors.NoColor, # Input prompt number
43 in_prompt2 = InputColors.NoColor, # Continuation prompt
43 in_prompt2 = InputColors.NoColor, # Continuation prompt
44 in_normal = InputColors.NoColor, # color off (usu. Colors.Normal)
44 in_normal = InputColors.NoColor, # color off (usu. Colors.Normal)
45
45
46 out_prompt = Colors.NoColor, # Output prompt
46 out_prompt = Colors.NoColor, # Output prompt
47 out_number = Colors.NoColor, # Output prompt number
47 out_number = Colors.NoColor, # Output prompt number
48
48
@@ -255,7 +255,7 b' class BasePrompt(object):'
255 # by all prompt classes through the cache. Nice OO spaghetti code!
255 # by all prompt classes through the cache. Nice OO spaghetti code!
256 self.cache = cache
256 self.cache = cache
257 self.sep = sep
257 self.sep = sep
258
258
259 # regexp to count the number of spaces at the end of a prompt
259 # regexp to count the number of spaces at the end of a prompt
260 # expression, useful for prompt auto-rewriting
260 # expression, useful for prompt auto-rewriting
261 self.rspace = re.compile(r'(\s*)$')
261 self.rspace = re.compile(r'(\s*)$')
@@ -281,7 +281,7 b' class BasePrompt(object):'
281 ('${self.sep}${self.col_p}',
281 ('${self.sep}${self.col_p}',
282 multiple_replace(prompt_specials, self.p_template),
282 multiple_replace(prompt_specials, self.p_template),
283 '${self.col_norm}'),self.cache.shell.user_ns,loc)
283 '${self.col_norm}'),self.cache.shell.user_ns,loc)
284
284
285 self.p_str_nocolor = ItplNS(multiple_replace(prompt_specials_nocolor,
285 self.p_str_nocolor = ItplNS(multiple_replace(prompt_specials_nocolor,
286 self.p_template),
286 self.p_template),
287 self.cache.shell.user_ns,loc)
287 self.cache.shell.user_ns,loc)
@@ -369,8 +369,8 b' class Prompt1(BasePrompt):'
369 self.col_norm = Colors.in_normal
369 self.col_norm = Colors.in_normal
370 # We need a non-input version of these escapes for the '--->'
370 # We need a non-input version of these escapes for the '--->'
371 # auto-call prompts used in the auto_rewrite() method.
371 # auto-call prompts used in the auto_rewrite() method.
372 self.col_p_ni = self.col_p.replace('\001','').replace('\002','')
372 self.col_p_ni = self.col_p.replace('\001','').replace('\002','')
373 self.col_norm_ni = Colors.normal
373 self.col_norm_ni = Colors.normal
374
374
375 def __str__(self):
375 def __str__(self):
376 self.cache.last_prompt = str_safe(self.p_str_nocolor).split('\n')[-1]
376 self.cache.last_prompt = str_safe(self.p_str_nocolor).split('\n')[-1]
@@ -405,7 +405,7 b' class PromptOut(BasePrompt):'
405
405
406 class Prompt2(BasePrompt):
406 class Prompt2(BasePrompt):
407 """Interactive continuation prompt."""
407 """Interactive continuation prompt."""
408
408
409 def __init__(self, cache, prompt=' .\\D.: ', pad_left=True):
409 def __init__(self, cache, prompt=' .\\D.: ', pad_left=True):
410 self.cache = cache
410 self.cache = cache
411 self.p_template = prompt
411 self.p_template = prompt
@@ -73,13 +73,13 b' The enhanced interactive Python shells have the following main features:'
73
73
74 * Easily embeddable in other Python programs and wxPython GUIs.
74 * Easily embeddable in other Python programs and wxPython GUIs.
75
75
76 * Integrated access to the pdb debugger and the Python profiler.
76 * Integrated access to the pdb debugger and the Python profiler.
77
77
78 The parallel computing architecture has the following main features:
78 The parallel computing architecture has the following main features:
79
79
80 * Quickly parallelize Python code from an interactive Python/IPython session.
80 * Quickly parallelize Python code from an interactive Python/IPython session.
81
81
82 * A flexible and dynamic process model that be deployed on anything from
82 * A flexible and dynamic process model that be deployed on anything from
83 multicore workstations to supercomputers.
83 multicore workstations to supercomputers.
84
84
85 * An architecture that supports many different styles of parallelism, from
85 * An architecture that supports many different styles of parallelism, from
@@ -90,7 +90,7 b' The parallel computing architecture has the following main features:'
90 * High level APIs that enable many things to be parallelized in a few lines
90 * High level APIs that enable many things to be parallelized in a few lines
91 of code.
91 of code.
92
92
93 * Share live parallel jobs with other users securely.
93 * Share live parallel jobs with other users securely.
94
94
95 * Dynamically load balanced task farming system.
95 * Dynamically load balanced task farming system.
96
96
@@ -37,7 +37,7 b' from IPython.utils import py3compat'
37
37
38 # Although it's not solely driven by the regex, note that:
38 # Although it's not solely driven by the regex, note that:
39 # ,;/% only trigger if they are the first character on the line
39 # ,;/% only trigger if they are the first character on the line
40 # ! and !! trigger if they are first char(s) *or* follow an indent
40 # ! and !! trigger if they are first char(s) *or* follow an indent
41 # ? triggers as first or last char.
41 # ? triggers as first or last char.
42
42
43 line_split = re.compile("""
43 line_split = re.compile("""
@@ -54,7 +54,7 b' def split_user_input(line, pattern=None):'
54 """
54 """
55 # We need to ensure that the rest of this routine deals only with unicode
55 # We need to ensure that the rest of this routine deals only with unicode
56 line = py3compat.cast_unicode(line, sys.stdin.encoding or 'utf-8')
56 line = py3compat.cast_unicode(line, sys.stdin.encoding or 'utf-8')
57
57
58 if pattern is None:
58 if pattern is None:
59 pattern = line_split
59 pattern = line_split
60 match = pattern.match(line)
60 match = pattern.match(line)
@@ -77,29 +77,29 b' def split_user_input(line, pattern=None):'
77 class LineInfo(object):
77 class LineInfo(object):
78 """A single line of input and associated info.
78 """A single line of input and associated info.
79
79
80 Includes the following as properties:
80 Includes the following as properties:
81
81
82 line
82 line
83 The original, raw line
83 The original, raw line
84
84
85 continue_prompt
85 continue_prompt
86 Is this line a continuation in a sequence of multiline input?
86 Is this line a continuation in a sequence of multiline input?
87
87
88 pre
88 pre
89 Any leading whitespace.
89 Any leading whitespace.
90
90
91 esc
91 esc
92 The escape character(s) in pre or the empty string if there isn't one.
92 The escape character(s) in pre or the empty string if there isn't one.
93 Note that '!!' and '??' are possible values for esc. Otherwise it will
93 Note that '!!' and '??' are possible values for esc. Otherwise it will
94 always be a single character.
94 always be a single character.
95
95
96 ifun
96 ifun
97 The 'function part', which is basically the maximal initial sequence
97 The 'function part', which is basically the maximal initial sequence
98 of valid python identifiers and the '.' character. This is what is
98 of valid python identifiers and the '.' character. This is what is
99 checked for alias and magic transformations, used for auto-calling,
99 checked for alias and magic transformations, used for auto-calling,
100 etc. In contrast to Python identifiers, it may start with "%" and contain
100 etc. In contrast to Python identifiers, it may start with "%" and contain
101 "*".
101 "*".
102
102
103 the_rest
103 the_rest
104 Everything else on the line.
104 Everything else on the line.
105 """
105 """
@@ -111,7 +111,7 b' class LineInfo(object):'
111 self.pre_char = self.pre.strip()
111 self.pre_char = self.pre.strip()
112 if self.pre_char:
112 if self.pre_char:
113 self.pre_whitespace = '' # No whitespace allowd before esc chars
113 self.pre_whitespace = '' # No whitespace allowd before esc chars
114 else:
114 else:
115 self.pre_whitespace = self.pre
115 self.pre_whitespace = self.pre
116
116
117 self._oinfo = None
117 self._oinfo = None
@@ -134,5 +134,5 b' class LineInfo(object):'
134 self._oinfo = ip.shell._ofind(self.ifun)
134 self._oinfo = ip.shell._ofind(self.ifun)
135 return self._oinfo
135 return self._oinfo
136
136
137 def __str__(self):
137 def __str__(self):
138 return "LineInfo [%s|%s|%s|%s]" %(self.pre, self.esc, self.ifun, self.the_rest)
138 return "LineInfo [%s|%s|%s|%s]" %(self.pre, self.esc, self.ifun, self.the_rest)
@@ -81,7 +81,7 b' def test_handlers():'
81 #("a = b # PYTHON-MODE", '_i'), # emacs -- avoids _in cache
81 #("a = b # PYTHON-MODE", '_i'), # emacs -- avoids _in cache
82
82
83 # post-esc-char whitespace goes inside
83 # post-esc-char whitespace goes inside
84 ("! true", 'get_ipython().system(u" true")'),
84 ("! true", 'get_ipython().system(u" true")'),
85
85
86 # handle_help
86 # handle_help
87
87
@@ -111,32 +111,32 b' def test_handlers():'
111 ('if 1:\n !!true', 'if 1:\n get_ipython().magic(u"sx true")'),
111 ('if 1:\n !!true', 'if 1:\n get_ipython().magic(u"sx true")'),
112
112
113 # Even with m_l_s on, autocall is off even with special chars
113 # Even with m_l_s on, autocall is off even with special chars
114 ('if 1:\n /fun 1 2', 'if 1:\n /fun 1 2'),
114 ('if 1:\n /fun 1 2', 'if 1:\n /fun 1 2'),
115 ('if 1:\n ;fun 1 2', 'if 1:\n ;fun 1 2'),
115 ('if 1:\n ;fun 1 2', 'if 1:\n ;fun 1 2'),
116 ('if 1:\n ,fun 1 2', 'if 1:\n ,fun 1 2'),
116 ('if 1:\n ,fun 1 2', 'if 1:\n ,fun 1 2'),
117 ('if 1:\n ?fun 1 2', 'if 1:\n ?fun 1 2'),
117 ('if 1:\n ?fun 1 2', 'if 1:\n ?fun 1 2'),
118 # What about !!
118 # What about !!
119 ])
119 ])
120
120
121 # Objects which are instances of IPyAutocall are *always* autocalled
121 # Objects which are instances of IPyAutocall are *always* autocalled
122 autocallable = Autocallable()
122 autocallable = Autocallable()
123 ip.user_ns['autocallable'] = autocallable
123 ip.user_ns['autocallable'] = autocallable
124
124
125 # auto
125 # auto
126 ip.magic('autocall 0')
126 ip.magic('autocall 0')
127 # Only explicit escapes or instances of IPyAutocallable should get
127 # Only explicit escapes or instances of IPyAutocallable should get
128 # expanded
128 # expanded
129 run([
129 run([
130 ('len "abc"', 'len "abc"'),
130 ('len "abc"', 'len "abc"'),
131 ('autocallable', 'autocallable()'),
131 ('autocallable', 'autocallable()'),
132 (",list 1 2 3", 'list("1", "2", "3")'),
132 (",list 1 2 3", 'list("1", "2", "3")'),
133 (";list 1 2 3", 'list("1 2 3")'),
133 (";list 1 2 3", 'list("1 2 3")'),
134 ("/len range(1,4)", 'len(range(1,4))'),
134 ("/len range(1,4)", 'len(range(1,4))'),
135 ])
135 ])
136 ip.magic('autocall 1')
136 ip.magic('autocall 1')
137 run([
137 run([
138 (",list 1 2 3", 'list("1", "2", "3")'),
138 (",list 1 2 3", 'list("1", "2", "3")'),
139 (";list 1 2 3", 'list("1 2 3")'),
139 (";list 1 2 3", 'list("1 2 3")'),
140 ("/len range(1,4)", 'len(range(1,4))'),
140 ("/len range(1,4)", 'len(range(1,4))'),
141 ('len "abc"', 'len("abc")'),
141 ('len "abc"', 'len("abc")'),
142 ('len "abc";', 'len("abc");'), # ; is special -- moves out of parens
142 ('len "abc";', 'len("abc");'), # ; is special -- moves out of parens
@@ -150,11 +150,11 b' def test_handlers():'
150 ip.magic('autocall 2')
150 ip.magic('autocall 2')
151 run([
151 run([
152 (",list 1 2 3", 'list("1", "2", "3")'),
152 (",list 1 2 3", 'list("1", "2", "3")'),
153 (";list 1 2 3", 'list("1 2 3")'),
153 (";list 1 2 3", 'list("1 2 3")'),
154 ("/len range(1,4)", 'len(range(1,4))'),
154 ("/len range(1,4)", 'len(range(1,4))'),
155 ('len "abc"', 'len("abc")'),
155 ('len "abc"', 'len("abc")'),
156 ('len "abc";', 'len("abc");'),
156 ('len "abc";', 'len("abc");'),
157 ('len [1,2]', 'len([1,2])'),
157 ('len [1,2]', 'len([1,2])'),
158 ('call_idx [1]', 'call_idx [1]'),
158 ('call_idx [1]', 'call_idx [1]'),
159 ('call_idx 1', 'call_idx(1)'),
159 ('call_idx 1', 'call_idx(1)'),
160 # This is what's different:
160 # This is what's different:
@@ -31,18 +31,18 b' def test_history():'
31 hist = ['a=1', 'def f():\n test = 1\n return test', u"b='€Æ¾÷ß'"]
31 hist = ['a=1', 'def f():\n test = 1\n return test', u"b='€Æ¾÷ß'"]
32 for i, h in enumerate(hist, start=1):
32 for i, h in enumerate(hist, start=1):
33 ip.history_manager.store_inputs(i, h)
33 ip.history_manager.store_inputs(i, h)
34
34
35 ip.history_manager.db_log_output = True
35 ip.history_manager.db_log_output = True
36 # Doesn't match the input, but we'll just check it's stored.
36 # Doesn't match the input, but we'll just check it's stored.
37 ip.history_manager.output_hist_reprs[3] = "spam"
37 ip.history_manager.output_hist_reprs[3] = "spam"
38 ip.history_manager.store_output(3)
38 ip.history_manager.store_output(3)
39
39
40 nt.assert_equal(ip.history_manager.input_hist_raw, [''] + hist)
40 nt.assert_equal(ip.history_manager.input_hist_raw, [''] + hist)
41
41
42 # Check whether specifying a range beyond the end of the current
42 # Check whether specifying a range beyond the end of the current
43 # session results in an error (gh-804)
43 # session results in an error (gh-804)
44 ip.magic('%hist 2-500')
44 ip.magic('%hist 2-500')
45
45
46 # New session
46 # New session
47 ip.history_manager.reset()
47 ip.history_manager.reset()
48 newcmds = ["z=5","class X(object):\n pass", "k='p'"]
48 newcmds = ["z=5","class X(object):\n pass", "k='p'"]
@@ -53,7 +53,7 b' def test_history():'
53 # Previous session:
53 # Previous session:
54 gothist = ip.history_manager.get_range(-1, 1, 4)
54 gothist = ip.history_manager.get_range(-1, 1, 4)
55 nt.assert_equal(list(gothist), zip([1,1,1],[1,2,3], hist))
55 nt.assert_equal(list(gothist), zip([1,1,1],[1,2,3], hist))
56
56
57 # Check get_hist_tail
57 # Check get_hist_tail
58 gothist = ip.history_manager.get_tail(4, output=True,
58 gothist = ip.history_manager.get_tail(4, output=True,
59 include_latest=True)
59 include_latest=True)
@@ -62,25 +62,25 b' def test_history():'
62 (2, 2, (newcmds[1], None)),
62 (2, 2, (newcmds[1], None)),
63 (2, 3, (newcmds[2], None)),]
63 (2, 3, (newcmds[2], None)),]
64 nt.assert_equal(list(gothist), expected)
64 nt.assert_equal(list(gothist), expected)
65
65
66 gothist = ip.history_manager.get_tail(2)
66 gothist = ip.history_manager.get_tail(2)
67 expected = [(2, 1, newcmds[0]),
67 expected = [(2, 1, newcmds[0]),
68 (2, 2, newcmds[1])]
68 (2, 2, newcmds[1])]
69 nt.assert_equal(list(gothist), expected)
69 nt.assert_equal(list(gothist), expected)
70
70
71 # Check get_hist_search
71 # Check get_hist_search
72 gothist = ip.history_manager.search("*test*")
72 gothist = ip.history_manager.search("*test*")
73 nt.assert_equal(list(gothist), [(1,2,hist[1])] )
73 nt.assert_equal(list(gothist), [(1,2,hist[1])] )
74 gothist = ip.history_manager.search("b*", output=True)
74 gothist = ip.history_manager.search("b*", output=True)
75 nt.assert_equal(list(gothist), [(1,3,(hist[2],"spam"))] )
75 nt.assert_equal(list(gothist), [(1,3,(hist[2],"spam"))] )
76
76
77 # Cross testing: check that magic %save can get previous session.
77 # Cross testing: check that magic %save can get previous session.
78 testfilename = os.path.realpath(os.path.join(tmpdir, "test.py"))
78 testfilename = os.path.realpath(os.path.join(tmpdir, "test.py"))
79 ip.magic_save(testfilename + " ~1/1-3")
79 ip.magic_save(testfilename + " ~1/1-3")
80 testfile = open(testfilename, "r")
80 testfile = open(testfilename, "r")
81 nt.assert_equal(testfile.read().decode("utf-8"),
81 nt.assert_equal(testfile.read().decode("utf-8"),
82 "# coding: utf-8\n" + "\n".join(hist))
82 "# coding: utf-8\n" + "\n".join(hist))
83
83
84 # Duplicate line numbers - check that it doesn't crash, and
84 # Duplicate line numbers - check that it doesn't crash, and
85 # gets a new session
85 # gets a new session
86 ip.history_manager.store_inputs(1, "rogue")
86 ip.history_manager.store_inputs(1, "rogue")
@@ -102,7 +102,7 b' def test_extract_hist_ranges():'
102 (-7, 1, 6)]
102 (-7, 1, 6)]
103 actual = list(extract_hist_ranges(instr))
103 actual = list(extract_hist_ranges(instr))
104 nt.assert_equal(actual, expected)
104 nt.assert_equal(actual, expected)
105
105
106 def test_magic_rerun():
106 def test_magic_rerun():
107 """Simple test for %rerun (no args -> rerun last line)"""
107 """Simple test for %rerun (no args -> rerun last line)"""
108 ip = get_ipython()
108 ip = get_ipython()
@@ -41,7 +41,7 b' def mini_interactive_loop(input_func):'
41 raw_input that simulates interactive input."""
41 raw_input that simulates interactive input."""
42
42
43 from IPython.core.inputsplitter import InputSplitter
43 from IPython.core.inputsplitter import InputSplitter
44
44
45 isp = InputSplitter()
45 isp = InputSplitter()
46 # In practice, this input loop would be wrapped in an outside loop to read
46 # In practice, this input loop would be wrapped in an outside loop to read
47 # input indefinitely, until some exit/quit command was issued. Here we
47 # input indefinitely, until some exit/quit command was issued. Here we
@@ -106,7 +106,7 b' def test_remove_comments():'
106 'line \nline\nline\nline \n\n'),
106 'line \nline\nline\nline \n\n'),
107 ]
107 ]
108 tt.check_pairs(isp.remove_comments, tests)
108 tt.check_pairs(isp.remove_comments, tests)
109
109
110 def test_has_comment():
110 def test_has_comment():
111 tests = [('text', False),
111 tests = [('text', False),
112 ('text #comment', True),
112 ('text #comment', True),
@@ -134,13 +134,13 b' class NoInputEncodingTestCase(unittest.TestCase):'
134 class X: pass
134 class X: pass
135 fake_stdin = X()
135 fake_stdin = X()
136 sys.stdin = fake_stdin
136 sys.stdin = fake_stdin
137
137
138 def test(self):
138 def test(self):
139 # Verify that if sys.stdin has no 'encoding' attribute we do the right
139 # Verify that if sys.stdin has no 'encoding' attribute we do the right
140 # thing
140 # thing
141 enc = isp.get_input_encoding()
141 enc = isp.get_input_encoding()
142 self.assertEqual(enc, 'ascii')
142 self.assertEqual(enc, 'ascii')
143
143
144 def tearDown(self):
144 def tearDown(self):
145 sys.stdin = self.old_stdin
145 sys.stdin = self.old_stdin
146
146
@@ -167,7 +167,7 b' class InputSplitterTestCase(unittest.TestCase):'
167 self.assertEqual(self.isp.source_reset(), '1\n2\n')
167 self.assertEqual(self.isp.source_reset(), '1\n2\n')
168 self.assertEqual(self.isp._buffer, [])
168 self.assertEqual(self.isp._buffer, [])
169 self.assertEqual(self.isp.source, '')
169 self.assertEqual(self.isp.source, '')
170
170
171 def test_indent(self):
171 def test_indent(self):
172 isp = self.isp # shorthand
172 isp = self.isp # shorthand
173 isp.push('x=1')
173 isp.push('x=1')
@@ -200,7 +200,7 b' class InputSplitterTestCase(unittest.TestCase):'
200 isp.push("if 1:")
200 isp.push("if 1:")
201 isp.push(" x = (1+\n 2)")
201 isp.push(" x = (1+\n 2)")
202 self.assertEqual(isp.indent_spaces, 4)
202 self.assertEqual(isp.indent_spaces, 4)
203
203
204 def test_indent4(self):
204 def test_indent4(self):
205 # In cell mode, inputs must be fed in whole blocks, so skip this test
205 # In cell mode, inputs must be fed in whole blocks, so skip this test
206 if self.isp.input_mode == 'cell': return
206 if self.isp.input_mode == 'cell': return
@@ -261,13 +261,13 b' class InputSplitterTestCase(unittest.TestCase):'
261 self.assertFalse(isp.push('if 1:'))
261 self.assertFalse(isp.push('if 1:'))
262 for line in [' x=1', '# a comment', ' y=2']:
262 for line in [' x=1', '# a comment', ' y=2']:
263 self.assertTrue(isp.push(line))
263 self.assertTrue(isp.push(line))
264
264
265 def test_push3(self):
265 def test_push3(self):
266 isp = self.isp
266 isp = self.isp
267 isp.push('if True:')
267 isp.push('if True:')
268 isp.push(' a = 1')
268 isp.push(' a = 1')
269 self.assertFalse(isp.push('b = [1,'))
269 self.assertFalse(isp.push('b = [1,'))
270
270
271 def test_replace_mode(self):
271 def test_replace_mode(self):
272 isp = self.isp
272 isp = self.isp
273 isp.input_mode = 'cell'
273 isp.input_mode = 'cell'
@@ -292,7 +292,7 b' class InputSplitterTestCase(unittest.TestCase):'
292 self.assertTrue(isp.push_accepts_more())
292 self.assertTrue(isp.push_accepts_more())
293 isp.push('')
293 isp.push('')
294 self.assertFalse(isp.push_accepts_more())
294 self.assertFalse(isp.push_accepts_more())
295
295
296 def test_push_accepts_more3(self):
296 def test_push_accepts_more3(self):
297 isp = self.isp
297 isp = self.isp
298 isp.push("x = (2+\n3)")
298 isp.push("x = (2+\n3)")
@@ -318,7 +318,7 b' class InputSplitterTestCase(unittest.TestCase):'
318 self.assertTrue(isp.push_accepts_more())
318 self.assertTrue(isp.push_accepts_more())
319 isp.push('')
319 isp.push('')
320 self.assertFalse(isp.push_accepts_more())
320 self.assertFalse(isp.push_accepts_more())
321
321
322 def test_push_accepts_more5(self):
322 def test_push_accepts_more5(self):
323 # In cell mode, inputs must be fed in whole blocks, so skip this test
323 # In cell mode, inputs must be fed in whole blocks, so skip this test
324 if self.isp.input_mode == 'cell': return
324 if self.isp.input_mode == 'cell': return
@@ -368,7 +368,7 b' class InteractiveLoopTestCase(unittest.TestCase):'
368 # we can check that the given dict is *contained* in test_ns
368 # we can check that the given dict is *contained* in test_ns
369 for k,v in ns.iteritems():
369 for k,v in ns.iteritems():
370 self.assertEqual(test_ns[k], v)
370 self.assertEqual(test_ns[k], v)
371
371
372 def test_simple(self):
372 def test_simple(self):
373 self.check_ns(['x=1'], dict(x=1))
373 self.check_ns(['x=1'], dict(x=1))
374
374
@@ -380,10 +380,10 b' class InteractiveLoopTestCase(unittest.TestCase):'
380
380
381 def test_abc(self):
381 def test_abc(self):
382 self.check_ns(['if 1:','a=1','b=2','c=3'], dict(a=1, b=2, c=3))
382 self.check_ns(['if 1:','a=1','b=2','c=3'], dict(a=1, b=2, c=3))
383
383
384 def test_multi(self):
384 def test_multi(self):
385 self.check_ns(['x =(1+','1+','2)'], dict(x=4))
385 self.check_ns(['x =(1+','1+','2)'], dict(x=4))
386
386
387
387
388 def test_LineInfo():
388 def test_LineInfo():
389 """Simple test for LineInfo construction and str()"""
389 """Simple test for LineInfo construction and str()"""
@@ -453,7 +453,7 b' syntax = \\'
453 ('?%hist', 'get_ipython().magic(u"pinfo %hist")'),
453 ('?%hist', 'get_ipython().magic(u"pinfo %hist")'),
454 ('?abc = qwe', 'get_ipython().magic(u"pinfo abc")'),
454 ('?abc = qwe', 'get_ipython().magic(u"pinfo abc")'),
455 ],
455 ],
456
456
457 end_help =
457 end_help =
458 [ ('x3?', 'get_ipython().magic(u"pinfo x3")'),
458 [ ('x3?', 'get_ipython().magic(u"pinfo x3")'),
459 ('x4??', 'get_ipython().magic(u"pinfo2 x4")'),
459 ('x4??', 'get_ipython().magic(u"pinfo2 x4")'),
@@ -473,7 +473,7 b' syntax = \\'
473 ('%cd /home', 'get_ipython().magic(u"cd /home")'),
473 ('%cd /home', 'get_ipython().magic(u"cd /home")'),
474 (' %magic', ' get_ipython().magic(u"magic")'),
474 (' %magic', ' get_ipython().magic(u"magic")'),
475 ],
475 ],
476
476
477 # Quoting with separate arguments
477 # Quoting with separate arguments
478 escaped_quote =
478 escaped_quote =
479 [ (',f', 'f("")'),
479 [ (',f', 'f("")'),
@@ -481,23 +481,23 b' syntax = \\'
481 (' ,f y', ' f("y")'),
481 (' ,f y', ' f("y")'),
482 (',f a b', 'f("a", "b")'),
482 (',f a b', 'f("a", "b")'),
483 ],
483 ],
484
484
485 # Quoting with single argument
485 # Quoting with single argument
486 escaped_quote2 =
486 escaped_quote2 =
487 [ (';f', 'f("")'),
487 [ (';f', 'f("")'),
488 (';f x', 'f("x")'),
488 (';f x', 'f("x")'),
489 (' ;f y', ' f("y")'),
489 (' ;f y', ' f("y")'),
490 (';f a b', 'f("a b")'),
490 (';f a b', 'f("a b")'),
491 ],
491 ],
492
492
493 # Simply apply parens
493 # Simply apply parens
494 escaped_paren =
494 escaped_paren =
495 [ ('/f', 'f()'),
495 [ ('/f', 'f()'),
496 ('/f x', 'f(x)'),
496 ('/f x', 'f(x)'),
497 (' /f y', ' f(y)'),
497 (' /f y', ' f(y)'),
498 ('/f a b', 'f(a, b)'),
498 ('/f a b', 'f(a, b)'),
499 ],
499 ],
500
500
501 # Check that we transform prompts before other transforms
501 # Check that we transform prompts before other transforms
502 mixed =
502 mixed =
503 [ ('In [1]: %lsmagic', 'get_ipython().magic(u"lsmagic")'),
503 [ ('In [1]: %lsmagic', 'get_ipython().magic(u"lsmagic")'),
@@ -532,7 +532,7 b' syntax_ml = \\'
532 def test_assign_system():
532 def test_assign_system():
533 tt.check_pairs(isp.transform_assign_system, syntax['assign_system'])
533 tt.check_pairs(isp.transform_assign_system, syntax['assign_system'])
534
534
535
535
536 def test_assign_magic():
536 def test_assign_magic():
537 tt.check_pairs(isp.transform_assign_magic, syntax['assign_magic'])
537 tt.check_pairs(isp.transform_assign_magic, syntax['assign_magic'])
538
538
@@ -541,7 +541,7 b' def test_classic_prompt():'
541 transform_checker(syntax['classic_prompt'], isp.transform_classic_prompt)
541 transform_checker(syntax['classic_prompt'], isp.transform_classic_prompt)
542 for example in syntax_ml['classic_prompt']:
542 for example in syntax_ml['classic_prompt']:
543 transform_checker(example, isp.transform_classic_prompt)
543 transform_checker(example, isp.transform_classic_prompt)
544
544
545
545
546 def test_ipy_prompt():
546 def test_ipy_prompt():
547 transform_checker(syntax['ipy_prompt'], isp.transform_ipy_prompt)
547 transform_checker(syntax['ipy_prompt'], isp.transform_ipy_prompt)
@@ -599,7 +599,7 b' class IPythonInputTestCase(InputSplitterTestCase):'
599 for raw, out_t in example:
599 for raw, out_t in example:
600 if raw.startswith(' '):
600 if raw.startswith(' '):
601 continue
601 continue
602
602
603 isp.push(raw)
603 isp.push(raw)
604 out, out_raw = isp.source_raw_reset()
604 out, out_raw = isp.source_raw_reset()
605 self.assertEqual(out.rstrip(), out_t,
605 self.assertEqual(out.rstrip(), out_t,
@@ -622,13 +622,13 b' class IPythonInputTestCase(InputSplitterTestCase):'
622 raw = '\n'.join(raw_parts).rstrip()
622 raw = '\n'.join(raw_parts).rstrip()
623 self.assertEqual(out.rstrip(), out_t)
623 self.assertEqual(out.rstrip(), out_t)
624 self.assertEqual(out_raw.rstrip(), raw)
624 self.assertEqual(out_raw.rstrip(), raw)
625
625
626
626
627 class BlockIPythonInputTestCase(IPythonInputTestCase):
627 class BlockIPythonInputTestCase(IPythonInputTestCase):
628
628
629 # Deactivate tests that don't make sense for the block mode
629 # Deactivate tests that don't make sense for the block mode
630 test_push3 = test_split = lambda s: None
630 test_push3 = test_split = lambda s: None
631
631
632 def setUp(self):
632 def setUp(self):
633 self.isp = isp.IPythonInputSplitter(input_mode='cell')
633 self.isp = isp.IPythonInputSplitter(input_mode='cell')
634
634
@@ -650,7 +650,7 b' class BlockIPythonInputTestCase(IPythonInputTestCase):'
650 # Match ignoring trailing whitespace
650 # Match ignoring trailing whitespace
651 self.assertEqual(out.rstrip(), out_t.rstrip())
651 self.assertEqual(out.rstrip(), out_t.rstrip())
652 self.assertEqual(out_raw.rstrip(), raw.rstrip())
652 self.assertEqual(out_raw.rstrip(), raw.rstrip())
653
653
654
654
655 #-----------------------------------------------------------------------------
655 #-----------------------------------------------------------------------------
656 # Main - use as a script, mostly for developer experiments
656 # Main - use as a script, mostly for developer experiments
@@ -667,7 +667,7 b" if __name__ == '__main__':"
667
667
668 autoindent = True
668 autoindent = True
669 #autoindent = False
669 #autoindent = False
670
670
671 try:
671 try:
672 while True:
672 while True:
673 prompt = start_prompt
673 prompt = start_prompt
@@ -45,7 +45,7 b' class Call(object):'
45
45
46 def method(self, x, z=2):
46 def method(self, x, z=2):
47 """Some method's docstring"""
47 """Some method's docstring"""
48
48
49 class OldStyle:
49 class OldStyle:
50 """An old-style class for testing."""
50 """An old-style class for testing."""
51 pass
51 pass
@@ -62,7 +62,7 b' def check_calltip(obj, name, call, docstring):'
62 info = inspector.info(obj, name)
62 info = inspector.info(obj, name)
63 call_line, ds = oinspect.call_tip(info)
63 call_line, ds = oinspect.call_tip(info)
64 nt.assert_equal(call_line, call)
64 nt.assert_equal(call_line, call)
65 nt.assert_equal(ds, docstring)
65 nt.assert_equal(ds, docstring)
66
66
67 #-----------------------------------------------------------------------------
67 #-----------------------------------------------------------------------------
68 # Tests
68 # Tests
@@ -92,7 +92,7 b' def test_calltip_function2():'
92
92
93 def test_calltip_builtin():
93 def test_calltip_builtin():
94 check_calltip(sum, 'sum', None, sum.__doc__)
94 check_calltip(sum, 'sum', None, sum.__doc__)
95
95
96 def test_info():
96 def test_info():
97 "Check that Inspector.info fills out various fields as expected."
97 "Check that Inspector.info fills out various fields as expected."
98 i = inspector.info(Call, oname='Call')
98 i = inspector.info(Call, oname='Call')
@@ -112,11 +112,11 b' def test_info():'
112 nt.assert_true(i['isclass'])
112 nt.assert_true(i['isclass'])
113 nt.assert_equal(i['init_definition'], "Call(self, x, y=1)\n")
113 nt.assert_equal(i['init_definition'], "Call(self, x, y=1)\n")
114 nt.assert_equal(i['init_docstring'], Call.__init__.__doc__)
114 nt.assert_equal(i['init_docstring'], Call.__init__.__doc__)
115
115
116 i = inspector.info(Call, detail_level=1)
116 i = inspector.info(Call, detail_level=1)
117 nt.assert_not_equal(i['source'], None)
117 nt.assert_not_equal(i['source'], None)
118 nt.assert_equal(i['docstring'], None)
118 nt.assert_equal(i['docstring'], None)
119
119
120 c = Call(1)
120 c = Call(1)
121 c.__doc__ = "Modified instance docstring"
121 c.__doc__ = "Modified instance docstring"
122 i = inspector.info(c)
122 i = inspector.info(c)
@@ -125,12 +125,12 b' def test_info():'
125 nt.assert_equal(i['class_docstring'], Call.__doc__)
125 nt.assert_equal(i['class_docstring'], Call.__doc__)
126 nt.assert_equal(i['init_docstring'], Call.__init__.__doc__)
126 nt.assert_equal(i['init_docstring'], Call.__init__.__doc__)
127 nt.assert_equal(i['call_docstring'], c.__call__.__doc__)
127 nt.assert_equal(i['call_docstring'], c.__call__.__doc__)
128
128
129 # Test old-style classes, which for example may not have an __init__ method.
129 # Test old-style classes, which for example may not have an __init__ method.
130 if not py3compat.PY3:
130 if not py3compat.PY3:
131 i = inspector.info(OldStyle)
131 i = inspector.info(OldStyle)
132 nt.assert_equal(i['type_name'], 'classobj')
132 nt.assert_equal(i['type_name'], 'classobj')
133
133
134 i = inspector.info(OldStyle())
134 i = inspector.info(OldStyle())
135 nt.assert_equal(i['type_name'], 'instance')
135 nt.assert_equal(i['type_name'], 'instance')
136 nt.assert_equal(i['docstring'], OldStyle.__doc__)
136 nt.assert_equal(i['docstring'], OldStyle.__doc__)
@@ -32,7 +32,7 b' def doctest_refbug():'
32
32
33 In [1]: _ip.clear_main_mod_cache()
33 In [1]: _ip.clear_main_mod_cache()
34 # random
34 # random
35
35
36 In [2]: %run refbug
36 In [2]: %run refbug
37
37
38 In [3]: call_f()
38 In [3]: call_f()
@@ -81,7 +81,7 b' def doctest_run_builtins():'
81 ....: os.unlink(fname)
81 ....: os.unlink(fname)
82 ....: except:
82 ....: except:
83 ....: pass
83 ....: pass
84 ....:
84 ....:
85 """
85 """
86
86
87 def doctest_reset_del():
87 def doctest_reset_del():
@@ -90,7 +90,7 b' def doctest_reset_del():'
90 In [2]: class A(object):
90 In [2]: class A(object):
91 ...: def __del__(self):
91 ...: def __del__(self):
92 ...: print str("Hi")
92 ...: print str("Hi")
93 ...:
93 ...:
94
94
95 In [3]: a = A()
95 In [3]: a = A()
96
96
@@ -127,7 +127,7 b' class TestMagicRunPass(tt.TempFileMixin):'
127
127
128 def test_builtins_type(self):
128 def test_builtins_type(self):
129 """Check that the type of __builtins__ doesn't change with %run.
129 """Check that the type of __builtins__ doesn't change with %run.
130
130
131 However, the above could pass if __builtins__ was already modified to
131 However, the above could pass if __builtins__ was already modified to
132 be a dict (it should be a module) by a previous use of %run. So we
132 be a dict (it should be a module) by a previous use of %run. So we
133 also check explicitly that it really is a module:
133 also check explicitly that it really is a module:
@@ -168,8 +168,8 b' class TestMagicRunSimple(tt.TempFileMixin):'
168 "a = A()\n")
168 "a = A()\n")
169 self.mktmp(src)
169 self.mktmp(src)
170 tt.ipexec_validate(self.fname, 'object A deleted')
170 tt.ipexec_validate(self.fname, 'object A deleted')
171
171
172 @dec.skip_known_failure
172 @dec.skip_known_failure
173 def test_aggressive_namespace_cleanup(self):
173 def test_aggressive_namespace_cleanup(self):
174 """Test that namespace cleanup is not too aggressive GH-238
174 """Test that namespace cleanup is not too aggressive GH-238
175
175
@@ -12,7 +12,7 b' Installation instructions for ColorTB:'
12 import sys,ultratb
12 import sys,ultratb
13 sys.excepthook = ultratb.ColorTB()
13 sys.excepthook = ultratb.ColorTB()
14
14
15 * VerboseTB
15 * VerboseTB
16 I've also included a port of Ka-Ping Yee's "cgitb.py" that produces all kinds
16 I've also included a port of Ka-Ping Yee's "cgitb.py" that produces all kinds
17 of useful info when a traceback occurs. Ping originally had it spit out HTML
17 of useful info when a traceback occurs. Ping originally had it spit out HTML
18 and intended it for CGI programmers, but why should they have all the fun? I
18 and intended it for CGI programmers, but why should they have all the fun? I
@@ -34,7 +34,7 b' Note:'
34 Verbose_novars mode instead of the regular Verbose, which avoids formatting
34 Verbose_novars mode instead of the regular Verbose, which avoids formatting
35 variables (but otherwise includes the information and context given by
35 variables (but otherwise includes the information and context given by
36 Verbose).
36 Verbose).
37
37
38
38
39 Installation instructions for ColorTB:
39 Installation instructions for ColorTB:
40 import sys,ultratb
40 import sys,ultratb
@@ -121,7 +121,7 b' def inspect_error():'
121 """Print a message about internal inspect errors.
121 """Print a message about internal inspect errors.
122
122
123 These are unfortunately quite common."""
123 These are unfortunately quite common."""
124
124
125 error('Internal Python error in the inspect module.\n'
125 error('Internal Python error in the inspect module.\n'
126 'Below is the traceback from this internal error.\n')
126 'Below is the traceback from this internal error.\n')
127
127
@@ -197,7 +197,7 b' def findsource(object):'
197 while lnum > 0:
197 while lnum > 0:
198 if pmatch(lines[lnum]): break
198 if pmatch(lines[lnum]): break
199 lnum -= 1
199 lnum -= 1
200
200
201 return lines, lnum
201 return lines, lnum
202 raise IOError('could not find code object')
202 raise IOError('could not find code object')
203
203
@@ -262,7 +262,7 b' def _fixed_getinnerframes(etb, context=1,tb_offset=0):'
262 # (SyntaxErrors have to be treated specially because they have no traceback)
262 # (SyntaxErrors have to be treated specially because they have no traceback)
263
263
264 _parser = PyColorize.Parser()
264 _parser = PyColorize.Parser()
265
265
266 def _format_traceback_lines(lnum, index, lines, Colors, lvals=None,scheme=None):
266 def _format_traceback_lines(lnum, index, lines, Colors, lvals=None,scheme=None):
267 numbers_width = INDENT_SIZE - 1
267 numbers_width = INDENT_SIZE - 1
268 res = []
268 res = []
@@ -285,10 +285,10 b' def _format_traceback_lines(lnum, index, lines, Colors, lvals=None,scheme=None):'
285 # is unicode-safe. So for now this is rather an ugly hack, but
285 # is unicode-safe. So for now this is rather an ugly hack, but
286 # necessary to at least have readable tracebacks. Improvements welcome!
286 # necessary to at least have readable tracebacks. Improvements welcome!
287 line = py3compat.cast_bytes_py2(line, 'utf-8')
287 line = py3compat.cast_bytes_py2(line, 'utf-8')
288
288
289 new_line, err = _line_format(line, 'str', scheme)
289 new_line, err = _line_format(line, 'str', scheme)
290 if not err: line = new_line
290 if not err: line = new_line
291
291
292 if i == lnum:
292 if i == lnum:
293 # This is the line with the error
293 # This is the line with the error
294 pad = numbers_width - len(str(i))
294 pad = numbers_width - len(str(i))
@@ -301,11 +301,11 b' def _format_traceback_lines(lnum, index, lines, Colors, lvals=None,scheme=None):'
301 else:
301 else:
302 marker = ''
302 marker = ''
303 num = marker + str(i)
303 num = marker + str(i)
304 line = '%s%s%s %s%s' %(Colors.linenoEm, num,
304 line = '%s%s%s %s%s' %(Colors.linenoEm, num,
305 Colors.line, line, Colors.Normal)
305 Colors.line, line, Colors.Normal)
306 else:
306 else:
307 num = '%*s' % (numbers_width,i)
307 num = '%*s' % (numbers_width,i)
308 line = '%s%s%s %s' %(Colors.lineno, num,
308 line = '%s%s%s %s' %(Colors.lineno, num,
309 Colors.Normal, line)
309 Colors.Normal, line)
310
310
311 res.append(line)
311 res.append(line)
@@ -352,7 +352,7 b' class TBTools(object):'
352 """Output stream that exceptions are written to.
352 """Output stream that exceptions are written to.
353
353
354 Valid values are:
354 Valid values are:
355
355
356 - None: the default, which means that IPython will dynamically resolve
356 - None: the default, which means that IPython will dynamically resolve
357 to io.stdout. This ensures compatibility with most tools, including
357 to io.stdout. This ensures compatibility with most tools, including
358 Windows (where plain stdout doesn't recognize ANSI escapes).
358 Windows (where plain stdout doesn't recognize ANSI escapes).
@@ -364,7 +364,7 b' class TBTools(object):'
364 def _set_ostream(self, val):
364 def _set_ostream(self, val):
365 assert val is None or (hasattr(val, 'write') and hasattr(val, 'flush'))
365 assert val is None or (hasattr(val, 'write') and hasattr(val, 'flush'))
366 self._ostream = val
366 self._ostream = val
367
367
368 ostream = property(_get_ostream, _set_ostream)
368 ostream = property(_get_ostream, _set_ostream)
369
369
370 def set_colors(self,*args,**kw):
370 def set_colors(self,*args,**kw):
@@ -380,7 +380,7 b' class TBTools(object):'
380
380
381 def color_toggle(self):
381 def color_toggle(self):
382 """Toggle between the currently active color scheme and NoColor."""
382 """Toggle between the currently active color scheme and NoColor."""
383
383
384 if self.color_scheme_table.active_scheme_name == 'NoColor':
384 if self.color_scheme_table.active_scheme_name == 'NoColor':
385 self.color_scheme_table.set_active_scheme(self.old_scheme)
385 self.color_scheme_table.set_active_scheme(self.old_scheme)
386 self.Colors = self.color_scheme_table.active_colors
386 self.Colors = self.color_scheme_table.active_colors
@@ -414,7 +414,7 b' class TBTools(object):'
414 #---------------------------------------------------------------------------
414 #---------------------------------------------------------------------------
415 class ListTB(TBTools):
415 class ListTB(TBTools):
416 """Print traceback information from a traceback list, with optional color.
416 """Print traceback information from a traceback list, with optional color.
417
417
418 Calling: requires 3 arguments:
418 Calling: requires 3 arguments:
419 (etype, evalue, elist)
419 (etype, evalue, elist)
420 as would be obtained by:
420 as would be obtained by:
@@ -434,7 +434,7 b' class ListTB(TBTools):'
434 def __init__(self,color_scheme = 'NoColor', call_pdb=False, ostream=None):
434 def __init__(self,color_scheme = 'NoColor', call_pdb=False, ostream=None):
435 TBTools.__init__(self, color_scheme=color_scheme, call_pdb=call_pdb,
435 TBTools.__init__(self, color_scheme=color_scheme, call_pdb=call_pdb,
436 ostream=ostream)
436 ostream=ostream)
437
437
438 def __call__(self, etype, value, elist):
438 def __call__(self, etype, value, elist):
439 self.ostream.flush()
439 self.ostream.flush()
440 self.ostream.write(self.text(etype, value, elist))
440 self.ostream.write(self.text(etype, value, elist))
@@ -458,7 +458,7 b' class ListTB(TBTools):'
458 tb_offset : int, optional
458 tb_offset : int, optional
459 Number of frames in the traceback to skip. If not given, the
459 Number of frames in the traceback to skip. If not given, the
460 instance value is used (set in constructor).
460 instance value is used (set in constructor).
461
461
462 context : int, optional
462 context : int, optional
463 Number of lines of context information to print.
463 Number of lines of context information to print.
464
464
@@ -473,7 +473,7 b' class ListTB(TBTools):'
473
473
474 if tb_offset and len(elist) > tb_offset:
474 if tb_offset and len(elist) > tb_offset:
475 elist = elist[tb_offset:]
475 elist = elist[tb_offset:]
476
476
477 out_list.append('Traceback %s(most recent call last)%s:' %
477 out_list.append('Traceback %s(most recent call last)%s:' %
478 (Colors.normalEm, Colors.Normal) + '\n')
478 (Colors.normalEm, Colors.Normal) + '\n')
479 out_list.extend(self._format_list(elist))
479 out_list.extend(self._format_list(elist))
@@ -482,7 +482,7 b' class ListTB(TBTools):'
482 out_list.append(lines)
482 out_list.append(lines)
483
483
484 # Note: this code originally read:
484 # Note: this code originally read:
485
485
486 ## for line in lines[:-1]:
486 ## for line in lines[:-1]:
487 ## out_list.append(" "+line)
487 ## out_list.append(" "+line)
488 ## out_list.append(lines[-1])
488 ## out_list.append(lines[-1])
@@ -490,7 +490,7 b' class ListTB(TBTools):'
490 # This means it was indenting everything but the last line by a little
490 # This means it was indenting everything but the last line by a little
491 # bit. I've disabled this for now, but if we see ugliness somewhre we
491 # bit. I've disabled this for now, but if we see ugliness somewhre we
492 # can restore it.
492 # can restore it.
493
493
494 return out_list
494 return out_list
495
495
496 def _format_list(self, extracted_list):
496 def _format_list(self, extracted_list):
@@ -502,7 +502,7 b' class ListTB(TBTools):'
502 same index in the argument list. Each string ends in a newline;
502 same index in the argument list. Each string ends in a newline;
503 the strings may contain internal newlines as well, for those items
503 the strings may contain internal newlines as well, for those items
504 whose source text line is not None.
504 whose source text line is not None.
505
505
506 Lifted almost verbatim from traceback.py
506 Lifted almost verbatim from traceback.py
507 """
507 """
508
508
@@ -510,7 +510,7 b' class ListTB(TBTools):'
510 list = []
510 list = []
511 for filename, lineno, name, line in extracted_list[:-1]:
511 for filename, lineno, name, line in extracted_list[:-1]:
512 item = ' File %s"%s"%s, line %s%d%s, in %s%s%s\n' % \
512 item = ' File %s"%s"%s, line %s%d%s, in %s%s%s\n' % \
513 (Colors.filename, filename, Colors.Normal,
513 (Colors.filename, filename, Colors.Normal,
514 Colors.lineno, lineno, Colors.Normal,
514 Colors.lineno, lineno, Colors.Normal,
515 Colors.name, name, Colors.Normal)
515 Colors.name, name, Colors.Normal)
516 if line:
516 if line:
@@ -530,7 +530,7 b' class ListTB(TBTools):'
530 list.append(item)
530 list.append(item)
531 #from pprint import pformat; print 'LISTTB', pformat(list) # dbg
531 #from pprint import pformat; print 'LISTTB', pformat(list) # dbg
532 return list
532 return list
533
533
534 def _format_exception_only(self, etype, value):
534 def _format_exception_only(self, etype, value):
535 """Format the exception part of a traceback.
535 """Format the exception part of a traceback.
536
536
@@ -541,7 +541,7 b' class ListTB(TBTools):'
541 printed) display detailed information about where the syntax error
541 printed) display detailed information about where the syntax error
542 occurred. The message indicating which exception occurred is the
542 occurred. The message indicating which exception occurred is the
543 always last string in the list.
543 always last string in the list.
544
544
545 Also lifted nearly verbatim from traceback.py
545 Also lifted nearly verbatim from traceback.py
546 """
546 """
547
547
@@ -573,7 +573,7 b' class ListTB(TBTools):'
573 while i < len(line) and line[i].isspace():
573 while i < len(line) and line[i].isspace():
574 i = i+1
574 i = i+1
575 list.append('%s %s%s\n' % (Colors.line,
575 list.append('%s %s%s\n' % (Colors.line,
576 line.strip(),
576 line.strip(),
577 Colors.Normal))
577 Colors.Normal))
578 if offset is not None:
578 if offset is not None:
579 s = ' '
579 s = ' '
@@ -602,7 +602,7 b' class ListTB(TBTools):'
602
602
603 def get_exception_only(self, etype, value):
603 def get_exception_only(self, etype, value):
604 """Only print the exception type and message, without a traceback.
604 """Only print the exception type and message, without a traceback.
605
605
606 Parameters
606 Parameters
607 ----------
607 ----------
608 etype : exception type
608 etype : exception type
@@ -613,7 +613,7 b' class ListTB(TBTools):'
613
613
614 def show_exception_only(self, etype, evalue):
614 def show_exception_only(self, etype, evalue):
615 """Only print the exception type and message, without a traceback.
615 """Only print the exception type and message, without a traceback.
616
616
617 Parameters
617 Parameters
618 ----------
618 ----------
619 etype : exception type
619 etype : exception type
@@ -725,7 +725,7 b' class VerboseTB(TBTools):'
725 # Header with the exception type, python version, and date
725 # Header with the exception type, python version, and date
726 pyver = 'Python ' + sys.version.split()[0] + ': ' + sys.executable
726 pyver = 'Python ' + sys.version.split()[0] + ': ' + sys.executable
727 date = time.ctime(time.time())
727 date = time.ctime(time.time())
728
728
729 head = '%s%s%s\n%s%s%s\n%s' % (Colors.topline, '-'*75, ColorsNormal,
729 head = '%s%s%s\n%s%s%s\n%s' % (Colors.topline, '-'*75, ColorsNormal,
730 exc, ' '*(75-len(str(etype))-len(pyver)),
730 exc, ' '*(75-len(str(etype))-len(pyver)),
731 pyver, date.rjust(75) )
731 pyver, date.rjust(75) )
@@ -797,7 +797,7 b' class VerboseTB(TBTools):'
797 inspect_error()
797 inspect_error()
798 traceback.print_exc(file=self.ostream)
798 traceback.print_exc(file=self.ostream)
799 info("\nIPython's exception reporting continues...\n")
799 info("\nIPython's exception reporting continues...\n")
800
800
801 if func == '?':
801 if func == '?':
802 call = ''
802 call = ''
803 else:
803 else:
@@ -838,7 +838,7 b' class VerboseTB(TBTools):'
838 there is no way to disambguate partial dotted structures until
838 there is no way to disambguate partial dotted structures until
839 the full list is known. The caller is responsible for pruning
839 the full list is known. The caller is responsible for pruning
840 the final list of duplicates before using it."""
840 the final list of duplicates before using it."""
841
841
842 # build composite names
842 # build composite names
843 if token == '.':
843 if token == '.':
844 try:
844 try:
@@ -887,7 +887,7 b' class VerboseTB(TBTools):'
887 "The following traceback may be corrupted or invalid\n"
887 "The following traceback may be corrupted or invalid\n"
888 "The error message is: %s\n" % msg)
888 "The error message is: %s\n" % msg)
889 error(_m)
889 error(_m)
890
890
891 # prune names list of duplicates, but keep the right order
891 # prune names list of duplicates, but keep the right order
892 unique_names = uniq_stable(names)
892 unique_names = uniq_stable(names)
893
893
@@ -965,11 +965,11 b' class VerboseTB(TBTools):'
965 if ipinst is not None:
965 if ipinst is not None:
966 ipinst.hooks.synchronize_with_editor(filepath, lnum, 0)
966 ipinst.hooks.synchronize_with_editor(filepath, lnum, 0)
967 # vds: <<
967 # vds: <<
968
968
969 # return all our info assembled as a single string
969 # return all our info assembled as a single string
970 # return '%s\n\n%s\n%s' % (head,'\n'.join(frames),''.join(exception[0]) )
970 # return '%s\n\n%s\n%s' % (head,'\n'.join(frames),''.join(exception[0]) )
971 return [head] + frames + [''.join(exception[0])]
971 return [head] + frames + [''.join(exception[0])]
972
972
973 def debugger(self,force=False):
973 def debugger(self,force=False):
974 """Call up the pdb debugger if desired, always clean up the tb
974 """Call up the pdb debugger if desired, always clean up the tb
975 reference.
975 reference.
@@ -1048,9 +1048,9 b' class FormattedTB(VerboseTB, ListTB):'
1048 one needs to remove a number of topmost frames from the traceback (such as
1048 one needs to remove a number of topmost frames from the traceback (such as
1049 occurs with python programs that themselves execute other python code,
1049 occurs with python programs that themselves execute other python code,
1050 like Python shells). """
1050 like Python shells). """
1051
1051
1052 def __init__(self, mode='Plain', color_scheme='Linux', call_pdb=False,
1052 def __init__(self, mode='Plain', color_scheme='Linux', call_pdb=False,
1053 ostream=None,
1053 ostream=None,
1054 tb_offset=0, long_header=False, include_vars=False,
1054 tb_offset=0, long_header=False, include_vars=False,
1055 check_cache=None):
1055 check_cache=None):
1056
1056
@@ -1068,7 +1068,7 b' class FormattedTB(VerboseTB, ListTB):'
1068 self._join_chars = dict(Plain='', Context='\n', Verbose='\n')
1068 self._join_chars = dict(Plain='', Context='\n', Verbose='\n')
1069 # set_mode also sets the tb_join_char attribute
1069 # set_mode also sets the tb_join_char attribute
1070 self.set_mode(mode)
1070 self.set_mode(mode)
1071
1071
1072 def _extract_tb(self,tb):
1072 def _extract_tb(self,tb):
1073 if tb:
1073 if tb:
1074 return traceback.extract_tb(tb)
1074 return traceback.extract_tb(tb)
@@ -1096,7 +1096,7 b' class FormattedTB(VerboseTB, ListTB):'
1096 def stb2text(self, stb):
1096 def stb2text(self, stb):
1097 """Convert a structured traceback (a list) to a string."""
1097 """Convert a structured traceback (a list) to a string."""
1098 return self.tb_join_char.join(stb)
1098 return self.tb_join_char.join(stb)
1099
1099
1100
1100
1101 def set_mode(self,mode=None):
1101 def set_mode(self,mode=None):
1102 """Switch to the desired mode.
1102 """Switch to the desired mode.
@@ -1134,14 +1134,14 b' class AutoFormattedTB(FormattedTB):'
1134 It will find out about exceptions by itself.
1134 It will find out about exceptions by itself.
1135
1135
1136 A brief example:
1136 A brief example:
1137
1137
1138 AutoTB = AutoFormattedTB(mode = 'Verbose',color_scheme='Linux')
1138 AutoTB = AutoFormattedTB(mode = 'Verbose',color_scheme='Linux')
1139 try:
1139 try:
1140 ...
1140 ...
1141 except:
1141 except:
1142 AutoTB() # or AutoTB(out=logfile) where logfile is an open file object
1142 AutoTB() # or AutoTB(out=logfile) where logfile is an open file object
1143 """
1143 """
1144
1144
1145 def __call__(self,etype=None,evalue=None,etb=None,
1145 def __call__(self,etype=None,evalue=None,etb=None,
1146 out=None,tb_offset=None):
1146 out=None,tb_offset=None):
1147 """Print out a formatted exception traceback.
1147 """Print out a formatted exception traceback.
@@ -1153,7 +1153,7 b' class AutoFormattedTB(FormattedTB):'
1153 per-call basis (this overrides temporarily the instance's tb_offset
1153 per-call basis (this overrides temporarily the instance's tb_offset
1154 given at initialization time. """
1154 given at initialization time. """
1155
1155
1156
1156
1157 if out is None:
1157 if out is None:
1158 out = self.ostream
1158 out = self.ostream
1159 out.flush()
1159 out.flush()
@@ -1230,7 +1230,7 b' if __name__ == "__main__":'
1230 except:
1230 except:
1231 traceback.print_exc()
1231 traceback.print_exc()
1232 print ''
1232 print ''
1233
1233
1234 handler = ColorTB()
1234 handler = ColorTB()
1235 print '*** ColorTB ***'
1235 print '*** ColorTB ***'
1236 try:
1236 try:
@@ -1238,7 +1238,7 b' if __name__ == "__main__":'
1238 except:
1238 except:
1239 apply(handler, sys.exc_info() )
1239 apply(handler, sys.exc_info() )
1240 print ''
1240 print ''
1241
1241
1242 handler = VerboseTB()
1242 handler = VerboseTB()
1243 print '*** VerboseTB ***'
1243 print '*** VerboseTB ***'
1244 try:
1244 try:
@@ -1246,4 +1246,4 b' if __name__ == "__main__":'
1246 except:
1246 except:
1247 apply(handler, sys.exc_info() )
1247 apply(handler, sys.exc_info() )
1248 print ''
1248 print ''
1249
1249
@@ -36,7 +36,7 b' Usage'
36
36
37 Almost all configuration in IPython is available via the command-line. Do
37 Almost all configuration in IPython is available via the command-line. Do
38 `ipython --help-all` to see all available options. For persistent
38 `ipython --help-all` to see all available options. For persistent
39 configuration, look into your `ipython_config.py` configuration file for
39 configuration, look into your `ipython_config.py` configuration file for
40 details.
40 details.
41
41
42 This file is typically installed in the `IPYTHON_DIR` directory, and there
42 This file is typically installed in the `IPYTHON_DIR` directory, and there
@@ -45,11 +45,11 b' Usage'
45 IPYTHON_DIR defaults to `$HOME/.config/ipython`, and for other Unix systems
45 IPYTHON_DIR defaults to `$HOME/.config/ipython`, and for other Unix systems
46 to `$HOME/.ipython`. For Windows users, $HOME resolves to C:\\Documents
46 to `$HOME/.ipython`. For Windows users, $HOME resolves to C:\\Documents
47 and Settings\\YourUserName in most instances.
47 and Settings\\YourUserName in most instances.
48
48
49 To initialize a profile with the default configuration file, do::
49 To initialize a profile with the default configuration file, do::
50
50
51 $> ipython profile create
51 $> ipython profile create
52
52
53 and start editing `IPYTHON_DIR/profile_default/ipython_config.py`
53 and start editing `IPYTHON_DIR/profile_default/ipython_config.py`
54
54
55 In IPython's documentation, we will refer to this directory as
55 In IPython's documentation, we will refer to this directory as
@@ -129,7 +129,7 b' MAIN FEATURES'
129 * Persistent command history across sessions.
129 * Persistent command history across sessions.
130
130
131 * Logging of input with the ability to save and restore a working session.
131 * Logging of input with the ability to save and restore a working session.
132
132
133 * System escape with !. Typing !ls will run 'ls' in the current directory.
133 * System escape with !. Typing !ls will run 'ls' in the current directory.
134
134
135 * The reload command does a 'deep' reload of a module: changes made to the
135 * The reload command does a 'deep' reload of a module: changes made to the
@@ -201,7 +201,7 b' MAIN FEATURES'
201 Note that the '/' MUST be the first character on the line! This
201 Note that the '/' MUST be the first character on the line! This
202 won't work:
202 won't work:
203 >>> print /globals # syntax error
203 >>> print /globals # syntax error
204
204
205 In most cases the automatic algorithm should work, so you should
205 In most cases the automatic algorithm should work, so you should
206 rarely need to explicitly invoke /. One notable exception is if you
206 rarely need to explicitly invoke /. One notable exception is if you
207 are trying to call a function with a list of tuples as arguments (the
207 are trying to call a function with a list of tuples as arguments (the
@@ -210,12 +210,12 b' MAIN FEATURES'
210 but this will work:
210 but this will work:
211 In [2]: /zip (1,2,3),(4,5,6)
211 In [2]: /zip (1,2,3),(4,5,6)
212 ------> zip ((1,2,3),(4,5,6))
212 ------> zip ((1,2,3),(4,5,6))
213 Out[2]= [(1, 4), (2, 5), (3, 6)]
213 Out[2]= [(1, 4), (2, 5), (3, 6)]
214
214
215 IPython tells you that it has altered your command line by
215 IPython tells you that it has altered your command line by
216 displaying the new command line preceded by -->. e.g.:
216 displaying the new command line preceded by -->. e.g.:
217 In [18]: callable list
217 In [18]: callable list
218 -------> callable (list)
218 -------> callable (list)
219
219
220 2. Auto-Quoting
220 2. Auto-Quoting
221 You can force auto-quoting of a function's arguments by using ',' as
221 You can force auto-quoting of a function's arguments by using ',' as
@@ -255,7 +255,7 b' obj?, obj?? : Get help, or more help for object (also works as'
255
255
256 Magic functions are prefixed by %, and typically take their arguments without
256 Magic functions are prefixed by %, and typically take their arguments without
257 parentheses, quotes or even commas for convenience.
257 parentheses, quotes or even commas for convenience.
258
258
259 Example magic function calls:
259 Example magic function calls:
260
260
261 %alias d ls -F : 'd' is now an alias for 'ls -F'
261 %alias d ls -F : 'd' is now an alias for 'ls -F'
@@ -265,7 +265,7 b' cd /usr/share : Obvious. cd -<tab> to choose from visited dirs.'
265 %cd?? : See help AND source for magic %cd
265 %cd?? : See help AND source for magic %cd
266
266
267 System commands:
267 System commands:
268
268
269 !cp a.txt b/ : System command escape, calls os.system()
269 !cp a.txt b/ : System command escape, calls os.system()
270 cp a.txt b/ : after %rehashx, most system commands work without !
270 cp a.txt b/ : after %rehashx, most system commands work without !
271 cp ${f}.txt $bar : Variable expansion in magics and system commands
271 cp ${f}.txt $bar : Variable expansion in magics and system commands
@@ -277,7 +277,7 b' History:'
277 _i, _ii, _iii : Previous, next previous, next next previous input
277 _i, _ii, _iii : Previous, next previous, next next previous input
278 _i4, _ih[2:5] : Input history line 4, lines 2-4
278 _i4, _ih[2:5] : Input history line 4, lines 2-4
279 exec _i81 : Execute input history line #81 again
279 exec _i81 : Execute input history line #81 again
280 %rep 81 : Edit input history line #81
280 %rep 81 : Edit input history line #81
281 _, __, ___ : previous, next previous, next next previous output
281 _, __, ___ : previous, next previous, next next previous output
282 _dh : Directory history
282 _dh : Directory history
283 _oh : Output history
283 _oh : Output history
@@ -327,10 +327,10 b' blocks are evaluated once a single blank line is entered::'
327
327
328 In [1]: print "Hello IPython!" # Enter was pressed at the end of the line
328 In [1]: print "Hello IPython!" # Enter was pressed at the end of the line
329 Hello IPython!
329 Hello IPython!
330
330
331 In [2]: for i in range(10):
331 In [2]: for i in range(10):
332 ...: print i,
332 ...: print i,
333 ...:
333 ...:
334 0 1 2 3 4 5 6 7 8 9
334 0 1 2 3 4 5 6 7 8 9
335
335
336 If you want to enter more than one expression in a single input block
336 If you want to enter more than one expression in a single input block
@@ -348,7 +348,7 b' cell is executed as if it was a script. An example should clarify this::'
348 ...: z=3
348 ...: z=3
349 ...: x**2 # This does *not* produce an Out[] value
349 ...: x**2 # This does *not* produce an Out[] value
350 ...: x+y+z # Only the last expression does
350 ...: x+y+z # Only the last expression does
351 ...:
351 ...:
352 Out[3]: 6
352 Out[3]: 6
353
353
354 The behavior where an extra blank line forces execution is only active if you
354 The behavior where an extra blank line forces execution is only active if you
@@ -150,13 +150,13 b' def zip_items(items,titles=None):'
150 with their index. Leave other plot items alone."""
150 with their index. Leave other plot items alone."""
151
151
152 class StandaloneItem(Exception): pass
152 class StandaloneItem(Exception): pass
153
153
154 def get_titles(titles):
154 def get_titles(titles):
155 """Return the next title and the input titles array.
155 """Return the next title and the input titles array.
156
156
157 The input array may be changed to None when no titles are left to
157 The input array may be changed to None when no titles are left to
158 prevent extra unnecessary calls to this function."""
158 prevent extra unnecessary calls to this function."""
159
159
160 try:
160 try:
161 title = titles[tit_ct[0]] # tit_ct[0] is in zip_items'scope
161 title = titles[tit_ct[0]] # tit_ct[0] is in zip_items'scope
162 except IndexError:
162 except IndexError:
@@ -258,33 +258,33 b' class Gnuplot(Gnuplot_ori.Gnuplot):'
258 explicit '' argument must be given as the limit to be kept.
258 explicit '' argument must be given as the limit to be kept.
259
259
260 Similar functions exist for [y{2}z{2}rtuv]range."""
260 Similar functions exist for [y{2}z{2}rtuv]range."""
261
261
262 self('set xrange [%s:%s]' % (min,max))
262 self('set xrange [%s:%s]' % (min,max))
263
263
264 def yrange(self,min='*',max='*'):
264 def yrange(self,min='*',max='*'):
265 self('set yrange [%s:%s]' % (min,max))
265 self('set yrange [%s:%s]' % (min,max))
266
266
267 def zrange(self,min='*',max='*'):
267 def zrange(self,min='*',max='*'):
268 self('set zrange [%s:%s]' % (min,max))
268 self('set zrange [%s:%s]' % (min,max))
269
269
270 def x2range(self,min='*',max='*'):
270 def x2range(self,min='*',max='*'):
271 self('set xrange [%s:%s]' % (min,max))
271 self('set xrange [%s:%s]' % (min,max))
272
272
273 def y2range(self,min='*',max='*'):
273 def y2range(self,min='*',max='*'):
274 self('set yrange [%s:%s]' % (min,max))
274 self('set yrange [%s:%s]' % (min,max))
275
275
276 def z2range(self,min='*',max='*'):
276 def z2range(self,min='*',max='*'):
277 self('set zrange [%s:%s]' % (min,max))
277 self('set zrange [%s:%s]' % (min,max))
278
278
279 def rrange(self,min='*',max='*'):
279 def rrange(self,min='*',max='*'):
280 self('set rrange [%s:%s]' % (min,max))
280 self('set rrange [%s:%s]' % (min,max))
281
281
282 def trange(self,min='*',max='*'):
282 def trange(self,min='*',max='*'):
283 self('set trange [%s:%s]' % (min,max))
283 self('set trange [%s:%s]' % (min,max))
284
284
285 def urange(self,min='*',max='*'):
285 def urange(self,min='*',max='*'):
286 self('set urange [%s:%s]' % (min,max))
286 self('set urange [%s:%s]' % (min,max))
287
287
288 def vrange(self,min='*',max='*'):
288 def vrange(self,min='*',max='*'):
289 self('set vrange [%s:%s]' % (min,max))
289 self('set vrange [%s:%s]' % (min,max))
290
290
@@ -319,7 +319,7 b' class Gnuplot(Gnuplot_ori.Gnuplot):'
319 # Filter out other options the original plot doesn't know
319 # Filter out other options the original plot doesn't know
320 hardcopy = popkey(keyw,'hardcopy',psargs['filename'] is not None)
320 hardcopy = popkey(keyw,'hardcopy',psargs['filename'] is not None)
321 titles = popkey(keyw,'titles',0)
321 titles = popkey(keyw,'titles',0)
322
322
323 # the filename keyword should control hardcopy generation, this is an
323 # the filename keyword should control hardcopy generation, this is an
324 # override switch only which needs to be explicitly set to zero
324 # override switch only which needs to be explicitly set to zero
325 if hardcopy:
325 if hardcopy:
@@ -410,7 +410,7 b' class Gnuplot(Gnuplot_ori.Gnuplot):'
410
410
411 - filename: a string, typically ending in .eps. If given, the plot is
411 - filename: a string, typically ending in .eps. If given, the plot is
412 sent to this file in PostScript format.
412 sent to this file in PostScript format.
413
413
414 - hardcopy: this can be set to 0 to override 'filename'. It does not
414 - hardcopy: this can be set to 0 to override 'filename'. It does not
415 need to be given to produce PostScript, its purpose is to allow
415 need to be given to produce PostScript, its purpose is to allow
416 switching PostScript output off globally in scripts without having to
416 switching PostScript output off globally in scripts without having to
@@ -421,7 +421,7 b' class Gnuplot(Gnuplot_ori.Gnuplot):'
421 PostScript.
421 PostScript.
422
422
423 For example:
423 For example:
424
424
425 In [1]: x=frange(0,2*pi,npts=100)
425 In [1]: x=frange(0,2*pi,npts=100)
426
426
427 Generate a plot in file 'sin.eps':
427 Generate a plot in file 'sin.eps':
@@ -439,16 +439,16 b' class Gnuplot(Gnuplot_ori.Gnuplot):'
439 PostScript generation through plot() is useful mainly for scripting
439 PostScript generation through plot() is useful mainly for scripting
440 uses where you are not interested in interactive plotting. For
440 uses where you are not interested in interactive plotting. For
441 interactive use, the hardcopy() function is typically more convenient:
441 interactive use, the hardcopy() function is typically more convenient:
442
442
443 In [5]: plot(x,sin(x))
443 In [5]: plot(x,sin(x))
444
444
445 In [6]: hardcopy('sin.eps') """
445 In [6]: hardcopy('sin.eps') """
446
446
447 self.__plot_ps(Gnuplot_ori.Gnuplot.plot,*items,**keyw)
447 self.__plot_ps(Gnuplot_ori.Gnuplot.plot,*items,**keyw)
448
448
449 def plot2(self,arg,**kw):
449 def plot2(self,arg,**kw):
450 """Plot the entries of a dictionary or a list/tuple of arrays.
450 """Plot the entries of a dictionary or a list/tuple of arrays.
451
451
452 This simple utility calls plot() with a list of Gnuplot.Data objects
452 This simple utility calls plot() with a list of Gnuplot.Data objects
453 constructed either from the values of the input dictionary, or the entries
453 constructed either from the values of the input dictionary, or the entries
454 in it if it is a tuple or list. Each item gets labeled with the key/index
454 in it if it is a tuple or list. Each item gets labeled with the key/index
@@ -493,7 +493,7 b' class Gnuplot(Gnuplot_ori.Gnuplot):'
493 Gnuplot.py, this version has several enhancements, listed in the
493 Gnuplot.py, this version has several enhancements, listed in the
494 plot() documentation.
494 plot() documentation.
495 """
495 """
496
496
497 self.__plot_ps(Gnuplot_ori.Gnuplot.splot,*items,**keyw)
497 self.__plot_ps(Gnuplot_ori.Gnuplot.splot,*items,**keyw)
498
498
499 def replot(self, *items, **keyw):
499 def replot(self, *items, **keyw):
@@ -508,7 +508,7 b' class Gnuplot(Gnuplot_ori.Gnuplot):'
508 'filename' keyword argument in each call to replot. The Gnuplot python
508 'filename' keyword argument in each call to replot. The Gnuplot python
509 interface has no way of knowing that your previous call to
509 interface has no way of knowing that your previous call to
510 Gnuplot.plot() was meant for PostScript output."""
510 Gnuplot.plot() was meant for PostScript output."""
511
511
512 self.__plot_ps(Gnuplot_ori.Gnuplot.replot,*items,**keyw)
512 self.__plot_ps(Gnuplot_ori.Gnuplot.replot,*items,**keyw)
513
513
514 # The original hardcopy has a bug. See fix at the end. The rest of the code
514 # The original hardcopy has a bug. See fix at the end. The rest of the code
@@ -38,13 +38,13 b' class _Helper(object):'
38 def __repr__(self):
38 def __repr__(self):
39 return "Type help() for interactive help, " \
39 return "Type help() for interactive help, " \
40 "or help(object) for help about object."
40 "or help(object) for help about object."
41
41
42 def __call__(self, *args, **kwds):
42 def __call__(self, *args, **kwds):
43 class DummyWriter(object):
43 class DummyWriter(object):
44 '''Dumy class to handle help output'''
44 '''Dumy class to handle help output'''
45 def __init__(self, pager):
45 def __init__(self, pager):
46 self._pager = pager
46 self._pager = pager
47
47
48 def write(self, data):
48 def write(self, data):
49 '''hook to fill self._pager'''
49 '''hook to fill self._pager'''
50 self._pager(data)
50 self._pager(data)
@@ -52,17 +52,17 b' class _Helper(object):'
52 import pydoc
52 import pydoc
53 pydoc.help.output = DummyWriter(self._pager)
53 pydoc.help.output = DummyWriter(self._pager)
54 pydoc.help.interact = lambda :1
54 pydoc.help.interact = lambda :1
55
55
56 return pydoc.help(*args, **kwds)
56 return pydoc.help(*args, **kwds)
57
57
58
58
59 ##############################################################################
59 ##############################################################################
60 class _CodeExecutor(ThreadEx):
60 class _CodeExecutor(ThreadEx):
61 ''' Thread that execute ipython code '''
61 ''' Thread that execute ipython code '''
62 def __init__(self, instance):
62 def __init__(self, instance):
63 ThreadEx.__init__(self)
63 ThreadEx.__init__(self)
64 self.instance = instance
64 self.instance = instance
65
65
66 def run(self):
66 def run(self):
67 '''Thread main loop'''
67 '''Thread main loop'''
68 try:
68 try:
@@ -70,17 +70,17 b' class _CodeExecutor(ThreadEx):'
70 self.instance._help_text = None
70 self.instance._help_text = None
71 self.instance._execute()
71 self.instance._execute()
72 # used for uper class to generate event after execution
72 # used for uper class to generate event after execution
73 self.instance._after_execute()
73 self.instance._after_execute()
74
74
75 except KeyboardInterrupt:
75 except KeyboardInterrupt:
76 pass
76 pass
77
77
78
78
79 ##############################################################################
79 ##############################################################################
80 class NonBlockingIPShell(object):
80 class NonBlockingIPShell(object):
81 '''
81 '''
82 Create an IPython instance, running the commands in a separate,
82 Create an IPython instance, running the commands in a separate,
83 non-blocking thread.
83 non-blocking thread.
84 This allows embedding in any GUI without blockage.
84 This allows embedding in any GUI without blockage.
85
85
86 Note: The ThreadEx class supports asynchroneous function call
86 Note: The ThreadEx class supports asynchroneous function call
@@ -111,7 +111,7 b' class NonBlockingIPShell(object):'
111 self.init_ipython0(user_ns, user_global_ns,
111 self.init_ipython0(user_ns, user_global_ns,
112 cin, cout, cerr,
112 cin, cout, cerr,
113 ask_exit_handler)
113 ask_exit_handler)
114
114
115 #vars used by _execute
115 #vars used by _execute
116 self._iter_more = 0
116 self._iter_more = 0
117 self._history_level = 0
117 self._history_level = 0
@@ -121,7 +121,7 b' class NonBlockingIPShell(object):'
121 #thread working vars
121 #thread working vars
122 self._line_to_execute = ''
122 self._line_to_execute = ''
123 self._threading = True
123 self._threading = True
124
124
125 #vars that will be checked by GUI loop to handle thread states...
125 #vars that will be checked by GUI loop to handle thread states...
126 #will be replaced later by PostEvent GUI funtions...
126 #will be replaced later by PostEvent GUI funtions...
127 self._doc_text = None
127 self._doc_text = None
@@ -132,7 +132,7 b' class NonBlockingIPShell(object):'
132 cin=None, cout=None, cerr=None,
132 cin=None, cout=None, cerr=None,
133 ask_exit_handler=None):
133 ask_exit_handler=None):
134 ''' Initialize an ipython0 instance '''
134 ''' Initialize an ipython0 instance '''
135
135
136 #first we redefine in/out/error functions of IPython
136 #first we redefine in/out/error functions of IPython
137 #BUG: we've got a limitation form ipython0 there
137 #BUG: we've got a limitation form ipython0 there
138 #only one instance can be instanciated else tehre will be
138 #only one instance can be instanciated else tehre will be
@@ -143,7 +143,7 b' class NonBlockingIPShell(object):'
143 Term.cout = cout
143 Term.cout = cout
144 if cerr:
144 if cerr:
145 Term.cerr = cerr
145 Term.cerr = cerr
146
146
147 excepthook = sys.excepthook
147 excepthook = sys.excepthook
148
148
149 #Hack to save sys.displayhook, because ipython seems to overwrite it...
149 #Hack to save sys.displayhook, because ipython seems to overwrite it...
@@ -165,11 +165,11 b' class NonBlockingIPShell(object):'
165 self._IP.stdin_encoding = loc
165 self._IP.stdin_encoding = loc
166 #we replace the ipython default pager by our pager
166 #we replace the ipython default pager by our pager
167 self._IP.set_hook('show_in_pager', self._pager)
167 self._IP.set_hook('show_in_pager', self._pager)
168
168
169 #we replace the ipython default shell command caller
169 #we replace the ipython default shell command caller
170 #by our shell handler
170 #by our shell handler
171 self._IP.set_hook('shell_hook', self._shell)
171 self._IP.set_hook('shell_hook', self._shell)
172
172
173 #we replace the ipython default input command caller by our method
173 #we replace the ipython default input command caller by our method
174 iplib.raw_input_original = self._raw_input_original
174 iplib.raw_input_original = self._raw_input_original
175 #we replace the ipython default exit command by our method
175 #we replace the ipython default exit command by our method
@@ -184,10 +184,10 b' class NonBlockingIPShell(object):'
184
184
185 import __builtin__
185 import __builtin__
186 __builtin__.raw_input = self._raw_input
186 __builtin__.raw_input = self._raw_input
187
187
188 sys.excepthook = excepthook
188 sys.excepthook = excepthook
189
189
190 #----------------------- Thread management section ----------------------
190 #----------------------- Thread management section ----------------------
191 def do_execute(self, line):
191 def do_execute(self, line):
192 """
192 """
193 Tell the thread to process the 'line' command
193 Tell the thread to process the 'line' command
@@ -196,8 +196,8 b' class NonBlockingIPShell(object):'
196 self._line_to_execute = line
196 self._line_to_execute = line
197
197
198 if self._threading:
198 if self._threading:
199 #we launch the ipython line execution in a thread to make it
199 #we launch the ipython line execution in a thread to make it
200 #interruptible with include it in self namespace to be able
200 #interruptible with include it in self namespace to be able
201 #to call ce.raise_exc(KeyboardInterrupt)
201 #to call ce.raise_exc(KeyboardInterrupt)
202 self.ce = _CodeExecutor(self)
202 self.ce = _CodeExecutor(self)
203 self.ce.start()
203 self.ce.start()
@@ -207,8 +207,8 b' class NonBlockingIPShell(object):'
207 self._help_text = None
207 self._help_text = None
208 self._execute()
208 self._execute()
209 # used for uper class to generate event after execution
209 # used for uper class to generate event after execution
210 self._after_execute()
210 self._after_execute()
211
211
212 except KeyboardInterrupt:
212 except KeyboardInterrupt:
213 pass
213 pass
214
214
@@ -225,7 +225,7 b' class NonBlockingIPShell(object):'
225 @rtype: bool
225 @rtype: bool
226 """
226 """
227 return self._threading
227 return self._threading
228
228
229 def set_threading(self, state):
229 def set_threading(self, state):
230 """
230 """
231 Sets threading state, if set to True, then each command sent to
231 Sets threading state, if set to True, then each command sent to
@@ -247,7 +247,7 b' class NonBlockingIPShell(object):'
247 @rtype: string
247 @rtype: string
248 """
248 """
249 return self._doc_text
249 return self._doc_text
250
250
251 def get_help_text(self):
251 def get_help_text(self):
252 """
252 """
253 Returns the output of the processing that need to be paged via help pager(if any)
253 Returns the output of the processing that need to be paged via help pager(if any)
@@ -265,7 +265,7 b' class NonBlockingIPShell(object):'
265 @rtype: string
265 @rtype: string
266 """
266 """
267 return self._IP.banner
267 return self._IP.banner
268
268
269 def get_prompt_count(self):
269 def get_prompt_count(self):
270 """
270 """
271 Returns the prompt number.
271 Returns the prompt number.
@@ -295,7 +295,7 b' class NonBlockingIPShell(object):'
295 @rtype: int
295 @rtype: int
296 """
296 """
297 return self._IP.indent_current_nsp
297 return self._IP.indent_current_nsp
298
298
299 def update_namespace(self, ns_dict):
299 def update_namespace(self, ns_dict):
300 '''
300 '''
301 Add the current dictionary to the shell namespace.
301 Add the current dictionary to the shell namespace.
@@ -354,7 +354,7 b' class NonBlockingIPShell(object):'
354 while((history == '' or history == '\n') and self._history_level >0):
354 while((history == '' or history == '\n') and self._history_level >0):
355 if self._history_level >= 1:
355 if self._history_level >= 1:
356 self._history_level -= 1
356 self._history_level -= 1
357 history = self._get_history()
357 history = self._get_history()
358 return history
358 return history
359
359
360 def history_forward(self):
360 def history_forward(self):
@@ -406,7 +406,7 b' class NonBlockingIPShell(object):'
406 @rtype: int
406 @rtype: int
407 '''
407 '''
408 return len(self._IP.input_hist_raw)-1
408 return len(self._IP.input_hist_raw)-1
409
409
410 def _get_history(self):
410 def _get_history(self):
411 '''
411 '''
412 Get's the command string of the current history level.
412 Get's the command string of the current history level.
@@ -428,7 +428,7 b' class NonBlockingIPShell(object):'
428 self._help_text = text
428 self._help_text = text
429 else:
429 else:
430 self._help_text += text
430 self._help_text += text
431
431
432 def _pager(self, IP, text):
432 def _pager(self, IP, text):
433 '''
433 '''
434 This function is used as a callback replacment to IPython pager function
434 This function is used as a callback replacment to IPython pager function
@@ -437,7 +437,7 b' class NonBlockingIPShell(object):'
437 get_doc_text function.
437 get_doc_text function.
438 '''
438 '''
439 self._doc_text = text
439 self._doc_text = text
440
440
441 def _raw_input_original(self, prompt=''):
441 def _raw_input_original(self, prompt=''):
442 '''
442 '''
443 Custom raw_input() replacement. Get's current line from console buffer.
443 Custom raw_input() replacement. Get's current line from console buffer.
@@ -454,7 +454,7 b' class NonBlockingIPShell(object):'
454 """ A replacement from python's raw_input.
454 """ A replacement from python's raw_input.
455 """
455 """
456 raise NotImplementedError
456 raise NotImplementedError
457
457
458 def _execute(self):
458 def _execute(self):
459 '''
459 '''
460 Executes the current line provided by the shell object.
460 Executes the current line provided by the shell object.
@@ -464,7 +464,7 b' class NonBlockingIPShell(object):'
464 sys.stdout = Term.cout
464 sys.stdout = Term.cout
465 #self.sys_displayhook_ori = sys.displayhook
465 #self.sys_displayhook_ori = sys.displayhook
466 #sys.displayhook = self.displayhook
466 #sys.displayhook = self.displayhook
467
467
468 try:
468 try:
469 line = self._IP.raw_input(None, self._iter_more)
469 line = self._IP.raw_input(None, self._iter_more)
470 if self._IP.autoindent:
470 if self._IP.autoindent:
@@ -497,7 +497,7 b' class NonBlockingIPShell(object):'
497
497
498 sys.stdout = orig_stdout
498 sys.stdout = orig_stdout
499 #sys.displayhook = self.sys_displayhook_ori
499 #sys.displayhook = self.sys_displayhook_ori
500
500
501 def _shell(self, ip, cmd):
501 def _shell(self, ip, cmd):
502 '''
502 '''
503 Replacement method to allow shell commands without them blocking.
503 Replacement method to allow shell commands without them blocking.
@@ -16,12 +16,12 b' class IPythonHistoryPanel(wx.Panel):'
16
16
17 def __init__(self, parent,flt_empty=True,
17 def __init__(self, parent,flt_empty=True,
18 flt_doc=True,flt_cmd=True,flt_magic=True):
18 flt_doc=True,flt_cmd=True,flt_magic=True):
19
19
20 wx.Panel.__init__(self,parent,-1)
20 wx.Panel.__init__(self,parent,-1)
21 #text_ctrl = wx.TextCtrl(self, -1, style=wx.TE_MULTILINE)
21 #text_ctrl = wx.TextCtrl(self, -1, style=wx.TE_MULTILINE)
22 text_ctrl = PythonSTC(self, -1)
22 text_ctrl = PythonSTC(self, -1)
23
23
24
24
25 st_filt = wx.StaticText(self, -1, " Filter:")
25 st_filt = wx.StaticText(self, -1, " Filter:")
26
26
27 self.filter_empty = wx.CheckBox(self, -1, "Empty commands")
27 self.filter_empty = wx.CheckBox(self, -1, "Empty commands")
@@ -52,12 +52,12 b' class IPythonHistoryPanel(wx.Panel):'
52 self.filter_doc.Bind(wx.EVT_CHECKBOX, self.evtCheckDocFilter)
52 self.filter_doc.Bind(wx.EVT_CHECKBOX, self.evtCheckDocFilter)
53 self.filter_cmd.Bind(wx.EVT_CHECKBOX, self.evtCheckCmdFilter)
53 self.filter_cmd.Bind(wx.EVT_CHECKBOX, self.evtCheckCmdFilter)
54 self.filter_magic.Bind(wx.EVT_CHECKBOX, self.evtCheckMagicFilter)
54 self.filter_magic.Bind(wx.EVT_CHECKBOX, self.evtCheckMagicFilter)
55
55
56 #self.filter_empty.SetValue(flt_empty)
56 #self.filter_empty.SetValue(flt_empty)
57 #self.filter_doc.SetValue(flt_doc)
57 #self.filter_doc.SetValue(flt_doc)
58 #self.filter_cmd.SetValue(flt_cmd)
58 #self.filter_cmd.SetValue(flt_cmd)
59 #self.filter_magic.SetValue(flt_magic)
59 #self.filter_magic.SetValue(flt_magic)
60
60
61 sizer = wx.BoxSizer(wx.VERTICAL)
61 sizer = wx.BoxSizer(wx.VERTICAL)
62
62
63 sizer.Add(text_ctrl, 1, wx.EXPAND)
63 sizer.Add(text_ctrl, 1, wx.EXPAND)
@@ -83,7 +83,7 b' class IPythonHistoryPanel(wx.Panel):'
83 text_ctrl.SetMarginType(1, stc.STC_MARGIN_NUMBER)
83 text_ctrl.SetMarginType(1, stc.STC_MARGIN_NUMBER)
84 text_ctrl.SetMarginWidth(1, 15)
84 text_ctrl.SetMarginWidth(1, 15)
85
85
86
86
87 def write(self,history_line):
87 def write(self,history_line):
88 add = True
88 add = True
89 if self.filter_empty.GetValue() == True and history_line == '':
89 if self.filter_empty.GetValue() == True and history_line == '':
@@ -106,10 +106,10 b' class IPythonHistoryPanel(wx.Panel):'
106 self.options[name]['value']='False'
106 self.options[name]['value']='False'
107 self.updateOptionTracker(name,
107 self.updateOptionTracker(name,
108 self.options[name]['value'])
108 self.options[name]['value'])
109
109
110 def evtCheckEmptyFilter(self, event):
110 def evtCheckEmptyFilter(self, event):
111 self.processOptionCheckedEvt(event, 'filter_empty')
111 self.processOptionCheckedEvt(event, 'filter_empty')
112
112
113 def evtCheckDocFilter(self, event):
113 def evtCheckDocFilter(self, event):
114 self.processOptionCheckedEvt(event, 'filter_doc')
114 self.processOptionCheckedEvt(event, 'filter_doc')
115
115
@@ -118,10 +118,10 b' class IPythonHistoryPanel(wx.Panel):'
118
118
119 def evtCheckMagicFilter(self, event):
119 def evtCheckMagicFilter(self, event):
120 self.processOptionCheckedEvt(event, 'filter_magic')
120 self.processOptionCheckedEvt(event, 'filter_magic')
121
121
122 def getOptions(self):
122 def getOptions(self):
123 return self.options
123 return self.options
124
124
125 def reloadOptions(self,options):
125 def reloadOptions(self,options):
126 self.options = options
126 self.options = options
127 for key in self.options.keys():
127 for key in self.options.keys():
@@ -135,14 +135,14 b' class IPythonHistoryPanel(wx.Panel):'
135 Default history tracker (does nothing)
135 Default history tracker (does nothing)
136 '''
136 '''
137 pass
137 pass
138
138
139 def setOptionTrackerHook(self,func):
139 def setOptionTrackerHook(self,func):
140 '''
140 '''
141 Define a new history tracker
141 Define a new history tracker
142 '''
142 '''
143 self.updateOptionTracker = func
143 self.updateOptionTracker = func
144
144
145
145
146 #----------------------------------------------------------------------
146 #----------------------------------------------------------------------
147 # Font definition for Styled Text Control
147 # Font definition for Styled Text Control
148
148
@@ -177,7 +177,7 b' else:'
177 class PythonSTC(stc.StyledTextCtrl):
177 class PythonSTC(stc.StyledTextCtrl):
178
178
179 fold_symbols = 3
179 fold_symbols = 3
180
180
181 def __init__(self, parent, ID,
181 def __init__(self, parent, ID,
182 pos=wx.DefaultPosition, size=wx.DefaultSize,
182 pos=wx.DefaultPosition, size=wx.DefaultSize,
183 style=0):
183 style=0):
@@ -197,14 +197,14 b' class PythonSTC(stc.StyledTextCtrl):'
197 #self.SetViewEOL(True)
197 #self.SetViewEOL(True)
198 self.SetEOLMode(stc.STC_EOL_CRLF)
198 self.SetEOLMode(stc.STC_EOL_CRLF)
199 #self.SetUseAntiAliasing(True)
199 #self.SetUseAntiAliasing(True)
200
200
201 self.SetEdgeMode(stc.STC_EDGE_LINE)
201 self.SetEdgeMode(stc.STC_EDGE_LINE)
202 self.SetEdgeColumn(80)
202 self.SetEdgeColumn(80)
203 self.SetEdgeColour(wx.LIGHT_GREY)
203 self.SetEdgeColour(wx.LIGHT_GREY)
204 self.SetLayoutCache(stc.STC_CACHE_PAGE)
204 self.SetLayoutCache(stc.STC_CACHE_PAGE)
205
205
206 # Setup a margin to hold fold markers
206 # Setup a margin to hold fold markers
207 #self.SetFoldFlags(16)
207 #self.SetFoldFlags(16)
208 ### WHAT IS THIS VALUE? WHAT ARE THE OTHER FLAGS? DOES IT MATTER?
208 ### WHAT IS THIS VALUE? WHAT ARE THE OTHER FLAGS? DOES IT MATTER?
209 self.SetMarginType(2, stc.STC_MARGIN_SYMBOL)
209 self.SetMarginType(2, stc.STC_MARGIN_SYMBOL)
210 self.SetMarginMask(2, stc.STC_MASK_FOLDERS)
210 self.SetMarginMask(2, stc.STC_MASK_FOLDERS)
@@ -212,7 +212,7 b' class PythonSTC(stc.StyledTextCtrl):'
212 self.SetMarginWidth(2, 12)
212 self.SetMarginWidth(2, 12)
213
213
214 if self.fold_symbols == 0:
214 if self.fold_symbols == 0:
215 # Arrow pointing right for contracted folders,
215 # Arrow pointing right for contracted folders,
216 # arrow pointing down for expanded
216 # arrow pointing down for expanded
217 self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN, \
217 self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN, \
218 stc.STC_MARK_ARROWDOWN, "black", "black")
218 stc.STC_MARK_ARROWDOWN, "black", "black")
@@ -228,7 +228,7 b' class PythonSTC(stc.StyledTextCtrl):'
228 stc.STC_MARK_EMPTY, "white", "black")
228 stc.STC_MARK_EMPTY, "white", "black")
229 self.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, \
229 self.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, \
230 stc.STC_MARK_EMPTY, "white", "black")
230 stc.STC_MARK_EMPTY, "white", "black")
231
231
232 elif self.fold_symbols == 1:
232 elif self.fold_symbols == 1:
233 # Plus for contracted folders, minus for expanded
233 # Plus for contracted folders, minus for expanded
234 self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN, \
234 self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN, \
@@ -301,7 +301,7 b' class PythonSTC(stc.StyledTextCtrl):'
301 self.StyleSetSpec(stc.STC_STYLE_BRACEBAD, "fore:#000000,back:#FF0000,bold")
301 self.StyleSetSpec(stc.STC_STYLE_BRACEBAD, "fore:#000000,back:#FF0000,bold")
302
302
303 # Python styles
303 # Python styles
304 # Default
304 # Default
305 self.StyleSetSpec(stc.STC_P_DEFAULT, "fore:#000000,face:%(helv)s,size:%(size)d" % faces)
305 self.StyleSetSpec(stc.STC_P_DEFAULT, "fore:#000000,face:%(helv)s,size:%(size)d" % faces)
306 # Comments
306 # Comments
307 self.StyleSetSpec(stc.STC_P_COMMENTLINE, "fore:#007F00,face:%(other)s,size:%(size)d" % faces)
307 self.StyleSetSpec(stc.STC_P_COMMENTLINE, "fore:#007F00,face:%(other)s,size:%(size)d" % faces)
@@ -335,9 +335,9 b' class PythonSTC(stc.StyledTextCtrl):'
335
335
336 # register some images for use in the AutoComplete box.
336 # register some images for use in the AutoComplete box.
337 #self.RegisterImage(1, images.getSmilesBitmap())
337 #self.RegisterImage(1, images.getSmilesBitmap())
338 #self.RegisterImage(2,
338 #self.RegisterImage(2,
339 # wx.ArtProvider.GetBitmap(wx.ART_NEW, size=(16,16)))
339 # wx.ArtProvider.GetBitmap(wx.ART_NEW, size=(16,16)))
340 #self.RegisterImage(3,
340 #self.RegisterImage(3,
341 # wx.ArtProvider.GetBitmap(wx.ART_COPY, size=(16,16)))
341 # wx.ArtProvider.GetBitmap(wx.ART_COPY, size=(16,16)))
342
342
343
343
@@ -365,7 +365,7 b' class PythonSTC(stc.StyledTextCtrl):'
365 #self.AutoCompShow(0, st)
365 #self.AutoCompShow(0, st)
366
366
367 kw = keyword.kwlist[:]
367 kw = keyword.kwlist[:]
368
368
369 kw.sort() # Python sorts are case sensitive
369 kw.sort() # Python sorts are case sensitive
370 self.AutoCompSetIgnoreCase(False) # so this needs to match
370 self.AutoCompSetIgnoreCase(False) # so this needs to match
371
371
@@ -398,7 +398,7 b' class PythonSTC(stc.StyledTextCtrl):'
398 if braceAtCaret < 0:
398 if braceAtCaret < 0:
399 charAfter = self.GetCharAt(caretPos)
399 charAfter = self.GetCharAt(caretPos)
400 styleAfter = self.GetStyleAt(caretPos)
400 styleAfter = self.GetStyleAt(caretPos)
401
401
402 if charAfter and chr(charAfter) in "[]{}()" and styleAfter == stc.STC_P_OPERATOR:
402 if charAfter and chr(charAfter) in "[]{}()" and styleAfter == stc.STC_P_OPERATOR:
403 braceAtCaret = caretPos
403 braceAtCaret = caretPos
404
404
@@ -53,11 +53,11 b' class WxNonBlockingIPShell(NonBlockingIPShell):'
53 '''
53 '''
54 An NonBlockingIPShell Thread that is WX dependent.
54 An NonBlockingIPShell Thread that is WX dependent.
55 '''
55 '''
56 def __init__(self, parent,
56 def __init__(self, parent,
57 argv=[],user_ns={},user_global_ns=None,
57 argv=[],user_ns={},user_global_ns=None,
58 cin=None, cout=None, cerr=None,
58 cin=None, cout=None, cerr=None,
59 ask_exit_handler=None):
59 ask_exit_handler=None):
60
60
61 NonBlockingIPShell.__init__(self, argv, user_ns, user_global_ns,
61 NonBlockingIPShell.__init__(self, argv, user_ns, user_global_ns,
62 cin, cout, cerr,
62 cin, cout, cerr,
63 ask_exit_handler)
63 ask_exit_handler)
@@ -68,22 +68,22 b' class WxNonBlockingIPShell(NonBlockingIPShell):'
68 self._IP.exit = self._ask_exit
68 self._IP.exit = self._ask_exit
69
69
70 def addGUIShortcut(self, text, func):
70 def addGUIShortcut(self, text, func):
71 wx.CallAfter(self.parent.add_button_handler,
71 wx.CallAfter(self.parent.add_button_handler,
72 button_info={ 'text':text,
72 button_info={ 'text':text,
73 'func':self.parent.doExecuteLine(func)})
73 'func':self.parent.doExecuteLine(func)})
74
74
75 def _raw_input(self, prompt=''):
75 def _raw_input(self, prompt=''):
76 """ A replacement from python's raw_input.
76 """ A replacement from python's raw_input.
77 """
77 """
78 self.answer = None
78 self.answer = None
79 if(self._threading == True):
79 if(self._threading == True):
80 wx.CallAfter(self._yesNoBox, prompt)
80 wx.CallAfter(self._yesNoBox, prompt)
81 while self.answer is None:
81 while self.answer is None:
82 time.sleep(.1)
82 time.sleep(.1)
83 else:
83 else:
84 self._yesNoBox(prompt)
84 self._yesNoBox(prompt)
85 return self.answer
85 return self.answer
86
86
87 def _yesNoBox(self, prompt):
87 def _yesNoBox(self, prompt):
88 """ yes/no box managed with wx.CallAfter jsut in case caler is executed in a thread"""
88 """ yes/no box managed with wx.CallAfter jsut in case caler is executed in a thread"""
89 dlg = wx.TextEntryDialog(
89 dlg = wx.TextEntryDialog(
@@ -94,21 +94,21 b' class WxNonBlockingIPShell(NonBlockingIPShell):'
94 answer = ''
94 answer = ''
95 if dlg.ShowModal() == wx.ID_OK:
95 if dlg.ShowModal() == wx.ID_OK:
96 answer = dlg.GetValue()
96 answer = dlg.GetValue()
97
97
98 dlg.Destroy()
98 dlg.Destroy()
99 self.answer = answer
99 self.answer = answer
100
100
101 def _ask_exit(self):
101 def _ask_exit(self):
102 wx.CallAfter(self.ask_exit_callback, ())
102 wx.CallAfter(self.ask_exit_callback, ())
103
103
104 def _after_execute(self):
104 def _after_execute(self):
105 wx.CallAfter(self.parent.evtStateExecuteDone, ())
105 wx.CallAfter(self.parent.evtStateExecuteDone, ())
106
106
107
107
108 class WxConsoleView(stc.StyledTextCtrl):
108 class WxConsoleView(stc.StyledTextCtrl):
109 '''
109 '''
110 Specialized styled text control view for console-like workflow.
110 Specialized styled text control view for console-like workflow.
111 We use here a scintilla frontend thus it can be reused in any GUI that
111 We use here a scintilla frontend thus it can be reused in any GUI that
112 supports scintilla with less work.
112 supports scintilla with less work.
113
113
114 @cvar ANSI_COLORS_BLACK: Mapping of terminal colors to X11 names.
114 @cvar ANSI_COLORS_BLACK: Mapping of terminal colors to X11 names.
@@ -128,7 +128,7 b' class WxConsoleView(stc.StyledTextCtrl):'
128 '0;36': [6, 'CYAN'], '0;37': [7, 'LIGHT GREY'],
128 '0;36': [6, 'CYAN'], '0;37': [7, 'LIGHT GREY'],
129 '1;30': [8, 'DARK GREY'], '1;31': [9, 'RED'],
129 '1;30': [8, 'DARK GREY'], '1;31': [9, 'RED'],
130 '1;32': [10, 'SEA GREEN'], '1;33': [11, 'YELLOW'],
130 '1;32': [10, 'SEA GREEN'], '1;33': [11, 'YELLOW'],
131 '1;34': [12, 'LIGHT BLUE'], '1;35':
131 '1;34': [12, 'LIGHT BLUE'], '1;35':
132 [13, 'MEDIUM VIOLET RED'],
132 [13, 'MEDIUM VIOLET RED'],
133 '1;36': [14, 'LIGHT STEEL BLUE'], '1;37': [15, 'YELLOW']}
133 '1;36': [14, 'LIGHT STEEL BLUE'], '1;37': [15, 'YELLOW']}
134
134
@@ -163,8 +163,8 b' class WxConsoleView(stc.StyledTextCtrl):'
163 stc.StyledTextCtrl.__init__(self, parent, ID, pos, size, style)
163 stc.StyledTextCtrl.__init__(self, parent, ID, pos, size, style)
164
164
165 ####### Scintilla configuration ###################################
165 ####### Scintilla configuration ###################################
166
166
167 # Ctrl + B or Ctrl + N can be used to zoomin/zoomout the text inside
167 # Ctrl + B or Ctrl + N can be used to zoomin/zoomout the text inside
168 # the widget
168 # the widget
169 self.CmdKeyAssign(ord('B'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMIN)
169 self.CmdKeyAssign(ord('B'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMIN)
170 self.CmdKeyAssign(ord('N'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMOUT)
170 self.CmdKeyAssign(ord('N'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMOUT)
@@ -188,7 +188,7 b' class WxConsoleView(stc.StyledTextCtrl):'
188 self.SetTabWidth(4)
188 self.SetTabWidth(4)
189
189
190 self.EnsureCaretVisible()
190 self.EnsureCaretVisible()
191
191
192 self.SetMargins(3, 3) #text is moved away from border with 3px
192 self.SetMargins(3, 3) #text is moved away from border with 3px
193 # Suppressing Scintilla margins
193 # Suppressing Scintilla margins
194 self.SetMarginWidth(0, 0)
194 self.SetMarginWidth(0, 0)
@@ -197,19 +197,19 b' class WxConsoleView(stc.StyledTextCtrl):'
197
197
198 self.background_color = background_color
198 self.background_color = background_color
199 self.buildStyles()
199 self.buildStyles()
200
200
201 self.indent = 0
201 self.indent = 0
202 self.prompt_count = 0
202 self.prompt_count = 0
203 self.color_pat = re.compile('\x01?\x1b\[(.*?)m\x02?')
203 self.color_pat = re.compile('\x01?\x1b\[(.*?)m\x02?')
204
204
205 self.write(intro)
205 self.write(intro)
206 self.setPrompt(prompt)
206 self.setPrompt(prompt)
207 self.showPrompt()
207 self.showPrompt()
208
208
209 self.autocomplete_mode = autocomplete_mode
209 self.autocomplete_mode = autocomplete_mode
210
210
211 self.Bind(wx.EVT_KEY_DOWN, self._onKeypress)
211 self.Bind(wx.EVT_KEY_DOWN, self._onKeypress)
212
212
213 def buildStyles(self):
213 def buildStyles(self):
214 #we define platform specific fonts
214 #we define platform specific fonts
215 if wx.Platform == '__WXMSW__':
215 if wx.Platform == '__WXMSW__':
@@ -246,29 +246,29 b' class WxConsoleView(stc.StyledTextCtrl):'
246 self.SetCaretForeground("WHITE")
246 self.SetCaretForeground("WHITE")
247 self.ANSI_STYLES = self.ANSI_STYLES_BLACK
247 self.ANSI_STYLES = self.ANSI_STYLES_BLACK
248
248
249 self.StyleSetSpec(stc.STC_STYLE_DEFAULT,
249 self.StyleSetSpec(stc.STC_STYLE_DEFAULT,
250 "fore:%s,back:%s,size:%d,face:%s"
250 "fore:%s,back:%s,size:%d,face:%s"
251 % (self.ANSI_STYLES['0;30'][1],
251 % (self.ANSI_STYLES['0;30'][1],
252 self.background_color,
252 self.background_color,
253 faces['size'], faces['mono']))
253 faces['size'], faces['mono']))
254 self.StyleClearAll()
254 self.StyleClearAll()
255 self.StyleSetSpec(stc.STC_STYLE_BRACELIGHT,
255 self.StyleSetSpec(stc.STC_STYLE_BRACELIGHT,
256 "fore:#FF0000,back:#0000FF,bold")
256 "fore:#FF0000,back:#0000FF,bold")
257 self.StyleSetSpec(stc.STC_STYLE_BRACEBAD,
257 self.StyleSetSpec(stc.STC_STYLE_BRACEBAD,
258 "fore:#000000,back:#FF0000,bold")
258 "fore:#000000,back:#FF0000,bold")
259
259
260 for style in self.ANSI_STYLES.values():
260 for style in self.ANSI_STYLES.values():
261 self.StyleSetSpec(style[0], "bold,fore:%s" % style[1])
261 self.StyleSetSpec(style[0], "bold,fore:%s" % style[1])
262
262
263 #######################################################################
263 #######################################################################
264
264
265 def setBackgroundColor(self, color):
265 def setBackgroundColor(self, color):
266 self.background_color = color
266 self.background_color = color
267 self.buildStyles()
267 self.buildStyles()
268
268
269 def getBackgroundColor(self, color):
269 def getBackgroundColor(self, color):
270 return self.background_color
270 return self.background_color
271
271
272 def asyncWrite(self, text):
272 def asyncWrite(self, text):
273 '''
273 '''
274 Write given text to buffer in an asynchroneous way.
274 Write given text to buffer in an asynchroneous way.
@@ -278,16 +278,16 b' class WxConsoleView(stc.StyledTextCtrl):'
278 '''
278 '''
279 try:
279 try:
280 wx.MutexGuiEnter()
280 wx.MutexGuiEnter()
281
281
282 #be sure not to be interrutpted before the MutexGuiLeave!
282 #be sure not to be interrutpted before the MutexGuiLeave!
283 self.write(text)
283 self.write(text)
284
284
285 except KeyboardInterrupt:
285 except KeyboardInterrupt:
286 wx.MutexGuiLeave()
286 wx.MutexGuiLeave()
287 raise KeyboardInterrupt
287 raise KeyboardInterrupt
288 wx.MutexGuiLeave()
288 wx.MutexGuiLeave()
289
289
290
290
291 def write(self, text):
291 def write(self, text):
292 '''
292 '''
293 Write given text to buffer.
293 Write given text to buffer.
@@ -299,7 +299,7 b' class WxConsoleView(stc.StyledTextCtrl):'
299 segment = segments.pop(0)
299 segment = segments.pop(0)
300 self.StartStyling(self.getCurrentLineEnd(), 0xFF)
300 self.StartStyling(self.getCurrentLineEnd(), 0xFF)
301 self.AppendText(segment)
301 self.AppendText(segment)
302
302
303 if segments:
303 if segments:
304 ansi_tags = self.color_pat.findall(text)
304 ansi_tags = self.color_pat.findall(text)
305
305
@@ -312,9 +312,9 b' class WxConsoleView(stc.StyledTextCtrl):'
312 self.SetStyling(len(segments[i+1]), self.ANSI_STYLES[tag][0])
312 self.SetStyling(len(segments[i+1]), self.ANSI_STYLES[tag][0])
313
313
314 segments.pop(i)
314 segments.pop(i)
315
315
316 self.moveCursor(self.getCurrentLineEnd())
316 self.moveCursor(self.getCurrentLineEnd())
317
317
318 def getPromptLen(self):
318 def getPromptLen(self):
319 '''
319 '''
320 Return the length of current prompt
320 Return the length of current prompt
@@ -326,10 +326,10 b' class WxConsoleView(stc.StyledTextCtrl):'
326
326
327 def setIndentation(self, indentation):
327 def setIndentation(self, indentation):
328 self.indent = indentation
328 self.indent = indentation
329
329
330 def setPromptCount(self, count):
330 def setPromptCount(self, count):
331 self.prompt_count = count
331 self.prompt_count = count
332
332
333 def showPrompt(self):
333 def showPrompt(self):
334 '''
334 '''
335 Prints prompt at start of line.
335 Prints prompt at start of line.
@@ -340,11 +340,11 b' class WxConsoleView(stc.StyledTextCtrl):'
340 self.write(self.prompt)
340 self.write(self.prompt)
341 #now we update the position of end of prompt
341 #now we update the position of end of prompt
342 self.current_start = self.getCurrentLineEnd()
342 self.current_start = self.getCurrentLineEnd()
343
343
344 autoindent = self.indent*' '
344 autoindent = self.indent*' '
345 autoindent = autoindent.replace(' ','\t')
345 autoindent = autoindent.replace(' ','\t')
346 self.write(autoindent)
346 self.write(autoindent)
347
347
348 def changeLine(self, text):
348 def changeLine(self, text):
349 '''
349 '''
350 Replace currently entered command line with given text.
350 Replace currently entered command line with given text.
@@ -379,15 +379,15 b' class WxConsoleView(stc.StyledTextCtrl):'
379 #If cursor is at wrong position put it at last line...
379 #If cursor is at wrong position put it at last line...
380 if self.GetCurrentPos() < self.getCurrentPromptStart():
380 if self.GetCurrentPos() < self.getCurrentPromptStart():
381 self.GotoPos(self.getCurrentPromptStart())
381 self.GotoPos(self.getCurrentPromptStart())
382
382
383 def removeFromTo(self, from_pos, to_pos):
383 def removeFromTo(self, from_pos, to_pos):
384 if from_pos < to_pos:
384 if from_pos < to_pos:
385 self.SetSelection(from_pos, to_pos)
385 self.SetSelection(from_pos, to_pos)
386 self.DeleteBack()
386 self.DeleteBack()
387
387
388 def removeCurrentLine(self):
388 def removeCurrentLine(self):
389 self.LineDelete()
389 self.LineDelete()
390
390
391 def moveCursor(self, position):
391 def moveCursor(self, position):
392 self.GotoPos(position)
392 self.GotoPos(position)
393
393
@@ -397,7 +397,7 b' class WxConsoleView(stc.StyledTextCtrl):'
397 def selectFromTo(self, from_pos, to_pos):
397 def selectFromTo(self, from_pos, to_pos):
398 self.SetSelectionStart(from_pos)
398 self.SetSelectionStart(from_pos)
399 self.SetSelectionEnd(to_pos)
399 self.SetSelectionEnd(to_pos)
400
400
401 def writeHistory(self, history):
401 def writeHistory(self, history):
402 self.removeFromTo(self.getCurrentPromptStart(), self.getCurrentLineEnd())
402 self.removeFromTo(self.getCurrentPromptStart(), self.getCurrentLineEnd())
403 self.changeLine(history)
403 self.changeLine(history)
@@ -410,19 +410,19 b' class WxConsoleView(stc.StyledTextCtrl):'
410
410
411 def getCompletionMethod(self, completion):
411 def getCompletionMethod(self, completion):
412 return self.autocomplete_mode
412 return self.autocomplete_mode
413
413
414 def writeCompletion(self, possibilities):
414 def writeCompletion(self, possibilities):
415 if self.autocomplete_mode == 'IPYTHON':
415 if self.autocomplete_mode == 'IPYTHON':
416 max_len = len(max(possibilities, key=len))
416 max_len = len(max(possibilities, key=len))
417 max_symbol = ' '*max_len
417 max_symbol = ' '*max_len
418
418
419 #now we check how much symbol we can put on a line...
419 #now we check how much symbol we can put on a line...
420 test_buffer = max_symbol + ' '*4
420 test_buffer = max_symbol + ' '*4
421
421
422 allowed_symbols = 80/len(test_buffer)
422 allowed_symbols = 80/len(test_buffer)
423 if allowed_symbols == 0:
423 if allowed_symbols == 0:
424 allowed_symbols = 1
424 allowed_symbols = 1
425
425
426 pos = 1
426 pos = 1
427 buf = ''
427 buf = ''
428 for symbol in possibilities:
428 for symbol in possibilities:
@@ -445,7 +445,7 b' class WxConsoleView(stc.StyledTextCtrl):'
445 for breaker in splitter:
445 for breaker in splitter:
446 last_word = last_word.split(breaker)[-1]
446 last_word = last_word.split(breaker)[-1]
447 self.AutoCompShow(len(last_word), " ".join(possibilities))
447 self.AutoCompShow(len(last_word), " ".join(possibilities))
448
448
449 def _onKeypress(self, event, skip=True):
449 def _onKeypress(self, event, skip=True):
450 '''
450 '''
451 Key press callback used for correcting behavior for console-like
451 Key press callback used for correcting behavior for console-like
@@ -476,7 +476,7 b' class WxConsoleView(stc.StyledTextCtrl):'
476 elif event.GetKeyCode() == wx.WXK_LEFT:
476 elif event.GetKeyCode() == wx.WXK_LEFT:
477 if event.Modifiers == wx.MOD_NONE:
477 if event.Modifiers == wx.MOD_NONE:
478 self.moveCursorOnNewValidKey()
478 self.moveCursorOnNewValidKey()
479
479
480 self.moveCursor(self.getCursorPos()-1)
480 self.moveCursor(self.getCursorPos()-1)
481 if self.getCursorPos() < self.getCurrentPromptStart():
481 if self.getCursorPos() < self.getCurrentPromptStart():
482 self.moveCursor(self.getCurrentPromptStart())
482 self.moveCursor(self.getCurrentPromptStart())
@@ -487,18 +487,18 b' class WxConsoleView(stc.StyledTextCtrl):'
487 if self.getCursorPos() > self.getCurrentPromptStart():
487 if self.getCursorPos() > self.getCurrentPromptStart():
488 event.Skip()
488 event.Skip()
489 return True
489 return True
490
490
491 if skip:
491 if skip:
492 if event.GetKeyCode() not in [wx.WXK_PAGEUP, wx.WXK_PAGEDOWN]\
492 if event.GetKeyCode() not in [wx.WXK_PAGEUP, wx.WXK_PAGEDOWN]\
493 and event.Modifiers == wx.MOD_NONE:
493 and event.Modifiers == wx.MOD_NONE:
494 self.moveCursorOnNewValidKey()
494 self.moveCursorOnNewValidKey()
495
495
496 event.Skip()
496 event.Skip()
497 return True
497 return True
498 return False
498 return False
499 else:
499 else:
500 event.Skip()
500 event.Skip()
501
501
502 def OnUpdateUI(self, evt):
502 def OnUpdateUI(self, evt):
503 # check for matching braces
503 # check for matching braces
504 braceAtCaret = -1
504 braceAtCaret = -1
@@ -533,19 +533,19 b' class WxConsoleView(stc.StyledTextCtrl):'
533 #self.Refresh(True, wxRect(pt.x, pt.y, 5,5))
533 #self.Refresh(True, wxRect(pt.x, pt.y, 5,5))
534 #print pt
534 #print pt
535 #self.Refresh(False)
535 #self.Refresh(False)
536
536
537 class IPShellWidget(wx.Panel):
537 class IPShellWidget(wx.Panel):
538 '''
538 '''
539 This is wx.Panel that embbed the IPython Thread and the wx.StyledTextControl
539 This is wx.Panel that embbed the IPython Thread and the wx.StyledTextControl
540 If you want to port this to any other GUI toolkit, just replace the
540 If you want to port this to any other GUI toolkit, just replace the
541 WxConsoleView by YOURGUIConsoleView and make YOURGUIIPythonView derivate
541 WxConsoleView by YOURGUIConsoleView and make YOURGUIIPythonView derivate
542 from whatever container you want. I've choosed to derivate from a wx.Panel
542 from whatever container you want. I've choosed to derivate from a wx.Panel
543 because it seems to be more useful
543 because it seems to be more useful
544 Any idea to make it more 'generic' welcomed.
544 Any idea to make it more 'generic' welcomed.
545 '''
545 '''
546
546
547 def __init__(self, parent, intro=None,
547 def __init__(self, parent, intro=None,
548 background_color="BLACK", add_button_handler=None,
548 background_color="BLACK", add_button_handler=None,
549 wx_ip_shell=None, user_ns={},user_global_ns=None,
549 wx_ip_shell=None, user_ns={},user_global_ns=None,
550 ):
550 ):
551 '''
551 '''
@@ -570,7 +570,7 b' class IPShellWidget(wx.Panel):'
570
570
571 ### IPython wx console view instanciation ###
571 ### IPython wx console view instanciation ###
572 #If user didn't defined an intro text, we create one for him
572 #If user didn't defined an intro text, we create one for him
573 #If you really wnat an empty intro just call wxIPythonViewPanel
573 #If you really wnat an empty intro just call wxIPythonViewPanel
574 #with intro=''
574 #with intro=''
575 if intro is None:
575 if intro is None:
576 welcome_text = "Welcome to WxIPython Shell.\n\n"
576 welcome_text = "Welcome to WxIPython Shell.\n\n"
@@ -598,7 +598,7 b' class IPShellWidget(wx.Panel):'
598 self.threading_option.SetToolTip(wx.ToolTip(
598 self.threading_option.SetToolTip(wx.ToolTip(
599 "Use threading: infinite loop don't freeze the GUI and commands can be breaked\nNo threading: maximum compatibility"))
599 "Use threading: infinite loop don't freeze the GUI and commands can be breaked\nNo threading: maximum compatibility"))
600 #self.threading_option.SetValue(False)
600 #self.threading_option.SetValue(False)
601
601
602 self.options={'completion':{'value':'IPYTHON',
602 self.options={'completion':{'value':'IPYTHON',
603 'checkbox':self.completion_option,'STC':True,'IPYTHON':False,
603 'checkbox':self.completion_option,'STC':True,'IPYTHON':False,
604 'setfunc':self.text_ctrl.setCompletionMethod},
604 'setfunc':self.text_ctrl.setCompletionMethod},
@@ -614,12 +614,12 b' class IPShellWidget(wx.Panel):'
614 self.cout.write = self.text_ctrl.asyncWrite
614 self.cout.write = self.text_ctrl.asyncWrite
615 #we reloard options
615 #we reloard options
616 self.reloadOptions(self.options)
616 self.reloadOptions(self.options)
617
617
618 self.text_ctrl.Bind(wx.EVT_KEY_DOWN, self.keyPress)
618 self.text_ctrl.Bind(wx.EVT_KEY_DOWN, self.keyPress)
619 self.completion_option.Bind(wx.EVT_CHECKBOX, self.evtCheckOptionCompletion)
619 self.completion_option.Bind(wx.EVT_CHECKBOX, self.evtCheckOptionCompletion)
620 self.background_option.Bind(wx.EVT_CHECKBOX, self.evtCheckOptionBackgroundColor)
620 self.background_option.Bind(wx.EVT_CHECKBOX, self.evtCheckOptionBackgroundColor)
621 self.threading_option.Bind(wx.EVT_CHECKBOX, self.evtCheckOptionThreading)
621 self.threading_option.Bind(wx.EVT_CHECKBOX, self.evtCheckOptionThreading)
622
622
623 ### making the layout of the panel ###
623 ### making the layout of the panel ###
624 sizer = wx.BoxSizer(wx.VERTICAL)
624 sizer = wx.BoxSizer(wx.VERTICAL)
625 sizer.Add(self.text_ctrl, 1, wx.EXPAND)
625 sizer.Add(self.text_ctrl, 1, wx.EXPAND)
@@ -648,7 +648,7 b' class IPShellWidget(wx.Panel):'
648
648
649 def askExitCallback(self, event):
649 def askExitCallback(self, event):
650 self.askExitHandler(event)
650 self.askExitHandler(event)
651
651
652 #---------------------- IPython Thread Management ------------------------
652 #---------------------- IPython Thread Management ------------------------
653 def stateDoExecuteLine(self):
653 def stateDoExecuteLine(self):
654 lines=self.text_ctrl.getCurrentLine()
654 lines=self.text_ctrl.getCurrentLine()
@@ -660,7 +660,7 b' class IPShellWidget(wx.Panel):'
660 if(self.text_ctrl.getCursorPos()!=0):
660 if(self.text_ctrl.getCursorPos()!=0):
661 self.text_ctrl.removeCurrentLine()
661 self.text_ctrl.removeCurrentLine()
662 self.setCurrentState('WAIT_END_OF_EXECUTION')
662 self.setCurrentState('WAIT_END_OF_EXECUTION')
663
663
664 def evtStateExecuteDone(self,evt):
664 def evtStateExecuteDone(self,evt):
665 self.doc = self.IP.get_doc_text()
665 self.doc = self.IP.get_doc_text()
666 self.help = self.IP.get_help_text()
666 self.help = self.IP.get_help_text()
@@ -673,7 +673,7 b' class IPShellWidget(wx.Panel):'
673 self.pager_lines = self.help.split('\n')
673 self.pager_lines = self.help.split('\n')
674 self.pager_state = 'INIT'
674 self.pager_state = 'INIT'
675 self.setCurrentState('SHOW_DOC')
675 self.setCurrentState('SHOW_DOC')
676 self.pager(self.help)
676 self.pager(self.help)
677 else:
677 else:
678 if(self.text_ctrl.getCursorPos()!=0):
678 if(self.text_ctrl.getCursorPos()!=0):
679 self.text_ctrl.removeCurrentLine()
679 self.text_ctrl.removeCurrentLine()
@@ -714,7 +714,7 b' class IPShellWidget(wx.Panel):'
714 self.text_ctrl.write(">\x01\x1b[1;36m\x02"+self.pager_lines[self.pager_index]+'\n')
714 self.text_ctrl.write(">\x01\x1b[1;36m\x02"+self.pager_lines[self.pager_index]+'\n')
715 else:
715 else:
716 self.text_ctrl.write("\x01\x1b[1;36m\x02 "+self.pager_lines[self.pager_index]+'\n')
716 self.text_ctrl.write("\x01\x1b[1;36m\x02 "+self.pager_lines[self.pager_index]+'\n')
717
717
718 for line in self.pager_lines[self.pager_index+1:self.pager_index+9]:
718 for line in self.pager_lines[self.pager_index+1:self.pager_index+9]:
719 self.text_ctrl.write("\x01\x1b[1;36m\x02 "+line+'\n')
719 self.text_ctrl.write("\x01\x1b[1;36m\x02 "+line+'\n')
720 self.pager_index += 10
720 self.pager_index += 10
@@ -730,7 +730,7 b' class IPShellWidget(wx.Panel):'
730 self.text_ctrl.write(">\x01\x1b[1;36m\x02"+self.pager_lines[self.pager_index]+'\n')
730 self.text_ctrl.write(">\x01\x1b[1;36m\x02"+self.pager_lines[self.pager_index]+'\n')
731 else:
731 else:
732 self.text_ctrl.write("\x01\x1b[1;36m\x02 "+self.pager_lines[self.pager_index]+'\n')
732 self.text_ctrl.write("\x01\x1b[1;36m\x02 "+self.pager_lines[self.pager_index]+'\n')
733
733
734 self.pager_index += 1
734 self.pager_index += 1
735 self.pager_nb_lines -= 1
735 self.pager_nb_lines -= 1
736 if self.pager_nb_lines > 0:
736 if self.pager_nb_lines > 0:
@@ -739,7 +739,7 b' class IPShellWidget(wx.Panel):'
739 self.pager_nb_lines = 0
739 self.pager_nb_lines = 0
740 self.pager_state = 'DONE'
740 self.pager_state = 'DONE'
741 self.stateShowPrompt()
741 self.stateShowPrompt()
742
742
743 #------------------------ Key Handler ------------------------------------
743 #------------------------ Key Handler ------------------------------------
744 def keyPress(self, event):
744 def keyPress(self, event):
745 '''
745 '''
@@ -752,7 +752,7 b' class IPShellWidget(wx.Panel):'
752 #we raise an exception inside the IPython thread container
752 #we raise an exception inside the IPython thread container
753 self.IP.ce.raise_exc(KeyboardInterrupt)
753 self.IP.ce.raise_exc(KeyboardInterrupt)
754 return
754 return
755
755
756 #let this before 'wx.WXK_RETURN' because we have to put 'IDLE'
756 #let this before 'wx.WXK_RETURN' because we have to put 'IDLE'
757 #mode if AutoComp has been set as inactive
757 #mode if AutoComp has been set as inactive
758 if self.cur_state == 'COMPLETING':
758 if self.cur_state == 'COMPLETING':
@@ -772,13 +772,13 b' class IPShellWidget(wx.Panel):'
772 self.pager_state = 'PROCESS_LINES'
772 self.pager_state = 'PROCESS_LINES'
773 self.pager(self.doc)
773 self.pager(self.doc)
774 return
774 return
775
775
776 if self.cur_state == 'WAITING_USER_INPUT':
776 if self.cur_state == 'WAITING_USER_INPUT':
777 line=self.text_ctrl.getCurrentLine()
777 line=self.text_ctrl.getCurrentLine()
778 self.text_ctrl.write('\n')
778 self.text_ctrl.write('\n')
779 self.setCurrentState('WAIT_END_OF_EXECUTION')
779 self.setCurrentState('WAIT_END_OF_EXECUTION')
780 return
780 return
781
781
782 if event.GetKeyCode() in [ord('q'),ord('Q')]:
782 if event.GetKeyCode() in [ord('q'),ord('Q')]:
783 if self.pager_state == 'WAITING':
783 if self.pager_state == 'WAITING':
784 self.pager_state = 'DONE'
784 self.pager_state = 'DONE'
@@ -787,8 +787,8 b' class IPShellWidget(wx.Panel):'
787 return
787 return
788
788
789 if self.cur_state == 'WAITING_USER_INPUT':
789 if self.cur_state == 'WAITING_USER_INPUT':
790 event.Skip()
790 event.Skip()
791
791
792 if self.cur_state == 'IDLE':
792 if self.cur_state == 'IDLE':
793 if event.KeyCode == wx.WXK_UP:
793 if event.KeyCode == wx.WXK_UP:
794 history = self.IP.history_back()
794 history = self.IP.history_back()
@@ -805,7 +805,7 b' class IPShellWidget(wx.Panel):'
805 return
805 return
806 completed, possibilities = self.IP.complete(self.text_ctrl.getCurrentLine())
806 completed, possibilities = self.IP.complete(self.text_ctrl.getCurrentLine())
807 if len(possibilities) > 1:
807 if len(possibilities) > 1:
808 if self.text_ctrl.autocomplete_mode == 'IPYTHON':
808 if self.text_ctrl.autocomplete_mode == 'IPYTHON':
809 cur_slice = self.text_ctrl.getCurrentLine()
809 cur_slice = self.text_ctrl.getCurrentLine()
810 self.text_ctrl.write('\n')
810 self.text_ctrl.write('\n')
811 self.text_ctrl.writeCompletion(possibilities)
811 self.text_ctrl.writeCompletion(possibilities)
@@ -855,31 +855,31 b' class IPShellWidget(wx.Panel):'
855 self.updateOptionTracker('threading',
855 self.updateOptionTracker('threading',
856 self.options['threading']['value'])
856 self.options['threading']['value'])
857 self.text_ctrl.SetFocus()
857 self.text_ctrl.SetFocus()
858
858
859 def getOptions(self):
859 def getOptions(self):
860 return self.options
860 return self.options
861
861
862 def reloadOptions(self,options):
862 def reloadOptions(self,options):
863 self.options = options
863 self.options = options
864 for key in self.options.keys():
864 for key in self.options.keys():
865 value = self.options[key]['value']
865 value = self.options[key]['value']
866 self.options[key]['checkbox'].SetValue(self.options[key][value])
866 self.options[key]['checkbox'].SetValue(self.options[key][value])
867 self.options[key]['setfunc'](value)
867 self.options[key]['setfunc'](value)
868
868
869 if self.options['threading']['value']=='True':
869 if self.options['threading']['value']=='True':
870 self.IP.set_threading(True)
870 self.IP.set_threading(True)
871 self.cout.write = self.text_ctrl.asyncWrite
871 self.cout.write = self.text_ctrl.asyncWrite
872 else:
872 else:
873 self.IP.set_threading(False)
873 self.IP.set_threading(False)
874 self.cout.write = self.text_ctrl.write
874 self.cout.write = self.text_ctrl.write
875
875
876 #------------------------ Hook Section -----------------------------------
876 #------------------------ Hook Section -----------------------------------
877 def updateOptionTracker(self,name,value):
877 def updateOptionTracker(self,name,value):
878 '''
878 '''
879 Default history tracker (does nothing)
879 Default history tracker (does nothing)
880 '''
880 '''
881 pass
881 pass
882
882
883 def setOptionTrackerHook(self,func):
883 def setOptionTrackerHook(self,func):
884 '''
884 '''
885 Define a new history tracker
885 Define a new history tracker
@@ -891,7 +891,7 b' class IPShellWidget(wx.Panel):'
891 Default history tracker (does nothing)
891 Default history tracker (does nothing)
892 '''
892 '''
893 pass
893 pass
894
894
895 def setHistoryTrackerHook(self,func):
895 def setHistoryTrackerHook(self,func):
896 '''
896 '''
897 Define a new history tracker
897 Define a new history tracker
@@ -903,7 +903,7 b' class IPShellWidget(wx.Panel):'
903 Default status tracker (does nothing)
903 Default status tracker (does nothing)
904 '''
904 '''
905 pass
905 pass
906
906
907 def setStatusTrackerHook(self,func):
907 def setStatusTrackerHook(self,func):
908 '''
908 '''
909 Define a new status tracker
909 Define a new status tracker
@@ -6,8 +6,8 b' raise_exc.'
6 import threading
6 import threading
7 import inspect
7 import inspect
8 import ctypes
8 import ctypes
9
9
10
10
11 def _async_raise(tid, exctype):
11 def _async_raise(tid, exctype):
12 """raises the exception, performs cleanup if needed"""
12 """raises the exception, performs cleanup if needed"""
13 if not inspect.isclass(exctype):
13 if not inspect.isclass(exctype):
@@ -16,35 +16,35 b' def _async_raise(tid, exctype):'
16 if res == 0:
16 if res == 0:
17 raise ValueError("invalid thread id")
17 raise ValueError("invalid thread id")
18 elif res != 1:
18 elif res != 1:
19 # """if it returns a number greater than one, you're in trouble,
19 # """if it returns a number greater than one, you're in trouble,
20 # and you should call it again with exc=NULL to revert the effect"""
20 # and you should call it again with exc=NULL to revert the effect"""
21 ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, 0)
21 ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, 0)
22 raise SystemError("PyThreadState_SetAsyncExc failed")
22 raise SystemError("PyThreadState_SetAsyncExc failed")
23
23
24
24
25 class ThreadEx(threading.Thread):
25 class ThreadEx(threading.Thread):
26 def _get_my_tid(self):
26 def _get_my_tid(self):
27 """determines this (self's) thread id"""
27 """determines this (self's) thread id"""
28 if not self.isAlive():
28 if not self.isAlive():
29 raise threading.ThreadError("the thread is not active")
29 raise threading.ThreadError("the thread is not active")
30
30
31 # do we have it cached?
31 # do we have it cached?
32 if hasattr(self, "_thread_id"):
32 if hasattr(self, "_thread_id"):
33 return self._thread_id
33 return self._thread_id
34
34
35 # no, look for it in the _active dict
35 # no, look for it in the _active dict
36 for tid, tobj in threading._active.items():
36 for tid, tobj in threading._active.items():
37 if tobj is self:
37 if tobj is self:
38 self._thread_id = tid
38 self._thread_id = tid
39 return tid
39 return tid
40
40
41 raise AssertionError("could not determine the thread's id")
41 raise AssertionError("could not determine the thread's id")
42
42
43 def raise_exc(self, exctype):
43 def raise_exc(self, exctype):
44 """raises the given exception type in the context of this thread"""
44 """raises the given exception type in the context of this thread"""
45 _async_raise(self._get_my_tid(), exctype)
45 _async_raise(self._get_my_tid(), exctype)
46
46
47 def kill(self):
47 def kill(self):
48 """raises SystemExit in the context of the given thread, which should
48 """raises SystemExit in the context of the given thread, which should
49 cause the thread to exit silently (unless caught)"""
49 cause the thread to exit silently (unless caught)"""
50 self.raise_exc(SystemExit)
50 self.raise_exc(SystemExit)
@@ -27,26 +27,26 b' __email__ = "laurent.dufrechou _at_ gmail.com"'
27 __license__ = "BSD"
27 __license__ = "BSD"
28
28
29 #-----------------------------------------
29 #-----------------------------------------
30 # Creating one main frame for our
30 # Creating one main frame for our
31 # application with movables windows
31 # application with movables windows
32 #-----------------------------------------
32 #-----------------------------------------
33 class MyFrame(wx.Frame):
33 class MyFrame(wx.Frame):
34 """Creating one main frame for our
34 """Creating one main frame for our
35 application with movables windows"""
35 application with movables windows"""
36 def __init__(self, parent=None, id=-1, title="WxIPython",
36 def __init__(self, parent=None, id=-1, title="WxIPython",
37 pos=wx.DefaultPosition,
37 pos=wx.DefaultPosition,
38 size=(800, 600), style=wx.DEFAULT_FRAME_STYLE, sync_ok=False):
38 size=(800, 600), style=wx.DEFAULT_FRAME_STYLE, sync_ok=False):
39 wx.Frame.__init__(self, parent, id, title, pos, size, style)
39 wx.Frame.__init__(self, parent, id, title, pos, size, style)
40 self._mgr = wx.aui.AuiManager()
40 self._mgr = wx.aui.AuiManager()
41
41
42 # notify PyAUI which frame to use
42 # notify PyAUI which frame to use
43 self._mgr.SetManagedWindow(self)
43 self._mgr.SetManagedWindow(self)
44
44
45 #create differents panels and make them persistant
45 #create differents panels and make them persistant
46 self.history_panel = IPythonHistoryPanel(self)
46 self.history_panel = IPythonHistoryPanel(self)
47
47
48 self.history_panel.setOptionTrackerHook(self.optionSave)
48 self.history_panel.setOptionTrackerHook(self.optionSave)
49
49
50 self.ipython_panel = IPShellWidget(self,background_color = "BLACK")
50 self.ipython_panel = IPShellWidget(self,background_color = "BLACK")
51 #self.ipython_panel = IPShellWidget(self,background_color = "WHITE")
51 #self.ipython_panel = IPShellWidget(self,background_color = "WHITE")
52 if(sync_ok):
52 if(sync_ok):
@@ -60,12 +60,12 b' class MyFrame(wx.Frame):'
60
60
61 #Create a notebook to display different IPython shell implementations
61 #Create a notebook to display different IPython shell implementations
62 self.nb = wx.aui.AuiNotebook(self)
62 self.nb = wx.aui.AuiNotebook(self)
63
63
64 self.optionLoad()
64 self.optionLoad()
65
65
66 self.statusbar = self.createStatus()
66 self.statusbar = self.createStatus()
67 self.createMenu()
67 self.createMenu()
68
68
69 ########################################################################
69 ########################################################################
70 ### add the panes to the manager
70 ### add the panes to the manager
71 # main panels
71 # main panels
@@ -75,12 +75,12 b' class MyFrame(wx.Frame):'
75 self.nb.AddPage(self.ipython_panel2, "IPython1 Synchroneous Shell")
75 self.nb.AddPage(self.ipython_panel2, "IPython1 Synchroneous Shell")
76
76
77 self._mgr.AddPane(self.history_panel , wx.RIGHT, "IPython history")
77 self._mgr.AddPane(self.history_panel , wx.RIGHT, "IPython history")
78
78
79 # now we specify some panel characteristics
79 # now we specify some panel characteristics
80 self._mgr.GetPane(self.ipython_panel).CaptionVisible(True);
80 self._mgr.GetPane(self.ipython_panel).CaptionVisible(True);
81 self._mgr.GetPane(self.history_panel).CaptionVisible(True);
81 self._mgr.GetPane(self.history_panel).CaptionVisible(True);
82 self._mgr.GetPane(self.history_panel).MinSize((200,400));
82 self._mgr.GetPane(self.history_panel).MinSize((200,400));
83
83
84 # tell the manager to "commit" all the changes just made
84 # tell the manager to "commit" all the changes just made
85 self._mgr.Update()
85 self._mgr.Update()
86
86
@@ -91,14 +91,14 b' class MyFrame(wx.Frame):'
91 self.Bind(wx.EVT_MENU, self.OnShowHistoryPanel,id=wx.ID_HIGHEST+2)
91 self.Bind(wx.EVT_MENU, self.OnShowHistoryPanel,id=wx.ID_HIGHEST+2)
92 self.Bind(wx.EVT_MENU, self.OnShowAbout, id=wx.ID_HIGHEST+3)
92 self.Bind(wx.EVT_MENU, self.OnShowAbout, id=wx.ID_HIGHEST+3)
93 self.Bind(wx.EVT_MENU, self.OnShowAllPanel,id=wx.ID_HIGHEST+6)
93 self.Bind(wx.EVT_MENU, self.OnShowAllPanel,id=wx.ID_HIGHEST+6)
94
94
95 warn_text = 'Hello from IPython and wxPython.\n'
95 warn_text = 'Hello from IPython and wxPython.\n'
96 warn_text +='Please Note that this work is still EXPERIMENTAL\n'
96 warn_text +='Please Note that this work is still EXPERIMENTAL\n'
97 warn_text +='It does NOT emulate currently all the IPython functions.\n'
97 warn_text +='It does NOT emulate currently all the IPython functions.\n'
98 warn_text +="\nIf you use MATPLOTLIB with show() you'll need to deactivate the THREADING option.\n"
98 warn_text +="\nIf you use MATPLOTLIB with show() you'll need to deactivate the THREADING option.\n"
99 if(not sync_ok):
99 if(not sync_ok):
100 warn_text +="\n->No twisted package detected, IPython1 example deactivated."
100 warn_text +="\n->No twisted package detected, IPython1 example deactivated."
101
101
102 dlg = wx.MessageDialog(self,
102 dlg = wx.MessageDialog(self,
103 warn_text,
103 warn_text,
104 'Warning Box',
104 'Warning Box',
@@ -120,9 +120,9 b' class MyFrame(wx.Frame):'
120 opt.write(key + '=' + options_ipython_panel[key]['value']+'\n')
120 opt.write(key + '=' + options_ipython_panel[key]['value']+'\n')
121 for key in options_history_panel.keys():
121 for key in options_history_panel.keys():
122 opt.write(key + '=' + options_history_panel[key]['value']+'\n')
122 opt.write(key + '=' + options_history_panel[key]['value']+'\n')
123 finally:
123 finally:
124 opt.close()
124 opt.close()
125
125
126 def optionLoad(self):
126 def optionLoad(self):
127 try:
127 try:
128 ip = get()
128 ip = get()
@@ -130,10 +130,10 b' class MyFrame(wx.Frame):'
130 opt = open(path + '/options.conf','r')
130 opt = open(path + '/options.conf','r')
131 lines = opt.readlines()
131 lines = opt.readlines()
132 opt.close()
132 opt.close()
133
133
134 options_ipython_panel = self.ipython_panel.getOptions()
134 options_ipython_panel = self.ipython_panel.getOptions()
135 options_history_panel = self.history_panel.getOptions()
135 options_history_panel = self.history_panel.getOptions()
136
136
137 for line in lines:
137 for line in lines:
138 key = line.split('=')[0]
138 key = line.split('=')[0]
139 value = line.split('=')[1].replace('\n','').replace('\r','')
139 value = line.split('=')[1].replace('\n','').replace('\r','')
@@ -145,25 +145,25 b' class MyFrame(wx.Frame):'
145 print >>sys.__stdout__,"Warning: key ",key,"not found in widget options. Check Options.conf"
145 print >>sys.__stdout__,"Warning: key ",key,"not found in widget options. Check Options.conf"
146 self.ipython_panel.reloadOptions(options_ipython_panel)
146 self.ipython_panel.reloadOptions(options_ipython_panel)
147 self.history_panel.reloadOptions(options_history_panel)
147 self.history_panel.reloadOptions(options_history_panel)
148
148
149 except IOError:
149 except IOError:
150 print >>sys.__stdout__,"Could not open Options.conf, defaulting to default values."
150 print >>sys.__stdout__,"Could not open Options.conf, defaulting to default values."
151
151
152
152
153 def createMenu(self):
153 def createMenu(self):
154 """local method used to create one menu bar"""
154 """local method used to create one menu bar"""
155
155
156 mb = wx.MenuBar()
156 mb = wx.MenuBar()
157
157
158 file_menu = wx.Menu()
158 file_menu = wx.Menu()
159 file_menu.Append(wx.ID_EXIT, "Exit")
159 file_menu.Append(wx.ID_EXIT, "Exit")
160
160
161 view_menu = wx.Menu()
161 view_menu = wx.Menu()
162 view_menu.Append(wx.ID_HIGHEST+1, "Show IPython Panel")
162 view_menu.Append(wx.ID_HIGHEST+1, "Show IPython Panel")
163 view_menu.Append(wx.ID_HIGHEST+2, "Show History Panel")
163 view_menu.Append(wx.ID_HIGHEST+2, "Show History Panel")
164 view_menu.AppendSeparator()
164 view_menu.AppendSeparator()
165 view_menu.Append(wx.ID_HIGHEST+6, "Show All")
165 view_menu.Append(wx.ID_HIGHEST+6, "Show All")
166
166
167 about_menu = wx.Menu()
167 about_menu = wx.Menu()
168 about_menu.Append(wx.ID_HIGHEST+3, "About")
168 about_menu.Append(wx.ID_HIGHEST+3, "About")
169
169
@@ -171,7 +171,7 b' class MyFrame(wx.Frame):'
171 mb.Append(view_menu, "View")
171 mb.Append(view_menu, "View")
172 mb.Append(about_menu, "About")
172 mb.Append(about_menu, "About")
173 #mb.Append(options_menu, "Options")
173 #mb.Append(options_menu, "Options")
174
174
175 self.SetMenuBar(mb)
175 self.SetMenuBar(mb)
176
176
177 def createStatus(self):
177 def createStatus(self):
@@ -189,14 +189,14 b' class MyFrame(wx.Frame):'
189 'SHOW_DOC':'Showing doc',
189 'SHOW_DOC':'Showing doc',
190 'SHOW_PROMPT':'Showing prompt'}
190 'SHOW_PROMPT':'Showing prompt'}
191 self.statusbar.SetStatusText(states[text], 0)
191 self.statusbar.SetStatusText(states[text], 0)
192
192
193 def OnClose(self, event):
193 def OnClose(self, event):
194 """#event used to close program """
194 """#event used to close program """
195 # deinitialize the frame manager
195 # deinitialize the frame manager
196 self._mgr.UnInit()
196 self._mgr.UnInit()
197 self.Destroy()
197 self.Destroy()
198 event.Skip()
198 event.Skip()
199
199
200 def OnExitDlg(self, event):
200 def OnExitDlg(self, event):
201 dlg = wx.MessageDialog(self, 'Are you sure you want to quit WxIPython',
201 dlg = wx.MessageDialog(self, 'Are you sure you want to quit WxIPython',
202 'WxIPython exit',
202 'WxIPython exit',
@@ -208,17 +208,17 b' class MyFrame(wx.Frame):'
208 self._mgr.UnInit()
208 self._mgr.UnInit()
209 self.Destroy()
209 self.Destroy()
210 dlg.Destroy()
210 dlg.Destroy()
211
211
212 #event to display IPython pannel
212 #event to display IPython pannel
213 def OnShowIPythonPanel(self,event):
213 def OnShowIPythonPanel(self,event):
214 """ #event to display Boxpannel """
214 """ #event to display Boxpannel """
215 self._mgr.GetPane(self.ipython_panel).Show(True)
215 self._mgr.GetPane(self.ipython_panel).Show(True)
216 self._mgr.Update()
216 self._mgr.Update()
217 #event to display History pannel
217 #event to display History pannel
218 def OnShowHistoryPanel(self,event):
218 def OnShowHistoryPanel(self,event):
219 self._mgr.GetPane(self.history_panel).Show(True)
219 self._mgr.GetPane(self.history_panel).Show(True)
220 self._mgr.Update()
220 self._mgr.Update()
221
221
222 def OnShowAllPanel(self,event):
222 def OnShowAllPanel(self,event):
223 """#event to display all Pannels"""
223 """#event to display all Pannels"""
224 self._mgr.GetPane(self.ipython_panel).Show(True)
224 self._mgr.GetPane(self.ipython_panel).Show(True)
@@ -240,22 +240,22 b' class MyFrame(wx.Frame):'
240 info.License = wordwrap(licenseText, 500, wx.ClientDC(self))
240 info.License = wordwrap(licenseText, 500, wx.ClientDC(self))
241
241
242 # Then we call wx.AboutBox giving it that info object
242 # Then we call wx.AboutBox giving it that info object
243 wx.AboutBox(info)
243 wx.AboutBox(info)
244
244
245 #-----------------------------------------
245 #-----------------------------------------
246 #Creating our application
246 #Creating our application
247 #-----------------------------------------
247 #-----------------------------------------
248 class MyApp(wx.PySimpleApp):
248 class MyApp(wx.PySimpleApp):
249 """Creating our application"""
249 """Creating our application"""
250 def __init__(self, sync_ok=False):
250 def __init__(self, sync_ok=False):
251 wx.PySimpleApp.__init__(self)
251 wx.PySimpleApp.__init__(self)
252
252
253 self.frame = MyFrame(sync_ok=sync_ok)
253 self.frame = MyFrame(sync_ok=sync_ok)
254 self.frame.Show()
254 self.frame.Show()
255
255
256 #-----------------------------------------
256 #-----------------------------------------
257 #Main loop
257 #Main loop
258 #-----------------------------------------
258 #-----------------------------------------
259 def main():
259 def main():
260 app = MyApp(is_sync_frontend_ok)
260 app = MyApp(is_sync_frontend_ok)
261 app.SetTopWindow(app.frame)
261 app.SetTopWindow(app.frame)
@@ -3,18 +3,18 b''
3
3
4 Definition of Fundamental Physical Constants, CODATA Recommended Values
4 Definition of Fundamental Physical Constants, CODATA Recommended Values
5
5
6 Source, Peter J. Mohr and Barry N. Taylor,
6 Source, Peter J. Mohr and Barry N. Taylor,
7 CODATA Recommended Values of the Fundamental
7 CODATA Recommended Values of the Fundamental
8 Physical Constants, 1998
8 Physical Constants, 1998
9
9
10 Website: physics.nist.gov/constants
10 Website: physics.nist.gov/constants
11 """
11 """
12 # License: BSD-like
12 # License: BSD-like
13 # Copyright: Gael Varoquaux (gael.varoquaux@normalesup.org)
13 # Copyright: Gael Varoquaux (gael.varoquaux@normalesup.org)
14
14
15 # inspired by maxima's physconst.mac by Cliff Yapp
15 # inspired by maxima's physconst.mac by Cliff Yapp
16
16
17 #from math import * # math MUST be imported BEFORE PhysicalQInteractive
17 #from math import * # math MUST be imported BEFORE PhysicalQInteractive
18 from IPython.extensions.PhysicalQInteractive import PhysicalQuantityInteractive
18 from IPython.extensions.PhysicalQInteractive import PhysicalQuantityInteractive
19
19
20 # Math constants:
20 # Math constants:
@@ -111,7 +111,7 b' ueVT_N.__doc__ = """nuclear magneton in eV T-1 """'
111 # Atomic and Nuclear Constants
111 # Atomic and Nuclear Constants
112 # General
112 # General
113 #-------------------------------------------------------------------------
113 #-------------------------------------------------------------------------
114 # fine-structure constant
114 # fine-structure constant
115 alpha = 7.297352533E-3
115 alpha = 7.297352533E-3
116
116
117
117
@@ -163,19 +163,19 b' me_MeV.__doc__ = """electron mass - energy equivalent in MeV"""'
163 # electron-muon mass ratio
163 # electron-muon mass ratio
164 memu = 4.83633210E-3
164 memu = 4.83633210E-3
165
165
166 # electron-tau mass ratio
166 # electron-tau mass ratio
167 metau = 2.87555E-4
167 metau = 2.87555E-4
168
168
169 # electron-proton mass ratio
169 # electron-proton mass ratio
170 memp = 5.446170232E-4
170 memp = 5.446170232E-4
171
171
172 # electron-neutron mass ratio
172 # electron-neutron mass ratio
173 memn = 5.438673462E-4
173 memn = 5.438673462E-4
174
174
175 # electron-deuteron mass ratio
175 # electron-deuteron mass ratio
176 memd = 2.7244371170E-4
176 memd = 2.7244371170E-4
177
177
178 # electron to alpha particle mass ratio
178 # electron to alpha particle mass ratio
179 memalpha = 1.3709335611E-4
179 memalpha = 1.3709335611E-4
180
180
181
181
@@ -202,31 +202,31 b' sigma_e.__doc__ = """Thomson cross section """'
202 u_e = PhysicalQuantityInteractive(-928.476362E-26 , 'J/T')
202 u_e = PhysicalQuantityInteractive(-928.476362E-26 , 'J/T')
203 u_e.__doc__ = """electron magnetic moment """
203 u_e.__doc__ = """electron magnetic moment """
204
204
205 # electron magnetic moment to Bohr magneton ratio
205 # electron magnetic moment to Bohr magneton ratio
206 ueuB = -1.0011596521869
206 ueuB = -1.0011596521869
207
207
208 # electron magnetic moment to nuclear magneton ratio
208 # electron magnetic moment to nuclear magneton ratio
209 ueuN = -1838.2819660
209 ueuN = -1838.2819660
210
210
211 # electron magnetic moment anomaly |ue|/uB - 1
211 # electron magnetic moment anomaly |ue|/uB - 1
212 a_e = 1.1596521869E-3
212 a_e = 1.1596521869E-3
213
213
214 # electron g-factor
214 # electron g-factor
215 g_e = -2.0023193043737
215 g_e = -2.0023193043737
216
216
217 # electron-muon magnetic moment ratio
217 # electron-muon magnetic moment ratio
218 ueuu = 206.7669720
218 ueuu = 206.7669720
219
219
220 # electron-proton magnetic moment ratio
220 # electron-proton magnetic moment ratio
221 ueup = -658.2106875
221 ueup = -658.2106875
222
222
223 # electron to shielded proton magnetic moment ratio (H2O, sphere, 25 C)
223 # electron to shielded proton magnetic moment ratio (H2O, sphere, 25 C)
224 ueusp = -658.2275954
224 ueusp = -658.2275954
225
225
226 # electron-neutron magnetic moment ratio
226 # electron-neutron magnetic moment ratio
227 ueun = 960.92050
227 ueun = 960.92050
228
228
229 # electron-deuteron magnetic moment ratio
229 # electron-deuteron magnetic moment ratio
230 ueud = -2143.923498
230 ueud = -2143.923498
231
231
232 # electron to shielded helione magnetic moment ratio (gas, sphere, 25 C)
232 # electron to shielded helione magnetic moment ratio (gas, sphere, 25 C)
@@ -252,7 +252,7 b' muc2_J.__doc__ = """energy equivalent """'
252 muc2_MeV = PhysicalQuantityInteractive(105.6583568 , 'MeV')
252 muc2_MeV = PhysicalQuantityInteractive(105.6583568 , 'MeV')
253 muc2_MeV.__doc__ = """energy equivalent in MeV """
253 muc2_MeV.__doc__ = """energy equivalent in MeV """
254
254
255 # muon-electron mass ratio
255 # muon-electron mass ratio
256 mume = 206.7682657
256 mume = 206.7682657
257
257
258 # muon-tau mass ratio
258 # muon-tau mass ratio
@@ -261,7 +261,7 b' mum = 5.94572E-2'
261 # muon-proton mass ratio
261 # muon-proton mass ratio
262 mump = 0.1126095173
262 mump = 0.1126095173
263
263
264 # muon-neutron mass ratio
264 # muon-neutron mass ratio
265 mumn = 0.1124545079
265 mumn = 0.1124545079
266
266
267
267
@@ -276,19 +276,19 b' lambda_C_u.__doc__ = """muon Compton wavelength """'
276 uu = PhysicalQuantityInteractive(-4.49044813E-26 , 'J/T')
276 uu = PhysicalQuantityInteractive(-4.49044813E-26 , 'J/T')
277 uu.__doc__ = """muon magnetic moment """
277 uu.__doc__ = """muon magnetic moment """
278
278
279 # ratio of muon magnetic moment to Bohr magneton ratio
279 # ratio of muon magnetic moment to Bohr magneton ratio
280 uuuB = -4.84197085E-3
280 uuuB = -4.84197085E-3
281
281
282 # ratio of muon magnetic moment to nuclear magneton ratio
282 # ratio of muon magnetic moment to nuclear magneton ratio
283 uuuN = -8.89059770
283 uuuN = -8.89059770
284
284
285 # muon magnetic moment anomaly |uu|/(e /2mu) - 1
285 # muon magnetic moment anomaly |uu|/(e /2mu) - 1
286 a_u = 1.16591602E-3
286 a_u = 1.16591602E-3
287
287
288 # muon g-factor -2(1 + au)
288 # muon g-factor -2(1 + au)
289 g_u = -2.0023318320
289 g_u = -2.0023318320
290
290
291 # muon-proton magnetic moment ratio
291 # muon-proton magnetic moment ratio
292 uuup = -3.18334539
292 uuup = -3.18334539
293
293
294 # Tau, tau-
294 # Tau, tau-
@@ -308,16 +308,16 b' mtauc2_J.__doc__ = """tau mass energy equivalent """'
308 mtauc2_MeV = PhysicalQuantityInteractive(1777.05 , 'MeV')
308 mtauc2_MeV = PhysicalQuantityInteractive(1777.05 , 'MeV')
309 mtauc2_MeV.__doc__ = """tau mass energy equivalent in MeV """
309 mtauc2_MeV.__doc__ = """tau mass energy equivalent in MeV """
310
310
311 # tau-electron mass ratio
311 # tau-electron mass ratio
312 mtaume = 3477.60
312 mtaume = 3477.60
313
313
314 # tau-muon mass ratio
314 # tau-muon mass ratio
315 mtaumu = 16.8188
315 mtaumu = 16.8188
316
316
317 # tau-proton mass ratio
317 # tau-proton mass ratio
318 mtaump = 1.89396
318 mtaump = 1.89396
319
319
320 # tau-neutron mass ratio
320 # tau-neutron mass ratio
321 mtaumn = 1.89135
321 mtaumn = 1.89135
322
322
323
323
@@ -344,16 +344,16 b' mpc2_J.__doc__ = """energy equivalent """'
344 mpc2_MeV = PhysicalQuantityInteractive(938.271998 , 'MeV')
344 mpc2_MeV = PhysicalQuantityInteractive(938.271998 , 'MeV')
345 mpc2_MeV.__doc__ = """energy equivalent in MeV """
345 mpc2_MeV.__doc__ = """energy equivalent in MeV """
346
346
347 # proton-electron mass ratio
347 # proton-electron mass ratio
348 mpme = 1836.1526675
348 mpme = 1836.1526675
349
349
350 # proton-muon mass ratio
350 # proton-muon mass ratio
351 mpmu = 8.88024408
351 mpmu = 8.88024408
352
352
353 # proton-tau mass ratio
353 # proton-tau mass ratio
354 mpmtau = 0.527994
354 mpmtau = 0.527994
355
355
356 # proton-neutron mass ratio
356 # proton-neutron mass ratio
357 mpmn = 0.99862347855
357 mpmn = 0.99862347855
358
358
359
359
@@ -372,26 +372,26 b' lambda_C_p.__doc__ = """proton Compton wavelength h/mpc """'
372 up = PhysicalQuantityInteractive(1.410606633E-26 , 'J/T')
372 up = PhysicalQuantityInteractive(1.410606633E-26 , 'J/T')
373 up.__doc__ = """proton magnetic moment """
373 up.__doc__ = """proton magnetic moment """
374
374
375 # proton magnetic moment to Bohr magneton ratio
375 # proton magnetic moment to Bohr magneton ratio
376 upuB = 1.521032203E-3
376 upuB = 1.521032203E-3
377
377
378 # proton magnetic moment to nuclear magneton ratio
378 # proton magnetic moment to nuclear magneton ratio
379 upuN = 2.792847337
379 upuN = 2.792847337
380
380
381 # proton g-factor 2up/uN
381 # proton g-factor 2up/uN
382 g_p = 5.585694675
382 g_p = 5.585694675
383
383
384 # proton-neutron magnetic moment ratio
384 # proton-neutron magnetic moment ratio
385 upun = -1.45989805
385 upun = -1.45989805
386
386
387
387
388 usp = PhysicalQuantityInteractive(1.410570399E-26 , 'J/T')
388 usp = PhysicalQuantityInteractive(1.410570399E-26 , 'J/T')
389 usp.__doc__ = """shielded proton magnetic moment (H2O, sphere, 25 C)"""
389 usp.__doc__ = """shielded proton magnetic moment (H2O, sphere, 25 C)"""
390
390
391 # shielded proton magnetic moment to Bohr magneton ratio
391 # shielded proton magnetic moment to Bohr magneton ratio
392 uspuB = 1.520993132E-3
392 uspuB = 1.520993132E-3
393
393
394 # shielded proton magnetic moment to nuclear magneton ratio
394 # shielded proton magnetic moment to nuclear magneton ratio
395 uspuN = 2.792775597
395 uspuN = 2.792775597
396
396
397 # proton magnetic shielding correction 1 - u p/up (H2O, sphere, 25 C)
397 # proton magnetic shielding correction 1 - u p/up (H2O, sphere, 25 C)
@@ -422,16 +422,16 b' mnc2_J.__doc__ = """neutron mass energy equivalent """'
422 mnc2_MeV = PhysicalQuantityInteractive(939.565330 , 'MeV')
422 mnc2_MeV = PhysicalQuantityInteractive(939.565330 , 'MeV')
423 mnc2_MeV.__doc__ = """neutron mass energy equivalent in MeV """
423 mnc2_MeV.__doc__ = """neutron mass energy equivalent in MeV """
424
424
425 # neutron-electron mass ratio
425 # neutron-electron mass ratio
426 mnme = 1838.6836550
426 mnme = 1838.6836550
427
427
428 # neutron-muon mass ratio
428 # neutron-muon mass ratio
429 mnmu = 8.89248478
429 mnmu = 8.89248478
430
430
431 # neutron-tau mass ratio
431 # neutron-tau mass ratio
432 mnm = 0.528722
432 mnm = 0.528722
433
433
434 # neutron-proton mass ratio
434 # neutron-proton mass ratio
435 mnmp = 1.00137841887
435 mnmp = 1.00137841887
436
436
437
437
@@ -446,19 +446,19 b' lambda_C_n.__doc__ = """neutron Compton wavelength"""'
446 un = PhysicalQuantityInteractive(-0.96623640E-26 , 'J/T')
446 un = PhysicalQuantityInteractive(-0.96623640E-26 , 'J/T')
447 un.__doc__ = """neutron magnetic moment """
447 un.__doc__ = """neutron magnetic moment """
448
448
449 # neutron magnetic moment to Bohr magneton ratio
449 # neutron magnetic moment to Bohr magneton ratio
450 unuB = -1.04187563E-3
450 unuB = -1.04187563E-3
451
451
452 # neutron magnetic moment to nuclear magneton ratio
452 # neutron magnetic moment to nuclear magneton ratio
453 unuN = -1.91304272
453 unuN = -1.91304272
454
454
455 # neutron g-factor
455 # neutron g-factor
456 g_n = -3.82608545
456 g_n = -3.82608545
457
457
458 # neutron-electron magnetic moment ratio
458 # neutron-electron magnetic moment ratio
459 unue = 1.04066882E-3
459 unue = 1.04066882E-3
460
460
461 # neutron-proton magnetic moment ratio
461 # neutron-proton magnetic moment ratio
462 unup = -0.68497934
462 unup = -0.68497934
463
463
464 # neutron to shielded proton magnetic moment ratio (H2O, sphere, 25 C)
464 # neutron to shielded proton magnetic moment ratio (H2O, sphere, 25 C)
@@ -486,10 +486,10 b' mdc2_J.__doc__ = """deuteron mass energy equivalent """'
486 mdc2_eV = PhysicalQuantityInteractive(1875.612762 , 'MeV')
486 mdc2_eV = PhysicalQuantityInteractive(1875.612762 , 'MeV')
487 mdc2_eV.__doc__ = """deuteron mass energy equivalent in MeV """
487 mdc2_eV.__doc__ = """deuteron mass energy equivalent in MeV """
488
488
489 # deuteron-electron mass ratio
489 # deuteron-electron mass ratio
490 mdme = 3670.4829550
490 mdme = 3670.4829550
491
491
492 # deuteron-proton mass ratio
492 # deuteron-proton mass ratio
493 mdmp = 1.99900750083
493 mdmp = 1.99900750083
494
494
495
495
@@ -500,19 +500,19 b' Molar_d.__doc__ = """deuteron molar mass """'
500 ud = PhysicalQuantityInteractive(0.433073457E-26 , 'J/T')
500 ud = PhysicalQuantityInteractive(0.433073457E-26 , 'J/T')
501 ud.__doc__ = """deuteron magnetic moment """
501 ud.__doc__ = """deuteron magnetic moment """
502
502
503 # deuteron magnetic moment to Bohr magneton ratio
503 # deuteron magnetic moment to Bohr magneton ratio
504 uduB = 0.4669754556E-3
504 uduB = 0.4669754556E-3
505
505
506 # deuteron magnetic moment to nuclear magneton ratio
506 # deuteron magnetic moment to nuclear magneton ratio
507 uduN = 0.8574382284
507 uduN = 0.8574382284
508
508
509 # deuteron-electron magnetic moment ratio
509 # deuteron-electron magnetic moment ratio
510 udue = -4.664345537E-4
510 udue = -4.664345537E-4
511
511
512 # deuteron-proton magnetic moment ratio
512 # deuteron-proton magnetic moment ratio
513 udup = 0.3070122083
513 udup = 0.3070122083
514
514
515 # deuteron-neutron magnetic moment ratio
515 # deuteron-neutron magnetic moment ratio
516 udun = -0.44820652
516 udun = -0.44820652
517
517
518 # Helion, h
518 # Helion, h
@@ -532,10 +532,10 b' mhc2_J.__doc__ = """helion mass energy equivalent """'
532 mhc2_MeV = PhysicalQuantityInteractive(2808.39132 , 'MeV')
532 mhc2_MeV = PhysicalQuantityInteractive(2808.39132 , 'MeV')
533 mhc2_MeV.__doc__ = """helion mass energy equivalent in MeV """
533 mhc2_MeV.__doc__ = """helion mass energy equivalent in MeV """
534
534
535 # helion-electron mass ratio
535 # helion-electron mass ratio
536 mhme = 5495.885238
536 mhme = 5495.885238
537
537
538 # helion-proton mass ratio
538 # helion-proton mass ratio
539 mhmp = 2.99315265850
539 mhmp = 2.99315265850
540
540
541
541
@@ -546,10 +546,10 b' Molar_h.__doc__ = """helion molar mass """'
546 ush = PhysicalQuantityInteractive(-1.074552967E-26 , 'J/T')
546 ush = PhysicalQuantityInteractive(-1.074552967E-26 , 'J/T')
547 ush.__doc__ = """shielded helion magnetic moment (gas, sphere, 25 C)"""
547 ush.__doc__ = """shielded helion magnetic moment (gas, sphere, 25 C)"""
548
548
549 # shielded helion magnetic moment to Bohr magneton ratio
549 # shielded helion magnetic moment to Bohr magneton ratio
550 ushuB = -1.158671474E-3
550 ushuB = -1.158671474E-3
551
551
552 # shielded helion magnetic moment to nuclear magneton ratio
552 # shielded helion magnetic moment to nuclear magneton ratio
553 ushuN = -2.127497718
553 ushuN = -2.127497718
554
554
555 # shielded helion to proton magnetic moment ratio (gas, sphere, 25 C)
555 # shielded helion to proton magnetic moment ratio (gas, sphere, 25 C)
@@ -562,7 +562,7 b' ushusp = -0.7617861313'
562 gamma_h = PhysicalQuantityInteractive(2.037894764E8 , '1/(s*T)')
562 gamma_h = PhysicalQuantityInteractive(2.037894764E8 , '1/(s*T)')
563 gamma_h.__doc__ = """shielded helion gyromagnetic (gas, sphere, 25 C) """
563 gamma_h.__doc__ = """shielded helion gyromagnetic (gas, sphere, 25 C) """
564
564
565 # Alpha particle,
565 # Alpha particle,
566 #-------------------------------------------------------------------------
566 #-------------------------------------------------------------------------
567
567
568 m_alpha = PhysicalQuantityInteractive(6.64465598E-27 , 'kg')
568 m_alpha = PhysicalQuantityInteractive(6.64465598E-27 , 'kg')
@@ -579,10 +579,10 b' malphac2_J.__doc__ = """alpha particle mass energy equivalent """'
579 malphac2_MeV = PhysicalQuantityInteractive(3727.37904 , 'MeV')
579 malphac2_MeV = PhysicalQuantityInteractive(3727.37904 , 'MeV')
580 malphac2_MeV.__doc__ = """alpha particle mass energy equivalent in MeV """
580 malphac2_MeV.__doc__ = """alpha particle mass energy equivalent in MeV """
581
581
582 # alpha particle to electron mass ratio
582 # alpha particle to electron mass ratio
583 malphame = 7294.299508
583 malphame = 7294.299508
584
584
585 # alpha particle to proton mass ratio
585 # alpha particle to proton mass ratio
586 malphamp = 3.9725996846
586 malphamp = 3.9725996846
587
587
588
588
@@ -642,9 +642,9 b" Vm_2 = PhysicalQuantityInteractive(22.710981E-3 , 'm**3/mol')"
642 Vm_2.__doc__ = """molar volume of ideal gas RT/p T = 273.15 K, p = 100 kPa """
642 Vm_2.__doc__ = """molar volume of ideal gas RT/p T = 273.15 K, p = 100 kPa """
643
643
644 # Sackur-Tetrode constant (absolute entropy constant) 52 + ln_(2 mukT1/h2)3/2kT1/p0
644 # Sackur-Tetrode constant (absolute entropy constant) 52 + ln_(2 mukT1/h2)3/2kT1/p0
645 # T1 = 1 K, p0 = 100 kPa
645 # T1 = 1 K, p0 = 100 kPa
646 S_0R_1 = -1.1517048
646 S_0R_1 = -1.1517048
647 # T1 = 1 K, p0 = 101.325 kPa
647 # T1 = 1 K, p0 = 101.325 kPa
648 S_0R_2 = -1.1648678
648 S_0R_2 = -1.1648678
649
649
650
650
@@ -1,10 +1,10 b''
1 """ Set default options for IPython.
1 """ Set default options for IPython.
2
2
3 Just import this module to get reasonable defaults for everything.
3 Just import this module to get reasonable defaults for everything.
4
4
5 These configurations used to be performed in ipythonrc (or ipythonrc.ini).
5 These configurations used to be performed in ipythonrc (or ipythonrc.ini).
6 Therefore importing this in your config files makes ipython basically
6 Therefore importing this in your config files makes ipython basically
7 ignore your ipythonrc. This is *not* imported by default, you need to import
7 ignore your ipythonrc. This is *not* imported by default, you need to import
8 this manually in one of your config files.
8 this manually in one of your config files.
9
9
10 You can further override these defaults in e.g. your ipy_user_config.py,
10 You can further override these defaults in e.g. your ipy_user_config.py,
@@ -58,5 +58,5 b' set show-all-if-ambiguous on'
58 if readline.have_readline:
58 if readline.have_readline:
59 for cmd in rlopts.split('\n'):
59 for cmd in rlopts.split('\n'):
60 readline.parse_and_bind(cmd)
60 readline.parse_and_bind(cmd)
61
61
62
62
@@ -2,7 +2,7 b''
2
2
3 Start ipython in shell mode by invoking "ipython -p sh"
3 Start ipython in shell mode by invoking "ipython -p sh"
4
4
5 (the old version, "ipython -p pysh" still works but this is the more "modern"
5 (the old version, "ipython -p pysh" still works but this is the more "modern"
6 shell mode and is recommended for users who don't care about pysh-mode
6 shell mode and is recommended for users who don't care about pysh-mode
7 compatibility)
7 compatibility)
8 """
8 """
@@ -16,29 +16,29 b' import os,re,textwrap'
16
16
17 import ipy_defaults
17 import ipy_defaults
18
18
19 def main():
19 def main():
20 ip = ipapi.get()
20 ip = ipapi.get()
21 o = ip.options
21 o = ip.options
22 # autocall to "full" mode (smart mode is default, I like full mode)
22 # autocall to "full" mode (smart mode is default, I like full mode)
23
23
24 o.autocall = 2
24 o.autocall = 2
25
25
26 # Jason Orendorff's path class is handy to have in user namespace
26 # Jason Orendorff's path class is handy to have in user namespace
27 # if you are doing shell-like stuff
27 # if you are doing shell-like stuff
28 try:
28 try:
29 ip.ex("from IPython.external.path import path" )
29 ip.ex("from IPython.external.path import path" )
30 except ImportError:
30 except ImportError:
31 pass
31 pass
32
32
33 # beefed up %env is handy in shell mode
33 # beefed up %env is handy in shell mode
34 import envpersist
34 import envpersist
35
35
36 # To see where mycmd resides (in path/aliases), do %which mycmd
36 # To see where mycmd resides (in path/aliases), do %which mycmd
37 import ipy_which
37 import ipy_which
38
38
39 # tab completers for hg, svn, ...
39 # tab completers for hg, svn, ...
40 import ipy_app_completers
40 import ipy_app_completers
41
41
42 # To make executables foo and bar in mybin usable without PATH change, do:
42 # To make executables foo and bar in mybin usable without PATH change, do:
43 # %rehashdir c:/mybin
43 # %rehashdir c:/mybin
44 # %store foo
44 # %store foo
@@ -47,45 +47,45 b' def main():'
47
47
48 # does not work without subprocess module!
48 # does not work without subprocess module!
49 #import ipy_signals
49 #import ipy_signals
50
50
51 ip.ex('import os')
51 ip.ex('import os')
52 ip.ex("def up(): os.chdir('..')")
52 ip.ex("def up(): os.chdir('..')")
53 ip.user_ns['LA'] = LastArgFinder()
53 ip.user_ns['LA'] = LastArgFinder()
54
54
55 # You can assign to _prompt_title variable
55 # You can assign to _prompt_title variable
56 # to provide some extra information for prompt
56 # to provide some extra information for prompt
57 # (e.g. the current mode, host/username...)
57 # (e.g. the current mode, host/username...)
58
58
59 ip.user_ns['_prompt_title'] = ''
59 ip.user_ns['_prompt_title'] = ''
60
60
61 # Nice prompt
61 # Nice prompt
62 o.prompt_in1= r'\C_Green${_prompt_title}\C_LightBlue[\C_LightCyan\Y2\C_LightBlue]\C_Green|\#> '
62 o.prompt_in1= r'\C_Green${_prompt_title}\C_LightBlue[\C_LightCyan\Y2\C_LightBlue]\C_Green|\#> '
63 o.prompt_in2= r'\C_Green|\C_LightGreen\D\C_Green> '
63 o.prompt_in2= r'\C_Green|\C_LightGreen\D\C_Green> '
64 o.prompt_out= '<\#> '
64 o.prompt_out= '<\#> '
65
65
66 from IPython.core import release
66 from IPython.core import release
67
67
68 import sys
68 import sys
69 # Non-chatty banner
69 # Non-chatty banner
70 o.banner = "IPython %s [on Py %s]\n" % (release.version,sys.version.split(None,1)[0])
70 o.banner = "IPython %s [on Py %s]\n" % (release.version,sys.version.split(None,1)[0])
71
71
72
72
73 ip.default_option('cd','-q')
73 ip.default_option('cd','-q')
74 ip.default_option('macro', '-r')
74 ip.default_option('macro', '-r')
75 # If you only rarely want to execute the things you %edit...
75 # If you only rarely want to execute the things you %edit...
76 #ip.default_option('edit','-x')
76 #ip.default_option('edit','-x')
77
77
78
78
79 o.prompts_pad_left="1"
79 o.prompts_pad_left="1"
80 # Remove all blank lines in between prompts, like a normal shell.
80 # Remove all blank lines in between prompts, like a normal shell.
81 o.separate_in="0"
81 o.separate_in="0"
82 o.separate_out="0"
82 o.separate_out="0"
83 o.separate_out2="0"
83 o.separate_out2="0"
84
84
85 # now alias all syscommands
85 # now alias all syscommands
86
86
87 db = ip.db
87 db = ip.db
88
88
89 syscmds = db.get("syscmdlist",[] )
89 syscmds = db.get("syscmdlist",[] )
90 if not syscmds:
90 if not syscmds:
91 print textwrap.dedent("""
91 print textwrap.dedent("""
@@ -95,47 +95,47 b' def main():'
95 """)
95 """)
96 ip.magic('rehashx')
96 ip.magic('rehashx')
97 syscmds = db.get("syscmdlist")
97 syscmds = db.get("syscmdlist")
98
98
99 # lowcase aliases on win32 only
99 # lowcase aliases on win32 only
100 if os.name == 'posix':
100 if os.name == 'posix':
101 mapper = lambda s:s
101 mapper = lambda s:s
102 else:
102 else:
103 def mapper(s): return s.lower()
103 def mapper(s): return s.lower()
104
104
105 for cmd in syscmds:
105 for cmd in syscmds:
106 # print "sys",cmd #dbg
106 # print "sys",cmd #dbg
107 noext, ext = os.path.splitext(cmd)
107 noext, ext = os.path.splitext(cmd)
108 if ext.lower() == '.exe':
108 if ext.lower() == '.exe':
109 cmd = noext
109 cmd = noext
110
110
111 key = mapper(cmd)
111 key = mapper(cmd)
112 if key not in ip.alias_manager.alias_table:
112 if key not in ip.alias_manager.alias_table:
113 # Dots will be removed from alias names, since ipython
113 # Dots will be removed from alias names, since ipython
114 # assumes names with dots to be python code
114 # assumes names with dots to be python code
115
115
116 ip.define_alias(key.replace('.',''), cmd)
116 ip.define_alias(key.replace('.',''), cmd)
117
117
118 # mglob combines 'find', recursion, exclusion... '%mglob?' to learn more
118 # mglob combines 'find', recursion, exclusion... '%mglob?' to learn more
119 ip.load("IPython.external.mglob")
119 ip.load("IPython.external.mglob")
120
120
121 # win32 is crippled w/o cygwin, try to help it a little bit
121 # win32 is crippled w/o cygwin, try to help it a little bit
122 if sys.platform == 'win32':
122 if sys.platform == 'win32':
123 if 'cygwin' in os.environ['PATH'].lower():
123 if 'cygwin' in os.environ['PATH'].lower():
124 # use the colors of cygwin ls (recommended)
124 # use the colors of cygwin ls (recommended)
125 ip.define_alias('d', 'ls -F --color=auto')
125 ip.define_alias('d', 'ls -F --color=auto')
126 else:
126 else:
127 # get icp, imv, imkdir, igrep, irm,...
127 # get icp, imv, imkdir, igrep, irm,...
128 ip.load('ipy_fsops')
128 ip.load('ipy_fsops')
129
129
130 # and the next best thing to real 'ls -F'
130 # and the next best thing to real 'ls -F'
131 ip.define_alias('d','dir /w /og /on')
131 ip.define_alias('d','dir /w /og /on')
132
132
133 ip.set_hook('input_prefilter', slash_prefilter_f)
133 ip.set_hook('input_prefilter', slash_prefilter_f)
134 extend_shell_behavior(ip)
134 extend_shell_behavior(ip)
135
135
136 class LastArgFinder:
136 class LastArgFinder:
137 """ Allow $LA to work as "last argument of previous command", like $! in bash
137 """ Allow $LA to work as "last argument of previous command", like $! in bash
138
138
139 To call this in normal IPython code, do LA()
139 To call this in normal IPython code, do LA()
140 """
140 """
141 def __call__(self, hist_idx = None):
141 def __call__(self, hist_idx = None):
@@ -144,7 +144,7 b' class LastArgFinder:'
144 return str(self)
144 return str(self)
145 return ip.input_hist_raw[hist_idx].strip().split()[-1]
145 return ip.input_hist_raw[hist_idx].strip().split()[-1]
146 def __str__(self):
146 def __str__(self):
147 ip = ipapi.get()
147 ip = ipapi.get()
148 for cmd in reversed(ip.input_hist_raw):
148 for cmd in reversed(ip.input_hist_raw):
149 parts = cmd.strip().split()
149 parts = cmd.strip().split()
150 if len(parts) < 2 or parts[-1] in ['$LA', 'LA()']:
150 if len(parts) < 2 or parts[-1] in ['$LA', 'LA()']:
@@ -154,7 +154,7 b' class LastArgFinder:'
154
154
155 def slash_prefilter_f(self,line):
155 def slash_prefilter_f(self,line):
156 """ ./foo, ~/foo and /bin/foo now run foo as system command
156 """ ./foo, ~/foo and /bin/foo now run foo as system command
157
157
158 Removes the need for doing !./foo, !~/foo or !/bin/foo
158 Removes the need for doing !./foo, !~/foo or !/bin/foo
159 """
159 """
160 from IPython.utils import genutils
160 from IPython.utils import genutils
@@ -253,7 +253,7 b' def extend_shell_behavior(ip):'
253 if command or more:
253 if command or more:
254 # push to raw history, so hist line numbers stay in sync
254 # push to raw history, so hist line numbers stay in sync
255 ip.input_hist_raw.append("# " + command + "\n")
255 ip.input_hist_raw.append("# " + command + "\n")
256
256
257 more = ip.push_line(ip.prefilter(command,more))
257 more = ip.push_line(ip.prefilter(command,more))
258 command = ''
258 command = ''
259 # IPython's runsource returns None if there was an error
259 # IPython's runsource returns None if there was an error
@@ -186,7 +186,7 b' class ZopeDebug(object):'
186 query = {}
186 query = {}
187 if indexes.get('path'):
187 if indexes.get('path'):
188 from string import join
188 from string import join
189 path = join(obj.getPhysicalPath(), '/')
189 path = join(obj.getPhysicalPath(), '/')
190 query.update({'path': path})
190 query.update({'path': path})
191 if indexes.get('getID'):
191 if indexes.get('getID'):
192 query.update({'getID': obj.id, })
192 query.update({'getID': obj.id, })
@@ -288,7 +288,7 b' def main():'
288 ip = ipapi.get()
288 ip = ipapi.get()
289 o = ip.options
289 o = ip.options
290 # autocall to "full" mode (smart mode is default, I like full mode)
290 # autocall to "full" mode (smart mode is default, I like full mode)
291
291
292 SOFTWARE_HOME = os.environ.get( "SOFTWARE_HOME" )
292 SOFTWARE_HOME = os.environ.get( "SOFTWARE_HOME" )
293 sys.path.append( SOFTWARE_HOME )
293 sys.path.append( SOFTWARE_HOME )
294 print "SOFTWARE_HOME=%s\n" % SOFTWARE_HOME
294 print "SOFTWARE_HOME=%s\n" % SOFTWARE_HOME
@@ -310,7 +310,7 b' def main():'
310 app
310 app
311 portal
311 portal
312 utils.{ %s }
312 utils.{ %s }
313
313
314 Uses the $SOFTWARE_HOME and $CONFIG_FILE environment
314 Uses the $SOFTWARE_HOME and $CONFIG_FILE environment
315 variables.
315 variables.
316 """ % ( ",".join([ x for x in dir(zope_debug.utils) if not x.startswith("_") ] ) ) )
316 """ % ( ",".join([ x for x in dir(zope_debug.utils) if not x.startswith("_") ] ) ) )
@@ -1,10 +1,10 b''
1 """ Integration with gvim, by Erich Heine
1 """ Integration with gvim, by Erich Heine
2
2
3 Provides a %vim magic command, and reuses the same vim session. Uses
3 Provides a %vim magic command, and reuses the same vim session. Uses
4 unix domain sockets for communication between vim and IPython. ipy.vim is
4 unix domain sockets for communication between vim and IPython. ipy.vim is
5 available in doc/examples of the IPython distribution.
5 available in doc/examples of the IPython distribution.
6
6
7 Slightly touched up email announcement (and description how to use it) by
7 Slightly touched up email announcement (and description how to use it) by
8 Erich Heine is here:
8 Erich Heine is here:
9
9
10 Ive recently been playing with ipython, and like it quite a bit. I did
10 Ive recently been playing with ipython, and like it quite a bit. I did
@@ -22,7 +22,7 b' for having gvim and ipython work very nicely together. Ive attached'
22 both to this email (hoping of course that the mailing list allows such
22 both to this email (hoping of course that the mailing list allows such
23 things).
23 things).
24
24
25 There are 2 files:
25 There are 2 files:
26
26
27 ipy_vimserver.py -- this file contains the ipython stuff
27 ipy_vimserver.py -- this file contains the ipython stuff
28 ipy.vim -- this file contains the gvim stuff
28 ipy.vim -- this file contains the gvim stuff
@@ -40,7 +40,7 b' from Numeric import *'
40 inf = infty = Infinity = (array([1])/0.0)[0]
40 inf = infty = Infinity = (array([1])/0.0)[0]
41
41
42 #****************************************************************************
42 #****************************************************************************
43 # function definitions
43 # function definitions
44 exp_safe_MIN = math.log(2.2250738585072014e-308)
44 exp_safe_MIN = math.log(2.2250738585072014e-308)
45 exp_safe_MAX = 1.7976931348623157e+308
45 exp_safe_MAX = 1.7976931348623157e+308
46
46
@@ -140,12 +140,12 b' def norm(a,p=2):'
140
140
141 Ref: http://mathworld.wolfram.com/VectorNorm.html
141 Ref: http://mathworld.wolfram.com/VectorNorm.html
142 http://mathworld.wolfram.com/L-Infinity-Norm.html"""
142 http://mathworld.wolfram.com/L-Infinity-Norm.html"""
143
143
144 if p in ('inf','Infinity'):
144 if p in ('inf','Infinity'):
145 return max(absolute(a).flat)
145 return max(absolute(a).flat)
146 else:
146 else:
147 return (sum_flat(absolute(a)**p))**(1.0/p)
147 return (sum_flat(absolute(a)**p))**(1.0/p)
148
148
149 def frange(xini,xfin=None,delta=None,**kw):
149 def frange(xini,xfin=None,delta=None,**kw):
150 """frange([start,] stop[, step, keywords]) -> array of floats
150 """frange([start,] stop[, step, keywords]) -> array of floats
151
151
@@ -183,14 +183,14 b' def frange(xini,xfin=None,delta=None,**kw):'
183 #defaults
183 #defaults
184 kw.setdefault('closed',1)
184 kw.setdefault('closed',1)
185 endpoint = kw['closed'] != 0
185 endpoint = kw['closed'] != 0
186
186
187 # funny logic to allow the *first* argument to be optional (like range())
187 # funny logic to allow the *first* argument to be optional (like range())
188 # This was modified with a simpler version from a similar frange() found
188 # This was modified with a simpler version from a similar frange() found
189 # at http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66472
189 # at http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66472
190 if xfin == None:
190 if xfin == None:
191 xfin = xini + 0.0
191 xfin = xini + 0.0
192 xini = 0.0
192 xini = 0.0
193
193
194 if delta == None:
194 if delta == None:
195 delta = 1.0
195 delta = 1.0
196
196
@@ -223,7 +223,7 b" def identity(n,rank=2,typecode='l'):"
223
223
224 Since rank defaults to 2, this function behaves in the default case (when
224 Since rank defaults to 2, this function behaves in the default case (when
225 only n is given) like the Numeric identity function."""
225 only n is given) like the Numeric identity function."""
226
226
227 iden = zeros((n,)*rank,typecode=typecode)
227 iden = zeros((n,)*rank,typecode=typecode)
228 for i in range(n):
228 for i in range(n):
229 idx = (i,)*rank
229 idx = (i,)*rank
@@ -250,7 +250,7 b' def binary_repr(number, max_length = 1025):'
250 Increase the value of max_length for very large numbers. Note that on
250 Increase the value of max_length for very large numbers. Note that on
251 32-bit machines, 2**1023 is the largest integer power of 2 which can be
251 32-bit machines, 2**1023 is the largest integer power of 2 which can be
252 converted to a Python float."""
252 converted to a Python float."""
253
253
254 assert number < 2L << max_length
254 assert number < 2L << max_length
255 shifts = map (operator.rshift, max_length * [number], \
255 shifts = map (operator.rshift, max_length * [number], \
256 range (max_length - 1, -1, -1))
256 range (max_length - 1, -1, -1))
@@ -261,7 +261,7 b' def binary_repr(number, max_length = 1025):'
261
261
262 def log2(x,ln2 = math.log(2.0)):
262 def log2(x,ln2 = math.log(2.0)):
263 """Return the log(x) in base 2.
263 """Return the log(x) in base 2.
264
264
265 This is a _slow_ function but which is guaranteed to return the correct
265 This is a _slow_ function but which is guaranteed to return the correct
266 integer value if the input is an ineger exact power of 2."""
266 integer value if the input is an ineger exact power of 2."""
267
267
@@ -288,7 +288,7 b' def ispower2(n):'
288
288
289 def fromfunction_kw(function, dimensions, **kwargs):
289 def fromfunction_kw(function, dimensions, **kwargs):
290 """Drop-in replacement for fromfunction() from Numerical Python.
290 """Drop-in replacement for fromfunction() from Numerical Python.
291
291
292 Allows passing keyword arguments to the desired function.
292 Allows passing keyword arguments to the desired function.
293
293
294 Call it as (keywords are optional):
294 Call it as (keywords are optional):
@@ -38,10 +38,10 b' class AsyncFrontEndBase(FrontEndBase):'
38 Overrides FrontEndBase to wrap execute in a deferred result.
38 Overrides FrontEndBase to wrap execute in a deferred result.
39 All callbacks are made as callbacks on the deferred result.
39 All callbacks are made as callbacks on the deferred result.
40 """
40 """
41
41
42 implements(IFrontEnd)
42 implements(IFrontEnd)
43 classProvides(IFrontEndFactory)
43 classProvides(IFrontEndFactory)
44
44
45 def __init__(self, engine=None, history=None):
45 def __init__(self, engine=None, history=None):
46 assert(engine==None or IEngineCore.providedBy(engine))
46 assert(engine==None or IEngineCore.providedBy(engine))
47 self.engine = IEngineCore(engine)
47 self.engine = IEngineCore(engine)
@@ -49,26 +49,26 b' class AsyncFrontEndBase(FrontEndBase):'
49 self.history = FrontEndHistory(input_cache=[''])
49 self.history = FrontEndHistory(input_cache=[''])
50 else:
50 else:
51 self.history = history
51 self.history = history
52
52
53 def execute(self, block, blockID=None):
53 def execute(self, block, blockID=None):
54 """Execute the block and return the deferred result.
54 """Execute the block and return the deferred result.
55
55
56 Parameters:
56 Parameters:
57 block : {str, AST}
57 block : {str, AST}
58 blockID : any
58 blockID : any
59 Caller may provide an ID to identify this block.
59 Caller may provide an ID to identify this block.
60 result['blockID'] := blockID
60 result['blockID'] := blockID
61
61
62 Result:
62 Result:
63 Deferred result of self.interpreter.execute
63 Deferred result of self.interpreter.execute
64 """
64 """
65
65
66 if(not self.is_complete(block)):
66 if(not self.is_complete(block)):
67 return Failure(Exception("Block is not compilable"))
67 return Failure(Exception("Block is not compilable"))
68
68
69 if(blockID == None):
69 if(blockID == None):
70 blockID = guid.generate()
70 blockID = guid.generate()
71
71
72 d = self.engine.execute(block)
72 d = self.engine.execute(block)
73 d.addCallback(self._add_history, block=block)
73 d.addCallback(self._add_history, block=block)
74 d.addCallbacks(self._add_block_id_for_result,
74 d.addCallbacks(self._add_block_id_for_result,
@@ -76,7 +76,7 b' class AsyncFrontEndBase(FrontEndBase):'
76 callbackArgs=(blockID,),
76 callbackArgs=(blockID,),
77 errbackArgs=(blockID,))
77 errbackArgs=(blockID,))
78 d.addBoth(self.update_cell_prompt, blockID=blockID)
78 d.addBoth(self.update_cell_prompt, blockID=blockID)
79 d.addCallbacks(self.render_result,
79 d.addCallbacks(self.render_result,
80 errback=self.render_error)
80 errback=self.render_error)
81
81
82 return d
82 return d
@@ -1,10 +1,10 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 # -*- test-case-name: IPython.frontend.cocoa.tests.test_cocoa_frontend -*-
2 # -*- test-case-name: IPython.frontend.cocoa.tests.test_cocoa_frontend -*-
3
3
4 """PyObjC classes to provide a Cocoa frontend to the
4 """PyObjC classes to provide a Cocoa frontend to the
5 IPython.kernel.engineservice.IEngineBase.
5 IPython.kernel.engineservice.IEngineBase.
6
6
7 To add an IPython interpreter to a cocoa app, instantiate an
7 To add an IPython interpreter to a cocoa app, instantiate an
8 IPythonCocoaController in a XIB and connect its textView outlet to an
8 IPythonCocoaController in a XIB and connect its textView outlet to an
9 NSTextView instance in your UI. That's it.
9 NSTextView instance in your UI. That's it.
10
10
@@ -32,7 +32,7 b' from Foundation import NSObject, NSMutableArray, NSMutableDictionary,\\'
32 NSLog, NSNotificationCenter, NSMakeRange,\
32 NSLog, NSNotificationCenter, NSMakeRange,\
33 NSLocalizedString, NSIntersectionRange,\
33 NSLocalizedString, NSIntersectionRange,\
34 NSString, NSAutoreleasePool
34 NSString, NSAutoreleasePool
35
35
36 from AppKit import NSApplicationWillTerminateNotification, NSBeep,\
36 from AppKit import NSApplicationWillTerminateNotification, NSBeep,\
37 NSTextView, NSRulerView, NSVerticalRuler
37 NSTextView, NSRulerView, NSVerticalRuler
38
38
@@ -49,14 +49,14 b' from twisted.python.failure import Failure'
49 # Classes to implement the Cocoa frontend
49 # Classes to implement the Cocoa frontend
50 #-----------------------------------------------------------------------------
50 #-----------------------------------------------------------------------------
51
51
52 # TODO:
52 # TODO:
53 # 1. use MultiEngineClient and out-of-process engine rather than
53 # 1. use MultiEngineClient and out-of-process engine rather than
54 # ThreadedEngineService?
54 # ThreadedEngineService?
55 # 2. integrate Xgrid launching of engines
55 # 2. integrate Xgrid launching of engines
56
56
57 class AutoreleasePoolWrappedThreadedEngineService(ThreadedEngineService):
57 class AutoreleasePoolWrappedThreadedEngineService(ThreadedEngineService):
58 """Wrap all blocks in an NSAutoreleasePool"""
58 """Wrap all blocks in an NSAutoreleasePool"""
59
59
60 def wrapped_execute(self, msg, lines):
60 def wrapped_execute(self, msg, lines):
61 """wrapped_execute"""
61 """wrapped_execute"""
62 try:
62 try:
@@ -65,9 +65,9 b' class AutoreleasePoolWrappedThreadedEngineService(ThreadedEngineService):'
65 self).wrapped_execute(msg, lines)
65 self).wrapped_execute(msg, lines)
66 finally:
66 finally:
67 p.drain()
67 p.drain()
68
68
69 return result
69 return result
70
70
71
71
72
72
73 class Cell(NSObject):
73 class Cell(NSObject):
@@ -75,20 +75,20 b' class Cell(NSObject):'
75 Representation of the prompts, input and output of a cell in the
75 Representation of the prompts, input and output of a cell in the
76 frontend
76 frontend
77 """
77 """
78
78
79 blockNumber = objc.ivar().unsigned_long()
79 blockNumber = objc.ivar().unsigned_long()
80 blockID = objc.ivar()
80 blockID = objc.ivar()
81 inputBlock = objc.ivar()
81 inputBlock = objc.ivar()
82 output = objc.ivar()
82 output = objc.ivar()
83
84
83
85
84
85
86 class CellBlock(object):
86 class CellBlock(object):
87 """
87 """
88 Storage for information about text ranges relating to a single cell
88 Storage for information about text ranges relating to a single cell
89 """
89 """
90
90
91
91
92 def __init__(self, inputPromptRange, inputRange=None, outputPromptRange=None,
92 def __init__(self, inputPromptRange, inputRange=None, outputPromptRange=None,
93 outputRange=None):
93 outputRange=None):
94 super(CellBlock, self).__init__()
94 super(CellBlock, self).__init__()
@@ -96,10 +96,10 b' class CellBlock(object):'
96 self.inputRange = inputRange
96 self.inputRange = inputRange
97 self.outputPromptRange = outputPromptRange
97 self.outputPromptRange = outputPromptRange
98 self.outputRange = outputRange
98 self.outputRange = outputRange
99
99
100 def update_ranges_for_insertion(self, text, textRange):
100 def update_ranges_for_insertion(self, text, textRange):
101 """Update ranges for text insertion at textRange"""
101 """Update ranges for text insertion at textRange"""
102
102
103 for r in [self.inputPromptRange,self.inputRange,
103 for r in [self.inputPromptRange,self.inputRange,
104 self.outputPromptRange, self.outputRange]:
104 self.outputPromptRange, self.outputRange]:
105 if(r == None):
105 if(r == None):
@@ -117,11 +117,11 b' class CellBlock(object):'
117 r.length += len(text) - intersection.length
117 r.length += len(text) - intersection.length
118 else:
118 else:
119 r.length -= intersection.length
119 r.length -= intersection.length
120
120
121
121
122 def update_ranges_for_deletion(self, textRange):
122 def update_ranges_for_deletion(self, textRange):
123 """Update ranges for text deletion at textRange"""
123 """Update ranges for text deletion at textRange"""
124
124
125 for r in [self.inputPromptRange,self.inputRange,
125 for r in [self.inputPromptRange,self.inputRange,
126 self.outputPromptRange, self.outputRange]:
126 self.outputPromptRange, self.outputRange]:
127 if(r==None):
127 if(r==None):
@@ -139,52 +139,52 b' class CellBlock(object):'
139 r.length += intersection.length
139 r.length += intersection.length
140 else:
140 else:
141 r.length -= intersection.length
141 r.length -= intersection.length
142
142
143 def __repr__(self):
143 def __repr__(self):
144 return 'CellBlock('+ str((self.inputPromptRange,
144 return 'CellBlock('+ str((self.inputPromptRange,
145 self.inputRange,
145 self.inputRange,
146 self.outputPromptRange,
146 self.outputPromptRange,
147 self.outputRange)) + ')'
147 self.outputRange)) + ')'
148
149
148
150
149
151
150
151
152 class IPythonCocoaController(NSObject, AsyncFrontEndBase):
152 class IPythonCocoaController(NSObject, AsyncFrontEndBase):
153 userNS = objc.ivar() #mirror of engine.user_ns (key=>str(value))
153 userNS = objc.ivar() #mirror of engine.user_ns (key=>str(value))
154 waitingForEngine = objc.ivar().bool()
154 waitingForEngine = objc.ivar().bool()
155 textView = objc.IBOutlet()
155 textView = objc.IBOutlet()
156
156
157 def init(self):
157 def init(self):
158 self = super(IPythonCocoaController, self).init()
158 self = super(IPythonCocoaController, self).init()
159 AsyncFrontEndBase.__init__(self,
159 AsyncFrontEndBase.__init__(self,
160 engine=AutoreleasePoolWrappedThreadedEngineService())
160 engine=AutoreleasePoolWrappedThreadedEngineService())
161 if(self != None):
161 if(self != None):
162 self._common_init()
162 self._common_init()
163
163
164 return self
164 return self
165
165
166 def _common_init(self):
166 def _common_init(self):
167 """_common_init"""
167 """_common_init"""
168
168
169 self.userNS = NSMutableDictionary.dictionary()
169 self.userNS = NSMutableDictionary.dictionary()
170 self.waitingForEngine = False
170 self.waitingForEngine = False
171
171
172 self.lines = {}
172 self.lines = {}
173 self.tabSpaces = 4
173 self.tabSpaces = 4
174 self.tabUsesSpaces = True
174 self.tabUsesSpaces = True
175 self.currentBlockID = self.next_block_ID()
175 self.currentBlockID = self.next_block_ID()
176 self.blockRanges = {} # blockID=>CellBlock
176 self.blockRanges = {} # blockID=>CellBlock
177
177
178
178
179 def awakeFromNib(self):
179 def awakeFromNib(self):
180 """awakeFromNib"""
180 """awakeFromNib"""
181
181
182 self._common_init()
182 self._common_init()
183
183
184 # Start the IPython engine
184 # Start the IPython engine
185 self.engine.startService()
185 self.engine.startService()
186 NSLog('IPython engine started')
186 NSLog('IPython engine started')
187
187
188 # Register for app termination
188 # Register for app termination
189 nc = NSNotificationCenter.defaultCenter()
189 nc = NSNotificationCenter.defaultCenter()
190 nc.addObserver_selector_name_object_(
190 nc.addObserver_selector_name_object_(
@@ -192,7 +192,7 b' class IPythonCocoaController(NSObject, AsyncFrontEndBase):'
192 'appWillTerminate:',
192 'appWillTerminate:',
193 NSApplicationWillTerminateNotification,
193 NSApplicationWillTerminateNotification,
194 None)
194 None)
195
195
196 self.textView.setDelegate_(self)
196 self.textView.setDelegate_(self)
197 self.textView.enclosingScrollView().setHasVerticalRuler_(True)
197 self.textView.enclosingScrollView().setHasVerticalRuler_(True)
198 r = NSRulerView.alloc().initWithScrollView_orientation_(
198 r = NSRulerView.alloc().initWithScrollView_orientation_(
@@ -202,30 +202,30 b' class IPythonCocoaController(NSObject, AsyncFrontEndBase):'
202 self.verticalRulerView.setClientView_(self.textView)
202 self.verticalRulerView.setClientView_(self.textView)
203 self._start_cli_banner()
203 self._start_cli_banner()
204 self.start_new_block()
204 self.start_new_block()
205
205
206
206
207 def appWillTerminate_(self, notification):
207 def appWillTerminate_(self, notification):
208 """appWillTerminate"""
208 """appWillTerminate"""
209
209
210 self.engine.stopService()
210 self.engine.stopService()
211
211
212
212
213 def complete(self, token):
213 def complete(self, token):
214 """Complete token in engine's user_ns
214 """Complete token in engine's user_ns
215
215
216 Parameters
216 Parameters
217 ----------
217 ----------
218 token : string
218 token : string
219
219
220 Result
220 Result
221 ------
221 ------
222 Deferred result of
222 Deferred result of
223 IPython.kernel.engineservice.IEngineBase.complete
223 IPython.kernel.engineservice.IEngineBase.complete
224 """
224 """
225
225
226 return self.engine.complete(token)
226 return self.engine.complete(token)
227
227
228
228
229 def execute(self, block, blockID=None):
229 def execute(self, block, blockID=None):
230 self.waitingForEngine = True
230 self.waitingForEngine = True
231 self.willChangeValueForKey_('commandHistory')
231 self.willChangeValueForKey_('commandHistory')
@@ -233,87 +233,87 b' class IPythonCocoaController(NSObject, AsyncFrontEndBase):'
233 blockID)
233 blockID)
234 d.addBoth(self._engine_done)
234 d.addBoth(self._engine_done)
235 d.addCallback(self._update_user_ns)
235 d.addCallback(self._update_user_ns)
236
236
237 return d
237 return d
238
238
239
239
240 def push_(self, namespace):
240 def push_(self, namespace):
241 """Push dictionary of key=>values to python namespace"""
241 """Push dictionary of key=>values to python namespace"""
242
242
243 self.waitingForEngine = True
243 self.waitingForEngine = True
244 self.willChangeValueForKey_('commandHistory')
244 self.willChangeValueForKey_('commandHistory')
245 d = self.engine.push(namespace)
245 d = self.engine.push(namespace)
246 d.addBoth(self._engine_done)
246 d.addBoth(self._engine_done)
247 d.addCallback(self._update_user_ns)
247 d.addCallback(self._update_user_ns)
248
248
249
249
250 def pull_(self, keys):
250 def pull_(self, keys):
251 """Pull keys from python namespace"""
251 """Pull keys from python namespace"""
252
252
253 self.waitingForEngine = True
253 self.waitingForEngine = True
254 result = blockingCallFromThread(self.engine.pull, keys)
254 result = blockingCallFromThread(self.engine.pull, keys)
255 self.waitingForEngine = False
255 self.waitingForEngine = False
256
256
257 @objc.signature('v@:@I')
257 @objc.signature('v@:@I')
258 def executeFileAtPath_encoding_(self, path, encoding):
258 def executeFileAtPath_encoding_(self, path, encoding):
259 """Execute file at path in an empty namespace. Update the engine
259 """Execute file at path in an empty namespace. Update the engine
260 user_ns with the resulting locals."""
260 user_ns with the resulting locals."""
261
261
262 lines,err = NSString.stringWithContentsOfFile_encoding_error_(
262 lines,err = NSString.stringWithContentsOfFile_encoding_error_(
263 path,
263 path,
264 encoding,
264 encoding,
265 None)
265 None)
266 self.engine.execute(lines)
266 self.engine.execute(lines)
267
267
268
268
269 def _engine_done(self, x):
269 def _engine_done(self, x):
270 self.waitingForEngine = False
270 self.waitingForEngine = False
271 self.didChangeValueForKey_('commandHistory')
271 self.didChangeValueForKey_('commandHistory')
272 return x
272 return x
273
273
274 def _update_user_ns(self, result):
274 def _update_user_ns(self, result):
275 """Update self.userNS from self.engine's namespace"""
275 """Update self.userNS from self.engine's namespace"""
276 d = self.engine.keys()
276 d = self.engine.keys()
277 d.addCallback(self._get_engine_namespace_values_for_keys)
277 d.addCallback(self._get_engine_namespace_values_for_keys)
278
278
279 return result
279 return result
280
280
281
281
282 def _get_engine_namespace_values_for_keys(self, keys):
282 def _get_engine_namespace_values_for_keys(self, keys):
283 d = self.engine.pull(keys)
283 d = self.engine.pull(keys)
284 d.addCallback(self._store_engine_namespace_values, keys=keys)
284 d.addCallback(self._store_engine_namespace_values, keys=keys)
285
285
286
286
287 def _store_engine_namespace_values(self, values, keys=[]):
287 def _store_engine_namespace_values(self, values, keys=[]):
288 assert(len(values) == len(keys))
288 assert(len(values) == len(keys))
289 self.willChangeValueForKey_('userNS')
289 self.willChangeValueForKey_('userNS')
290 for (k,v) in zip(keys,values):
290 for (k,v) in zip(keys,values):
291 self.userNS[k] = saferepr(v)
291 self.userNS[k] = saferepr(v)
292 self.didChangeValueForKey_('userNS')
292 self.didChangeValueForKey_('userNS')
293
293
294
294
295 def update_cell_prompt(self, result, blockID=None):
295 def update_cell_prompt(self, result, blockID=None):
296 print self.blockRanges
296 print self.blockRanges
297 if(isinstance(result, Failure)):
297 if(isinstance(result, Failure)):
298 prompt = self.input_prompt()
298 prompt = self.input_prompt()
299
299
300 else:
300 else:
301 prompt = self.input_prompt(number=result['number'])
301 prompt = self.input_prompt(number=result['number'])
302
302
303 r = self.blockRanges[blockID].inputPromptRange
303 r = self.blockRanges[blockID].inputPromptRange
304 self.insert_text(prompt,
304 self.insert_text(prompt,
305 textRange=r,
305 textRange=r,
306 scrollToVisible=False
306 scrollToVisible=False
307 )
307 )
308
308
309 return result
309 return result
310
310
311
311
312 def render_result(self, result):
312 def render_result(self, result):
313 blockID = result['blockID']
313 blockID = result['blockID']
314 inputRange = self.blockRanges[blockID].inputRange
314 inputRange = self.blockRanges[blockID].inputRange
315 del self.blockRanges[blockID]
315 del self.blockRanges[blockID]
316
316
317 #print inputRange,self.current_block_range()
317 #print inputRange,self.current_block_range()
318 self.insert_text('\n' +
318 self.insert_text('\n' +
319 self.output_prompt(number=result['number']) +
319 self.output_prompt(number=result['number']) +
@@ -322,8 +322,8 b' class IPythonCocoaController(NSObject, AsyncFrontEndBase):'
322 textRange=NSMakeRange(inputRange.location+inputRange.length,
322 textRange=NSMakeRange(inputRange.location+inputRange.length,
323 0))
323 0))
324 return result
324 return result
325
325
326
326
327 def render_error(self, failure):
327 def render_error(self, failure):
328 print failure
328 print failure
329 blockID = failure.blockID
329 blockID = failure.blockID
@@ -338,82 +338,82 b' class IPythonCocoaController(NSObject, AsyncFrontEndBase):'
338 0))
338 0))
339 self.start_new_block()
339 self.start_new_block()
340 return failure
340 return failure
341
341
342
342
343 def _start_cli_banner(self):
343 def _start_cli_banner(self):
344 """Print banner"""
344 """Print banner"""
345
345
346 banner = """IPython1 %s -- An enhanced Interactive Python.""" % \
346 banner = """IPython1 %s -- An enhanced Interactive Python.""" % \
347 IPython.__version__
347 IPython.__version__
348
348
349 self.insert_text(banner + '\n\n')
349 self.insert_text(banner + '\n\n')
350
350
351
351
352 def start_new_block(self):
352 def start_new_block(self):
353 """"""
353 """"""
354
354
355 self.currentBlockID = self.next_block_ID()
355 self.currentBlockID = self.next_block_ID()
356 self.blockRanges[self.currentBlockID] = self.new_cell_block()
356 self.blockRanges[self.currentBlockID] = self.new_cell_block()
357 self.insert_text(self.input_prompt(),
357 self.insert_text(self.input_prompt(),
358 textRange=self.current_block_range().inputPromptRange)
358 textRange=self.current_block_range().inputPromptRange)
359
359
360
360
361
361
362 def next_block_ID(self):
362 def next_block_ID(self):
363
363
364 return guid.generate()
364 return guid.generate()
365
365
366 def new_cell_block(self):
366 def new_cell_block(self):
367 """A new CellBlock at the end of self.textView.textStorage()"""
367 """A new CellBlock at the end of self.textView.textStorage()"""
368
368
369 return CellBlock(NSMakeRange(self.textView.textStorage().length(),
369 return CellBlock(NSMakeRange(self.textView.textStorage().length(),
370 0), #len(self.input_prompt())),
370 0), #len(self.input_prompt())),
371 NSMakeRange(self.textView.textStorage().length(),# + len(self.input_prompt()),
371 NSMakeRange(self.textView.textStorage().length(),# + len(self.input_prompt()),
372 0))
372 0))
373
373
374
374
375 def current_block_range(self):
375 def current_block_range(self):
376 return self.blockRanges.get(self.currentBlockID,
376 return self.blockRanges.get(self.currentBlockID,
377 self.new_cell_block())
377 self.new_cell_block())
378
378
379 def current_block(self):
379 def current_block(self):
380 """The current block's text"""
380 """The current block's text"""
381
381
382 return self.text_for_range(self.current_block_range().inputRange)
382 return self.text_for_range(self.current_block_range().inputRange)
383
383
384 def text_for_range(self, textRange):
384 def text_for_range(self, textRange):
385 """text_for_range"""
385 """text_for_range"""
386
386
387 ts = self.textView.textStorage()
387 ts = self.textView.textStorage()
388 return ts.string().substringWithRange_(textRange)
388 return ts.string().substringWithRange_(textRange)
389
389
390 def current_line(self):
390 def current_line(self):
391 block = self.text_for_range(self.current_block_range().inputRange)
391 block = self.text_for_range(self.current_block_range().inputRange)
392 block = block.split('\n')
392 block = block.split('\n')
393 return block[-1]
393 return block[-1]
394
394
395
395
396 def insert_text(self, string=None, textRange=None, scrollToVisible=True):
396 def insert_text(self, string=None, textRange=None, scrollToVisible=True):
397 """Insert text into textView at textRange, updating blockRanges
397 """Insert text into textView at textRange, updating blockRanges
398 as necessary
398 as necessary
399 """
399 """
400 if(textRange == None):
400 if(textRange == None):
401 #range for end of text
401 #range for end of text
402 textRange = NSMakeRange(self.textView.textStorage().length(), 0)
402 textRange = NSMakeRange(self.textView.textStorage().length(), 0)
403
403
404
404
405 self.textView.replaceCharactersInRange_withString_(
405 self.textView.replaceCharactersInRange_withString_(
406 textRange, string)
406 textRange, string)
407
407
408 for r in self.blockRanges.itervalues():
408 for r in self.blockRanges.itervalues():
409 r.update_ranges_for_insertion(string, textRange)
409 r.update_ranges_for_insertion(string, textRange)
410
410
411 self.textView.setSelectedRange_(textRange)
411 self.textView.setSelectedRange_(textRange)
412 if(scrollToVisible):
412 if(scrollToVisible):
413 self.textView.scrollRangeToVisible_(textRange)
413 self.textView.scrollRangeToVisible_(textRange)
414
414
415
415
416
416
417 def replace_current_block_with_string(self, textView, string):
417 def replace_current_block_with_string(self, textView, string):
418 textView.replaceCharactersInRange_withString_(
418 textView.replaceCharactersInRange_withString_(
419 self.current_block_range().inputRange,
419 self.current_block_range().inputRange,
@@ -422,53 +422,53 b' class IPythonCocoaController(NSObject, AsyncFrontEndBase):'
422 r = NSMakeRange(textView.textStorage().length(), 0)
422 r = NSMakeRange(textView.textStorage().length(), 0)
423 textView.scrollRangeToVisible_(r)
423 textView.scrollRangeToVisible_(r)
424 textView.setSelectedRange_(r)
424 textView.setSelectedRange_(r)
425
425
426
426
427 def current_indent_string(self):
427 def current_indent_string(self):
428 """returns string for indent or None if no indent"""
428 """returns string for indent or None if no indent"""
429
429
430 return self._indent_for_block(self.current_block())
430 return self._indent_for_block(self.current_block())
431
431
432
432
433 def _indent_for_block(self, block):
433 def _indent_for_block(self, block):
434 lines = block.split('\n')
434 lines = block.split('\n')
435 if(len(lines) > 1):
435 if(len(lines) > 1):
436 currentIndent = len(lines[-1]) - len(lines[-1].lstrip())
436 currentIndent = len(lines[-1]) - len(lines[-1].lstrip())
437 if(currentIndent == 0):
437 if(currentIndent == 0):
438 currentIndent = self.tabSpaces
438 currentIndent = self.tabSpaces
439
439
440 if(self.tabUsesSpaces):
440 if(self.tabUsesSpaces):
441 result = ' ' * currentIndent
441 result = ' ' * currentIndent
442 else:
442 else:
443 result = '\t' * (currentIndent/self.tabSpaces)
443 result = '\t' * (currentIndent/self.tabSpaces)
444 else:
444 else:
445 result = None
445 result = None
446
446
447 return result
447 return result
448
448
449
449
450 # NSTextView delegate methods...
450 # NSTextView delegate methods...
451 def textView_doCommandBySelector_(self, textView, selector):
451 def textView_doCommandBySelector_(self, textView, selector):
452 assert(textView == self.textView)
452 assert(textView == self.textView)
453 NSLog("textView_doCommandBySelector_: "+selector)
453 NSLog("textView_doCommandBySelector_: "+selector)
454
454
455
455
456 if(selector == 'insertNewline:'):
456 if(selector == 'insertNewline:'):
457 indent = self.current_indent_string()
457 indent = self.current_indent_string()
458 if(indent):
458 if(indent):
459 line = indent + self.current_line()
459 line = indent + self.current_line()
460 else:
460 else:
461 line = self.current_line()
461 line = self.current_line()
462
462
463 if(self.is_complete(self.current_block())):
463 if(self.is_complete(self.current_block())):
464 self.execute(self.current_block(),
464 self.execute(self.current_block(),
465 blockID=self.currentBlockID)
465 blockID=self.currentBlockID)
466 self.start_new_block()
466 self.start_new_block()
467
467
468 return True
468 return True
469
469
470 return False
470 return False
471
471
472 elif(selector == 'moveUp:'):
472 elif(selector == 'moveUp:'):
473 prevBlock = self.get_history_previous(self.current_block())
473 prevBlock = self.get_history_previous(self.current_block())
474 if(prevBlock != None):
474 if(prevBlock != None):
@@ -476,7 +476,7 b' class IPythonCocoaController(NSObject, AsyncFrontEndBase):'
476 else:
476 else:
477 NSBeep()
477 NSBeep()
478 return True
478 return True
479
479
480 elif(selector == 'moveDown:'):
480 elif(selector == 'moveDown:'):
481 nextBlock = self.get_history_next()
481 nextBlock = self.get_history_next()
482 if(nextBlock != None):
482 if(nextBlock != None):
@@ -484,10 +484,10 b' class IPythonCocoaController(NSObject, AsyncFrontEndBase):'
484 else:
484 else:
485 NSBeep()
485 NSBeep()
486 return True
486 return True
487
487
488 elif(selector == 'moveToBeginningOfParagraph:'):
488 elif(selector == 'moveToBeginningOfParagraph:'):
489 textView.setSelectedRange_(NSMakeRange(
489 textView.setSelectedRange_(NSMakeRange(
490 self.current_block_range().inputRange.location,
490 self.current_block_range().inputRange.location,
491 0))
491 0))
492 return True
492 return True
493 elif(selector == 'moveToEndOfParagraph:'):
493 elif(selector == 'moveToEndOfParagraph:'):
@@ -499,16 +499,16 b' class IPythonCocoaController(NSObject, AsyncFrontEndBase):'
499 if(textView.selectedRange().location <= \
499 if(textView.selectedRange().location <= \
500 self.current_block_range().location):
500 self.current_block_range().location):
501 raise NotImplemented()
501 raise NotImplemented()
502
502
503 return False # don't actually handle the delete
503 return False # don't actually handle the delete
504
504
505 elif(selector == 'insertTab:'):
505 elif(selector == 'insertTab:'):
506 if(len(self.current_line().strip()) == 0): #only white space
506 if(len(self.current_line().strip()) == 0): #only white space
507 return False
507 return False
508 else:
508 else:
509 self.textView.complete_(self)
509 self.textView.complete_(self)
510 return True
510 return True
511
511
512 elif(selector == 'deleteBackward:'):
512 elif(selector == 'deleteBackward:'):
513 #if we're at the beginning of the current block, ignore
513 #if we're at the beginning of the current block, ignore
514 if(textView.selectedRange().location == \
514 if(textView.selectedRange().location == \
@@ -523,17 +523,17 b' class IPythonCocoaController(NSObject, AsyncFrontEndBase):'
523 r.update_ranges_for_deletion(deleteRange)
523 r.update_ranges_for_deletion(deleteRange)
524 return False
524 return False
525 return False
525 return False
526
526
527
527
528 def textView_shouldChangeTextInRanges_replacementStrings_(self,
528 def textView_shouldChangeTextInRanges_replacementStrings_(self,
529 textView, ranges, replacementStrings):
529 textView, ranges, replacementStrings):
530 """
530 """
531 Delegate method for NSTextView.
531 Delegate method for NSTextView.
532
532
533 Refuse change text in ranges not at end, but make those changes at
533 Refuse change text in ranges not at end, but make those changes at
534 end.
534 end.
535 """
535 """
536
536
537 assert(len(ranges) == len(replacementStrings))
537 assert(len(ranges) == len(replacementStrings))
538 allow = True
538 allow = True
539 for r,s in zip(ranges, replacementStrings):
539 for r,s in zip(ranges, replacementStrings):
@@ -542,10 +542,10 b' class IPythonCocoaController(NSObject, AsyncFrontEndBase):'
542 r.location < self.current_block_range().inputRange.location):
542 r.location < self.current_block_range().inputRange.location):
543 self.insert_text(s)
543 self.insert_text(s)
544 allow = False
544 allow = False
545
545
546 return allow
546 return allow
547
547
548 def textView_completions_forPartialWordRange_indexOfSelectedItem_(self,
548 def textView_completions_forPartialWordRange_indexOfSelectedItem_(self,
549 textView, words, charRange, index):
549 textView, words, charRange, index):
550 try:
550 try:
551 ts = textView.textStorage()
551 ts = textView.textStorage()
@@ -554,7 +554,7 b' class IPythonCocoaController(NSObject, AsyncFrontEndBase):'
554 except:
554 except:
555 completions = objc.nil
555 completions = objc.nil
556 NSBeep()
556 NSBeep()
557
557
558 return (completions,0)
558 return (completions,0)
559
559
560
560
@@ -2,7 +2,7 b''
2 """
2 """
3 setup.py
3 setup.py
4
4
5 Setuptools installer script for generating a Cocoa plugin for the
5 Setuptools installer script for generating a Cocoa plugin for the
6 IPython cocoa frontend
6 IPython cocoa frontend
7
7
8 Author: Barry Wark
8 Author: Barry Wark
@@ -1,18 +1,18 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """This file contains unittests for the
2 """This file contains unittests for the
3 IPython.frontend.cocoa.cocoa_frontend module.
3 IPython.frontend.cocoa.cocoa_frontend module.
4 """
4 """
5 __docformat__ = "restructuredtext en"
5 __docformat__ = "restructuredtext en"
6
6
7 #---------------------------------------------------------------------------
7 #---------------------------------------------------------------------------
8 # Copyright (C) 2005 The IPython Development Team
8 # Copyright (C) 2005 The IPython Development Team
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 # Imports
15 # Imports
16 #---------------------------------------------------------------------------
16 #---------------------------------------------------------------------------
17
17
18 # Tell nose to skip this module
18 # Tell nose to skip this module
@@ -84,14 +84,14 b' class TestIPythonCocoaControler(unittest.TestCase):'
84 """test that current_indent_string returns current indent or None.
84 """test that current_indent_string returns current indent or None.
85 Uses _indent_for_block for direct unit testing.
85 Uses _indent_for_block for direct unit testing.
86 """
86 """
87
87
88 self.controller.tabUsesSpaces = True
88 self.controller.tabUsesSpaces = True
89 self.assert_(self.controller._indent_for_block("""a=3""") == None)
89 self.assert_(self.controller._indent_for_block("""a=3""") == None)
90 self.assert_(self.controller._indent_for_block("") == None)
90 self.assert_(self.controller._indent_for_block("") == None)
91 block = """def test():\n a=3"""
91 block = """def test():\n a=3"""
92 self.assert_(self.controller._indent_for_block(block) == \
92 self.assert_(self.controller._indent_for_block(block) == \
93 ' ' * self.controller.tabSpaces)
93 ' ' * self.controller.tabSpaces)
94
94
95 block = """if(True):\n%sif(False):\n%spass""" % \
95 block = """if(True):\n%sif(False):\n%spass""" % \
96 (' '*self.controller.tabSpaces,
96 (' '*self.controller.tabSpaces,
97 2*' '*self.controller.tabSpaces)
97 2*' '*self.controller.tabSpaces)
@@ -1,10 +1,10 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 # -*- test-case-name: IPython.frontend.tests.test_frontendbase -*-
2 # -*- test-case-name: IPython.frontend.tests.test_frontendbase -*-
3 """
3 """
4 frontendbase provides an interface and base class for GUI frontends for
4 frontendbase provides an interface and base class for GUI frontends for
5 IPython.kernel/IPython.kernel.core.
5 IPython.kernel/IPython.kernel.core.
6
6
7 Frontend implementations will likely want to subclass FrontEndBase.
7 Frontend implementations will likely want to subclass FrontEndBase.
8
8
9 Author: Barry Wark
9 Author: Barry Wark
10 """
10 """
@@ -26,8 +26,8 b' from IPython.external import guid'
26
26
27
27
28 from IPython.frontend.zopeinterface import (
28 from IPython.frontend.zopeinterface import (
29 Interface,
29 Interface,
30 Attribute,
30 Attribute,
31 )
31 )
32 from IPython.kernel.core.history import FrontEndHistory
32 from IPython.kernel.core.history import FrontEndHistory
33 from IPython.kernel.core.util import Bunch
33 from IPython.kernel.core.util import Bunch
@@ -47,103 +47,103 b" rc.prompt_out = r'Out [$number]: '"
47
47
48 class IFrontEndFactory(Interface):
48 class IFrontEndFactory(Interface):
49 """Factory interface for frontends."""
49 """Factory interface for frontends."""
50
50
51 def __call__(engine=None, history=None):
51 def __call__(engine=None, history=None):
52 """
52 """
53 Parameters:
53 Parameters:
54 interpreter : IPython.kernel.engineservice.IEngineCore
54 interpreter : IPython.kernel.engineservice.IEngineCore
55 """
55 """
56
56
57 pass
57 pass
58
58
59
59
60 class IFrontEnd(Interface):
60 class IFrontEnd(Interface):
61 """Interface for frontends. All methods return t.i.d.Deferred"""
61 """Interface for frontends. All methods return t.i.d.Deferred"""
62
62
63 Attribute("input_prompt_template", "string.Template instance\
63 Attribute("input_prompt_template", "string.Template instance\
64 substituteable with execute result.")
64 substituteable with execute result.")
65 Attribute("output_prompt_template", "string.Template instance\
65 Attribute("output_prompt_template", "string.Template instance\
66 substituteable with execute result.")
66 substituteable with execute result.")
67 Attribute("continuation_prompt_template", "string.Template instance\
67 Attribute("continuation_prompt_template", "string.Template instance\
68 substituteable with execute result.")
68 substituteable with execute result.")
69
69
70 def update_cell_prompt(result, blockID=None):
70 def update_cell_prompt(result, blockID=None):
71 """Subclass may override to update the input prompt for a block.
71 """Subclass may override to update the input prompt for a block.
72
72
73 In asynchronous frontends, this method will be called as a
73 In asynchronous frontends, this method will be called as a
74 twisted.internet.defer.Deferred's callback/errback.
74 twisted.internet.defer.Deferred's callback/errback.
75 Implementations should thus return result when finished.
75 Implementations should thus return result when finished.
76
76
77 Result is a result dict in case of success, and a
77 Result is a result dict in case of success, and a
78 twisted.python.util.failure.Failure in case of an error
78 twisted.python.util.failure.Failure in case of an error
79 """
79 """
80
80
81 pass
81 pass
82
82
83 def render_result(result):
83 def render_result(result):
84 """Render the result of an execute call. Implementors may choose the
84 """Render the result of an execute call. Implementors may choose the
85 method of rendering.
85 method of rendering.
86 For example, a notebook-style frontend might render a Chaco plot
86 For example, a notebook-style frontend might render a Chaco plot
87 inline.
87 inline.
88
88
89 Parameters:
89 Parameters:
90 result : dict (result of IEngineBase.execute )
90 result : dict (result of IEngineBase.execute )
91 blockID = result['blockID']
91 blockID = result['blockID']
92
92
93 Result:
93 Result:
94 Output of frontend rendering
94 Output of frontend rendering
95 """
95 """
96
96
97 pass
97 pass
98
98
99 def render_error(failure):
99 def render_error(failure):
100 """Subclasses must override to render the failure.
100 """Subclasses must override to render the failure.
101
101
102 In asynchronous frontend, since this method will be called as a
102 In asynchronous frontend, since this method will be called as a
103 twisted.internet.defer.Deferred's callback. Implementations
103 twisted.internet.defer.Deferred's callback. Implementations
104 should thus return result when finished.
104 should thus return result when finished.
105
105
106 blockID = failure.blockID
106 blockID = failure.blockID
107 """
107 """
108
108
109 pass
109 pass
110
110
111 def input_prompt(number=''):
111 def input_prompt(number=''):
112 """Returns the input prompt by subsituting into
112 """Returns the input prompt by subsituting into
113 self.input_prompt_template
113 self.input_prompt_template
114 """
114 """
115 pass
115 pass
116
116
117 def output_prompt(number=''):
117 def output_prompt(number=''):
118 """Returns the output prompt by subsituting into
118 """Returns the output prompt by subsituting into
119 self.output_prompt_template
119 self.output_prompt_template
120 """
120 """
121
121
122 pass
122 pass
123
123
124 def continuation_prompt():
124 def continuation_prompt():
125 """Returns the continuation prompt by subsituting into
125 """Returns the continuation prompt by subsituting into
126 self.continuation_prompt_template
126 self.continuation_prompt_template
127 """
127 """
128
128
129 pass
129 pass
130
130
131 def is_complete(block):
131 def is_complete(block):
132 """Returns True if block is complete, False otherwise."""
132 """Returns True if block is complete, False otherwise."""
133
133
134 pass
134 pass
135
135
136
136
137 def get_history_previous(current_block):
137 def get_history_previous(current_block):
138 """Returns the block previous in the history. Saves currentBlock if
138 """Returns the block previous in the history. Saves currentBlock if
139 the history_cursor is currently at the end of the input history"""
139 the history_cursor is currently at the end of the input history"""
140 pass
140 pass
141
141
142 def get_history_next():
142 def get_history_next():
143 """Returns the next block in the history."""
143 """Returns the next block in the history."""
144
144
145 pass
145 pass
146
146
147 def complete(self, line):
147 def complete(self, line):
148 """Returns the list of possible completions, and the completed
148 """Returns the list of possible completions, and the completed
149 line.
149 line.
@@ -156,7 +156,7 b' class IFrontEnd(Interface):'
156
156
157
157
158 ##############################################################################
158 ##############################################################################
159 # Base class for all the frontends.
159 # Base class for all the frontends.
160 ##############################################################################
160 ##############################################################################
161
161
162 class FrontEndBase(object):
162 class FrontEndBase(object):
@@ -164,86 +164,86 b' class FrontEndBase(object):'
164 FrontEndBase manages the state tasks for a CLI frontend:
164 FrontEndBase manages the state tasks for a CLI frontend:
165 - Input and output history management
165 - Input and output history management
166 - Input/continuation and output prompt generation
166 - Input/continuation and output prompt generation
167
167
168 Some issues (due to possibly unavailable engine):
168 Some issues (due to possibly unavailable engine):
169 - How do we get the current cell number for the engine?
169 - How do we get the current cell number for the engine?
170 - How do we handle completions?
170 - How do we handle completions?
171 """
171 """
172
172
173 history_cursor = 0
173 history_cursor = 0
174
174
175 input_prompt_template = string.Template(rc.prompt_in1)
175 input_prompt_template = string.Template(rc.prompt_in1)
176 output_prompt_template = string.Template(rc.prompt_out)
176 output_prompt_template = string.Template(rc.prompt_out)
177 continuation_prompt_template = string.Template(rc.prompt_in2)
177 continuation_prompt_template = string.Template(rc.prompt_in2)
178
178
179 def __init__(self, shell=None, history=None):
179 def __init__(self, shell=None, history=None):
180 self.shell = shell
180 self.shell = shell
181 if history is None:
181 if history is None:
182 self.history = FrontEndHistory(input_cache=[''])
182 self.history = FrontEndHistory(input_cache=[''])
183 else:
183 else:
184 self.history = history
184 self.history = history
185
185
186
186
187 def input_prompt(self, number=''):
187 def input_prompt(self, number=''):
188 """Returns the current input prompt
188 """Returns the current input prompt
189
189
190 It would be great to use ipython1.core.prompts.Prompt1 here
190 It would be great to use ipython1.core.prompts.Prompt1 here
191 """
191 """
192 return self.input_prompt_template.safe_substitute({'number':number})
192 return self.input_prompt_template.safe_substitute({'number':number})
193
193
194
194
195 def continuation_prompt(self):
195 def continuation_prompt(self):
196 """Returns the current continuation prompt"""
196 """Returns the current continuation prompt"""
197
197
198 return self.continuation_prompt_template.safe_substitute()
198 return self.continuation_prompt_template.safe_substitute()
199
199
200 def output_prompt(self, number=''):
200 def output_prompt(self, number=''):
201 """Returns the output prompt for result"""
201 """Returns the output prompt for result"""
202
202
203 return self.output_prompt_template.safe_substitute({'number':number})
203 return self.output_prompt_template.safe_substitute({'number':number})
204
204
205
205
206 def is_complete(self, block):
206 def is_complete(self, block):
207 """Determine if block is complete.
207 """Determine if block is complete.
208
208
209 Parameters
209 Parameters
210 block : string
210 block : string
211
211
212 Result
212 Result
213 True if block can be sent to the engine without compile errors.
213 True if block can be sent to the engine without compile errors.
214 False otherwise.
214 False otherwise.
215 """
215 """
216
216
217 try:
217 try:
218 is_complete = codeop.compile_command(block.rstrip() + '\n\n',
218 is_complete = codeop.compile_command(block.rstrip() + '\n\n',
219 "<string>", "exec")
219 "<string>", "exec")
220 except:
220 except:
221 return False
221 return False
222
222
223 lines = block.split('\n')
223 lines = block.split('\n')
224 return ((is_complete is not None)
224 return ((is_complete is not None)
225 and (len(lines)==1 or str(lines[-1])==''))
225 and (len(lines)==1 or str(lines[-1])==''))
226
226
227
227
228 def execute(self, block, blockID=None):
228 def execute(self, block, blockID=None):
229 """Execute the block and return the result.
229 """Execute the block and return the result.
230
230
231 Parameters:
231 Parameters:
232 block : {str, AST}
232 block : {str, AST}
233 blockID : any
233 blockID : any
234 Caller may provide an ID to identify this block.
234 Caller may provide an ID to identify this block.
235 result['blockID'] := blockID
235 result['blockID'] := blockID
236
236
237 Result:
237 Result:
238 Deferred result of self.interpreter.execute
238 Deferred result of self.interpreter.execute
239 """
239 """
240
240
241 if(not self.is_complete(block)):
241 if(not self.is_complete(block)):
242 raise Exception("Block is not compilable")
242 raise Exception("Block is not compilable")
243
243
244 if(blockID == None):
244 if(blockID == None):
245 blockID = guid.generate()
245 blockID = guid.generate()
246
246
247 try:
247 try:
248 result = self.shell.execute(block)
248 result = self.shell.execute(block)
249 except Exception,e:
249 except Exception,e:
@@ -254,90 +254,90 b' class FrontEndBase(object):'
254 result = self._add_block_id_for_result(result, blockID=blockID)
254 result = self._add_block_id_for_result(result, blockID=blockID)
255 result = self.update_cell_prompt(result, blockID=blockID)
255 result = self.update_cell_prompt(result, blockID=blockID)
256 result = self.render_result(result)
256 result = self.render_result(result)
257
257
258 return result
258 return result
259
259
260
260
261 def _add_block_id_for_result(self, result, blockID):
261 def _add_block_id_for_result(self, result, blockID):
262 """Add the blockID to result or failure. Unfortunatley, we have to
262 """Add the blockID to result or failure. Unfortunatley, we have to
263 treat failures differently than result dicts.
263 treat failures differently than result dicts.
264 """
264 """
265
265
266 result['blockID'] = blockID
266 result['blockID'] = blockID
267
267
268 return result
268 return result
269
269
270 def _add_block_id_for_failure(self, failure, blockID):
270 def _add_block_id_for_failure(self, failure, blockID):
271 """_add_block_id_for_failure"""
271 """_add_block_id_for_failure"""
272 failure.blockID = blockID
272 failure.blockID = blockID
273 return failure
273 return failure
274
274
275
275
276 def _add_history(self, result, block=None):
276 def _add_history(self, result, block=None):
277 """Add block to the history"""
277 """Add block to the history"""
278
278
279 assert(block != None)
279 assert(block != None)
280 self.history.add_items([block])
280 self.history.add_items([block])
281 self.history_cursor += 1
281 self.history_cursor += 1
282
282
283 return result
283 return result
284
284
285
285
286 def get_history_previous(self, current_block):
286 def get_history_previous(self, current_block):
287 """ Returns previous history string and decrement history cursor.
287 """ Returns previous history string and decrement history cursor.
288 """
288 """
289 command = self.history.get_history_item(self.history_cursor - 1)
289 command = self.history.get_history_item(self.history_cursor - 1)
290
290
291 if command is not None:
291 if command is not None:
292 if(self.history_cursor+1 == len(self.history.input_cache)):
292 if(self.history_cursor+1 == len(self.history.input_cache)):
293 self.history.input_cache[self.history_cursor] = current_block
293 self.history.input_cache[self.history_cursor] = current_block
294 self.history_cursor -= 1
294 self.history_cursor -= 1
295 return command
295 return command
296
296
297
297
298 def get_history_next(self):
298 def get_history_next(self):
299 """ Returns next history string and increment history cursor.
299 """ Returns next history string and increment history cursor.
300 """
300 """
301 command = self.history.get_history_item(self.history_cursor+1)
301 command = self.history.get_history_item(self.history_cursor+1)
302
302
303 if command is not None:
303 if command is not None:
304 self.history_cursor += 1
304 self.history_cursor += 1
305 return command
305 return command
306
306
307 ###
307 ###
308 # Subclasses probably want to override these methods...
308 # Subclasses probably want to override these methods...
309 ###
309 ###
310
310
311 def update_cell_prompt(self, result, blockID=None):
311 def update_cell_prompt(self, result, blockID=None):
312 """Subclass may override to update the input prompt for a block.
312 """Subclass may override to update the input prompt for a block.
313
313
314 This method only really makes sens in asyncrhonous frontend.
314 This method only really makes sens in asyncrhonous frontend.
315 Since this method will be called as a
315 Since this method will be called as a
316 twisted.internet.defer.Deferred's callback, implementations should
316 twisted.internet.defer.Deferred's callback, implementations should
317 return result when finished.
317 return result when finished.
318 """
318 """
319
319
320 raise NotImplementedError
320 raise NotImplementedError
321
321
322
322
323 def render_result(self, result):
323 def render_result(self, result):
324 """Subclasses must override to render result.
324 """Subclasses must override to render result.
325
325
326 In asynchronous frontends, this method will be called as a
326 In asynchronous frontends, this method will be called as a
327 twisted.internet.defer.Deferred's callback. Implementations
327 twisted.internet.defer.Deferred's callback. Implementations
328 should thus return result when finished.
328 should thus return result when finished.
329 """
329 """
330
330
331 raise NotImplementedError
331 raise NotImplementedError
332
332
333
333
334 def render_error(self, failure):
334 def render_error(self, failure):
335 """Subclasses must override to render the failure.
335 """Subclasses must override to render the failure.
336
336
337 In asynchronous frontends, this method will be called as a
337 In asynchronous frontends, this method will be called as a
338 twisted.internet.defer.Deferred's callback. Implementations
338 twisted.internet.defer.Deferred's callback. Implementations
339 should thus return result when finished.
339 should thus return result when finished.
340 """
340 """
341
341
342 raise NotImplementedError
342 raise NotImplementedError
343
343
@@ -48,13 +48,13 b' class LineFrontEndBase(FrontEndBase):'
48 to be the base class behind all the frontend that are line-oriented,
48 to be the base class behind all the frontend that are line-oriented,
49 rather than block-oriented.
49 rather than block-oriented.
50 """
50 """
51
51
52 # We need to keep the prompt number, to be able to increment
52 # We need to keep the prompt number, to be able to increment
53 # it when there is an exception.
53 # it when there is an exception.
54 prompt_number = 1
54 prompt_number = 1
55
55
56 # We keep a reference to the last result: it helps testing and
56 # We keep a reference to the last result: it helps testing and
57 # programatic control of the frontend.
57 # programatic control of the frontend.
58 last_result = dict(number=0)
58 last_result = dict(number=0)
59
59
60 # The last prompt displayed. Useful for continuation prompts.
60 # The last prompt displayed. Useful for continuation prompts.
@@ -93,11 +93,11 b' class LineFrontEndBase(FrontEndBase):'
93
93
94 def complete(self, line):
94 def complete(self, line):
95 """Complete line in engine's user_ns
95 """Complete line in engine's user_ns
96
96
97 Parameters
97 Parameters
98 ----------
98 ----------
99 line : string
99 line : string
100
100
101 Returns
101 Returns
102 -------
102 -------
103 The replacement for the line and the list of possible completions.
103 The replacement for the line and the list of possible completions.
@@ -105,11 +105,11 b' class LineFrontEndBase(FrontEndBase):'
105 completions = self.shell.complete(line)
105 completions = self.shell.complete(line)
106 complete_sep = re.compile('[\s\{\}\[\]\(\)\=]')
106 complete_sep = re.compile('[\s\{\}\[\]\(\)\=]')
107 if completions:
107 if completions:
108 prefix = common_prefix(completions)
108 prefix = common_prefix(completions)
109 residual = complete_sep.split(line)[:-1]
109 residual = complete_sep.split(line)[:-1]
110 line = line[:-len(residual)] + prefix
110 line = line[:-len(residual)] + prefix
111 return line, completions
111 return line, completions
112
112
113
113
114 def render_result(self, result):
114 def render_result(self, result):
115 """ Frontend-specific rendering of the result of a calculation
115 """ Frontend-specific rendering of the result of a calculation
@@ -118,15 +118,15 b' class LineFrontEndBase(FrontEndBase):'
118 if 'stdout' in result and result['stdout']:
118 if 'stdout' in result and result['stdout']:
119 self.write('\n' + result['stdout'])
119 self.write('\n' + result['stdout'])
120 if 'display' in result and result['display']:
120 if 'display' in result and result['display']:
121 self.write("%s%s\n" % (
121 self.write("%s%s\n" % (
122 self.output_prompt_template.substitute(
122 self.output_prompt_template.substitute(
123 number=result['number']),
123 number=result['number']),
124 result['display']['pprint']
124 result['display']['pprint']
125 ) )
125 ) )
126
126
127
127
128 def render_error(self, failure):
128 def render_error(self, failure):
129 """ Frontend-specific rendering of error.
129 """ Frontend-specific rendering of error.
130 """
130 """
131 self.write('\n\n'+str(failure)+'\n\n')
131 self.write('\n\n'+str(failure)+'\n\n')
132 return failure
132 return failure
@@ -146,7 +146,7 b' class LineFrontEndBase(FrontEndBase):'
146 # thus want to consider an empty string as a complete
146 # thus want to consider an empty string as a complete
147 # statement.
147 # statement.
148 return True
148 return True
149 elif ( len(self.input_buffer.split('\n'))>2
149 elif ( len(self.input_buffer.split('\n'))>2
150 and not re.findall(r"\n[\t ]*\n[\t ]*$", string)):
150 and not re.findall(r"\n[\t ]*\n[\t ]*$", string)):
151 return False
151 return False
152 else:
152 else:
@@ -157,7 +157,7 b' class LineFrontEndBase(FrontEndBase):'
157 # This should probably be done in a different place (like
157 # This should probably be done in a different place (like
158 # maybe 'prefilter_input' method? For now, this works.
158 # maybe 'prefilter_input' method? For now, this works.
159 clean_string = string.rstrip('\n')
159 clean_string = string.rstrip('\n')
160 if not clean_string.endswith('\\'): clean_string +='\n\n'
160 if not clean_string.endswith('\\'): clean_string +='\n\n'
161 is_complete = codeop.compile_command(clean_string,
161 is_complete = codeop.compile_command(clean_string,
162 "<string>", "exec")
162 "<string>", "exec")
163 self.release_output()
163 self.release_output()
@@ -228,10 +228,10 b' class LineFrontEndBase(FrontEndBase):'
228
228
229
229
230 def complete_current_input(self):
230 def complete_current_input(self):
231 """ Do code completion on current line.
231 """ Do code completion on current line.
232 """
232 """
233 if self.debug:
233 if self.debug:
234 print >>sys.__stdout__, "complete_current_input",
234 print >>sys.__stdout__, "complete_current_input",
235 line = self.input_buffer
235 line = self.input_buffer
236 new_line, completions = self.complete(line)
236 new_line, completions = self.complete(line)
237 if len(completions)>1:
237 if len(completions)>1:
@@ -241,7 +241,7 b' class LineFrontEndBase(FrontEndBase):'
241 if self.debug:
241 if self.debug:
242 print >>sys.__stdout__, 'line', line
242 print >>sys.__stdout__, 'line', line
243 print >>sys.__stdout__, 'new_line', new_line
243 print >>sys.__stdout__, 'new_line', new_line
244 print >>sys.__stdout__, completions
244 print >>sys.__stdout__, completions
245
245
246
246
247 def get_line_width(self):
247 def get_line_width(self):
@@ -259,10 +259,10 b' class LineFrontEndBase(FrontEndBase):'
259 """
259 """
260 if new_line is None:
260 if new_line is None:
261 new_line = self.input_buffer
261 new_line = self.input_buffer
262
262
263 self.write('\n')
263 self.write('\n')
264 max_len = len(max(possibilities, key=len)) + 1
264 max_len = len(max(possibilities, key=len)) + 1
265
265
266 # Now we check how much symbol we can put on a line...
266 # Now we check how much symbol we can put on a line...
267 chars_per_line = self.get_line_width()
267 chars_per_line = self.get_line_width()
268 symbols_per_line = max(1, chars_per_line/max_len)
268 symbols_per_line = max(1, chars_per_line/max_len)
@@ -283,7 +283,7 b' class LineFrontEndBase(FrontEndBase):'
283
283
284
284
285 def new_prompt(self, prompt):
285 def new_prompt(self, prompt):
286 """ Prints a prompt and starts a new editing buffer.
286 """ Prints a prompt and starts a new editing buffer.
287
287
288 Subclasses should use this method to make sure that the
288 Subclasses should use this method to make sure that the
289 terminal is put in a state favorable for a new line
289 terminal is put in a state favorable for a new line
@@ -297,7 +297,7 b' class LineFrontEndBase(FrontEndBase):'
297 """Returns the current continuation prompt.
297 """Returns the current continuation prompt.
298 """
298 """
299 return ("."*(len(self.last_prompt)-2) + ': ')
299 return ("."*(len(self.last_prompt)-2) + ': ')
300
300
301
301
302 def execute_command(self, command, hidden=False):
302 def execute_command(self, command, hidden=False):
303 """ Execute a command, not only in the model, but also in the
303 """ Execute a command, not only in the model, but also in the
@@ -308,7 +308,7 b' class LineFrontEndBase(FrontEndBase):'
308 #--------------------------------------------------------------------------
308 #--------------------------------------------------------------------------
309 # Private API
309 # Private API
310 #--------------------------------------------------------------------------
310 #--------------------------------------------------------------------------
311
311
312 def _on_enter(self, new_line_pos=0):
312 def _on_enter(self, new_line_pos=0):
313 """ Called when the return key is pressed in a line editing
313 """ Called when the return key is pressed in a line editing
314 buffer.
314 buffer.
@@ -339,7 +339,7 b' class LineFrontEndBase(FrontEndBase):'
339 new_line_pos = -new_line_pos
339 new_line_pos = -new_line_pos
340 lines = current_buffer.split('\n')[:-1]
340 lines = current_buffer.split('\n')[:-1]
341 prompt_less_lines = prompt_less_buffer.split('\n')
341 prompt_less_lines = prompt_less_buffer.split('\n')
342 # Create the new line, with the continuation prompt, and the
342 # Create the new line, with the continuation prompt, and the
343 # same amount of indent than the line above it.
343 # same amount of indent than the line above it.
344 new_line = self.continuation_prompt() + \
344 new_line = self.continuation_prompt() + \
345 self._get_indent_string('\n'.join(
345 self._get_indent_string('\n'.join(
@@ -356,7 +356,7 b' class LineFrontEndBase(FrontEndBase):'
356 else:
356 else:
357 lines.insert(new_line_pos, new_line)
357 lines.insert(new_line_pos, new_line)
358 self.input_buffer = '\n'.join(lines)
358 self.input_buffer = '\n'.join(lines)
359
359
360
360
361 def _get_indent_string(self, string):
361 def _get_indent_string(self, string):
362 """ Return the string of whitespace that prefixes a line. Used to
362 """ Return the string of whitespace that prefixes a line. Used to
@@ -369,5 +369,5 b' class LineFrontEndBase(FrontEndBase):'
369 ' '*(indent_chars % 4)
369 ' '*(indent_chars % 4)
370
370
371 return indent_string
371 return indent_string
372
372
373
373
@@ -51,7 +51,7 b' def mk_system_call(system_call_function, command):'
51 return my_system_call
51 return my_system_call
52
52
53 #-----------------------------------------------------------------------------
53 #-----------------------------------------------------------------------------
54 # Frontend class using ipython0 to do the prefiltering.
54 # Frontend class using ipython0 to do the prefiltering.
55 #-----------------------------------------------------------------------------
55 #-----------------------------------------------------------------------------
56
56
57 class PrefilterFrontEnd(LineFrontEndBase):
57 class PrefilterFrontEnd(LineFrontEndBase):
@@ -65,7 +65,7 b' class PrefilterFrontEnd(LineFrontEndBase):'
65 """
65 """
66
66
67 debug = False
67 debug = False
68
68
69 def __init__(self, ipython0=None, *args, **kwargs):
69 def __init__(self, ipython0=None, *args, **kwargs):
70 """ Parameters
70 """ Parameters
71 ----------
71 ----------
@@ -99,7 +99,7 b' class PrefilterFrontEnd(LineFrontEndBase):'
99 __builtin__.raw_input = old_rawinput
99 __builtin__.raw_input = old_rawinput
100 self.ipython0 = ipython0
100 self.ipython0 = ipython0
101 # Set the pager:
101 # Set the pager:
102 self.ipython0.set_hook('show_in_pager',
102 self.ipython0.set_hook('show_in_pager',
103 lambda s, string: self.write("\n" + string))
103 lambda s, string: self.write("\n" + string))
104 self.ipython0.write = self.write
104 self.ipython0.write = self.write
105 self._ip = _ip = self.ipython0
105 self._ip = _ip = self.ipython0
@@ -109,7 +109,7 b' class PrefilterFrontEnd(LineFrontEndBase):'
109 # XXX: Muck around with magics so that they work better
109 # XXX: Muck around with magics so that they work better
110 # in our environment
110 # in our environment
111 if not sys.platform.startswith('win'):
111 if not sys.platform.startswith('win'):
112 self.ipython0.magic_ls = mk_system_call(self.system_call,
112 self.ipython0.magic_ls = mk_system_call(self.system_call,
113 'ls -CF')
113 'ls -CF')
114 # And now clean up the mess created by ipython0
114 # And now clean up the mess created by ipython0
115 self.release_output()
115 self.release_output()
@@ -122,7 +122,7 b' class PrefilterFrontEnd(LineFrontEndBase):'
122 self.start()
122 self.start()
123
123
124 #--------------------------------------------------------------------------
124 #--------------------------------------------------------------------------
125 # FrontEndBase interface
125 # FrontEndBase interface
126 #--------------------------------------------------------------------------
126 #--------------------------------------------------------------------------
127
127
128 def show_traceback(self):
128 def show_traceback(self):
@@ -147,8 +147,8 b' class PrefilterFrontEnd(LineFrontEndBase):'
147
147
148 def save_output_hooks(self):
148 def save_output_hooks(self):
149 """ Store all the output hooks we can think of, to be able to
149 """ Store all the output hooks we can think of, to be able to
150 restore them.
150 restore them.
151
151
152 We need to do this early, as starting the ipython0 instance will
152 We need to do this early, as starting the ipython0 instance will
153 screw ouput hooks.
153 screw ouput hooks.
154 """
154 """
@@ -178,8 +178,8 b' class PrefilterFrontEnd(LineFrontEndBase):'
178 Term.cerr.write = self.__old_cerr_write
178 Term.cerr.write = self.__old_cerr_write
179 sys.stdout = self.__old_stdout
179 sys.stdout = self.__old_stdout
180 sys.stderr = self.__old_stderr
180 sys.stderr = self.__old_stderr
181 pydoc.help.output = self.__old_help_output
181 pydoc.help.output = self.__old_help_output
182 sys.displayhook = self.__old_display_hook
182 sys.displayhook = self.__old_display_hook
183
183
184
184
185 def complete(self, line):
185 def complete(self, line):
@@ -191,12 +191,12 b' class PrefilterFrontEnd(LineFrontEndBase):'
191 key = lambda x: x.replace('_', '')
191 key = lambda x: x.replace('_', '')
192 completions.sort(key=key)
192 completions.sort(key=key)
193 if completions:
193 if completions:
194 prefix = common_prefix(completions)
194 prefix = common_prefix(completions)
195 line = line[:-len(word)] + prefix
195 line = line[:-len(word)] + prefix
196 return line, completions
196 return line, completions
197
197
198 #--------------------------------------------------------------------------
198 #--------------------------------------------------------------------------
199 # LineFrontEndBase interface
199 # LineFrontEndBase interface
200 #--------------------------------------------------------------------------
200 #--------------------------------------------------------------------------
201
201
202 def prefilter_input(self, input_string):
202 def prefilter_input(self, input_string):
@@ -209,7 +209,7 b' class PrefilterFrontEnd(LineFrontEndBase):'
209 # capture it.
209 # capture it.
210 self.capture_output()
210 self.capture_output()
211 self.last_result = dict(number=self.prompt_number)
211 self.last_result = dict(number=self.prompt_number)
212
212
213 try:
213 try:
214 try:
214 try:
215 for line in input_string.split('\n'):
215 for line in input_string.split('\n'):
@@ -227,9 +227,9 b' class PrefilterFrontEnd(LineFrontEndBase):'
227 return filtered_string
227 return filtered_string
228
228
229 #--------------------------------------------------------------------------
229 #--------------------------------------------------------------------------
230 # PrefilterFrontEnd interface
230 # PrefilterFrontEnd interface
231 #--------------------------------------------------------------------------
231 #--------------------------------------------------------------------------
232
232
233 def system_call(self, command_string):
233 def system_call(self, command_string):
234 """ Allows for frontend to define their own system call, to be
234 """ Allows for frontend to define their own system call, to be
235 able capture output and redirect input.
235 able capture output and redirect input.
@@ -250,7 +250,7 b' class PrefilterFrontEnd(LineFrontEndBase):'
250 # that in the 'pyreadline' module (modes/basemode.py) where we break at
250 # that in the 'pyreadline' module (modes/basemode.py) where we break at
251 # each delimiter and try to complete the residual line, until we get a
251 # each delimiter and try to complete the residual line, until we get a
252 # successful list of completions.
252 # successful list of completions.
253 expression = '\s|=|,|:|\((?!.*\))|\[(?!.*\])|\{(?!.*\})'
253 expression = '\s|=|,|:|\((?!.*\))|\[(?!.*\])|\{(?!.*\})'
254 complete_sep = re.compile(expression)
254 complete_sep = re.compile(expression)
255 text = complete_sep.split(line)[-1]
255 text = complete_sep.split(line)[-1]
256 return text
256 return text
@@ -1,4 +1,4 b''
1 # Addapted from killableprocess.py.
1 # Addapted from killableprocess.py.
2 #______________________________________________________________________________
2 #______________________________________________________________________________
3 #
3 #
4 # killableprocess - subprocesses which can be reliably killed
4 # killableprocess - subprocesses which can be reliably killed
@@ -118,10 +118,10 b' else:'
118
118
119 if startupinfo is None:
119 if startupinfo is None:
120 startupinfo = winprocess.STARTUPINFO()
120 startupinfo = winprocess.STARTUPINFO()
121
121
122 if None not in (p2cread, c2pwrite, errwrite):
122 if None not in (p2cread, c2pwrite, errwrite):
123 startupinfo.dwFlags |= winprocess.STARTF_USESTDHANDLES
123 startupinfo.dwFlags |= winprocess.STARTF_USESTDHANDLES
124
124
125 startupinfo.hStdInput = int(p2cread)
125 startupinfo.hStdInput = int(p2cread)
126 startupinfo.hStdOutput = int(c2pwrite)
126 startupinfo.hStdOutput = int(c2pwrite)
127 startupinfo.hStdError = int(errwrite)
127 startupinfo.hStdError = int(errwrite)
@@ -132,7 +132,7 b' else:'
132 args = comspec + " /c " + args
132 args = comspec + " /c " + args
133
133
134 # We create a new job for this process, so that we can kill
134 # We create a new job for this process, so that we can kill
135 # the process and any sub-processes
135 # the process and any sub-processes
136 self._job = winprocess.CreateJobObject()
136 self._job = winprocess.CreateJobObject()
137
137
138 creationflags |= winprocess.CREATE_SUSPENDED
138 creationflags |= winprocess.CREATE_SUSPENDED
@@ -145,7 +145,7 b' else:'
145 creationflags,
145 creationflags,
146 winprocess.EnvironmentBlock(env),
146 winprocess.EnvironmentBlock(env),
147 cwd, startupinfo)
147 cwd, startupinfo)
148
148
149 self._child_created = True
149 self._child_created = True
150 self._handle = hp
150 self._handle = hp
151 self._thread = ht
151 self._thread = ht
@@ -173,7 +173,7 b' else:'
173 winprocess.TerminateJobObject(self._job, 127)
173 winprocess.TerminateJobObject(self._job, 127)
174 else:
174 else:
175 winprocess.TerminateProcess(self._handle, 127)
175 winprocess.TerminateProcess(self._handle, 127)
176 self.returncode = 127
176 self.returncode = 127
177 else:
177 else:
178 if group:
178 if group:
179 os.killpg(self.pid, signal.SIGKILL)
179 os.killpg(self.pid, signal.SIGKILL)
@@ -1,6 +1,6 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 Object for encapsulating process execution by using callbacks for stdout,
3 Object for encapsulating process execution by using callbacks for stdout,
4 stderr and stdin.
4 stderr and stdin.
5 """
5 """
6 __docformat__ = "restructuredtext en"
6 __docformat__ = "restructuredtext en"
@@ -26,10 +26,10 b' class PipedProcess(Thread):'
26 killing it.
26 killing it.
27 """
27 """
28
28
29 def __init__(self, command_string, out_callback,
29 def __init__(self, command_string, out_callback,
30 end_callback=None,):
30 end_callback=None,):
31 """ command_string: the command line executed to start the
31 """ command_string: the command line executed to start the
32 process.
32 process.
33
33
34 out_callback: the python callable called on stdout/stderr.
34 out_callback: the python callable called on stdout/stderr.
35
35
@@ -43,7 +43,7 b' class PipedProcess(Thread):'
43 self.out_callback = out_callback
43 self.out_callback = out_callback
44 self.end_callback = end_callback
44 self.end_callback = end_callback
45 Thread.__init__(self)
45 Thread.__init__(self)
46
46
47
47
48 def run(self):
48 def run(self):
49 """ Start the process and hook up the callbacks.
49 """ Start the process and hook up the callbacks.
@@ -70,5 +70,5 b' class PipedProcess(Thread):'
70
70
71 if self.end_callback is not None:
71 if self.end_callback is not None:
72 self.end_callback()
72 self.end_callback()
73
73
74
74
@@ -2,20 +2,20 b''
2 """This file contains unittests for the asyncfrontendbase module."""
2 """This file contains unittests for the asyncfrontendbase module."""
3
3
4 #---------------------------------------------------------------------------
4 #---------------------------------------------------------------------------
5 # Copyright (C) 2008-2009 The IPython Development Team
5 # Copyright (C) 2008-2009 The IPython Development Team
6 #
6 #
7 # Distributed under the terms of the BSD License. The full license is in
7 # Distributed under the terms of the BSD License. The full license is in
8 # the file COPYING, distributed as part of this software.
8 # the file COPYING, distributed as part of this software.
9 #---------------------------------------------------------------------------
9 #---------------------------------------------------------------------------
10
10
11 #---------------------------------------------------------------------------
11 #---------------------------------------------------------------------------
12 # Imports
12 # Imports
13 #---------------------------------------------------------------------------
13 #---------------------------------------------------------------------------
14
14
15 from twisted.trial import unittest
15 from twisted.trial import unittest
16
16
17 from IPython.frontend.asyncfrontendbase import AsyncFrontEndBase
17 from IPython.frontend.asyncfrontendbase import AsyncFrontEndBase
18 from IPython.frontend import frontendbase
18 from IPython.frontend import frontendbase
19 from IPython.kernel.engineservice import EngineService
19 from IPython.kernel.engineservice import EngineService
20 from IPython.testing.parametric import Parametric, parametric
20 from IPython.testing.parametric import Parametric, parametric
21
21
@@ -26,20 +26,20 b' from IPython.testing.parametric import Parametric, parametric'
26 class FrontEndCallbackChecker(AsyncFrontEndBase):
26 class FrontEndCallbackChecker(AsyncFrontEndBase):
27 """FrontEndBase subclass for checking callbacks"""
27 """FrontEndBase subclass for checking callbacks"""
28 def __init__(self, engine=None, history=None):
28 def __init__(self, engine=None, history=None):
29 super(FrontEndCallbackChecker, self).__init__(engine=engine,
29 super(FrontEndCallbackChecker, self).__init__(engine=engine,
30 history=history)
30 history=history)
31 self.updateCalled = False
31 self.updateCalled = False
32 self.renderResultCalled = False
32 self.renderResultCalled = False
33 self.renderErrorCalled = False
33 self.renderErrorCalled = False
34
34
35 def update_cell_prompt(self, result, blockID=None):
35 def update_cell_prompt(self, result, blockID=None):
36 self.updateCalled = True
36 self.updateCalled = True
37 return result
37 return result
38
38
39 def render_result(self, result):
39 def render_result(self, result):
40 self.renderResultCalled = True
40 self.renderResultCalled = True
41 return result
41 return result
42
42
43 def render_error(self, failure):
43 def render_error(self, failure):
44 self.renderErrorCalled = True
44 self.renderErrorCalled = True
45 return failure
45 return failure
@@ -48,50 +48,50 b' class FrontEndCallbackChecker(AsyncFrontEndBase):'
48 class TestAsyncFrontendBase(unittest.TestCase):
48 class TestAsyncFrontendBase(unittest.TestCase):
49 def setUp(self):
49 def setUp(self):
50 """Setup the EngineService and FrontEndBase"""
50 """Setup the EngineService and FrontEndBase"""
51
51
52 self.fb = FrontEndCallbackChecker(engine=EngineService())
52 self.fb = FrontEndCallbackChecker(engine=EngineService())
53
53
54 def test_implements_IFrontEnd(self):
54 def test_implements_IFrontEnd(self):
55 self.assert_(frontendbase.IFrontEnd.implementedBy(
55 self.assert_(frontendbase.IFrontEnd.implementedBy(
56 AsyncFrontEndBase))
56 AsyncFrontEndBase))
57
57
58 def test_is_complete_returns_False_for_incomplete_block(self):
58 def test_is_complete_returns_False_for_incomplete_block(self):
59 block = """def test(a):"""
59 block = """def test(a):"""
60 self.assert_(self.fb.is_complete(block) == False)
60 self.assert_(self.fb.is_complete(block) == False)
61
61
62 def test_is_complete_returns_True_for_complete_block(self):
62 def test_is_complete_returns_True_for_complete_block(self):
63 block = """def test(a): pass"""
63 block = """def test(a): pass"""
64 self.assert_(self.fb.is_complete(block))
64 self.assert_(self.fb.is_complete(block))
65 block = """a=3"""
65 block = """a=3"""
66 self.assert_(self.fb.is_complete(block))
66 self.assert_(self.fb.is_complete(block))
67
67
68 def test_blockID_added_to_result(self):
68 def test_blockID_added_to_result(self):
69 block = """3+3"""
69 block = """3+3"""
70 d = self.fb.execute(block, blockID='TEST_ID')
70 d = self.fb.execute(block, blockID='TEST_ID')
71 d.addCallback(lambda r: self.assert_(r['blockID']=='TEST_ID'))
71 d.addCallback(lambda r: self.assert_(r['blockID']=='TEST_ID'))
72 return d
72 return d
73
73
74 def test_blockID_added_to_failure(self):
74 def test_blockID_added_to_failure(self):
75 block = "raise Exception()"
75 block = "raise Exception()"
76 d = self.fb.execute(block,blockID='TEST_ID')
76 d = self.fb.execute(block,blockID='TEST_ID')
77 d.addErrback(lambda f: self.assert_(f.blockID=='TEST_ID'))
77 d.addErrback(lambda f: self.assert_(f.blockID=='TEST_ID'))
78 return d
78 return d
79
79
80 def test_callbacks_added_to_execute(self):
80 def test_callbacks_added_to_execute(self):
81 d = self.fb.execute("10+10")
81 d = self.fb.execute("10+10")
82 d.addCallback(lambda r: self.assert_(self.fb.updateCalled and self.fb.renderResultCalled))
82 d.addCallback(lambda r: self.assert_(self.fb.updateCalled and self.fb.renderResultCalled))
83 return d
83 return d
84
84
85 def test_error_callback_added_to_execute(self):
85 def test_error_callback_added_to_execute(self):
86 """Test that render_error called on execution error."""
86 """Test that render_error called on execution error."""
87
87
88 d = self.fb.execute("raise Exception()")
88 d = self.fb.execute("raise Exception()")
89 d.addErrback(lambda f: self.assert_(self.fb.renderErrorCalled))
89 d.addErrback(lambda f: self.assert_(self.fb.renderErrorCalled))
90 return d
90 return d
91
91
92 def test_history_returns_expected_block(self):
92 def test_history_returns_expected_block(self):
93 """Make sure history browsing doesn't fail."""
93 """Make sure history browsing doesn't fail."""
94
94
95 blocks = ["a=1","a=2","a=3"]
95 blocks = ["a=1","a=2","a=3"]
96 d = self.fb.execute(blocks[0])
96 d = self.fb.execute(blocks[0])
97 d.addCallback(lambda _: self.fb.execute(blocks[1]))
97 d.addCallback(lambda _: self.fb.execute(blocks[1]))
@@ -100,7 +100,7 b' class TestAsyncFrontendBase(unittest.TestCase):'
100 d.addCallback(lambda _: self.assert_(self.fb.get_history_previous("")==blocks[-3]))
100 d.addCallback(lambda _: self.assert_(self.fb.get_history_previous("")==blocks[-3]))
101 d.addCallback(lambda _: self.assert_(self.fb.get_history_next()==blocks[-2]))
101 d.addCallback(lambda _: self.assert_(self.fb.get_history_next()==blocks[-2]))
102 return d
102 return d
103
103
104 def test_history_returns_none_at_startup(self):
104 def test_history_returns_none_at_startup(self):
105 self.assert_(self.fb.get_history_previous("")==None)
105 self.assert_(self.fb.get_history_previous("")==None)
106 self.assert_(self.fb.get_history_next()==None)
106 self.assert_(self.fb.get_history_next()==None)
@@ -1,6 +1,6 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 Test the basic functionality of frontendbase.
3 Test the basic functionality of frontendbase.
4 """
4 """
5
5
6 __docformat__ = "restructuredtext en"
6 __docformat__ = "restructuredtext en"
@@ -15,7 +15,7 b' __docformat__ = "restructuredtext en"'
15 from IPython.frontend.frontendbase import FrontEndBase
15 from IPython.frontend.frontendbase import FrontEndBase
16
16
17 def test_iscomplete():
17 def test_iscomplete():
18 """ Check that is_complete works.
18 """ Check that is_complete works.
19 """
19 """
20 f = FrontEndBase()
20 f = FrontEndBase()
21 assert f.is_complete('(a + a)')
21 assert f.is_complete('(a + a)')
@@ -1,6 +1,6 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 Test the LineFrontEnd
3 Test the LineFrontEnd
4 """
4 """
5
5
6 __docformat__ = "restructuredtext en"
6 __docformat__ = "restructuredtext en"
@@ -27,7 +27,7 b' from IPython.testing.globalipapp import get_ipython'
27 #-----------------------------------------------------------------------------
27 #-----------------------------------------------------------------------------
28
28
29 class TestPrefilterFrontEnd(PrefilterFrontEnd):
29 class TestPrefilterFrontEnd(PrefilterFrontEnd):
30
30
31 input_prompt_template = string.Template('')
31 input_prompt_template = string.Template('')
32 output_prompt_template = string.Template('')
32 output_prompt_template = string.Template('')
33 banner = ''
33 banner = ''
@@ -42,7 +42,7 b' class TestPrefilterFrontEnd(PrefilterFrontEnd):'
42 self.out.truncate()
42 self.out.truncate()
43
43
44 def write(self, string, *args, **kwargs):
44 def write(self, string, *args, **kwargs):
45 self.out.write(string)
45 self.out.write(string)
46
46
47 def _on_enter(self):
47 def _on_enter(self):
48 self.input_buffer += '\n'
48 self.input_buffer += '\n'
@@ -151,11 +151,11 b' def test_capture():'
151 out_value = f.out.getvalue()
151 out_value = f.out.getvalue()
152 yield assert_equal, out_value, '1'
152 yield assert_equal, out_value, '1'
153
153
154
154
155 @isolate_ipython0
155 @isolate_ipython0
156 def test_magic():
156 def test_magic():
157 """ Test the magic expansion and history.
157 """ Test the magic expansion and history.
158
158
159 This test is fairly fragile and will break when magics change.
159 This test is fairly fragile and will break when magics change.
160 """
160 """
161 f = TestPrefilterFrontEnd()
161 f = TestPrefilterFrontEnd()
@@ -188,7 +188,7 b' def test_help():'
188 assert 'traceback' not in f.last_result
188 assert 'traceback' not in f.last_result
189 ## XXX: ipython doctest magic breaks this. I have no clue why
189 ## XXX: ipython doctest magic breaks this. I have no clue why
190 #out_value = f.out.getvalue()
190 #out_value = f.out.getvalue()
191 #assert out_value.split()[-1] == 'foobar'
191 #assert out_value.split()[-1] == 'foobar'
192
192
193
193
194 @isolate_ipython0
194 @isolate_ipython0
@@ -35,7 +35,7 b' def test_io():'
35 """ Checks that we can send characters on stdin to the process.
35 """ Checks that we can send characters on stdin to the process.
36 """
36 """
37 s = StringIO()
37 s = StringIO()
38 p = PipedProcess(sys.executable + ' -c "a = raw_input(); print a"',
38 p = PipedProcess(sys.executable + ' -c "a = raw_input(); print a"',
39 out_callback=s.write, )
39 out_callback=s.write, )
40 p.start()
40 p.start()
41 test_string = '12345\n'
41 test_string = '12345\n'
@@ -52,12 +52,12 b' def test_kill():'
52 """ Check that we can kill a process, and its subprocess.
52 """ Check that we can kill a process, and its subprocess.
53 """
53 """
54 s = StringIO()
54 s = StringIO()
55 p = PipedProcess(sys.executable + ' -c "a = raw_input();"',
55 p = PipedProcess(sys.executable + ' -c "a = raw_input();"',
56 out_callback=s.write, )
56 out_callback=s.write, )
57 p.start()
57 p.start()
58 while not hasattr(p, 'process'):
58 while not hasattr(p, 'process'):
59 sleep(0.1)
59 sleep(0.1)
60 p.process.kill()
60 p.process.kill()
61 assert p.process.poll() is not None
61 assert p.process.poll() is not None
62
62
63
63
@@ -36,7 +36,7 b' import re'
36 # FIXME: Need to provide an API for non user-generated display on the
36 # FIXME: Need to provide an API for non user-generated display on the
37 # screen: this should not be editable by the user.
37 # screen: this should not be editable by the user.
38 #-------------------------------------------------------------------------------
38 #-------------------------------------------------------------------------------
39 # Constants
39 # Constants
40 #-------------------------------------------------------------------------------
40 #-------------------------------------------------------------------------------
41 _COMPLETE_BUFFER_MARKER = 31
41 _COMPLETE_BUFFER_MARKER = 31
42 _ERROR_MARKER = 30
42 _ERROR_MARKER = 30
@@ -75,7 +75,7 b' _DEFAULT_STYLE = {'
75 # Default scintilla settings
75 # Default scintilla settings
76 'antialiasing' : True,
76 'antialiasing' : True,
77 'carret_color' : 'BLACK',
77 'carret_color' : 'BLACK',
78 'background_color' :'WHITE',
78 'background_color' :'WHITE',
79
79
80 #prompt definition
80 #prompt definition
81 'prompt_in1' : \
81 'prompt_in1' : \
@@ -94,14 +94,14 b' _TRACE_STYLE = 17'
94 # system colors
94 # system colors
95 #SYS_COLOUR_BACKGROUND = wx.SystemSettings.GetColour(wx.SYS_COLOUR_BACKGROUND)
95 #SYS_COLOUR_BACKGROUND = wx.SystemSettings.GetColour(wx.SYS_COLOUR_BACKGROUND)
96
96
97 # Translation table from ANSI escape sequences to color.
97 # Translation table from ANSI escape sequences to color.
98 ANSI_STYLES = {'0;30': [0, 'BLACK'], '0;31': [1, 'RED'],
98 ANSI_STYLES = {'0;30': [0, 'BLACK'], '0;31': [1, 'RED'],
99 '0;32': [2, 'GREEN'], '0;33': [3, 'BROWN'],
99 '0;32': [2, 'GREEN'], '0;33': [3, 'BROWN'],
100 '0;34': [4, 'BLUE'], '0;35': [5, 'PURPLE'],
100 '0;34': [4, 'BLUE'], '0;35': [5, 'PURPLE'],
101 '0;36': [6, 'CYAN'], '0;37': [7, 'LIGHT GREY'],
101 '0;36': [6, 'CYAN'], '0;37': [7, 'LIGHT GREY'],
102 '1;30': [8, 'DARK GREY'], '1;31': [9, 'RED'],
102 '1;30': [8, 'DARK GREY'], '1;31': [9, 'RED'],
103 '1;32': [10, 'SEA GREEN'], '1;33': [11, 'YELLOW'],
103 '1;32': [10, 'SEA GREEN'], '1;33': [11, 'YELLOW'],
104 '1;34': [12, 'LIGHT BLUE'], '1;35':
104 '1;34': [12, 'LIGHT BLUE'], '1;35':
105 [13, 'MEDIUM VIOLET RED'],
105 [13, 'MEDIUM VIOLET RED'],
106 '1;36': [14, 'LIGHT STEEL BLUE'], '1;37': [15, 'YELLOW']}
106 '1;36': [14, 'LIGHT STEEL BLUE'], '1;37': [15, 'YELLOW']}
107
107
@@ -133,7 +133,7 b' else:'
133 'size' : 10,
133 'size' : 10,
134 'size2': 8,
134 'size2': 8,
135 }
135 }
136
136
137
137
138 #-----------------------------------------------------------------------------
138 #-----------------------------------------------------------------------------
139 # The console widget class
139 # The console widget class
@@ -174,36 +174,36 b' class ConsoleWidget(editwindow.EditWindow):'
174 # Translation table from ANSI escape sequences to color. Override
174 # Translation table from ANSI escape sequences to color. Override
175 # this to specify your colors.
175 # this to specify your colors.
176 ANSI_STYLES = ANSI_STYLES.copy()
176 ANSI_STYLES = ANSI_STYLES.copy()
177
177
178 # Font faces
178 # Font faces
179 faces = FACES.copy()
179 faces = FACES.copy()
180
180
181 # Store the last time a refresh was done
181 # Store the last time a refresh was done
182 _last_refresh_time = 0
182 _last_refresh_time = 0
183
183
184 #--------------------------------------------------------------------------
184 #--------------------------------------------------------------------------
185 # Public API
185 # Public API
186 #--------------------------------------------------------------------------
186 #--------------------------------------------------------------------------
187
187
188 def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition,
188 def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition,
189 size=wx.DefaultSize, style=wx.WANTS_CHARS, ):
189 size=wx.DefaultSize, style=wx.WANTS_CHARS, ):
190 editwindow.EditWindow.__init__(self, parent, id, pos, size, style)
190 editwindow.EditWindow.__init__(self, parent, id, pos, size, style)
191 self.configure_scintilla()
191 self.configure_scintilla()
192 # Track if 'enter' key as ever been processed
192 # Track if 'enter' key as ever been processed
193 # This variable will only be reallowed until key goes up
193 # This variable will only be reallowed until key goes up
194 self.enter_catched = False
194 self.enter_catched = False
195 self.current_prompt_pos = 0
195 self.current_prompt_pos = 0
196
196
197 self.Bind(wx.EVT_KEY_DOWN, self._on_key_down)
197 self.Bind(wx.EVT_KEY_DOWN, self._on_key_down)
198 self.Bind(wx.EVT_KEY_UP, self._on_key_up)
198 self.Bind(wx.EVT_KEY_UP, self._on_key_up)
199
199
200
200
201 def write(self, text, refresh=True):
201 def write(self, text, refresh=True):
202 """ Write given text to buffer, while translating the ansi escape
202 """ Write given text to buffer, while translating the ansi escape
203 sequences.
203 sequences.
204 """
204 """
205 # XXX: do not put print statements to sys.stdout/sys.stderr in
205 # XXX: do not put print statements to sys.stdout/sys.stderr in
206 # this method, the print statements will call this method, as
206 # this method, the print statements will call this method, as
207 # you will end up with an infinit loop
207 # you will end up with an infinit loop
208 title = self.title_pat.split(text)
208 title = self.title_pat.split(text)
209 if len(title)>1:
209 if len(title)>1:
@@ -219,7 +219,7 b' class ConsoleWidget(editwindow.EditWindow):'
219 except UnicodeDecodeError:
219 except UnicodeDecodeError:
220 # XXX: Do I really want to skip the exception?
220 # XXX: Do I really want to skip the exception?
221 pass
221 pass
222
222
223 if segments:
223 if segments:
224 for ansi_tag, text in zip(segments[::2], segments[1::2]):
224 for ansi_tag, text in zip(segments[::2], segments[1::2]):
225 self.StartStyling(self.GetLength(), 0xFF)
225 self.StartStyling(self.GetLength(), 0xFF)
@@ -234,8 +234,8 b' class ConsoleWidget(editwindow.EditWindow):'
234 else:
234 else:
235 style = self.ANSI_STYLES[ansi_tag][0]
235 style = self.ANSI_STYLES[ansi_tag][0]
236
236
237 self.SetStyling(len(text), style)
237 self.SetStyling(len(text), style)
238
238
239 self.GotoPos(self.GetLength())
239 self.GotoPos(self.GetLength())
240 if refresh:
240 if refresh:
241 current_time = time.time()
241 current_time = time.time()
@@ -245,9 +245,9 b' class ConsoleWidget(editwindow.EditWindow):'
245 else:
245 else:
246 wx.Yield()
246 wx.Yield()
247 # self.ProcessEvent(wx.PaintEvent())
247 # self.ProcessEvent(wx.PaintEvent())
248 self._last_refresh_time = current_time
248 self._last_refresh_time = current_time
249
249
250
250
251 def new_prompt(self, prompt):
251 def new_prompt(self, prompt):
252 """ Prints a prompt at start of line, and move the start of the
252 """ Prints a prompt at start of line, and move the start of the
253 current block there.
253 current block there.
@@ -270,7 +270,7 b' class ConsoleWidget(editwindow.EditWindow):'
270 # ASCII-less prompt
270 # ASCII-less prompt
271 ascii_less = ''.join(self.color_pat.split(self.last_prompt)[2::2])
271 ascii_less = ''.join(self.color_pat.split(self.last_prompt)[2::2])
272 return "."*(len(ascii_less)-2) + ': '
272 return "."*(len(ascii_less)-2) + ': '
273
273
274
274
275 def scroll_to_bottom(self):
275 def scroll_to_bottom(self):
276 maxrange = self.GetScrollRange(wx.VERTICAL)
276 maxrange = self.GetScrollRange(wx.VERTICAL)
@@ -299,7 +299,7 b' class ConsoleWidget(editwindow.EditWindow):'
299 widget.
299 widget.
300 """
300 """
301 p = self.style.copy()
301 p = self.style.copy()
302
302
303 # Marker for complete buffer.
303 # Marker for complete buffer.
304 self.MarkerDefine(_COMPLETE_BUFFER_MARKER, stc.STC_MARK_BACKGROUND,
304 self.MarkerDefine(_COMPLETE_BUFFER_MARKER, stc.STC_MARK_BACKGROUND,
305 background=p['trace'])
305 background=p['trace'])
@@ -313,14 +313,14 b' class ConsoleWidget(editwindow.EditWindow):'
313
313
314 self.SetEOLMode(stc.STC_EOL_LF)
314 self.SetEOLMode(stc.STC_EOL_LF)
315
315
316 # Ctrl"+" or Ctrl "-" can be used to zoomin/zoomout the text inside
316 # Ctrl"+" or Ctrl "-" can be used to zoomin/zoomout the text inside
317 # the widget
317 # the widget
318 self.CmdKeyAssign(ord('+'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMIN)
318 self.CmdKeyAssign(ord('+'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMIN)
319 self.CmdKeyAssign(ord('-'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMOUT)
319 self.CmdKeyAssign(ord('-'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMOUT)
320 # Also allow Ctrl Shift "=" for poor non US keyboard users.
320 # Also allow Ctrl Shift "=" for poor non US keyboard users.
321 self.CmdKeyAssign(ord('='), stc.STC_SCMOD_CTRL|stc.STC_SCMOD_SHIFT,
321 self.CmdKeyAssign(ord('='), stc.STC_SCMOD_CTRL|stc.STC_SCMOD_SHIFT,
322 stc.STC_CMD_ZOOMIN)
322 stc.STC_CMD_ZOOMIN)
323
323
324 # Keys: we need to clear some of the keys the that don't play
324 # Keys: we need to clear some of the keys the that don't play
325 # well with a console.
325 # well with a console.
326 self.CmdKeyClear(ord('D'), stc.STC_SCMOD_CTRL)
326 self.CmdKeyClear(ord('D'), stc.STC_SCMOD_CTRL)
@@ -341,7 +341,7 b' class ConsoleWidget(editwindow.EditWindow):'
341 self.SetIndent(4)
341 self.SetIndent(4)
342 self.SetTabWidth(4)
342 self.SetTabWidth(4)
343
343
344 # we don't want scintilla's autocompletion to choose
344 # we don't want scintilla's autocompletion to choose
345 # automaticaly out of a single choice list, as we pop it up
345 # automaticaly out of a single choice list, as we pop it up
346 # automaticaly
346 # automaticaly
347 self.AutoCompSetChooseSingle(False)
347 self.AutoCompSetChooseSingle(False)
@@ -360,11 +360,11 b' class ConsoleWidget(editwindow.EditWindow):'
360 self.title_pat = re.compile('\x1b]0;(.*?)\x07')
360 self.title_pat = re.compile('\x1b]0;(.*?)\x07')
361
361
362 # styles
362 # styles
363
363
364 self.SetCaretForeground(p['carret_color'])
364 self.SetCaretForeground(p['carret_color'])
365
365
366 background_color = p['background_color']
366 background_color = p['background_color']
367
367
368 if 'default' in p:
368 if 'default' in p:
369 if 'back' not in p['default']:
369 if 'back' not in p['default']:
370 p['default'] += ',back:%s' % background_color
370 p['default'] += ',back:%s' % background_color
@@ -372,20 +372,20 b' class ConsoleWidget(editwindow.EditWindow):'
372 p['default'] += ',size:%s' % self.faces['size']
372 p['default'] += ',size:%s' % self.faces['size']
373 if 'face' not in p['default']:
373 if 'face' not in p['default']:
374 p['default'] += ',face:%s' % self.faces['mono']
374 p['default'] += ',face:%s' % self.faces['mono']
375
375
376 self.StyleSetSpec(stc.STC_STYLE_DEFAULT, p['default'])
376 self.StyleSetSpec(stc.STC_STYLE_DEFAULT, p['default'])
377 else:
377 else:
378 self.StyleSetSpec(stc.STC_STYLE_DEFAULT,
378 self.StyleSetSpec(stc.STC_STYLE_DEFAULT,
379 "fore:%s,back:%s,size:%d,face:%s"
379 "fore:%s,back:%s,size:%d,face:%s"
380 % (self.ANSI_STYLES['0;30'][1],
380 % (self.ANSI_STYLES['0;30'][1],
381 background_color,
381 background_color,
382 self.faces['size'], self.faces['mono']))
382 self.faces['size'], self.faces['mono']))
383
383
384 self.StyleClearAll()
384 self.StyleClearAll()
385
385
386 # XXX: two lines below are usefull if not using the lexer
386 # XXX: two lines below are usefull if not using the lexer
387 #for style in self.ANSI_STYLES.values():
387 #for style in self.ANSI_STYLES.values():
388 # self.StyleSetSpec(style[0], "bold,fore:%s" % style[1])
388 # self.StyleSetSpec(style[0], "bold,fore:%s" % style[1])
389
389
390 # prompt definition
390 # prompt definition
391 self.prompt_in1 = p['prompt_in1']
391 self.prompt_in1 = p['prompt_in1']
@@ -417,25 +417,25 b' class ConsoleWidget(editwindow.EditWindow):'
417 #we add a vertical line to console widget
417 #we add a vertical line to console widget
418 self.SetEdgeMode(stc.STC_EDGE_LINE)
418 self.SetEdgeMode(stc.STC_EDGE_LINE)
419 self.SetEdgeColumn(edge_column)
419 self.SetEdgeColumn(edge_column)
420
420
421
421
422 #--------------------------------------------------------------------------
422 #--------------------------------------------------------------------------
423 # EditWindow API
423 # EditWindow API
424 #--------------------------------------------------------------------------
424 #--------------------------------------------------------------------------
425
425
426 def OnUpdateUI(self, event):
426 def OnUpdateUI(self, event):
427 """ Override the OnUpdateUI of the EditWindow class, to prevent
427 """ Override the OnUpdateUI of the EditWindow class, to prevent
428 syntax highlighting both for faster redraw, and for more
428 syntax highlighting both for faster redraw, and for more
429 consistent look and feel.
429 consistent look and feel.
430 """
430 """
431
431
432
432
433 #--------------------------------------------------------------------------
433 #--------------------------------------------------------------------------
434 # Private API
434 # Private API
435 #--------------------------------------------------------------------------
435 #--------------------------------------------------------------------------
436
436
437 def _on_key_down(self, event, skip=True):
437 def _on_key_down(self, event, skip=True):
438 """ Key press callback used for correcting behavior for
438 """ Key press callback used for correcting behavior for
439 console-like interfaces: the cursor is constraint to be after
439 console-like interfaces: the cursor is constraint to be after
440 the last prompt.
440 the last prompt.
441
441
@@ -487,7 +487,7 b' class ConsoleWidget(editwindow.EditWindow):'
487 if event.ShiftDown():
487 if event.ShiftDown():
488 # Try to force execution
488 # Try to force execution
489 self.GotoPos(self.GetLength())
489 self.GotoPos(self.GetLength())
490 self.write('\n' + self.continuation_prompt(),
490 self.write('\n' + self.continuation_prompt(),
491 refresh=False)
491 refresh=False)
492 self._on_enter()
492 self._on_enter()
493 else:
493 else:
@@ -501,7 +501,7 b' class ConsoleWidget(editwindow.EditWindow):'
501 else:
501 else:
502 # FIXME: This behavior is not ideal: if the selection
502 # FIXME: This behavior is not ideal: if the selection
503 # is already started, it will jump.
503 # is already started, it will jump.
504 self.SetSelectionStart(self.current_prompt_pos)
504 self.SetSelectionStart(self.current_prompt_pos)
505 self.SetSelectionEnd(self.GetCurrentPos())
505 self.SetSelectionEnd(self.GetCurrentPos())
506 catched = True
506 catched = True
507
507
@@ -591,15 +591,15 b' class ConsoleWidget(editwindow.EditWindow):'
591 # Jump back up
591 # Jump back up
592 self.GotoPos(self.GetLineEndPosition(line_num-1))
592 self.GotoPos(self.GetLineEndPosition(line_num-1))
593 return True
593 return True
594 elif ( current_pos > self.GetLineEndPosition(line_num)
594 elif ( current_pos > self.GetLineEndPosition(line_num)
595 and not current_pos == self.GetLength()):
595 and not current_pos == self.GetLength()):
596 # Jump to next line
596 # Jump to next line
597 self.GotoPos(current_pos + 1 +
597 self.GotoPos(current_pos + 1 +
598 len(continuation_prompt))
598 len(continuation_prompt))
599 return True
599 return True
600
600
601 # We re-allow enter event processing
601 # We re-allow enter event processing
602 self.enter_catched = False
602 self.enter_catched = False
603 return False
603 return False
604
604
605
605
@@ -38,7 +38,7 b' class IPythonXController(WxController):'
38 self._input_state == 'readline':
38 self._input_state == 'readline':
39 wx.CallAfter(self.ask_exit)
39 wx.CallAfter(self.ask_exit)
40 else:
40 else:
41 WxController._on_key_down(self, event, skip=skip)
41 WxController._on_key_down(self, event, skip=skip)
42
42
43
43
44 def ask_exit(self):
44 def ask_exit(self):
@@ -56,7 +56,7 b' class IPythonXController(WxController):'
56 else:
56 else:
57 wx.CallAfter(wx.GetApp().Exit)
57 wx.CallAfter(wx.GetApp().Exit)
58 self.write('Exiting ...', refresh=False)
58 self.write('Exiting ...', refresh=False)
59
59
60
60
61 def do_exit(self):
61 def do_exit(self):
62 """ Exits the interpreter, kills the windows.
62 """ Exits the interpreter, kills the windows.
@@ -81,10 +81,10 b' class IPythonX(wx.Frame):'
81 self.Show(True)
81 self.Show(True)
82 wx.EVT_CLOSE(self, self.on_close)
82 wx.EVT_CLOSE(self, self.on_close)
83
83
84
84
85 def on_close(self, event):
85 def on_close(self, event):
86 """ Called on closing the windows.
86 """ Called on closing the windows.
87
87
88 Stops the event loop, to close all the child windows.
88 Stops the event loop, to close all the child windows.
89 """
89 """
90 wx.CallAfter(wx.Exit)
90 wx.CallAfter(wx.Exit)
@@ -47,7 +47,7 b' class WxController(ConsoleWidget, PrefilterFrontEnd):'
47 This class inherits from ConsoleWidget, that provides a console-like
47 This class inherits from ConsoleWidget, that provides a console-like
48 widget to provide a text-rendering widget suitable for a terminal.
48 widget to provide a text-rendering widget suitable for a terminal.
49 """
49 """
50
50
51 # Print debug info on what is happening to the console.
51 # Print debug info on what is happening to the console.
52 debug = False
52 debug = False
53
53
@@ -83,7 +83,7 b' class WxController(ConsoleWidget, PrefilterFrontEnd):'
83
83
84 # A flag governing the behavior of the input. Can be:
84 # A flag governing the behavior of the input. Can be:
85 #
85 #
86 # 'readline' for readline-like behavior with a prompt
86 # 'readline' for readline-like behavior with a prompt
87 # and an edit buffer.
87 # and an edit buffer.
88 # 'raw_input' similar to readline, but triggered by a raw-input
88 # 'raw_input' similar to readline, but triggered by a raw-input
89 # call. Can be used by subclasses to act differently.
89 # call. Can be used by subclasses to act differently.
@@ -111,7 +111,7 b' class WxController(ConsoleWidget, PrefilterFrontEnd):'
111 #--------------------------------------------------------------------------
111 #--------------------------------------------------------------------------
112 # Public API
112 # Public API
113 #--------------------------------------------------------------------------
113 #--------------------------------------------------------------------------
114
114
115 def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition,
115 def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition,
116 size=wx.DefaultSize,
116 size=wx.DefaultSize,
117 style=wx.CLIP_CHILDREN|wx.WANTS_CHARS,
117 style=wx.CLIP_CHILDREN|wx.WANTS_CHARS,
@@ -129,7 +129,7 b' class WxController(ConsoleWidget, PrefilterFrontEnd):'
129 self.style = styledef
129 self.style = styledef
130 ConsoleWidget.__init__(self, parent, id, pos, size, style)
130 ConsoleWidget.__init__(self, parent, id, pos, size, style)
131 PrefilterFrontEnd.__init__(self, **kwds)
131 PrefilterFrontEnd.__init__(self, **kwds)
132
132
133 # Stick in our own raw_input:
133 # Stick in our own raw_input:
134 self.ipython0.raw_input = self.raw_input
134 self.ipython0.raw_input = self.raw_input
135
135
@@ -147,14 +147,14 b' class WxController(ConsoleWidget, PrefilterFrontEnd):'
147 self.shell.user_ns['self'] = self
147 self.shell.user_ns['self'] = self
148 # Inject our own raw_input in namespace
148 # Inject our own raw_input in namespace
149 self.shell.user_ns['raw_input'] = self.raw_input
149 self.shell.user_ns['raw_input'] = self.raw_input
150
150
151 def raw_input(self, prompt=''):
151 def raw_input(self, prompt=''):
152 """ A replacement from python's raw_input.
152 """ A replacement from python's raw_input.
153 """
153 """
154 self.new_prompt(prompt)
154 self.new_prompt(prompt)
155 self._input_state = 'raw_input'
155 self._input_state = 'raw_input'
156 if hasattr(self, '_cursor'):
156 if hasattr(self, '_cursor'):
157 del self._cursor
157 del self._cursor
158 self.SetCursor(wx.StockCursor(wx.CURSOR_CROSS))
158 self.SetCursor(wx.StockCursor(wx.CURSOR_CROSS))
159 self.__old_on_enter = self._on_enter
159 self.__old_on_enter = self._on_enter
160 event_loop = wx.EventLoop()
160 event_loop = wx.EventLoop()
@@ -162,7 +162,7 b' class WxController(ConsoleWidget, PrefilterFrontEnd):'
162 event_loop.Exit()
162 event_loop.Exit()
163 self._on_enter = my_on_enter
163 self._on_enter = my_on_enter
164 # XXX: Running a separate event_loop. Ugly.
164 # XXX: Running a separate event_loop. Ugly.
165 event_loop.Run()
165 event_loop.Run()
166 self._on_enter = self.__old_on_enter
166 self._on_enter = self.__old_on_enter
167 self._input_state = 'buffering'
167 self._input_state = 'buffering'
168 self._cursor = wx.BusyCursor()
168 self._cursor = wx.BusyCursor()
@@ -177,12 +177,12 b' class WxController(ConsoleWidget, PrefilterFrontEnd):'
177 self._running_process = False
177 self._running_process = False
178 event_loop.Exit()
178 event_loop.Exit()
179
179
180 self._running_process = PipedProcess(command_string,
180 self._running_process = PipedProcess(command_string,
181 out_callback=self.buffered_write,
181 out_callback=self.buffered_write,
182 end_callback = _end_system_call)
182 end_callback = _end_system_call)
183 self._running_process.start()
183 self._running_process.start()
184 # XXX: Running a separate event_loop. Ugly.
184 # XXX: Running a separate event_loop. Ugly.
185 event_loop.Run()
185 event_loop.Run()
186 # Be sure to flush the buffer.
186 # Be sure to flush the buffer.
187 self._buffer_flush(event=None)
187 self._buffer_flush(event=None)
188
188
@@ -191,7 +191,7 b' class WxController(ConsoleWidget, PrefilterFrontEnd):'
191 """ Analyse current and displays useful calltip for it.
191 """ Analyse current and displays useful calltip for it.
192 """
192 """
193 if self.debug:
193 if self.debug:
194 print >>sys.__stdout__, "do_calltip"
194 print >>sys.__stdout__, "do_calltip"
195 separators = re.compile('[\s\{\}\[\]\(\)\= ,:]')
195 separators = re.compile('[\s\{\}\[\]\(\)\= ,:]')
196 symbol = self.input_buffer
196 symbol = self.input_buffer
197 symbol_string = separators.split(symbol)[-1]
197 symbol_string = separators.split(symbol)[-1]
@@ -217,11 +217,11 b' class WxController(ConsoleWidget, PrefilterFrontEnd):'
217
217
218
218
219 def _popup_completion(self, create=False):
219 def _popup_completion(self, create=False):
220 """ Updates the popup completion menu if it exists. If create is
220 """ Updates the popup completion menu if it exists. If create is
221 true, open the menu.
221 true, open the menu.
222 """
222 """
223 if self.debug:
223 if self.debug:
224 print >>sys.__stdout__, "_popup_completion"
224 print >>sys.__stdout__, "_popup_completion"
225 line = self.input_buffer
225 line = self.input_buffer
226 if (self.AutoCompActive() and line and not line[-1] == '.') \
226 if (self.AutoCompActive() and line and not line[-1] == '.') \
227 or create==True:
227 or create==True:
@@ -230,7 +230,7 b' class WxController(ConsoleWidget, PrefilterFrontEnd):'
230 offset = len(self._get_completion_text(line))
230 offset = len(self._get_completion_text(line))
231 self.pop_completion(completions, offset=offset)
231 self.pop_completion(completions, offset=offset)
232 if self.debug:
232 if self.debug:
233 print >>sys.__stdout__, completions
233 print >>sys.__stdout__, completions
234
234
235
235
236 def buffered_write(self, text):
236 def buffered_write(self, text):
@@ -244,7 +244,7 b' class WxController(ConsoleWidget, PrefilterFrontEnd):'
244 self._out_buffer.append(text)
244 self._out_buffer.append(text)
245 self._out_buffer_lock.release()
245 self._out_buffer_lock.release()
246 if not self._buffer_flush_timer.IsRunning():
246 if not self._buffer_flush_timer.IsRunning():
247 wx.CallAfter(self._buffer_flush_timer.Start,
247 wx.CallAfter(self._buffer_flush_timer.Start,
248 milliseconds=100, oneShot=True)
248 milliseconds=100, oneShot=True)
249
249
250
250
@@ -257,9 +257,9 b' class WxController(ConsoleWidget, PrefilterFrontEnd):'
257
257
258
258
259 #--------------------------------------------------------------------------
259 #--------------------------------------------------------------------------
260 # LineFrontEnd interface
260 # LineFrontEnd interface
261 #--------------------------------------------------------------------------
261 #--------------------------------------------------------------------------
262
262
263 def execute(self, python_string, raw_string=None):
263 def execute(self, python_string, raw_string=None):
264 self._input_state = 'buffering'
264 self._input_state = 'buffering'
265 self.CallTipCancel()
265 self.CallTipCancel()
@@ -275,7 +275,7 b' class WxController(ConsoleWidget, PrefilterFrontEnd):'
275 # Use a callafter to update the display robustly under windows
275 # Use a callafter to update the display robustly under windows
276 def callback():
276 def callback():
277 self.GotoPos(self.GetLength())
277 self.GotoPos(self.GetLength())
278 PrefilterFrontEnd.execute(self, python_string,
278 PrefilterFrontEnd.execute(self, python_string,
279 raw_string=raw_string)
279 raw_string=raw_string)
280 wx.CallAfter(callback)
280 wx.CallAfter(callback)
281
281
@@ -314,7 +314,7 b' class WxController(ConsoleWidget, PrefilterFrontEnd):'
314 return True
314 return True
315
315
316
316
317 def save_output_hooks(self):
317 def save_output_hooks(self):
318 self.__old_raw_input = __builtin__.raw_input
318 self.__old_raw_input = __builtin__.raw_input
319 PrefilterFrontEnd.save_output_hooks(self)
319 PrefilterFrontEnd.save_output_hooks(self)
320
320
@@ -322,8 +322,8 b' class WxController(ConsoleWidget, PrefilterFrontEnd):'
322 self.SetLexer(stc.STC_LEX_NULL)
322 self.SetLexer(stc.STC_LEX_NULL)
323 PrefilterFrontEnd.capture_output(self)
323 PrefilterFrontEnd.capture_output(self)
324 __builtin__.raw_input = self.raw_input
324 __builtin__.raw_input = self.raw_input
325
325
326
326
327 def release_output(self):
327 def release_output(self):
328 __builtin__.raw_input = self.__old_raw_input
328 __builtin__.raw_input = self.__old_raw_input
329 PrefilterFrontEnd.release_output(self)
329 PrefilterFrontEnd.release_output(self)
@@ -346,11 +346,11 b' class WxController(ConsoleWidget, PrefilterFrontEnd):'
346 for i in range(start_line, self.GetCurrentLine()):
346 for i in range(start_line, self.GetCurrentLine()):
347 self._markers[i] = self.MarkerAdd(i, _ERROR_MARKER)
347 self._markers[i] = self.MarkerAdd(i, _ERROR_MARKER)
348
348
349
349
350 #--------------------------------------------------------------------------
350 #--------------------------------------------------------------------------
351 # FrontEndBase interface
351 # FrontEndBase interface
352 #--------------------------------------------------------------------------
352 #--------------------------------------------------------------------------
353
353
354 def render_error(self, e):
354 def render_error(self, e):
355 start_line = self.GetCurrentLine()
355 start_line = self.GetCurrentLine()
356 self.write('\n' + e + '\n')
356 self.write('\n' + e + '\n')
@@ -359,7 +359,7 b' class WxController(ConsoleWidget, PrefilterFrontEnd):'
359
359
360
360
361 #--------------------------------------------------------------------------
361 #--------------------------------------------------------------------------
362 # ConsoleWidget interface
362 # ConsoleWidget interface
363 #--------------------------------------------------------------------------
363 #--------------------------------------------------------------------------
364
364
365 def new_prompt(self, prompt):
365 def new_prompt(self, prompt):
@@ -405,7 +405,7 b' class WxController(ConsoleWidget, PrefilterFrontEnd):'
405 # get back to a prompt.
405 # get back to a prompt.
406 elif self._input_state == 'subprocess' and (
406 elif self._input_state == 'subprocess' and (
407 ( key_code <256 and not event.ControlDown() )
407 ( key_code <256 and not event.ControlDown() )
408 or
408 or
409 ( key_code in (ord('d'), ord('D')) and
409 ( key_code in (ord('d'), ord('D')) and
410 event.ControlDown())):
410 event.ControlDown())):
411 # We are running a process, we redirect keys.
411 # We are running a process, we redirect keys.
@@ -426,7 +426,7 b' class WxController(ConsoleWidget, PrefilterFrontEnd):'
426 self.do_calltip()
426 self.do_calltip()
427 elif self.AutoCompActive() and not key_code == ord('\t'):
427 elif self.AutoCompActive() and not key_code == ord('\t'):
428 event.Skip()
428 event.Skip()
429 if key_code in (wx.WXK_BACK, wx.WXK_DELETE):
429 if key_code in (wx.WXK_BACK, wx.WXK_DELETE):
430 wx.CallAfter(self._popup_completion, create=True)
430 wx.CallAfter(self._popup_completion, create=True)
431 elif not key_code in (wx.WXK_UP, wx.WXK_DOWN, wx.WXK_LEFT,
431 elif not key_code in (wx.WXK_UP, wx.WXK_DOWN, wx.WXK_LEFT,
432 wx.WXK_RIGHT, wx.WXK_ESCAPE):
432 wx.WXK_RIGHT, wx.WXK_ESCAPE):
@@ -455,7 +455,7 b' class WxController(ConsoleWidget, PrefilterFrontEnd):'
455 # Tab-completion
455 # Tab-completion
456 elif key_code == ord('\t'):
456 elif key_code == ord('\t'):
457 current_line, current_line_num = self.CurLine
457 current_line, current_line_num = self.CurLine
458 if not re.match(r'^%s\s*$' % self.continuation_prompt(),
458 if not re.match(r'^%s\s*$' % self.continuation_prompt(),
459 current_line):
459 current_line):
460 self.complete_current_input()
460 self.complete_current_input()
461 if self.AutoCompActive():
461 if self.AutoCompActive():
@@ -491,7 +491,7 b' class WxController(ConsoleWidget, PrefilterFrontEnd):'
491 ConsoleWidget._on_key_down(self, event, skip=skip)
491 ConsoleWidget._on_key_down(self, event, skip=skip)
492 else:
492 else:
493 ConsoleWidget._on_key_down(self, event, skip=skip)
493 ConsoleWidget._on_key_down(self, event, skip=skip)
494
494
495
495
496
496
497 def _on_key_up(self, event, skip=True):
497 def _on_key_up(self, event, skip=True):
@@ -503,7 +503,7 b' class WxController(ConsoleWidget, PrefilterFrontEnd):'
503 wx.CallAfter(self._popup_completion, create=True)
503 wx.CallAfter(self._popup_completion, create=True)
504 else:
504 else:
505 ConsoleWidget._on_key_up(self, event, skip=skip)
505 ConsoleWidget._on_key_up(self, event, skip=skip)
506 # Make sure the continuation_prompts are always followed by a
506 # Make sure the continuation_prompts are always followed by a
507 # whitespace
507 # whitespace
508 new_lines = []
508 new_lines = []
509 if self._input_state == 'readline':
509 if self._input_state == 'readline':
@@ -531,10 +531,10 b' class WxController(ConsoleWidget, PrefilterFrontEnd):'
531 if sys.platform == 'win32':
531 if sys.platform == 'win32':
532 self.input_buffer = self.input_buffer
532 self.input_buffer = self.input_buffer
533 old_prompt_num = self.current_prompt_pos
533 old_prompt_num = self.current_prompt_pos
534 has_executed = PrefilterFrontEnd._on_enter(self,
534 has_executed = PrefilterFrontEnd._on_enter(self,
535 new_line_pos=new_line_pos)
535 new_line_pos=new_line_pos)
536 if old_prompt_num == self.current_prompt_pos:
536 if old_prompt_num == self.current_prompt_pos:
537 # No execution has happened
537 # No execution has happened
538 self.GotoPos(self.GetLineEndPosition(current_line_num + 1))
538 self.GotoPos(self.GetLineEndPosition(current_line_num + 1))
539 return has_executed
539 return has_executed
540
540
@@ -544,7 +544,7 b' class WxController(ConsoleWidget, PrefilterFrontEnd):'
544 #--------------------------------------------------------------------------
544 #--------------------------------------------------------------------------
545
545
546 def OnUpdateUI(self, event):
546 def OnUpdateUI(self, event):
547 """ Override the OnUpdateUI of the EditWindow class, to prevent
547 """ Override the OnUpdateUI of the EditWindow class, to prevent
548 syntax highlighting both for faster redraw, and for more
548 syntax highlighting both for faster redraw, and for more
549 consistent look and feel.
549 consistent look and feel.
550 """
550 """
@@ -554,10 +554,10 b' class WxController(ConsoleWidget, PrefilterFrontEnd):'
554 #--------------------------------------------------------------------------
554 #--------------------------------------------------------------------------
555 # Private API
555 # Private API
556 #--------------------------------------------------------------------------
556 #--------------------------------------------------------------------------
557
557
558 def _buffer_flush(self, event):
558 def _buffer_flush(self, event):
559 """ Called by the timer to flush the write buffer.
559 """ Called by the timer to flush the write buffer.
560
560
561 This is always called in the mainloop, by the wx timer.
561 This is always called in the mainloop, by the wx timer.
562 """
562 """
563 self._out_buffer_lock.acquire()
563 self._out_buffer_lock.acquire()
@@ -4,7 +4,7 b''
4 zope.interface mock. If zope is installed, this module provides a zope
4 zope.interface mock. If zope is installed, this module provides a zope
5 interface classes, if not it provides mocks for them.
5 interface classes, if not it provides mocks for them.
6
6
7 Classes provided:
7 Classes provided:
8 Interface, Attribute, implements, classProvides
8 Interface, Attribute, implements, classProvides
9 """
9 """
10 __docformat__ = "restructuredtext en"
10 __docformat__ = "restructuredtext en"
@@ -23,7 +23,7 b' if len(sys.argv) > 1:'
23 if sys.argv[1] == '-v':
23 if sys.argv[1] == '-v':
24 sys.argv = sys.argv[:-1] # IPython is confused by -v, apparently
24 sys.argv = sys.argv[:-1] # IPython is confused by -v, apparently
25 verbose = True
25 verbose = True
26
26
27 IPython.Shell.start()
27 IPython.Shell.start()
28
28
29 ip = IPython.ipapi.get()
29 ip = IPython.ipapi.get()
@@ -41,7 +41,7 b' def install_mock_handler(name):'
41 handler func always returns '', which causes ipython to cease handling
41 handler func always returns '', which causes ipython to cease handling
42 the string immediately. That way, that it doesn't echo output, raise
42 the string immediately. That way, that it doesn't echo output, raise
43 exceptions, etc. But do note that testing multiline strings thus gets
43 exceptions, etc. But do note that testing multiline strings thus gets
44 a bit hard."""
44 a bit hard."""
45 def mock_handler(self, line, continue_prompt=None,
45 def mock_handler(self, line, continue_prompt=None,
46 pre=None,iFun=None,theRest=None,
46 pre=None,iFun=None,theRest=None,
47 obj=None):
47 obj=None):
@@ -76,7 +76,7 b' def reset_esc_handlers():'
76 s.ESC_SH_CAP : s.handle_shell_escape,
76 s.ESC_SH_CAP : s.handle_shell_escape,
77 }
77 }
78 reset_esc_handlers()
78 reset_esc_handlers()
79
79
80 # This is so I don't have to quote over and over. Gotta be a better way.
80 # This is so I don't have to quote over and over. Gotta be a better way.
81 handle_normal = 'handle_normal'
81 handle_normal = 'handle_normal'
82 handle_auto = 'handle_auto'
82 handle_auto = 'handle_auto'
@@ -96,18 +96,18 b' def check(assertion, failure_msg):'
96 if assertion:
96 if assertion:
97 if verbose:
97 if verbose:
98 sys.stdout.write('.')
98 sys.stdout.write('.')
99 sys.stdout.flush()
99 sys.stdout.flush()
100 else:
100 else:
101 if verbose:
101 if verbose:
102 sys.stdout.write('F')
102 sys.stdout.write('F')
103 sys.stdout.flush()
103 sys.stdout.flush()
104 failures.append(failure_msg)
104 failures.append(failure_msg)
105
105
106
106
107 def check_handler(expected_handler, line):
107 def check_handler(expected_handler, line):
108 """Verify that the expected hander was called (for the given line,
108 """Verify that the expected hander was called (for the given line,
109 passed in for failure reporting).
109 passed in for failure reporting).
110
110
111 Pulled out to its own function so that tests which don't use
111 Pulled out to its own function so that tests which don't use
112 run_handler_tests can still take advantage of it."""
112 run_handler_tests can still take advantage of it."""
113 check(handler_called == expected_handler,
113 check(handler_called == expected_handler,
@@ -115,16 +115,16 b' def check_handler(expected_handler, line):'
115 "instead %s called" % (expected_handler,
115 "instead %s called" % (expected_handler,
116 repr(line),
116 repr(line),
117 handler_called))
117 handler_called))
118
118
119
119
120 def run_handler_tests(h_tests):
120 def run_handler_tests(h_tests):
121 """Loop through a series of (input_line, handler_name) pairs, verifying
121 """Loop through a series of (input_line, handler_name) pairs, verifying
122 that, for each ip calls the given handler for the given line.
122 that, for each ip calls the given handler for the given line.
123
123
124 The verbose complaint includes the line passed in, so if that line can
124 The verbose complaint includes the line passed in, so if that line can
125 include enough info to find the error, the tests are modestly
125 include enough info to find the error, the tests are modestly
126 self-documenting.
126 self-documenting.
127 """
127 """
128 for ln, expected_handler in h_tests:
128 for ln, expected_handler in h_tests:
129 global handler_called
129 global handler_called
130 handler_called = None
130 handler_called = None
@@ -133,7 +133,7 b' def run_handler_tests(h_tests):'
133
133
134 def run_one_test(ln, expected_handler):
134 def run_one_test(ln, expected_handler):
135 run_handler_tests([(ln, expected_handler)])
135 run_handler_tests([(ln, expected_handler)])
136
136
137
137
138 # =========================================
138 # =========================================
139 # Tests
139 # Tests
@@ -153,12 +153,12 b' esc_handler_tests = ['
153 ( '%magic', handle_magic),
153 ( '%magic', handle_magic),
154 # XXX Possibly, add test for /,; once those are unhooked from %autocall
154 # XXX Possibly, add test for /,; once those are unhooked from %autocall
155 ( 'emacs_mode # PYTHON-MODE', handle_emacs ),
155 ( 'emacs_mode # PYTHON-MODE', handle_emacs ),
156 ( ' ', handle_normal),
156 ( ' ', handle_normal),
157
157
158 # Trailing qmark combos. Odd special cases abound
158 # Trailing qmark combos. Odd special cases abound
159
159
160 # ! always takes priority!
160 # ! always takes priority!
161 ( '!thing?', handle_shell_escape),
161 ( '!thing?', handle_shell_escape),
162 ( '!thing arg?', handle_shell_escape),
162 ( '!thing arg?', handle_shell_escape),
163 ( '!!thing?', handle_shell_escape),
163 ( '!!thing?', handle_shell_escape),
164 ( '!!thing arg?', handle_shell_escape),
164 ( '!!thing arg?', handle_shell_escape),
@@ -186,8 +186,8 b' run_handler_tests(esc_handler_tests)'
186 old_mls = ip.options.multi_line_specials
186 old_mls = ip.options.multi_line_specials
187 for ln in [ ' !ls $f multi_line_specials %s',
187 for ln in [ ' !ls $f multi_line_specials %s',
188 ' !!ls $f multi_line_specials %s', # !! escapes work on mls
188 ' !!ls $f multi_line_specials %s', # !! escapes work on mls
189 # Trailing ? doesn't trigger help:
189 # Trailing ? doesn't trigger help:
190 ' !ls $f multi_line_specials %s ?',
190 ' !ls $f multi_line_specials %s ?',
191 ' !!ls $f multi_line_specials %s ?',
191 ' !!ls $f multi_line_specials %s ?',
192 ]:
192 ]:
193 ip.options.multi_line_specials = 1
193 ip.options.multi_line_specials = 1
@@ -271,16 +271,16 b' class AttributeMutator(object):'
271 attr_mutator = AttributeMutator()
271 attr_mutator = AttributeMutator()
272 ip.to_user_ns('attr_mutator')
272 ip.to_user_ns('attr_mutator')
273
273
274 ip.options.autocall = 1
274 ip.options.autocall = 1
275
275
276 run_one_test('attr_mutator.foo should mutate', handle_normal)
276 run_one_test('attr_mutator.foo should mutate', handle_normal)
277 check(attr_mutator.called, 'ofind should be called in absence of assign characters')
277 check(attr_mutator.called, 'ofind should be called in absence of assign characters')
278
278
279 for c in list('!=()<>+*/%^&|'):
279 for c in list('!=()<>+*/%^&|'):
280 attr_mutator.called = False
280 attr_mutator.called = False
281 run_one_test('attr_mutator.foo %s should *not* mutate' % c, handle_normal)
281 run_one_test('attr_mutator.foo %s should *not* mutate' % c, handle_normal)
282 run_one_test('attr_mutator.foo%s should *not* mutate' % c, handle_normal)
282 run_one_test('attr_mutator.foo%s should *not* mutate' % c, handle_normal)
283
283
284 check(not attr_mutator.called,
284 check(not attr_mutator.called,
285 'ofind should not be called near character %s' % c)
285 'ofind should not be called near character %s' % c)
286
286
@@ -302,7 +302,7 b' for ac_state in [0,1]:'
302 run_handler_tests([
302 run_handler_tests([
303 ("alias_cmd", handle_alias),
303 ("alias_cmd", handle_alias),
304 # XXX See note above
304 # XXX See note above
305 #("alias_head.with_dot unshadowed, autocall=%s" % ac_state, handle_alias),
305 #("alias_head.with_dot unshadowed, autocall=%s" % ac_state, handle_alias),
306 ("alias_cmd.something aliases must match whole expr", handle_normal),
306 ("alias_cmd.something aliases must match whole expr", handle_normal),
307 ("alias_cmd /", handle_alias),
307 ("alias_cmd /", handle_alias),
308 ])
308 ])
@@ -331,7 +331,7 b' import IPython.ipapi'
331 class Autocallable(IPython.ipapi.IPyAutocall):
331 class Autocallable(IPython.ipapi.IPyAutocall):
332 def __call__(self):
332 def __call__(self):
333 return "called"
333 return "called"
334
334
335 autocallable = Autocallable()
335 autocallable = Autocallable()
336 ip.to_user_ns('autocallable')
336 ip.to_user_ns('autocallable')
337
337
@@ -344,13 +344,13 b' run_handler_tests( ['
344 ( 'len autocall_0', handle_normal),
344 ( 'len autocall_0', handle_normal),
345 ( 'thing autocall_0', handle_normal),
345 ( 'thing autocall_0', handle_normal),
346 ( 'autocallable', handle_auto),
346 ( 'autocallable', handle_auto),
347
347
348 # With explicit escapes, callable and non-callables both get expanded,
348 # With explicit escapes, callable and non-callables both get expanded,
349 # regardless of the %autocall setting:
349 # regardless of the %autocall setting:
350 ( '/len autocall_0', handle_auto),
350 ( '/len autocall_0', handle_auto),
351 ( ',len autocall_0 b0', handle_auto),
351 ( ',len autocall_0 b0', handle_auto),
352 ( ';len autocall_0 b0', handle_auto),
352 ( ';len autocall_0 b0', handle_auto),
353
353
354 ( '/thing autocall_0', handle_auto),
354 ( '/thing autocall_0', handle_auto),
355 ( ',thing autocall_0 b0', handle_auto),
355 ( ',thing autocall_0 b0', handle_auto),
356 ( ';thing autocall_0 b0', handle_auto),
356 ( ';thing autocall_0 b0', handle_auto),
@@ -370,7 +370,7 b' run_handler_tests( ['
370
370
371
371
372 # Now, with autocall in default, 'smart' mode
372 # Now, with autocall in default, 'smart' mode
373 ip.options.autocall = 1
373 ip.options.autocall = 1
374 run_handler_tests( [
374 run_handler_tests( [
375 # Autocalls without escapes -- only expand if it's callable
375 # Autocalls without escapes -- only expand if it's callable
376 ( 'len a1', handle_auto),
376 ( 'len a1', handle_auto),
@@ -416,8 +416,8 b' for b in bin_ops:'
416 bin_tests.append((';len %s binop_autocall' % b, handle_auto))
416 bin_tests.append((';len %s binop_autocall' % b, handle_auto))
417 bin_tests.append((',len %s binop_autocall' % b, handle_auto))
417 bin_tests.append((',len %s binop_autocall' % b, handle_auto))
418 bin_tests.append(('/len %s binop_autocall' % b, handle_auto))
418 bin_tests.append(('/len %s binop_autocall' % b, handle_auto))
419
419
420 # Who loves auto-generating tests?
420 # Who loves auto-generating tests?
421 run_handler_tests(bin_tests)
421 run_handler_tests(bin_tests)
422
422
423
423
@@ -431,7 +431,7 b' run_handler_tests(bin_tests)'
431 # ============
431 # ============
432 num_f = len(failures)
432 num_f = len(failures)
433 if verbose:
433 if verbose:
434 print
434 print
435 print "%s tests run, %s failure%s" % (num_tests,
435 print "%s tests run, %s failure%s" % (num_tests,
436 num_f,
436 num_f,
437 num_f != 1 and "s" or "")
437 num_f != 1 and "s" or "")
@@ -10,7 +10,7 b' import sys'
10 from twisted.internet import reactor, threads
10 from twisted.internet import reactor, threads
11
11
12 from IPython.core.ipmaker import make_IPython
12 from IPython.core.ipmaker import make_IPython
13 from IPython.core.iplib import InteractiveShell
13 from IPython.core.iplib import InteractiveShell
14 from IPython.utils.ipstruct import Struct
14 from IPython.utils.ipstruct import Struct
15 import Queue,thread,threading,signal
15 import Queue,thread,threading,signal
16 from signal import signal, SIGINT
16 from signal import signal, SIGINT
@@ -43,7 +43,7 b' def hijack_reactor():'
43 return getattr(orig_reactor, name)
43 return getattr(orig_reactor, name)
44 def __setattr__(self, name, value):
44 def __setattr__(self, name, value):
45 return setattr(orig_reactor, name, value)
45 return setattr(orig_reactor, name, value)
46
46
47 internet.reactor = DummyReactor()
47 internet.reactor = DummyReactor()
48 return orig_reactor
48 return orig_reactor
49
49
@@ -62,12 +62,12 b' class TwistedInteractiveShell(InteractiveShell):'
62 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
62 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
63 user_ns=None,user_global_ns=None,banner2='',**kw):
63 user_ns=None,user_global_ns=None,banner2='',**kw):
64 """Similar to the normal InteractiveShell, but with threading control"""
64 """Similar to the normal InteractiveShell, but with threading control"""
65
65
66 InteractiveShell.__init__(self,name,usage,rc,user_ns,
66 InteractiveShell.__init__(self,name,usage,rc,user_ns,
67 user_global_ns,banner2)
67 user_global_ns,banner2)
68
68
69
69
70 # A queue to hold the code to be executed.
70 # A queue to hold the code to be executed.
71 self.code_queue = Queue.Queue()
71 self.code_queue = Queue.Queue()
72
72
73 # Stuff to do at closing time
73 # Stuff to do at closing time
@@ -82,13 +82,13 b' class TwistedInteractiveShell(InteractiveShell):'
82 self.worker_ident = None
82 self.worker_ident = None
83 self.reactor_started = False
83 self.reactor_started = False
84 self.first_run = True
84 self.first_run = True
85
85
86 def runsource(self, source, filename="<input>", symbol="single"):
86 def runsource(self, source, filename="<input>", symbol="single"):
87 """Compile and run some source in the interpreter.
87 """Compile and run some source in the interpreter.
88
88
89 Modified version of code.py's runsource(), to handle threading issues.
89 Modified version of code.py's runsource(), to handle threading issues.
90 See the original for full docstring details."""
90 See the original for full docstring details."""
91
91
92 # If Ctrl-C was typed, we reset the flag and return right away
92 # If Ctrl-C was typed, we reset the flag and return right away
93 if shellglobals.KBINT:
93 if shellglobals.KBINT:
94 shellglobals.KBINT = False
94 shellglobals.KBINT = False
@@ -97,7 +97,7 b' class TwistedInteractiveShell(InteractiveShell):'
97 if self._kill:
97 if self._kill:
98 # can't queue new code if we are being killed
98 # can't queue new code if we are being killed
99 return True
99 return True
100
100
101 try:
101 try:
102 code = self.compile(source, filename, symbol)
102 code = self.compile(source, filename, symbol)
103 except (OverflowError, SyntaxError, ValueError):
103 except (OverflowError, SyntaxError, ValueError):
@@ -109,21 +109,21 b' class TwistedInteractiveShell(InteractiveShell):'
109 # Case 2
109 # Case 2
110 return True
110 return True
111
111
112 # shortcut - if we are in worker thread, or the worker thread is not running,
112 # shortcut - if we are in worker thread, or the worker thread is not running,
113 # execute directly (to allow recursion and prevent deadlock if code is run early
113 # execute directly (to allow recursion and prevent deadlock if code is run early
114 # in IPython construction)
114 # in IPython construction)
115
115
116 if (not self.reactor_started or (self.worker_ident is None and not self.first_run)
116 if (not self.reactor_started or (self.worker_ident is None and not self.first_run)
117 or self.worker_ident == thread.get_ident() or shellglobals.run_in_frontend(source)):
117 or self.worker_ident == thread.get_ident() or shellglobals.run_in_frontend(source)):
118 InteractiveShell.runcode(self,code)
118 InteractiveShell.runcode(self,code)
119 return
119 return
120
120
121 # Case 3
121 # Case 3
122 # Store code in queue, so the execution thread can handle it.
122 # Store code in queue, so the execution thread can handle it.
123
123
124 self.first_run = False
124 self.first_run = False
125 completed_ev, received_ev = threading.Event(), threading.Event()
125 completed_ev, received_ev = threading.Event(), threading.Event()
126
126
127 self.code_queue.put((code,completed_ev, received_ev))
127 self.code_queue.put((code,completed_ev, received_ev))
128
128
129 reactor.callLater(0.0,self.runcode)
129 reactor.callLater(0.0,self.runcode)
@@ -133,18 +133,18 b' class TwistedInteractiveShell(InteractiveShell):'
133 print "Warning: Timeout for mainloop thread exceeded"
133 print "Warning: Timeout for mainloop thread exceeded"
134 print "switching to nonthreaded mode (until mainloop wakes up again)"
134 print "switching to nonthreaded mode (until mainloop wakes up again)"
135 self.worker_ident = None
135 self.worker_ident = None
136 else:
136 else:
137 completed_ev.wait()
137 completed_ev.wait()
138
138
139 return False
139 return False
140
140
141 def runcode(self):
141 def runcode(self):
142 """Execute a code object.
142 """Execute a code object.
143
143
144 Multithreaded wrapper around IPython's runcode()."""
144 Multithreaded wrapper around IPython's runcode()."""
145
145
146
146
147 # we are in worker thread, stash out the id for runsource()
147 # we are in worker thread, stash out the id for runsource()
148 self.worker_ident = thread.get_ident()
148 self.worker_ident = thread.get_ident()
149
149
150 if self._kill:
150 if self._kill:
@@ -172,12 +172,12 b' class TwistedInteractiveShell(InteractiveShell):'
172 code_to_run = None
172 code_to_run = None
173 while 1:
173 while 1:
174 try:
174 try:
175 code_to_run, completed_ev, received_ev = self.code_queue.get_nowait()
175 code_to_run, completed_ev, received_ev = self.code_queue.get_nowait()
176 except Queue.Empty:
176 except Queue.Empty:
177 break
177 break
178 received_ev.set()
178 received_ev.set()
179
179
180
180
181 # Exceptions need to be raised differently depending on which
181 # Exceptions need to be raised differently depending on which
182 # thread is active. This convoluted try/except is only there to
182 # thread is active. This convoluted try/except is only there to
183 # protect against asynchronous exceptions, to ensure that a shellglobals.KBINT
183 # protect against asynchronous exceptions, to ensure that a shellglobals.KBINT
@@ -196,8 +196,8 b' class TwistedInteractiveShell(InteractiveShell):'
196 finally:
196 finally:
197 shellglobals.CODE_RUN = False
197 shellglobals.CODE_RUN = False
198 # allow runsource() return from wait
198 # allow runsource() return from wait
199 completed_ev.set()
199 completed_ev.set()
200
200
201 # This MUST return true for gtk threading to work
201 # This MUST return true for gtk threading to work
202 return True
202 return True
203
203
@@ -237,7 +237,7 b' class IPShellTwisted:'
237 while True and not self.quitting:
237 while True and not self.quitting:
238 reactorrun_orig()
238 reactorrun_orig()
239 self.reactor.run = reactorrun
239 self.reactor.run = reactorrun
240
240
241 self.IP = make_IPython(argv, user_ns=user_ns, debug=debug,
241 self.IP = make_IPython(argv, user_ns=user_ns, debug=debug,
242 shell_class=shell_class,
242 shell_class=shell_class,
243 on_kill=[mainquit])
243 on_kill=[mainquit])
@@ -258,8 +258,8 b' class IPShellTwisted:'
258 reactor.callWhenRunning(spawnMainloopThread)
258 reactor.callWhenRunning(spawnMainloopThread)
259 self.IP.reactor_started = True
259 self.IP.reactor_started = True
260 self.reactor.run()
260 self.reactor.run()
261 print "mainloop ending...."
261 print "mainloop ending...."
262
262
263 exists = True
263 exists = True
264
264
265
265
@@ -53,19 +53,19 b' class ParalleMagic(Plugin):'
53 def magic_result(self, ipself, parameter_s=''):
53 def magic_result(self, ipself, parameter_s=''):
54 """Print the result of command i on all engines..
54 """Print the result of command i on all engines..
55
55
56 To use this a :class:`DirectView` instance must be created
56 To use this a :class:`DirectView` instance must be created
57 and then activated by calling its :meth:`activate` method.
57 and then activated by calling its :meth:`activate` method.
58
58
59 Then you can do the following::
59 Then you can do the following::
60
60
61 In [23]: %result
61 In [23]: %result
62 Out[23]:
62 Out[23]:
63 <Results List>
63 <Results List>
64 [0] In [6]: a = 10
64 [0] In [6]: a = 10
65 [1] In [6]: a = 10
65 [1] In [6]: a = 10
66
66
67 In [22]: %result 6
67 In [22]: %result 6
68 Out[22]:
68 Out[22]:
69 <Results List>
69 <Results List>
70 [0] In [6]: a = 10
70 [0] In [6]: a = 10
71 [1] In [6]: a = 10
71 [1] In [6]: a = 10
@@ -85,14 +85,14 b' class ParalleMagic(Plugin):'
85 def magic_px(self, ipself, parameter_s=''):
85 def magic_px(self, ipself, parameter_s=''):
86 """Executes the given python command in parallel.
86 """Executes the given python command in parallel.
87
87
88 To use this a :class:`DirectView` instance must be created
88 To use this a :class:`DirectView` instance must be created
89 and then activated by calling its :meth:`activate` method.
89 and then activated by calling its :meth:`activate` method.
90
90
91 Then you can do the following::
91 Then you can do the following::
92
92
93 In [24]: %px a = 5
93 In [24]: %px a = 5
94 Parallel execution on engine(s): all
94 Parallel execution on engine(s): all
95 Out[24]:
95 Out[24]:
96 <Results List>
96 <Results List>
97 [0] In [7]: a = 5
97 [0] In [7]: a = 5
98 [1] In [7]: a = 5
98 [1] In [7]: a = 5
@@ -111,7 +111,7 b' class ParalleMagic(Plugin):'
111 def magic_autopx(self, ipself, parameter_s=''):
111 def magic_autopx(self, ipself, parameter_s=''):
112 """Toggles auto parallel mode.
112 """Toggles auto parallel mode.
113
113
114 To use this a :class:`DirectView` instance must be created
114 To use this a :class:`DirectView` instance must be created
115 and then activated by calling its :meth:`activate` method. Once this
115 and then activated by calling its :meth:`activate` method. Once this
116 is called, all commands typed at the command line are send to
116 is called, all commands typed at the command line are send to
117 the engines to be executed in parallel. To control which engine
117 the engines to be executed in parallel. To control which engine
@@ -142,7 +142,7 b' class ParalleMagic(Plugin):'
142 self._enable_autopx()
142 self._enable_autopx()
143
143
144 def _enable_autopx(self):
144 def _enable_autopx(self):
145 """Enable %autopx mode by saving the original run_cell and installing
145 """Enable %autopx mode by saving the original run_cell and installing
146 pxrun_cell.
146 pxrun_cell.
147 """
147 """
148 if self.active_view is None:
148 if self.active_view is None:
@@ -157,7 +157,7 b' class ParalleMagic(Plugin):'
157
157
158 self.autopx = True
158 self.autopx = True
159 print "%autopx enabled"
159 print "%autopx enabled"
160
160
161 def _disable_autopx(self):
161 def _disable_autopx(self):
162 """Disable %autopx by restoring the original InteractiveShell.run_cell.
162 """Disable %autopx by restoring the original InteractiveShell.run_cell.
163 """
163 """
@@ -178,7 +178,7 b' class ParalleMagic(Plugin):'
178 stdouts = [result.stdout.rstrip()]
178 stdouts = [result.stdout.rstrip()]
179 else:
179 else:
180 stdouts = [s.rstrip() for s in result.stdout]
180 stdouts = [s.rstrip() for s in result.stdout]
181
181
182 targets = self.active_view.targets
182 targets = self.active_view.targets
183 if isinstance(targets, int):
183 if isinstance(targets, int):
184 targets = [targets]
184 targets = [targets]
@@ -192,29 +192,29 b' class ParalleMagic(Plugin):'
192
192
193 def pxrun_cell(self, raw_cell, store_history=True):
193 def pxrun_cell(self, raw_cell, store_history=True):
194 """drop-in replacement for InteractiveShell.run_cell.
194 """drop-in replacement for InteractiveShell.run_cell.
195
195
196 This executes code remotely, instead of in the local namespace.
196 This executes code remotely, instead of in the local namespace.
197
197
198 See InteractiveShell.run_cell for details.
198 See InteractiveShell.run_cell for details.
199 """
199 """
200
200
201 if (not raw_cell) or raw_cell.isspace():
201 if (not raw_cell) or raw_cell.isspace():
202 return
202 return
203
203
204 ipself = self.shell
204 ipself = self.shell
205
205
206 with ipself.builtin_trap:
206 with ipself.builtin_trap:
207 cell = ipself.prefilter_manager.prefilter_lines(raw_cell)
207 cell = ipself.prefilter_manager.prefilter_lines(raw_cell)
208
208
209 # Store raw and processed history
209 # Store raw and processed history
210 if store_history:
210 if store_history:
211 ipself.history_manager.store_inputs(ipself.execution_count,
211 ipself.history_manager.store_inputs(ipself.execution_count,
212 cell, raw_cell)
212 cell, raw_cell)
213
213
214 # ipself.logger.log(cell, raw_cell)
214 # ipself.logger.log(cell, raw_cell)
215
215
216 cell_name = ipself.compile.cache(cell, ipself.execution_count)
216 cell_name = ipself.compile.cache(cell, ipself.execution_count)
217
217
218 try:
218 try:
219 code_ast = ast.parse(cell, filename=cell_name)
219 code_ast = ast.parse(cell, filename=cell_name)
220 except (OverflowError, SyntaxError, ValueError, TypeError, MemoryError):
220 except (OverflowError, SyntaxError, ValueError, TypeError, MemoryError):
@@ -232,7 +232,7 b' class ParalleMagic(Plugin):'
232 ipself.history_manager.store_output(ipself.execution_count)
232 ipself.history_manager.store_output(ipself.execution_count)
233 # Each cell is a *single* input, regardless of how many lines it has
233 # Each cell is a *single* input, regardless of how many lines it has
234 ipself.execution_count += 1
234 ipself.execution_count += 1
235
235
236 if re.search(r'get_ipython\(\)\.magic\(u?"%?autopx', cell):
236 if re.search(r'get_ipython\(\)\.magic\(u?"%?autopx', cell):
237 self._disable_autopx()
237 self._disable_autopx()
238 return False
238 return False
@@ -94,7 +94,7 b' def matchorfail(text, pos):'
94
94
95 class Itpl:
95 class Itpl:
96 """Class representing a string with interpolation abilities.
96 """Class representing a string with interpolation abilities.
97
97
98 Upon creation, an instance works out what parts of the format
98 Upon creation, an instance works out what parts of the format
99 string are literal and what parts need to be evaluated. The
99 string are literal and what parts need to be evaluated. The
100 evaluation and substitution happens in the namespace of the
100 evaluation and substitution happens in the namespace of the
@@ -106,10 +106,10 b' class Itpl:'
106
106
107 The format string is parsed according to the following rules:
107 The format string is parsed according to the following rules:
108
108
109 1. A dollar sign and a name, possibly followed by any of:
109 1. A dollar sign and a name, possibly followed by any of:
110 - an open-paren, and anything up to the matching paren
110 - an open-paren, and anything up to the matching paren
111 - an open-bracket, and anything up to the matching bracket
111 - an open-bracket, and anything up to the matching bracket
112 - a period and a name
112 - a period and a name
113 any number of times, is evaluated as a Python expression.
113 any number of times, is evaluated as a Python expression.
114
114
115 2. A dollar sign immediately followed by an open-brace, and
115 2. A dollar sign immediately followed by an open-brace, and
@@ -135,7 +135,7 b' class Itpl:'
135 self.format = format
135 self.format = format
136 self.codec = codec
136 self.codec = codec
137 self.encoding_errors = encoding_errors
137 self.encoding_errors = encoding_errors
138
138
139 namechars = "abcdefghijklmnopqrstuvwxyz" \
139 namechars = "abcdefghijklmnopqrstuvwxyz" \
140 "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
140 "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
141 chunks = []
141 chunks = []
@@ -212,7 +212,7 b' class Itpl:'
212 loc, glob = frame.f_locals, frame.f_globals
212 loc, glob = frame.f_locals, frame.f_globals
213
213
214 return self._str(glob,loc)
214 return self._str(glob,loc)
215
215
216 class ItplNS(Itpl):
216 class ItplNS(Itpl):
217 """Class representing a string with interpolation abilities.
217 """Class representing a string with interpolation abilities.
218
218
@@ -221,7 +221,7 b' class ItplNS(Itpl):'
221 efficient, as no traceback needs to be extracte. It also allows the
221 efficient, as no traceback needs to be extracte. It also allows the
222 caller to supply a different namespace for the interpolation to occur than
222 caller to supply a different namespace for the interpolation to occur than
223 its own."""
223 its own."""
224
224
225 def __init__(self, format,globals,locals=None,
225 def __init__(self, format,globals,locals=None,
226 codec='utf_8',encoding_errors='backslashreplace'):
226 codec='utf_8',encoding_errors='backslashreplace'):
227 """ItplNS(format,globals[,locals]) -> interpolating string instance.
227 """ItplNS(format,globals[,locals]) -> interpolating string instance.
@@ -236,7 +236,7 b' class ItplNS(Itpl):'
236 self.globals = globals
236 self.globals = globals
237 self.locals = locals
237 self.locals = locals
238 Itpl.__init__(self,format,codec,encoding_errors)
238 Itpl.__init__(self,format,codec,encoding_errors)
239
239
240 def __str__(self):
240 def __str__(self):
241 """Evaluate and substitute the appropriate parts of the string."""
241 """Evaluate and substitute the appropriate parts of the string."""
242 return self._str(self.globals,self.locals)
242 return self._str(self.globals,self.locals)
@@ -260,7 +260,7 b' class ItplFile:'
260
260
261 def filter(file=sys.stdout):
261 def filter(file=sys.stdout):
262 """Return an ItplFile that filters writes to the given file object.
262 """Return an ItplFile that filters writes to the given file object.
263
263
264 'file = filter(file)' replaces 'file' with a filtered object that
264 'file = filter(file)' replaces 'file' with a filtered object that
265 has a write() method. When called with no argument, this creates
265 has a write() method. When called with no argument, this creates
266 a filter to sys.stdout."""
266 a filter to sys.stdout."""
@@ -268,7 +268,7 b' def filter(file=sys.stdout):'
268
268
269 def unfilter(ifile=None):
269 def unfilter(ifile=None):
270 """Return the original file that corresponds to the given ItplFile.
270 """Return the original file that corresponds to the given ItplFile.
271
271
272 'file = unfilter(file)' undoes the effect of 'file = filter(file)'.
272 'file = unfilter(file)' undoes the effect of 'file = filter(file)'.
273 'sys.stdout = unfilter()' undoes the effect of 'sys.stdout = filter()'."""
273 'sys.stdout = unfilter()' undoes the effect of 'sys.stdout = filter()'."""
274 return ifile and ifile.file or sys.stdout.file
274 return ifile and ifile.file or sys.stdout.file
@@ -3,12 +3,12 b''
3 ## Copyright (c) 2005, Michele Simionato
3 ## Copyright (c) 2005, Michele Simionato
4 ## All rights reserved.
4 ## All rights reserved.
5 ##
5 ##
6 ## Redistributions of source code must retain the above copyright
6 ## Redistributions of source code must retain the above copyright
7 ## notice, this list of conditions and the following disclaimer.
7 ## notice, this list of conditions and the following disclaimer.
8 ## Redistributions in bytecode form must reproduce the above copyright
8 ## Redistributions in bytecode form must reproduce the above copyright
9 ## notice, this list of conditions and the following disclaimer in
9 ## notice, this list of conditions and the following disclaimer in
10 ## the documentation and/or other materials provided with the
10 ## the documentation and/or other materials provided with the
11 ## distribution.
11 ## distribution.
12
12
13 ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
13 ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
14 ## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
14 ## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@@ -39,7 +39,7 b' except ImportError: # for Python version < 2.5'
39 "A simple replacement of functools.partial"
39 "A simple replacement of functools.partial"
40 def __init__(self, func, *args, **kw):
40 def __init__(self, func, *args, **kw):
41 self.func = func
41 self.func = func
42 self.args = args
42 self.args = args
43 self.keywords = kw
43 self.keywords = kw
44 def __call__(self, *otherargs, **otherkw):
44 def __call__(self, *otherargs, **otherkw):
45 kw = self.keywords.copy()
45 kw = self.keywords.copy()
@@ -61,7 +61,7 b' class FunctionMaker(object):'
61 # func can be a class or a callable, but not an instance method
61 # func can be a class or a callable, but not an instance method
62 self.name = func.__name__
62 self.name = func.__name__
63 if self.name == '<lambda>': # small hack for lambda functions
63 if self.name == '<lambda>': # small hack for lambda functions
64 self.name = '_lambda_'
64 self.name = '_lambda_'
65 self.doc = func.__doc__
65 self.doc = func.__doc__
66 self.module = func.__module__
66 self.module = func.__module__
67 if inspect.isfunction(func):
67 if inspect.isfunction(func):
@@ -138,7 +138,7 b' class FunctionMaker(object):'
138 """
138 """
139 if isinstance(obj, str): # "name(signature)"
139 if isinstance(obj, str): # "name(signature)"
140 name, rest = obj.strip().split('(', 1)
140 name, rest = obj.strip().split('(', 1)
141 signature = rest[:-1] #strip a right parens
141 signature = rest[:-1] #strip a right parens
142 func = None
142 func = None
143 else: # a function
143 else: # a function
144 name = None
144 name = None
@@ -146,9 +146,9 b' class FunctionMaker(object):'
146 func = obj
146 func = obj
147 fun = cls(func, name, signature, defaults, doc, module)
147 fun = cls(func, name, signature, defaults, doc, module)
148 ibody = '\n'.join(' ' + line for line in body.splitlines())
148 ibody = '\n'.join(' ' + line for line in body.splitlines())
149 return fun.make('def %(name)s(%(signature)s):\n' + ibody,
149 return fun.make('def %(name)s(%(signature)s):\n' + ibody,
150 evaldict, addsource, **attrs)
150 evaldict, addsource, **attrs)
151
151
152 def decorator(caller, func=None):
152 def decorator(caller, func=None):
153 """
153 """
154 decorator(caller) converts a caller function into a decorator;
154 decorator(caller) converts a caller function into a decorator;
@@ -164,7 +164,7 b' def decorator(caller, func=None):'
164 # otherwise assume caller is a function
164 # otherwise assume caller is a function
165 f = inspect.getargspec(caller)[0][0] # first arg
165 f = inspect.getargspec(caller)[0][0] # first arg
166 return FunctionMaker.create(
166 return FunctionMaker.create(
167 '%s(%s)' % (caller.__name__, f),
167 '%s(%s)' % (caller.__name__, f),
168 'return decorator(_call_, %s)' % f,
168 'return decorator(_call_, %s)' % f,
169 dict(_call_=caller, decorator=decorator), undecorated=caller,
169 dict(_call_=caller, decorator=decorator), undecorated=caller,
170 doc=caller.__doc__, module=caller.__module__)
170 doc=caller.__doc__, module=caller.__module__)
@@ -191,7 +191,7 b' def getinfo(func):'
191 - doc (the docstring : str)
191 - doc (the docstring : str)
192 - module (the module name : str)
192 - module (the module name : str)
193 - dict (the function __dict__ : str)
193 - dict (the function __dict__ : str)
194
194
195 >>> def f(self, x=1, y=2, *args, **kw): pass
195 >>> def f(self, x=1, y=2, *args, **kw): pass
196
196
197 >>> info = getinfo(f)
197 >>> info = getinfo(f)
@@ -200,7 +200,7 b' def getinfo(func):'
200 'f'
200 'f'
201 >>> info["argnames"]
201 >>> info["argnames"]
202 ['self', 'x', 'y', 'args', 'kw']
202 ['self', 'x', 'y', 'args', 'kw']
203
203
204 >>> info["defaults"]
204 >>> info["defaults"]
205 (1, 2)
205 (1, 2)
206
206
@@ -237,7 +237,7 b' def update_wrapper(wrapper, model, infodict=None):'
237 def new_wrapper(wrapper, model):
237 def new_wrapper(wrapper, model):
238 """
238 """
239 An improvement over functools.update_wrapper. The wrapper is a generic
239 An improvement over functools.update_wrapper. The wrapper is a generic
240 callable object. It works by generating a copy of the wrapper with the
240 callable object. It works by generating a copy of the wrapper with the
241 right signature and by updating the copy, not the original.
241 right signature and by updating the copy, not the original.
242 Moreovoer, 'model' can be a dictionary with keys 'name', 'doc', 'module',
242 Moreovoer, 'model' can be a dictionary with keys 'name', 'doc', 'module',
243 'dict', 'defaults'.
243 'dict', 'defaults'.
@@ -138,9 +138,9 b' def skipif(skip_condition, msg=None):'
138
138
139 def get_msg(func,msg=None):
139 def get_msg(func,msg=None):
140 """Skip message with information about function being skipped."""
140 """Skip message with information about function being skipped."""
141 if msg is None:
141 if msg is None:
142 out = 'Test skipped due to test condition'
142 out = 'Test skipped due to test condition'
143 else:
143 else:
144 out = '\n'+msg
144 out = '\n'+msg
145
145
146 return "Skipping test: %s%s" % (func.__name__,out)
146 return "Skipping test: %s%s" % (func.__name__,out)
@@ -167,7 +167,7 b' def skipif(skip_condition, msg=None):'
167 skipper = skipper_gen
167 skipper = skipper_gen
168 else:
168 else:
169 skipper = skipper_func
169 skipper = skipper_func
170
170
171 return nose.tools.make_decorator(f)(skipper)
171 return nose.tools.make_decorator(f)(skipper)
172
172
173 return skip_decorator
173 return skip_decorator
@@ -5,41 +5,41 b''
5 #
5 #
6 # Copyright (c) 2006 Conan C. Albrecht
6 # Copyright (c) 2006 Conan C. Albrecht
7 #
7 #
8 # Permission is hereby granted, free of charge, to any person obtaining a copy
8 # Permission is hereby granted, free of charge, to any person obtaining a copy
9 # of this software and associated documentation files (the "Software"), to deal
9 # of this software and associated documentation files (the "Software"), to deal
10 # in the Software without restriction, including without limitation the rights
10 # in the Software without restriction, including without limitation the rights
11 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 # copies of the Software, and to permit persons to whom the Software is furnished
12 # copies of the Software, and to permit persons to whom the Software is furnished
13 # to do so, subject to the following conditions:
13 # to do so, subject to the following conditions:
14 #
14 #
15 # The above copyright notice and this permission notice shall be included in all
15 # The above copyright notice and this permission notice shall be included in all
16 # copies or substantial portions of the Software.
16 # copies or substantial portions of the Software.
17 #
17 #
18 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
18 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
19 # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
19 # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
20 # PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
20 # PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
21 # FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21 # FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
22 # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 # DEALINGS IN THE SOFTWARE.
23 # DEALINGS IN THE SOFTWARE.
24
24
25
25
26
26
27 ##################################################################################################
27 ##################################################################################################
28 ### A globally-unique identifier made up of time and ip and 8 digits for a counter:
28 ### A globally-unique identifier made up of time and ip and 8 digits for a counter:
29 ### each GUID is 40 characters wide
29 ### each GUID is 40 characters wide
30 ###
30 ###
31 ### A globally unique identifier that combines ip, time, and a counter. Since the
31 ### A globally unique identifier that combines ip, time, and a counter. Since the
32 ### time is listed first, you can sort records by guid. You can also extract the time
32 ### time is listed first, you can sort records by guid. You can also extract the time
33 ### and ip if needed.
33 ### and ip if needed.
34 ###
34 ###
35 ### Since the counter has eight hex characters, you can create up to
35 ### Since the counter has eight hex characters, you can create up to
36 ### 0xffffffff (4294967295) GUIDs every millisecond. If your processor
36 ### 0xffffffff (4294967295) GUIDs every millisecond. If your processor
37 ### is somehow fast enough to create more than that in a millisecond (looking
37 ### is somehow fast enough to create more than that in a millisecond (looking
38 ### toward the future, of course), the function will wait until the next
38 ### toward the future, of course), the function will wait until the next
39 ### millisecond to return.
39 ### millisecond to return.
40 ###
40 ###
41 ### GUIDs make wonderful database keys. They require no access to the
41 ### GUIDs make wonderful database keys. They require no access to the
42 ### database (to get the max index number), they are extremely unique, and they sort
42 ### database (to get the max index number), they are extremely unique, and they sort
43 ### automatically by time. GUIDs prevent key clashes when merging
43 ### automatically by time. GUIDs prevent key clashes when merging
44 ### two databases together, combining data, or generating keys in distributed
44 ### two databases together, combining data, or generating keys in distributed
45 ### systems.
45 ### systems.
@@ -57,9 +57,9 b''
57 # December 2, 2003 Fixed duplicating GUIDs. Sometimes they duplicate if multiples are created
57 # December 2, 2003 Fixed duplicating GUIDs. Sometimes they duplicate if multiples are created
58 # in the same millisecond (it checks the last 100 GUIDs now and has a larger random part)
58 # in the same millisecond (it checks the last 100 GUIDs now and has a larger random part)
59 # December 9, 2003 Fixed MAX_RANDOM, which was going over sys.maxint
59 # December 9, 2003 Fixed MAX_RANDOM, which was going over sys.maxint
60 # June 12, 2004 Allowed a custom IP address to be sent in rather than always using the
60 # June 12, 2004 Allowed a custom IP address to be sent in rather than always using the
61 # local IP address.
61 # local IP address.
62 # November 4, 2005 Changed the random part to a counter variable. Now GUIDs are totally
62 # November 4, 2005 Changed the random part to a counter variable. Now GUIDs are totally
63 # unique and more efficient, as long as they are created by only
63 # unique and more efficient, as long as they are created by only
64 # on runtime on a given machine. The counter part is after the time
64 # on runtime on a given machine. The counter part is after the time
65 # part so it sorts correctly.
65 # part so it sorts correctly.
@@ -87,7 +87,7 b' import threading'
87
87
88 #Makes a hex IP from a decimal dot-separated ip (eg: 127.0.0.1)
88 #Makes a hex IP from a decimal dot-separated ip (eg: 127.0.0.1)
89 make_hexip = lambda ip: ''.join(["%04x" % long(i) for i in ip.split('.')]) # leave space for ip v6 (65K in each sub)
89 make_hexip = lambda ip: ''.join(["%04x" % long(i) for i in ip.split('.')]) # leave space for ip v6 (65K in each sub)
90
90
91 MAX_COUNTER = 0xfffffffe
91 MAX_COUNTER = 0xfffffffe
92 counter = 0L
92 counter = 0L
93 firstcounter = MAX_COUNTER
93 firstcounter = MAX_COUNTER
@@ -104,7 +104,7 b" except: # if we don't have an ip, default to someting in the 10.x.x.x private ra"
104 ip += '.' + str(rand.randrange(1, 0xffff)) # might as well use IPv6 range if we're making it up
104 ip += '.' + str(rand.randrange(1, 0xffff)) # might as well use IPv6 range if we're making it up
105 hexip = make_hexip(ip)
105 hexip = make_hexip(ip)
106
106
107
107
108 #################################
108 #################################
109 ### Public module functions
109 ### Public module functions
110
110
@@ -121,7 +121,7 b' def generate(ip=None):'
121
121
122 # do we need to wait for the next millisecond (are we out of counters?)
122 # do we need to wait for the next millisecond (are we out of counters?)
123 now = long(time.time() * 1000)
123 now = long(time.time() * 1000)
124 while lasttime == now and counter == firstcounter:
124 while lasttime == now and counter == firstcounter:
125 time.sleep(.01)
125 time.sleep(.01)
126 now = long(time.time() * 1000)
126 now = long(time.time() * 1000)
127
127
@@ -136,7 +136,7 b' def generate(ip=None):'
136 if counter > MAX_COUNTER:
136 if counter > MAX_COUNTER:
137 counter = 0
137 counter = 0
138 lasttime = now
138 lasttime = now
139 parts.append("%08x" % (counter))
139 parts.append("%08x" % (counter))
140
140
141 # ip part
141 # ip part
142 parts.append(hexip)
142 parts.append(hexip)
@@ -145,10 +145,10 b' def generate(ip=None):'
145 return ''.join(parts)
145 return ''.join(parts)
146 finally:
146 finally:
147 lock.release()
147 lock.release()
148
148
149
149
150 def extract_time(guid):
150 def extract_time(guid):
151 '''Extracts the time portion out of the guid and returns the
151 '''Extracts the time portion out of the guid and returns the
152 number of seconds since the epoch as a float'''
152 number of seconds since the epoch as a float'''
153 return float(long(guid[0:16], 16)) / 1000.0
153 return float(long(guid[0:16], 16)) / 1000.0
154
154
@@ -1,26 +1,26 b''
1 r""" mglob - enhanced file list expansion module
1 r""" mglob - enhanced file list expansion module
2
2
3 Use as stand-alone utility (for xargs, `backticks` etc.),
3 Use as stand-alone utility (for xargs, `backticks` etc.),
4 or a globbing library for own python programs. Globbing the sys.argv is something
4 or a globbing library for own python programs. Globbing the sys.argv is something
5 that almost every Windows script has to perform manually, and this module is here
5 that almost every Windows script has to perform manually, and this module is here
6 to help with that task. Also Unix users will benefit from enhanced modes
6 to help with that task. Also Unix users will benefit from enhanced modes
7 such as recursion, exclusion, directory omission...
7 such as recursion, exclusion, directory omission...
8
8
9 Unlike glob.glob, directories are not included in the glob unless specified
9 Unlike glob.glob, directories are not included in the glob unless specified
10 with 'dir:'
10 with 'dir:'
11
11
12 'expand' is the function to use in python programs. Typical use
12 'expand' is the function to use in python programs. Typical use
13 to expand argv (esp. in windows)::
13 to expand argv (esp. in windows)::
14
14
15 try:
15 try:
16 import mglob
16 import mglob
17 files = mglob.expand(sys.argv[1:])
17 files = mglob.expand(sys.argv[1:])
18 except ImportError:
18 except ImportError:
19 print "mglob not found; try 'easy_install mglob' for extra features"
19 print "mglob not found; try 'easy_install mglob' for extra features"
20 files = sys.argv[1:]
20 files = sys.argv[1:]
21
21
22 Note that for unix, shell expands *normal* wildcards (*.cpp, etc.) in argv.
22 Note that for unix, shell expands *normal* wildcards (*.cpp, etc.) in argv.
23 Therefore, you might want to use quotes with normal wildcards to prevent this
23 Therefore, you might want to use quotes with normal wildcards to prevent this
24 expansion, in order for mglob to see the wildcards and get the wanted behaviour.
24 expansion, in order for mglob to see the wildcards and get the wanted behaviour.
25 Not quoting the wildcards is harmless and typically has equivalent results, though.
25 Not quoting the wildcards is harmless and typically has equivalent results, though.
26
26
@@ -34,27 +34,27 b' License: MIT Open Source license'
34 globsyntax = """\
34 globsyntax = """\
35 This program allows specifying filenames with "mglob" mechanism.
35 This program allows specifying filenames with "mglob" mechanism.
36 Supported syntax in globs (wilcard matching patterns)::
36 Supported syntax in globs (wilcard matching patterns)::
37
37
38 *.cpp ?ellowo*
38 *.cpp ?ellowo*
39 - obvious. Differs from normal glob in that dirs are not included.
39 - obvious. Differs from normal glob in that dirs are not included.
40 Unix users might want to write this as: "*.cpp" "?ellowo*"
40 Unix users might want to write this as: "*.cpp" "?ellowo*"
41 rec:/usr/share=*.txt,*.doc
41 rec:/usr/share=*.txt,*.doc
42 - get all *.txt and *.doc under /usr/share,
42 - get all *.txt and *.doc under /usr/share,
43 recursively
43 recursively
44 rec:/usr/share
44 rec:/usr/share
45 - All files under /usr/share, recursively
45 - All files under /usr/share, recursively
46 rec:*.py
46 rec:*.py
47 - All .py files under current working dir, recursively
47 - All .py files under current working dir, recursively
48 foo
48 foo
49 - File or dir foo
49 - File or dir foo
50 !*.bak readme*
50 !*.bak readme*
51 - readme*, exclude files ending with .bak
51 - readme*, exclude files ending with .bak
52 !.svn/ !.hg/ !*_Data/ rec:.
52 !.svn/ !.hg/ !*_Data/ rec:.
53 - Skip .svn, .hg, foo_Data dirs (and their subdirs) in recurse.
53 - Skip .svn, .hg, foo_Data dirs (and their subdirs) in recurse.
54 Trailing / is the key, \ does not work! Use !.*/ for all hidden.
54 Trailing / is the key, \ does not work! Use !.*/ for all hidden.
55 dir:foo
55 dir:foo
56 - the directory foo if it exists (not files in foo)
56 - the directory foo if it exists (not files in foo)
57 dir:*
57 dir:*
58 - all directories in current folder
58 - all directories in current folder
59 foo.py bar.* !h* rec:*.py
59 foo.py bar.* !h* rec:*.py
60 - Obvious. !h* exclusion only applies for rec:*.py.
60 - Obvious. !h* exclusion only applies for rec:*.py.
@@ -71,16 +71,16 b' __version__ = "0.2"'
71
71
72
72
73 import os,glob,fnmatch,sys,re
73 import os,glob,fnmatch,sys,re
74
74
75 def expand(flist,exp_dirs = False):
75 def expand(flist,exp_dirs = False):
76 """ Expand the glob(s) in flist.
76 """ Expand the glob(s) in flist.
77
77
78 flist may be either a whitespace-separated list of globs/files
78 flist may be either a whitespace-separated list of globs/files
79 or an array of globs/files.
79 or an array of globs/files.
80
80
81 if exp_dirs is true, directory names in glob are expanded to the files
81 if exp_dirs is true, directory names in glob are expanded to the files
82 contained in them - otherwise, directory names are returned as is.
82 contained in them - otherwise, directory names are returned as is.
83
83
84 """
84 """
85 if isinstance(flist, basestring):
85 if isinstance(flist, basestring):
86 import shlex
86 import shlex
@@ -89,7 +89,7 b' def expand(flist,exp_dirs = False):'
89 denied_set = set()
89 denied_set = set()
90 cont_set = set()
90 cont_set = set()
91 cur_rejected_dirs = set()
91 cur_rejected_dirs = set()
92
92
93 def recfind(p, pats = ["*"]):
93 def recfind(p, pats = ["*"]):
94 denied_dirs = [os.path.dirname(d) for d in denied_set if d.endswith("/")]
94 denied_dirs = [os.path.dirname(d) for d in denied_set if d.endswith("/")]
95 for (dp,dnames,fnames) in os.walk(p):
95 for (dp,dnames,fnames) in os.walk(p):
@@ -103,7 +103,7 b' def expand(flist,exp_dirs = False):'
103 break
103 break
104 if deny:
104 if deny:
105 continue
105 continue
106
106
107
107
108 #print "dp",dp
108 #print "dp",dp
109 bname = os.path.basename(dp)
109 bname = os.path.basename(dp)
@@ -115,7 +115,7 b' def expand(flist,exp_dirs = False):'
115 if deny:
115 if deny:
116 continue
116 continue
117
117
118
118
119 for f in fnames:
119 for f in fnames:
120 matched = False
120 matched = False
121 for p in pats:
121 for p in pats:
@@ -123,7 +123,7 b' def expand(flist,exp_dirs = False):'
123 matched = True
123 matched = True
124 break
124 break
125 if matched:
125 if matched:
126 yield os.path.join(dp,f)
126 yield os.path.join(dp,f)
127
127
128 def once_filter(seq):
128 def once_filter(seq):
129 for it in seq:
129 for it in seq:
@@ -146,30 +146,30 b' def expand(flist,exp_dirs = False):'
146 if not re.search(pat,cont, re.IGNORECASE):
146 if not re.search(pat,cont, re.IGNORECASE):
147 deny = True
147 deny = True
148 break
148 break
149
149
150 if not deny:
150 if not deny:
151 yield it
151 yield it
152 return
152 return
153
153
154 res = []
154 res = []
155
155
156 for ent in flist:
156 for ent in flist:
157 ent = os.path.expanduser(os.path.expandvars(ent))
157 ent = os.path.expanduser(os.path.expandvars(ent))
158 if ent.lower().startswith('rec:'):
158 if ent.lower().startswith('rec:'):
159 fields = ent[4:].split('=')
159 fields = ent[4:].split('=')
160 if len(fields) == 2:
160 if len(fields) == 2:
161 pth, patlist = fields
161 pth, patlist = fields
162 elif len(fields) == 1:
162 elif len(fields) == 1:
163 if os.path.isdir(fields[0]):
163 if os.path.isdir(fields[0]):
164 # single arg is dir
164 # single arg is dir
165 pth, patlist = fields[0], '*'
165 pth, patlist = fields[0], '*'
166 else:
166 else:
167 # single arg is pattern
167 # single arg is pattern
168 pth, patlist = '.', fields[0]
168 pth, patlist = '.', fields[0]
169
169
170 elif len(fields) == 0:
170 elif len(fields) == 0:
171 pth, pathlist = '.','*'
171 pth, pathlist = '.','*'
172
172
173 pats = patlist.split(',')
173 pats = patlist.split(',')
174 res.extend(once_filter(recfind(pth, pats)))
174 res.extend(once_filter(recfind(pth, pats)))
175 # filelist
175 # filelist
@@ -186,7 +186,7 b' def expand(flist,exp_dirs = False):'
186 # get all files in the specified dir
186 # get all files in the specified dir
187 elif os.path.isdir(ent) and exp_dirs:
187 elif os.path.isdir(ent) and exp_dirs:
188 res.extend(once_filter(filter(os.path.isfile,glob.glob(ent + os.sep+"*"))))
188 res.extend(once_filter(filter(os.path.isfile,glob.glob(ent + os.sep+"*"))))
189
189
190 # glob only files
190 # glob only files
191
191
192 elif '*' in ent or '?' in ent:
192 elif '*' in ent or '?' in ent:
@@ -195,19 +195,19 b' def expand(flist,exp_dirs = False):'
195 else:
195 else:
196 res.extend(once_filter([ent]))
196 res.extend(once_filter([ent]))
197 return res
197 return res
198
198
199
199
200 def test():
200 def test():
201 assert (
201 assert (
202 expand("*.py ~/.ipython/*.py rec:/usr/share/doc-base") ==
202 expand("*.py ~/.ipython/*.py rec:/usr/share/doc-base") ==
203 expand( ['*.py', '~/.ipython/*.py', 'rec:/usr/share/doc-base'] )
203 expand( ['*.py', '~/.ipython/*.py', 'rec:/usr/share/doc-base'] )
204 )
204 )
205
205
206 def main():
206 def main():
207 if len(sys.argv) < 2:
207 if len(sys.argv) < 2:
208 print globsyntax
208 print globsyntax
209 return
209 return
210
210
211 print "\n".join(expand(sys.argv[1:])),
211 print "\n".join(expand(sys.argv[1:])),
212
212
213 def mglob_f(self, arg):
213 def mglob_f(self, arg):
@@ -220,8 +220,8 b' def mglob_f(self, arg):'
220 def init_ipython(ip):
220 def init_ipython(ip):
221 """ register %mglob for IPython """
221 """ register %mglob for IPython """
222 mglob_f.__doc__ = globsyntax
222 mglob_f.__doc__ = globsyntax
223 ip.define_magic("mglob",mglob_f)
223 ip.define_magic("mglob",mglob_f)
224
224
225 # test()
225 # test()
226 if __name__ == "__main__":
226 if __name__ == "__main__":
227 main()
227 main()
@@ -86,7 +86,7 b' __all__ = ['
86 'htmlComment', 'javaStyleComment', 'keepOriginalText', 'line', 'lineEnd', 'lineStart', 'lineno',
86 'htmlComment', 'javaStyleComment', 'keepOriginalText', 'line', 'lineEnd', 'lineStart', 'lineno',
87 'makeHTMLTags', 'makeXMLTags', 'matchOnlyAtCol', 'matchPreviousExpr', 'matchPreviousLiteral',
87 'makeHTMLTags', 'makeXMLTags', 'matchOnlyAtCol', 'matchPreviousExpr', 'matchPreviousLiteral',
88 'nestedExpr', 'nullDebugAction', 'nums', 'oneOf', 'opAssoc', 'operatorPrecedence', 'printables',
88 'nestedExpr', 'nullDebugAction', 'nums', 'oneOf', 'opAssoc', 'operatorPrecedence', 'printables',
89 'punc8bit', 'pythonStyleComment', 'quotedString', 'removeQuotes', 'replaceHTMLEntity',
89 'punc8bit', 'pythonStyleComment', 'quotedString', 'removeQuotes', 'replaceHTMLEntity',
90 'replaceWith', 'restOfLine', 'sglQuotedString', 'srange', 'stringEnd',
90 'replaceWith', 'restOfLine', 'sglQuotedString', 'srange', 'stringEnd',
91 'stringStart', 'traceParseAction', 'unicodeString', 'upcaseTokens', 'withAttribute',
91 'stringStart', 'traceParseAction', 'unicodeString', 'upcaseTokens', 'withAttribute',
92 'indentedBlock', 'originalTextFor',
92 'indentedBlock', 'originalTextFor',
@@ -430,7 +430,7 b' class ParseResults(object):'
430 self[k] = v
430 self[k] = v
431 if isinstance(v[0],ParseResults):
431 if isinstance(v[0],ParseResults):
432 v[0].__parent = wkref(self)
432 v[0].__parent = wkref(self)
433
433
434 self.__toklist += other.__toklist
434 self.__toklist += other.__toklist
435 self.__accumNames.update( other.__accumNames )
435 self.__accumNames.update( other.__accumNames )
436 del other
436 del other
@@ -3269,12 +3269,12 b' def originalTextFor(expr, asString=True):'
3269 restore the parsed fields of an HTML start tag into the raw tag text itself, or to
3269 restore the parsed fields of an HTML start tag into the raw tag text itself, or to
3270 revert separate tokens with intervening whitespace back to the original matching
3270 revert separate tokens with intervening whitespace back to the original matching
3271 input text. Simpler to use than the parse action keepOriginalText, and does not
3271 input text. Simpler to use than the parse action keepOriginalText, and does not
3272 require the inspect module to chase up the call stack. By default, returns a
3272 require the inspect module to chase up the call stack. By default, returns a
3273 string containing the original parsed text.
3273 string containing the original parsed text.
3274
3274
3275 If the optional asString argument is passed as False, then the return value is a
3275 If the optional asString argument is passed as False, then the return value is a
3276 ParseResults containing any results names that were originally matched, and a
3276 ParseResults containing any results names that were originally matched, and a
3277 single token containing the original matched text from the input string. So if
3277 single token containing the original matched text from the input string. So if
3278 the expression passed to originalTextFor contains expressions with defined
3278 the expression passed to originalTextFor contains expressions with defined
3279 results names, you must set asString to False if you want to preserve those
3279 results names, you must set asString to False if you want to preserve those
3280 results name values."""
3280 results name values."""
@@ -3290,7 +3290,7 b' def originalTextFor(expr, asString=True):'
3290 del t["_original_end"]
3290 del t["_original_end"]
3291 matchExpr.setParseAction(extractText)
3291 matchExpr.setParseAction(extractText)
3292 return matchExpr
3292 return matchExpr
3293
3293
3294 # convenience constants for positional expressions
3294 # convenience constants for positional expressions
3295 empty = Empty().setName("empty")
3295 empty = Empty().setName("empty")
3296 lineStart = LineStart().setName("lineStart")
3296 lineStart = LineStart().setName("lineStart")
@@ -3570,7 +3570,7 b' def nestedExpr(opener="(", closer=")", content=None, ignoreExpr=quotedString):'
3570 ).setParseAction(lambda t:t[0].strip()))
3570 ).setParseAction(lambda t:t[0].strip()))
3571 else:
3571 else:
3572 if ignoreExpr is not None:
3572 if ignoreExpr is not None:
3573 content = (Combine(OneOrMore(~ignoreExpr +
3573 content = (Combine(OneOrMore(~ignoreExpr +
3574 ~Literal(opener) + ~Literal(closer) +
3574 ~Literal(opener) + ~Literal(closer) +
3575 CharsNotIn(ParserElement.DEFAULT_WHITE_CHARS,exact=1))
3575 CharsNotIn(ParserElement.DEFAULT_WHITE_CHARS,exact=1))
3576 ).setParseAction(lambda t:t[0].strip()))
3576 ).setParseAction(lambda t:t[0].strip()))
@@ -40,7 +40,7 b' if QT_API is None:'
40 QT_API = QT_API_PYQT
40 QT_API = QT_API_PYQT
41 except ImportError:
41 except ImportError:
42 raise ImportError('Cannot import PySide >= 1.0.3 or PyQt4 >= 4.7')
42 raise ImportError('Cannot import PySide >= 1.0.3 or PyQt4 >= 4.7')
43
43
44 elif QT_API == QT_API_PYQT:
44 elif QT_API == QT_API_PYQT:
45 # Note: This must be called *before* PyQt4 is imported.
45 # Note: This must be called *before* PyQt4 is imported.
46 prepare_pyqt4()
46 prepare_pyqt4()
@@ -62,5 +62,5 b' elif QT_API == QT_API_PYSIDE:'
62 from PySide import QtCore, QtGui, QtSvg
62 from PySide import QtCore, QtGui, QtSvg
63
63
64 else:
64 else:
65 raise RuntimeError('Invalid Qt API %r, valid values are: %r or %r' %
65 raise RuntimeError('Invalid Qt API %r, valid values are: %r or %r' %
66 (QT_API, QT_API_PYQT, QT_API_PYSIDE))
66 (QT_API, QT_API_PYQT, QT_API_PYSIDE))
@@ -75,7 +75,7 b' def try_passwordless_ssh(server, keyfile, paramiko=None):'
75 """Attempt to make an ssh connection without a password.
75 """Attempt to make an ssh connection without a password.
76 This is mainly used for requiring password input only once
76 This is mainly used for requiring password input only once
77 when many tunnels may be connected to the same server.
77 when many tunnels may be connected to the same server.
78
78
79 If paramiko is None, the default for the platform is chosen.
79 If paramiko is None, the default for the platform is chosen.
80 """
80 """
81 if paramiko is None:
81 if paramiko is None:
@@ -130,12 +130,12 b' def _try_passwordless_paramiko(server, keyfile):'
130
130
131 def tunnel_connection(socket, addr, server, keyfile=None, password=None, paramiko=None, timeout=60):
131 def tunnel_connection(socket, addr, server, keyfile=None, password=None, paramiko=None, timeout=60):
132 """Connect a socket to an address via an ssh tunnel.
132 """Connect a socket to an address via an ssh tunnel.
133
133
134 This is a wrapper for socket.connect(addr), when addr is not accessible
134 This is a wrapper for socket.connect(addr), when addr is not accessible
135 from the local machine. It simply creates an ssh tunnel using the remaining args,
135 from the local machine. It simply creates an ssh tunnel using the remaining args,
136 and calls socket.connect('tcp://localhost:lport') where lport is the randomly
136 and calls socket.connect('tcp://localhost:lport') where lport is the randomly
137 selected local port of the tunnel.
137 selected local port of the tunnel.
138
138
139 """
139 """
140 new_url, tunnel = open_tunnel(addr, server, keyfile=keyfile, password=password, paramiko=paramiko, timeout=timeout)
140 new_url, tunnel = open_tunnel(addr, server, keyfile=keyfile, password=password, paramiko=paramiko, timeout=timeout)
141 socket.connect(new_url)
141 socket.connect(new_url)
@@ -144,15 +144,15 b' def tunnel_connection(socket, addr, server, keyfile=None, password=None, paramik'
144
144
145 def open_tunnel(addr, server, keyfile=None, password=None, paramiko=None, timeout=60):
145 def open_tunnel(addr, server, keyfile=None, password=None, paramiko=None, timeout=60):
146 """Open a tunneled connection from a 0MQ url.
146 """Open a tunneled connection from a 0MQ url.
147
147
148 For use inside tunnel_connection.
148 For use inside tunnel_connection.
149
149
150 Returns
150 Returns
151 -------
151 -------
152
152
153 (url, tunnel): The 0MQ url that has been forwarded, and the tunnel object
153 (url, tunnel): The 0MQ url that has been forwarded, and the tunnel object
154 """
154 """
155
155
156 lport = select_random_ports(1)[0]
156 lport = select_random_ports(1)[0]
157 transport, addr = addr.split('://')
157 transport, addr = addr.split('://')
158 ip,rport = addr.split(':')
158 ip,rport = addr.split(':')
@@ -163,7 +163,7 b' def open_tunnel(addr, server, keyfile=None, password=None, paramiko=None, timeou'
163 tunnelf = paramiko_tunnel
163 tunnelf = paramiko_tunnel
164 else:
164 else:
165 tunnelf = openssh_tunnel
165 tunnelf = openssh_tunnel
166
166
167 tunnel = tunnelf(lport, rport, server, remoteip=ip, keyfile=keyfile, password=password, timeout=timeout)
167 tunnel = tunnelf(lport, rport, server, remoteip=ip, keyfile=keyfile, password=password, timeout=timeout)
168 return 'tcp://127.0.0.1:%i'%lport, tunnel
168 return 'tcp://127.0.0.1:%i'%lport, tunnel
169
169
@@ -172,15 +172,15 b" def openssh_tunnel(lport, rport, server, remoteip='127.0.0.1', keyfile=None, pas"
172 on this machine to localhost:rport on server. The tunnel
172 on this machine to localhost:rport on server. The tunnel
173 will automatically close when not in use, remaining open
173 will automatically close when not in use, remaining open
174 for a minimum of timeout seconds for an initial connection.
174 for a minimum of timeout seconds for an initial connection.
175
175
176 This creates a tunnel redirecting `localhost:lport` to `remoteip:rport`,
176 This creates a tunnel redirecting `localhost:lport` to `remoteip:rport`,
177 as seen from `server`.
177 as seen from `server`.
178
178
179 keyfile and password may be specified, but ssh config is checked for defaults.
179 keyfile and password may be specified, but ssh config is checked for defaults.
180
180
181 Parameters
181 Parameters
182 ----------
182 ----------
183
183
184 lport : int
184 lport : int
185 local port for connecting to the tunnel from this machine.
185 local port for connecting to the tunnel from this machine.
186 rport : int
186 rport : int
@@ -192,11 +192,11 b" def openssh_tunnel(lport, rport, server, remoteip='127.0.0.1', keyfile=None, pas"
192 The remote ip, specifying the destination of the tunnel.
192 The remote ip, specifying the destination of the tunnel.
193 Default is localhost, which means that the tunnel would redirect
193 Default is localhost, which means that the tunnel would redirect
194 localhost:lport on this machine to localhost:rport on the *server*.
194 localhost:lport on this machine to localhost:rport on the *server*.
195
195
196 keyfile : str; path to public key file
196 keyfile : str; path to public key file
197 This specifies a key to be used in ssh login, default None.
197 This specifies a key to be used in ssh login, default None.
198 Regular default ssh keys will be used without specifying this argument.
198 Regular default ssh keys will be used without specifying this argument.
199 password : str;
199 password : str;
200 Your ssh password to the ssh server. Note that if this is left None,
200 Your ssh password to the ssh server. Note that if this is left None,
201 you will be prompted for it if passwordless key based login is unavailable.
201 you will be prompted for it if passwordless key based login is unavailable.
202 timeout : int [default: 60]
202 timeout : int [default: 60]
@@ -207,7 +207,7 b" def openssh_tunnel(lport, rport, server, remoteip='127.0.0.1', keyfile=None, pas"
207 raise ImportError("pexpect unavailable, use paramiko_tunnel")
207 raise ImportError("pexpect unavailable, use paramiko_tunnel")
208 ssh="ssh "
208 ssh="ssh "
209 if keyfile:
209 if keyfile:
210 ssh += "-i " + keyfile
210 ssh += "-i " + keyfile
211 cmd = ssh + " -f -L 127.0.0.1:%i:%s:%i %s sleep %i"%(lport, remoteip, rport, server, timeout)
211 cmd = ssh + " -f -L 127.0.0.1:%i:%s:%i %s sleep %i"%(lport, remoteip, rport, server, timeout)
212 tunnel = pexpect.spawn(cmd)
212 tunnel = pexpect.spawn(cmd)
213 failed = False
213 failed = False
@@ -232,7 +232,7 b" def openssh_tunnel(lport, rport, server, remoteip='127.0.0.1', keyfile=None, pas"
232 password = getpass("%s's password: "%(server))
232 password = getpass("%s's password: "%(server))
233 tunnel.sendline(password)
233 tunnel.sendline(password)
234 failed = True
234 failed = True
235
235
236 def _split_server(server):
236 def _split_server(server):
237 if '@' in server:
237 if '@' in server:
238 username,server = server.split('@', 1)
238 username,server = server.split('@', 1)
@@ -248,20 +248,20 b' def _split_server(server):'
248 def paramiko_tunnel(lport, rport, server, remoteip='127.0.0.1', keyfile=None, password=None, timeout=60):
248 def paramiko_tunnel(lport, rport, server, remoteip='127.0.0.1', keyfile=None, password=None, timeout=60):
249 """launch a tunner with paramiko in a subprocess. This should only be used
249 """launch a tunner with paramiko in a subprocess. This should only be used
250 when shell ssh is unavailable (e.g. Windows).
250 when shell ssh is unavailable (e.g. Windows).
251
251
252 This creates a tunnel redirecting `localhost:lport` to `remoteip:rport`,
252 This creates a tunnel redirecting `localhost:lport` to `remoteip:rport`,
253 as seen from `server`.
253 as seen from `server`.
254
254
255 If you are familiar with ssh tunnels, this creates the tunnel:
255 If you are familiar with ssh tunnels, this creates the tunnel:
256
256
257 ssh server -L localhost:lport:remoteip:rport
257 ssh server -L localhost:lport:remoteip:rport
258
258
259 keyfile and password may be specified, but ssh config is checked for defaults.
259 keyfile and password may be specified, but ssh config is checked for defaults.
260
260
261
261
262 Parameters
262 Parameters
263 ----------
263 ----------
264
264
265 lport : int
265 lport : int
266 local port for connecting to the tunnel from this machine.
266 local port for connecting to the tunnel from this machine.
267 rport : int
267 rport : int
@@ -273,33 +273,33 b" def paramiko_tunnel(lport, rport, server, remoteip='127.0.0.1', keyfile=None, pa"
273 The remote ip, specifying the destination of the tunnel.
273 The remote ip, specifying the destination of the tunnel.
274 Default is localhost, which means that the tunnel would redirect
274 Default is localhost, which means that the tunnel would redirect
275 localhost:lport on this machine to localhost:rport on the *server*.
275 localhost:lport on this machine to localhost:rport on the *server*.
276
276
277 keyfile : str; path to public key file
277 keyfile : str; path to public key file
278 This specifies a key to be used in ssh login, default None.
278 This specifies a key to be used in ssh login, default None.
279 Regular default ssh keys will be used without specifying this argument.
279 Regular default ssh keys will be used without specifying this argument.
280 password : str;
280 password : str;
281 Your ssh password to the ssh server. Note that if this is left None,
281 Your ssh password to the ssh server. Note that if this is left None,
282 you will be prompted for it if passwordless key based login is unavailable.
282 you will be prompted for it if passwordless key based login is unavailable.
283 timeout : int [default: 60]
283 timeout : int [default: 60]
284 The time (in seconds) after which no activity will result in the tunnel
284 The time (in seconds) after which no activity will result in the tunnel
285 closing. This prevents orphaned tunnels from running forever.
285 closing. This prevents orphaned tunnels from running forever.
286
286
287 """
287 """
288 if paramiko is None:
288 if paramiko is None:
289 raise ImportError("Paramiko not available")
289 raise ImportError("Paramiko not available")
290
290
291 if password is None:
291 if password is None:
292 if not _try_passwordless_paramiko(server, keyfile):
292 if not _try_passwordless_paramiko(server, keyfile):
293 password = getpass("%s's password: "%(server))
293 password = getpass("%s's password: "%(server))
294
294
295 p = Process(target=_paramiko_tunnel,
295 p = Process(target=_paramiko_tunnel,
296 args=(lport, rport, server, remoteip),
296 args=(lport, rport, server, remoteip),
297 kwargs=dict(keyfile=keyfile, password=password))
297 kwargs=dict(keyfile=keyfile, password=password))
298 p.daemon=False
298 p.daemon=False
299 p.start()
299 p.start()
300 atexit.register(_shutdown_process, p)
300 atexit.register(_shutdown_process, p)
301 return p
301 return p
302
302
303 def _shutdown_process(p):
303 def _shutdown_process(p):
304 if p.isalive():
304 if p.isalive():
305 p.terminate()
305 p.terminate()
@@ -342,7 +342,7 b" if sys.platform == 'win32':"
342 else:
342 else:
343 ssh_tunnel = openssh_tunnel
343 ssh_tunnel = openssh_tunnel
344
344
345
345
346 __all__ = ['tunnel_connection', 'ssh_tunnel', 'openssh_tunnel', 'paramiko_tunnel', 'try_passwordless_ssh']
346 __all__ = ['tunnel_connection', 'ssh_tunnel', 'openssh_tunnel', 'paramiko_tunnel', 'try_passwordless_ssh']
347
347
348
348
@@ -50,7 +50,7 b' class AuthenticatedHandler(web.RequestHandler):'
50 if not self.application.password:
50 if not self.application.password:
51 user_id = 'anonymous'
51 user_id = 'anonymous'
52 return user_id
52 return user_id
53
53
54
54
55 class NBBrowserHandler(AuthenticatedHandler):
55 class NBBrowserHandler(AuthenticatedHandler):
56 @web.authenticated
56 @web.authenticated
@@ -176,13 +176,13 b' class AuthenticatedZMQStreamHandler(ZMQStreamHandler):'
176 self.session = Session()
176 self.session = Session()
177 self.save_on_message = self.on_message
177 self.save_on_message = self.on_message
178 self.on_message = self.on_first_message
178 self.on_message = self.on_first_message
179
179
180 def get_current_user(self):
180 def get_current_user(self):
181 user_id = self.get_secure_cookie("user")
181 user_id = self.get_secure_cookie("user")
182 if user_id == '' or (user_id is None and not self.application.password):
182 if user_id == '' or (user_id is None and not self.application.password):
183 user_id = 'anonymous'
183 user_id = 'anonymous'
184 return user_id
184 return user_id
185
185
186 def _inject_cookie_message(self, msg):
186 def _inject_cookie_message(self, msg):
187 """Inject the first message, which is the document cookie,
187 """Inject the first message, which is the document cookie,
188 for authentication."""
188 for authentication."""
@@ -193,14 +193,14 b' class AuthenticatedZMQStreamHandler(ZMQStreamHandler):'
193 self._cookies = Cookie.SimpleCookie(msg)
193 self._cookies = Cookie.SimpleCookie(msg)
194 except:
194 except:
195 logging.warn("couldn't parse cookie string: %s",msg, exc_info=True)
195 logging.warn("couldn't parse cookie string: %s",msg, exc_info=True)
196
196
197 def on_first_message(self, msg):
197 def on_first_message(self, msg):
198 self._inject_cookie_message(msg)
198 self._inject_cookie_message(msg)
199 if self.get_current_user() is None:
199 if self.get_current_user() is None:
200 logging.warn("Couldn't authenticate WebSocket connection")
200 logging.warn("Couldn't authenticate WebSocket connection")
201 raise web.HTTPError(403)
201 raise web.HTTPError(403)
202 self.on_message = self.save_on_message
202 self.on_message = self.save_on_message
203
203
204
204
205 class IOPubHandler(AuthenticatedZMQStreamHandler):
205 class IOPubHandler(AuthenticatedZMQStreamHandler):
206
206
@@ -209,7 +209,7 b' class IOPubHandler(AuthenticatedZMQStreamHandler):'
209 self._beating = False
209 self._beating = False
210 self.iopub_stream = None
210 self.iopub_stream = None
211 self.hb_stream = None
211 self.hb_stream = None
212
212
213 def on_first_message(self, msg):
213 def on_first_message(self, msg):
214 try:
214 try:
215 super(IOPubHandler, self).on_first_message(msg)
215 super(IOPubHandler, self).on_first_message(msg)
@@ -231,12 +231,12 b' class IOPubHandler(AuthenticatedZMQStreamHandler):'
231 else:
231 else:
232 self.iopub_stream.on_recv(self._on_zmq_reply)
232 self.iopub_stream.on_recv(self._on_zmq_reply)
233 self.start_hb(self.kernel_died)
233 self.start_hb(self.kernel_died)
234
234
235 def on_message(self, msg):
235 def on_message(self, msg):
236 pass
236 pass
237
237
238 def on_close(self):
238 def on_close(self):
239 # This method can be called twice, once by self.kernel_died and once
239 # This method can be called twice, once by self.kernel_died and once
240 # from the WebSocket close event. If the WebSocket connection is
240 # from the WebSocket close event. If the WebSocket connection is
241 # closed before the ZMQ streams are setup, they could be None.
241 # closed before the ZMQ streams are setup, they could be None.
242 self.stop_hb()
242 self.stop_hb()
@@ -245,7 +245,7 b' class IOPubHandler(AuthenticatedZMQStreamHandler):'
245 self.iopub_stream.close()
245 self.iopub_stream.close()
246 if self.hb_stream is not None and not self.hb_stream.closed():
246 if self.hb_stream is not None and not self.hb_stream.closed():
247 self.hb_stream.close()
247 self.hb_stream.close()
248
248
249 def start_hb(self, callback):
249 def start_hb(self, callback):
250 """Start the heartbeating and call the callback if the kernel dies."""
250 """Start the heartbeating and call the callback if the kernel dies."""
251 if not self._beating:
251 if not self._beating:
@@ -12,7 +12,7 b' class BaseFrontendMixin(object):'
12 #---------------------------------------------------------------------------
12 #---------------------------------------------------------------------------
13 # 'BaseFrontendMixin' concrete interface
13 # 'BaseFrontendMixin' concrete interface
14 #---------------------------------------------------------------------------
14 #---------------------------------------------------------------------------
15
15
16 def _get_kernel_manager(self):
16 def _get_kernel_manager(self):
17 """ Returns the current kernel manager.
17 """ Returns the current kernel manager.
18 """
18 """
@@ -34,7 +34,7 b' class BaseFrontendMixin(object):'
34 old_manager.stdin_channel.message_received.disconnect(self._dispatch)
34 old_manager.stdin_channel.message_received.disconnect(self._dispatch)
35 old_manager.hb_channel.kernel_died.disconnect(
35 old_manager.hb_channel.kernel_died.disconnect(
36 self._handle_kernel_died)
36 self._handle_kernel_died)
37
37
38 # Handle the case where the old kernel manager is still listening.
38 # Handle the case where the old kernel manager is still listening.
39 if old_manager.channels_running:
39 if old_manager.channels_running:
40 self._stopped_channels()
40 self._stopped_channels()
@@ -77,9 +77,9 b' class BaseFrontendMixin(object):'
77 since_last_heartbeat : float
77 since_last_heartbeat : float
78 The time since the heartbeat was last received.
78 The time since the heartbeat was last received.
79 """
79 """
80
80
81 def _started_channels(self):
81 def _started_channels(self):
82 """ Called when the KernelManager channels have started listening or
82 """ Called when the KernelManager channels have started listening or
83 when the frontend is assigned an already listening KernelManager.
83 when the frontend is assigned an already listening KernelManager.
84 """
84 """
85
85
@@ -93,7 +93,7 b' class BaseFrontendMixin(object):'
93 #---------------------------------------------------------------------------
93 #---------------------------------------------------------------------------
94
94
95 def _dispatch(self, msg):
95 def _dispatch(self, msg):
96 """ Calls the frontend handler associated with the message type of the
96 """ Calls the frontend handler associated with the message type of the
97 given message.
97 given message.
98 """
98 """
99 msg_type = msg['header']['msg_type']
99 msg_type = msg['header']['msg_type']
@@ -112,7 +112,7 b' class AnsiCodeProcessor(object):'
112 ----------
112 ----------
113 command : str
113 command : str
114 The code identifier, i.e. the final character in the sequence.
114 The code identifier, i.e. the final character in the sequence.
115
115
116 params : sequence of integers, optional
116 params : sequence of integers, optional
117 The parameter codes for the command.
117 The parameter codes for the command.
118 """
118 """
@@ -143,7 +143,7 b' class AnsiCodeProcessor(object):'
143
143
144 def set_osc_code(self, params):
144 def set_osc_code(self, params):
145 """ Set attributes based on OSC (Operating System Command) parameters.
145 """ Set attributes based on OSC (Operating System Command) parameters.
146
146
147 Parameters
147 Parameters
148 ----------
148 ----------
149 params : sequence of str
149 params : sequence of str
@@ -162,7 +162,7 b' class AnsiCodeProcessor(object):'
162 self.color_map[color] = self._parse_xterm_color_spec(spec)
162 self.color_map[color] = self._parse_xterm_color_spec(spec)
163 except (IndexError, ValueError):
163 except (IndexError, ValueError):
164 pass
164 pass
165
165
166 def set_sgr_code(self, params):
166 def set_sgr_code(self, params):
167 """ Set attributes based on SGR (Select Graphic Rendition) codes.
167 """ Set attributes based on SGR (Select Graphic Rendition) codes.
168
168
@@ -200,7 +200,7 b' class AnsiCodeProcessor(object):'
200 self.underline = False
200 self.underline = False
201 elif code >= 30 and code <= 37:
201 elif code >= 30 and code <= 37:
202 self.foreground_color = code - 30
202 self.foreground_color = code - 30
203 elif code == 38 and params and params.pop(0) == 5:
203 elif code == 38 and params and params.pop(0) == 5:
204 # xterm-specific: 256 color support.
204 # xterm-specific: 256 color support.
205 if params:
205 if params:
206 self.foreground_color = params.pop(0)
206 self.foreground_color = params.pop(0)
@@ -226,7 +226,7 b' class AnsiCodeProcessor(object):'
226 if spec.startswith('rgb:'):
226 if spec.startswith('rgb:'):
227 return tuple(map(lambda x: int(x, 16), spec[4:].split('/')))
227 return tuple(map(lambda x: int(x, 16), spec[4:].split('/')))
228 elif spec.startswith('rgbi:'):
228 elif spec.startswith('rgbi:'):
229 return tuple(map(lambda x: int(float(x) * 255),
229 return tuple(map(lambda x: int(float(x) * 255),
230 spec[5:].split('/')))
230 spec[5:].split('/')))
231 elif spec == '?':
231 elif spec == '?':
232 raise ValueError('Unsupported xterm color spec')
232 raise ValueError('Unsupported xterm color spec')
@@ -237,7 +237,7 b' class AnsiCodeProcessor(object):'
237 if special == '\f':
237 if special == '\f':
238 self.actions.append(ScrollAction('scroll', 'down', 'page', 1))
238 self.actions.append(ScrollAction('scroll', 'down', 'page', 1))
239 return ''
239 return ''
240
240
241
241
242 class QtAnsiCodeProcessor(AnsiCodeProcessor):
242 class QtAnsiCodeProcessor(AnsiCodeProcessor):
243 """ Translates ANSI escape codes into QTextCharFormats.
243 """ Translates ANSI escape codes into QTextCharFormats.
@@ -288,7 +288,7 b' class QtAnsiCodeProcessor(AnsiCodeProcessor):'
288 return QtGui.QColor(*constructor)
288 return QtGui.QColor(*constructor)
289
289
290 return None
290 return None
291
291
292 def get_format(self):
292 def get_format(self):
293 """ Returns a QTextCharFormat that encodes the current style attributes.
293 """ Returns a QTextCharFormat that encodes the current style attributes.
294 """
294 """
@@ -322,7 +322,7 b' class QtAnsiCodeProcessor(AnsiCodeProcessor):'
322 self.default_color_map = self.darkbg_color_map.copy()
322 self.default_color_map = self.darkbg_color_map.copy()
323
323
324 if color.value() >= 127:
324 if color.value() >= 127:
325 # Colors appropriate for a terminal with a light background. For
325 # Colors appropriate for a terminal with a light background. For
326 # now, only use non-bright colors...
326 # now, only use non-bright colors...
327 for i in xrange(8):
327 for i in xrange(8):
328 self.default_color_map[i + 8] = self.default_color_map[i]
328 self.default_color_map[i + 8] = self.default_color_map[i]
@@ -9,7 +9,7 b' class BracketMatcher(QtCore.QObject):'
9 """ Matches square brackets, braces, and parentheses based on cursor
9 """ Matches square brackets, braces, and parentheses based on cursor
10 position.
10 position.
11 """
11 """
12
12
13 # Protected class variables.
13 # Protected class variables.
14 _opening_map = { '(':')', '{':'}', '[':']' }
14 _opening_map = { '(':')', '{':'}', '[':']' }
15 _closing_map = { ')':'(', '}':'{', ']':'[' }
15 _closing_map = { ')':'(', '}':'{', ']':'[' }
@@ -75,7 +75,7 b' class BracketMatcher(QtCore.QObject):'
75 selection = QtGui.QTextEdit.ExtraSelection()
75 selection = QtGui.QTextEdit.ExtraSelection()
76 cursor = self._text_edit.textCursor()
76 cursor = self._text_edit.textCursor()
77 cursor.setPosition(position)
77 cursor.setPosition(position)
78 cursor.movePosition(QtGui.QTextCursor.NextCharacter,
78 cursor.movePosition(QtGui.QTextCursor.NextCharacter,
79 QtGui.QTextCursor.KeepAnchor)
79 QtGui.QTextCursor.KeepAnchor)
80 selection.cursor = cursor
80 selection.cursor = cursor
81 selection.format = self.format
81 selection.format = self.format
@@ -134,7 +134,7 b' class CallTipWidget(QtGui.QLabel):'
134 doc = doc[:match.end()] + '\n[Documentation continues...]'
134 doc = doc[:match.end()] + '\n[Documentation continues...]'
135 else:
135 else:
136 doc = ''
136 doc = ''
137
137
138 if call_line:
138 if call_line:
139 doc = '\n\n'.join([call_line, doc])
139 doc = '\n\n'.join([call_line, doc])
140 return self.show_tip(doc)
140 return self.show_tip(doc)
@@ -147,7 +147,7 b' class CallTipWidget(QtGui.QLabel):'
147 document = text_edit.document()
147 document = text_edit.document()
148 cursor = text_edit.textCursor()
148 cursor = text_edit.textCursor()
149 search_pos = cursor.position() - 1
149 search_pos = cursor.position() - 1
150 self._start_position, _ = self._find_parenthesis(search_pos,
150 self._start_position, _ = self._find_parenthesis(search_pos,
151 forward=False)
151 forward=False)
152 if self._start_position == -1:
152 if self._start_position == -1:
153 return False
153 return False
@@ -155,7 +155,7 b' class CallTipWidget(QtGui.QLabel):'
155 # Set the text and resize the widget accordingly.
155 # Set the text and resize the widget accordingly.
156 self.setText(tip)
156 self.setText(tip)
157 self.resize(self.sizeHint())
157 self.resize(self.sizeHint())
158
158
159 # Locate and show the widget. Place the tip below the current line
159 # Locate and show the widget. Place the tip below the current line
160 # unless it would be off the screen. In that case, place it above
160 # unless it would be off the screen. In that case, place it above
161 # the current line.
161 # the current line.
@@ -171,7 +171,7 b' class CallTipWidget(QtGui.QLabel):'
171 self.move(point)
171 self.move(point)
172 self.show()
172 self.show()
173 return True
173 return True
174
174
175 #--------------------------------------------------------------------------
175 #--------------------------------------------------------------------------
176 # Protected interface
176 # Protected interface
177 #--------------------------------------------------------------------------
177 #--------------------------------------------------------------------------
@@ -3,7 +3,7 b' from pygments.token import Token, is_token_subtype'
3
3
4
4
5 class CompletionLexer(object):
5 class CompletionLexer(object):
6 """ Uses Pygments and some auxillary information to lex code snippets for
6 """ Uses Pygments and some auxillary information to lex code snippets for
7 symbol contexts.
7 symbol contexts.
8 """
8 """
9
9
@@ -30,7 +30,7 b' class CompletionLexer(object):'
30 if reversed_tokens and reversed_tokens[0][1].endswith('\n') and \
30 if reversed_tokens and reversed_tokens[0][1].endswith('\n') and \
31 not string.endswith('\n'):
31 not string.endswith('\n'):
32 reversed_tokens.pop(0)
32 reversed_tokens.pop(0)
33
33
34 current_op = ''
34 current_op = ''
35 for token, text in reversed_tokens:
35 for token, text in reversed_tokens:
36
36
@@ -71,4 +71,4 b' class CompletionLexer(object):'
71 self._name_separators = list(name_separators)
71 self._name_separators = list(name_separators)
72
72
73 lexer = property(get_lexer, set_lexer)
73 lexer = property(get_lexer, set_lexer)
74
74
@@ -39,15 +39,15 b' class CompletionWidget(QtGui.QListWidget):'
39
39
40 if etype == QtCore.QEvent.KeyPress:
40 if etype == QtCore.QEvent.KeyPress:
41 key, text = event.key(), event.text()
41 key, text = event.key(), event.text()
42 if key in (QtCore.Qt.Key_Return, QtCore.Qt.Key_Enter,
42 if key in (QtCore.Qt.Key_Return, QtCore.Qt.Key_Enter,
43 QtCore.Qt.Key_Tab):
43 QtCore.Qt.Key_Tab):
44 self._complete_current()
44 self._complete_current()
45 return True
45 return True
46 elif key == QtCore.Qt.Key_Escape:
46 elif key == QtCore.Qt.Key_Escape:
47 self.hide()
47 self.hide()
48 return True
48 return True
49 elif key in (QtCore.Qt.Key_Up, QtCore.Qt.Key_Down,
49 elif key in (QtCore.Qt.Key_Up, QtCore.Qt.Key_Down,
50 QtCore.Qt.Key_PageUp, QtCore.Qt.Key_PageDown,
50 QtCore.Qt.Key_PageUp, QtCore.Qt.Key_PageDown,
51 QtCore.Qt.Key_Home, QtCore.Qt.Key_End):
51 QtCore.Qt.Key_Home, QtCore.Qt.Key_End):
52 self.keyPressEvent(event)
52 self.keyPressEvent(event)
53 return True
53 return True
@@ -114,16 +114,16 b' class CompletionWidget(QtGui.QListWidget):'
114 """
114 """
115 cursor = self._text_edit.textCursor()
115 cursor = self._text_edit.textCursor()
116 if cursor.position() >= self._start_position:
116 if cursor.position() >= self._start_position:
117 cursor.setPosition(self._start_position,
117 cursor.setPosition(self._start_position,
118 QtGui.QTextCursor.KeepAnchor)
118 QtGui.QTextCursor.KeepAnchor)
119 return cursor
119 return cursor
120
120
121 def _update_current(self):
121 def _update_current(self):
122 """ Updates the current item based on the current text.
122 """ Updates the current item based on the current text.
123 """
123 """
124 prefix = self._current_text_cursor().selection().toPlainText()
124 prefix = self._current_text_cursor().selection().toPlainText()
125 if prefix:
125 if prefix:
126 items = self.findItems(prefix, (QtCore.Qt.MatchStartsWith |
126 items = self.findItems(prefix, (QtCore.Qt.MatchStartsWith |
127 QtCore.Qt.MatchCaseSensitive))
127 QtCore.Qt.MatchCaseSensitive))
128 if items:
128 if items:
129 self.setCurrentItem(items[0])
129 self.setCurrentItem(items[0])
@@ -40,11 +40,11 b' def is_letter_or_number(char):'
40 #-----------------------------------------------------------------------------
40 #-----------------------------------------------------------------------------
41
41
42 class ConsoleWidget(LoggingConfigurable, QtGui.QWidget):
42 class ConsoleWidget(LoggingConfigurable, QtGui.QWidget):
43 """ An abstract base class for console-type widgets. This class has
43 """ An abstract base class for console-type widgets. This class has
44 functionality for:
44 functionality for:
45
45
46 * Maintaining a prompt and editing region
46 * Maintaining a prompt and editing region
47 * Providing the traditional Unix-style console keyboard shortcuts
47 * Providing the traditional Unix-style console keyboard shortcuts
48 * Performing tab completion
48 * Performing tab completion
49 * Paging text
49 * Paging text
50 * Handling ANSI escape codes
50 * Handling ANSI escape codes
@@ -79,11 +79,11 b' class ConsoleWidget(LoggingConfigurable, QtGui.QWidget):'
79 """
79 """
80 )
80 )
81 # NOTE: this value can only be specified during initialization.
81 # NOTE: this value can only be specified during initialization.
82 paging = Enum(['inside', 'hsplit', 'vsplit', 'custom', 'none'],
82 paging = Enum(['inside', 'hsplit', 'vsplit', 'custom', 'none'],
83 default_value='inside', config=True,
83 default_value='inside', config=True,
84 help="""
84 help="""
85 The type of paging to use. Valid values are:
85 The type of paging to use. Valid values are:
86
86
87 'inside' : The widget pages like a traditional terminal.
87 'inside' : The widget pages like a traditional terminal.
88 'hsplit' : When paging is requested, the widget is split
88 'hsplit' : When paging is requested, the widget is split
89 horizontally. The top pane contains the console, and the
89 horizontally. The top pane contains the console, and the
@@ -264,7 +264,7 b' class ConsoleWidget(LoggingConfigurable, QtGui.QWidget):'
264 key = event.key()
264 key = event.key()
265 if self._control_key_down(event.modifiers()) and \
265 if self._control_key_down(event.modifiers()) and \
266 key in self._ctrl_down_remap:
266 key in self._ctrl_down_remap:
267 new_event = QtGui.QKeyEvent(QtCore.QEvent.KeyPress,
267 new_event = QtGui.QKeyEvent(QtCore.QEvent.KeyPress,
268 self._ctrl_down_remap[key],
268 self._ctrl_down_remap[key],
269 QtCore.Qt.NoModifier)
269 QtCore.Qt.NoModifier)
270 QtGui.qApp.sendEvent(obj, new_event)
270 QtGui.qApp.sendEvent(obj, new_event)
@@ -378,10 +378,10 b' class ConsoleWidget(LoggingConfigurable, QtGui.QWidget):'
378 """ Returns whether text can be cut to the clipboard.
378 """ Returns whether text can be cut to the clipboard.
379 """
379 """
380 cursor = self._control.textCursor()
380 cursor = self._control.textCursor()
381 return (cursor.hasSelection() and
381 return (cursor.hasSelection() and
382 self._in_buffer(cursor.anchor()) and
382 self._in_buffer(cursor.anchor()) and
383 self._in_buffer(cursor.position()))
383 self._in_buffer(cursor.position()))
384
384
385 def can_paste(self):
385 def can_paste(self):
386 """ Returns whether text can be pasted from the clipboard.
386 """ Returns whether text can be pasted from the clipboard.
387 """
387 """
@@ -390,7 +390,7 b' class ConsoleWidget(LoggingConfigurable, QtGui.QWidget):'
390 return False
390 return False
391
391
392 def clear(self, keep_input=True):
392 def clear(self, keep_input=True):
393 """ Clear the console.
393 """ Clear the console.
394
394
395 Parameters:
395 Parameters:
396 -----------
396 -----------
@@ -425,7 +425,7 b' class ConsoleWidget(LoggingConfigurable, QtGui.QWidget):'
425 input.
425 input.
426
426
427 Parameters:
427 Parameters:
428 -----------
428 -----------
429 source : str, optional
429 source : str, optional
430
430
431 The source to execute. If not specified, the input buffer will be
431 The source to execute. If not specified, the input buffer will be
@@ -467,7 +467,7 b' class ConsoleWidget(LoggingConfigurable, QtGui.QWidget):'
467 source += '\n'
467 source += '\n'
468 elif not hidden:
468 elif not hidden:
469 self.input_buffer = source
469 self.input_buffer = source
470
470
471 # Execute the source or show a continuation prompt if it is incomplete.
471 # Execute the source or show a continuation prompt if it is incomplete.
472 complete = self._is_complete(source, interactive)
472 complete = self._is_complete(source, interactive)
473 if hidden:
473 if hidden:
@@ -475,7 +475,7 b' class ConsoleWidget(LoggingConfigurable, QtGui.QWidget):'
475 self._execute(source, hidden)
475 self._execute(source, hidden)
476 else:
476 else:
477 error = 'Incomplete noninteractive input: "%s"'
477 error = 'Incomplete noninteractive input: "%s"'
478 raise RuntimeError(error % source)
478 raise RuntimeError(error % source)
479 else:
479 else:
480 if complete:
480 if complete:
481 self._append_plain_text('\n')
481 self._append_plain_text('\n')
@@ -494,7 +494,7 b' class ConsoleWidget(LoggingConfigurable, QtGui.QWidget):'
494
494
495 # Perform actual execution.
495 # Perform actual execution.
496 self._execute(source, hidden)
496 self._execute(source, hidden)
497
497
498 else:
498 else:
499 # Do this inside an edit block so continuation prompts are
499 # Do this inside an edit block so continuation prompts are
500 # removed seamlessly via undo/redo.
500 # removed seamlessly via undo/redo.
@@ -505,7 +505,7 b' class ConsoleWidget(LoggingConfigurable, QtGui.QWidget):'
505 cursor.endEditBlock()
505 cursor.endEditBlock()
506
506
507 # Do not do this inside the edit block. It works as expected
507 # Do not do this inside the edit block. It works as expected
508 # when using a QPlainTextEdit control, but does not have an
508 # when using a QPlainTextEdit control, but does not have an
509 # effect when using a QTextEdit. I believe this is a Qt bug.
509 # effect when using a QTextEdit. I believe this is a Qt bug.
510 self._control.moveCursor(QtGui.QTextCursor.End)
510 self._control.moveCursor(QtGui.QTextCursor.End)
511
511
@@ -617,7 +617,7 b' class ConsoleWidget(LoggingConfigurable, QtGui.QWidget):'
617 if self._get_cursor().blockNumber() < prompt_cursor.blockNumber():
617 if self._get_cursor().blockNumber() < prompt_cursor.blockNumber():
618 self._set_cursor(prompt_cursor)
618 self._set_cursor(prompt_cursor)
619 self._set_top_cursor(prompt_cursor)
619 self._set_top_cursor(prompt_cursor)
620
620
621 def redo(self):
621 def redo(self):
622 """ Redo the last operation. If there is no operation to redo, nothing
622 """ Redo the last operation. If there is no operation to redo, nothing
623 happens.
623 happens.
@@ -729,7 +729,7 b' class ConsoleWidget(LoggingConfigurable, QtGui.QWidget):'
729
729
730 def _append_custom(self, insert, input, before_prompt=False):
730 def _append_custom(self, insert, input, before_prompt=False):
731 """ A low-level method for appending content to the end of the buffer.
731 """ A low-level method for appending content to the end of the buffer.
732
732
733 If 'before_prompt' is enabled, the content will be inserted before the
733 If 'before_prompt' is enabled, the content will be inserted before the
734 current prompt, if there is one.
734 current prompt, if there is one.
735 """
735 """
@@ -750,7 +750,7 b' class ConsoleWidget(LoggingConfigurable, QtGui.QWidget):'
750 diff = cursor.position() - start_pos
750 diff = cursor.position() - start_pos
751 self._append_before_prompt_pos += diff
751 self._append_before_prompt_pos += diff
752 self._prompt_pos += diff
752 self._prompt_pos += diff
753
753
754 return result
754 return result
755
755
756 def _append_html(self, html, before_prompt=False):
756 def _append_html(self, html, before_prompt=False):
@@ -811,7 +811,7 b' class ConsoleWidget(LoggingConfigurable, QtGui.QWidget):'
811 self._cancel_text_completion()
811 self._cancel_text_completion()
812
812
813 if len(items) == 1:
813 if len(items) == 1:
814 cursor.setPosition(self._control.textCursor().position(),
814 cursor.setPosition(self._control.textCursor().position(),
815 QtGui.QTextCursor.KeepAnchor)
815 QtGui.QTextCursor.KeepAnchor)
816 cursor.insertText(items[0])
816 cursor.insertText(items[0])
817
817
@@ -825,7 +825,7 b' class ConsoleWidget(LoggingConfigurable, QtGui.QWidget):'
825
825
826 if self.gui_completion:
826 if self.gui_completion:
827 cursor.movePosition(QtGui.QTextCursor.Left, n=len(prefix))
827 cursor.movePosition(QtGui.QTextCursor.Left, n=len(prefix))
828 self._completion_widget.show_items(cursor, items)
828 self._completion_widget.show_items(cursor, items)
829 else:
829 else:
830 cursor.beginEditBlock()
830 cursor.beginEditBlock()
831 self._append_plain_text('\n')
831 self._append_plain_text('\n')
@@ -963,7 +963,7 b' class ConsoleWidget(LoggingConfigurable, QtGui.QWidget):'
963
963
964 elif key in (QtCore.Qt.Key_Return, QtCore.Qt.Key_Enter):
964 elif key in (QtCore.Qt.Key_Return, QtCore.Qt.Key_Enter):
965 intercepted = True
965 intercepted = True
966
966
967 # Special handling when tab completing in text mode.
967 # Special handling when tab completing in text mode.
968 self._cancel_text_completion()
968 self._cancel_text_completion()
969
969
@@ -1076,7 +1076,7 b' class ConsoleWidget(LoggingConfigurable, QtGui.QWidget):'
1076 if key == QtCore.Qt.Key_B:
1076 if key == QtCore.Qt.Key_B:
1077 self._set_cursor(self._get_word_start_cursor(position))
1077 self._set_cursor(self._get_word_start_cursor(position))
1078 intercepted = True
1078 intercepted = True
1079
1079
1080 elif key == QtCore.Qt.Key_F:
1080 elif key == QtCore.Qt.Key_F:
1081 self._set_cursor(self._get_word_end_cursor(position))
1081 self._set_cursor(self._get_word_end_cursor(position))
1082 intercepted = True
1082 intercepted = True
@@ -1103,7 +1103,7 b' class ConsoleWidget(LoggingConfigurable, QtGui.QWidget):'
1103 elif key == QtCore.Qt.Key_Greater:
1103 elif key == QtCore.Qt.Key_Greater:
1104 self._control.moveCursor(QtGui.QTextCursor.End)
1104 self._control.moveCursor(QtGui.QTextCursor.End)
1105 intercepted = True
1105 intercepted = True
1106
1106
1107 elif key == QtCore.Qt.Key_Less:
1107 elif key == QtCore.Qt.Key_Less:
1108 self._control.setTextCursor(self._get_prompt_cursor())
1108 self._control.setTextCursor(self._get_prompt_cursor())
1109 intercepted = True
1109 intercepted = True
@@ -1115,7 +1115,7 b' class ConsoleWidget(LoggingConfigurable, QtGui.QWidget):'
1115 anchormode = QtGui.QTextCursor.KeepAnchor
1115 anchormode = QtGui.QTextCursor.KeepAnchor
1116 else:
1116 else:
1117 anchormode = QtGui.QTextCursor.MoveAnchor
1117 anchormode = QtGui.QTextCursor.MoveAnchor
1118
1118
1119 if key == QtCore.Qt.Key_Escape:
1119 if key == QtCore.Qt.Key_Escape:
1120 self._keyboard_quit()
1120 self._keyboard_quit()
1121 intercepted = True
1121 intercepted = True
@@ -1144,19 +1144,19 b' class ConsoleWidget(LoggingConfigurable, QtGui.QWidget):'
1144 line, col = cursor.blockNumber(), cursor.columnNumber()
1144 line, col = cursor.blockNumber(), cursor.columnNumber()
1145 if line > self._get_prompt_cursor().blockNumber() and \
1145 if line > self._get_prompt_cursor().blockNumber() and \
1146 col == len(self._continuation_prompt):
1146 col == len(self._continuation_prompt):
1147 self._control.moveCursor(QtGui.QTextCursor.PreviousBlock,
1147 self._control.moveCursor(QtGui.QTextCursor.PreviousBlock,
1148 mode=anchormode)
1148 mode=anchormode)
1149 self._control.moveCursor(QtGui.QTextCursor.EndOfBlock,
1149 self._control.moveCursor(QtGui.QTextCursor.EndOfBlock,
1150 mode=anchormode)
1150 mode=anchormode)
1151 intercepted = True
1151 intercepted = True
1152
1152
1153 # Regular left movement
1153 # Regular left movement
1154 else:
1154 else:
1155 intercepted = not self._in_buffer(position - 1)
1155 intercepted = not self._in_buffer(position - 1)
1156
1156
1157 elif key == QtCore.Qt.Key_Right:
1157 elif key == QtCore.Qt.Key_Right:
1158 original_block_number = cursor.blockNumber()
1158 original_block_number = cursor.blockNumber()
1159 cursor.movePosition(QtGui.QTextCursor.Right,
1159 cursor.movePosition(QtGui.QTextCursor.Right,
1160 mode=anchormode)
1160 mode=anchormode)
1161 if cursor.blockNumber() != original_block_number:
1161 if cursor.blockNumber() != original_block_number:
1162 cursor.movePosition(QtGui.QTextCursor.Right,
1162 cursor.movePosition(QtGui.QTextCursor.Right,
@@ -1237,7 +1237,7 b' class ConsoleWidget(LoggingConfigurable, QtGui.QWidget):'
1237 return intercepted
1237 return intercepted
1238
1238
1239 def _event_filter_page_keypress(self, event):
1239 def _event_filter_page_keypress(self, event):
1240 """ Filter key events for the paging widget to create console-like
1240 """ Filter key events for the paging widget to create console-like
1241 interface.
1241 interface.
1242 """
1242 """
1243 key = event.key()
1243 key = event.key()
@@ -1253,7 +1253,7 b' class ConsoleWidget(LoggingConfigurable, QtGui.QWidget):'
1253 if key == QtCore.Qt.Key_Greater:
1253 if key == QtCore.Qt.Key_Greater:
1254 self._page_control.moveCursor(QtGui.QTextCursor.End)
1254 self._page_control.moveCursor(QtGui.QTextCursor.End)
1255 intercepted = True
1255 intercepted = True
1256
1256
1257 elif key == QtCore.Qt.Key_Less:
1257 elif key == QtCore.Qt.Key_Less:
1258 self._page_control.moveCursor(QtGui.QTextCursor.Start)
1258 self._page_control.moveCursor(QtGui.QTextCursor.Start)
1259 intercepted = True
1259 intercepted = True
@@ -1266,15 +1266,15 b' class ConsoleWidget(LoggingConfigurable, QtGui.QWidget):'
1266 return True
1266 return True
1267
1267
1268 elif key in (QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return):
1268 elif key in (QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return):
1269 new_event = QtGui.QKeyEvent(QtCore.QEvent.KeyPress,
1269 new_event = QtGui.QKeyEvent(QtCore.QEvent.KeyPress,
1270 QtCore.Qt.Key_PageDown,
1270 QtCore.Qt.Key_PageDown,
1271 QtCore.Qt.NoModifier)
1271 QtCore.Qt.NoModifier)
1272 QtGui.qApp.sendEvent(self._page_control, new_event)
1272 QtGui.qApp.sendEvent(self._page_control, new_event)
1273 return True
1273 return True
1274
1274
1275 elif key == QtCore.Qt.Key_Backspace:
1275 elif key == QtCore.Qt.Key_Backspace:
1276 new_event = QtGui.QKeyEvent(QtCore.QEvent.KeyPress,
1276 new_event = QtGui.QKeyEvent(QtCore.QEvent.KeyPress,
1277 QtCore.Qt.Key_PageUp,
1277 QtCore.Qt.Key_PageUp,
1278 QtCore.Qt.NoModifier)
1278 QtCore.Qt.NoModifier)
1279 QtGui.qApp.sendEvent(self._page_control, new_event)
1279 QtGui.qApp.sendEvent(self._page_control, new_event)
1280 return True
1280 return True
@@ -1300,7 +1300,7 b' class ConsoleWidget(LoggingConfigurable, QtGui.QWidget):'
1300 width = self._control.viewport().width()
1300 width = self._control.viewport().width()
1301 char_width = QtGui.QFontMetrics(self.font).width(' ')
1301 char_width = QtGui.QFontMetrics(self.font).width(' ')
1302 displaywidth = max(10, (width / char_width) - 1)
1302 displaywidth = max(10, (width / char_width) - 1)
1303
1303
1304 return columnize(items, separator, displaywidth)
1304 return columnize(items, separator, displaywidth)
1305
1305
1306 def _get_block_plain_text(self, block):
1306 def _get_block_plain_text(self, block):
@@ -1308,7 +1308,7 b' class ConsoleWidget(LoggingConfigurable, QtGui.QWidget):'
1308 """
1308 """
1309 cursor = QtGui.QTextCursor(block)
1309 cursor = QtGui.QTextCursor(block)
1310 cursor.movePosition(QtGui.QTextCursor.StartOfBlock)
1310 cursor.movePosition(QtGui.QTextCursor.StartOfBlock)
1311 cursor.movePosition(QtGui.QTextCursor.EndOfBlock,
1311 cursor.movePosition(QtGui.QTextCursor.EndOfBlock,
1312 QtGui.QTextCursor.KeepAnchor)
1312 QtGui.QTextCursor.KeepAnchor)
1313 return cursor.selection().toPlainText()
1313 return cursor.selection().toPlainText()
1314
1314
@@ -1316,7 +1316,7 b' class ConsoleWidget(LoggingConfigurable, QtGui.QWidget):'
1316 """ Convenience method that returns a cursor for the current position.
1316 """ Convenience method that returns a cursor for the current position.
1317 """
1317 """
1318 return self._control.textCursor()
1318 return self._control.textCursor()
1319
1319
1320 def _get_end_cursor(self):
1320 def _get_end_cursor(self):
1321 """ Convenience method that returns a cursor for the last character.
1321 """ Convenience method that returns a cursor for the last character.
1322 """
1322 """
@@ -1482,7 +1482,7 b' class ConsoleWidget(LoggingConfigurable, QtGui.QWidget):'
1482 self._set_top_cursor(cursor)
1482 self._set_top_cursor(cursor)
1483 cursor.joinPreviousEditBlock()
1483 cursor.joinPreviousEditBlock()
1484 cursor.deletePreviousChar()
1484 cursor.deletePreviousChar()
1485
1485
1486 format = self._ansi_processor.get_format()
1486 format = self._ansi_processor.get_format()
1487 cursor.insertText(substring, format)
1487 cursor.insertText(substring, format)
1488 else:
1488 else:
@@ -1545,7 +1545,7 b' class ConsoleWidget(LoggingConfigurable, QtGui.QWidget):'
1545 self._cancel_text_completion()
1545 self._cancel_text_completion()
1546 else:
1546 else:
1547 self.input_buffer = ''
1547 self.input_buffer = ''
1548
1548
1549 def _page(self, text, html=False):
1549 def _page(self, text, html=False):
1550 """ Displays text using the pager if it exceeds the height of the
1550 """ Displays text using the pager if it exceeds the height of the
1551 viewport.
1551 viewport.
@@ -1591,7 +1591,7 b' class ConsoleWidget(LoggingConfigurable, QtGui.QWidget):'
1591 def _prompt_started(self):
1591 def _prompt_started(self):
1592 """ Called immediately after a new prompt is displayed.
1592 """ Called immediately after a new prompt is displayed.
1593 """
1593 """
1594 # Temporarily disable the maximum block count to permit undo/redo and
1594 # Temporarily disable the maximum block count to permit undo/redo and
1595 # to ensure that the prompt position does not change due to truncation.
1595 # to ensure that the prompt position does not change due to truncation.
1596 self._control.document().setMaximumBlockCount(0)
1596 self._control.document().setMaximumBlockCount(0)
1597 self._control.setUndoRedoEnabled(True)
1597 self._control.setUndoRedoEnabled(True)
@@ -1613,7 +1613,7 b' class ConsoleWidget(LoggingConfigurable, QtGui.QWidget):'
1613 self._control.moveCursor(QtGui.QTextCursor.End)
1613 self._control.moveCursor(QtGui.QTextCursor.End)
1614
1614
1615 def _readline(self, prompt='', callback=None):
1615 def _readline(self, prompt='', callback=None):
1616 """ Reads one line of input from the user.
1616 """ Reads one line of input from the user.
1617
1617
1618 Parameters
1618 Parameters
1619 ----------
1619 ----------
@@ -1669,7 +1669,7 b' class ConsoleWidget(LoggingConfigurable, QtGui.QWidget):'
1669 else:
1669 else:
1670 self._continuation_prompt = prompt
1670 self._continuation_prompt = prompt
1671 self._continuation_prompt_html = None
1671 self._continuation_prompt_html = None
1672
1672
1673 def _set_cursor(self, cursor):
1673 def _set_cursor(self, cursor):
1674 """ Convenience method to set the current cursor.
1674 """ Convenience method to set the current cursor.
1675 """
1675 """
@@ -1699,16 +1699,16 b' class ConsoleWidget(LoggingConfigurable, QtGui.QWidget):'
1699 as plain text, though ANSI color codes will be handled.
1699 as plain text, though ANSI color codes will be handled.
1700
1700
1701 newline : bool, optional (default True)
1701 newline : bool, optional (default True)
1702 If set, a new line will be written before showing the prompt if
1702 If set, a new line will be written before showing the prompt if
1703 there is not already a newline at the end of the buffer.
1703 there is not already a newline at the end of the buffer.
1704 """
1704 """
1705 # Save the current end position to support _append*(before_prompt=True).
1705 # Save the current end position to support _append*(before_prompt=True).
1706 cursor = self._get_end_cursor()
1706 cursor = self._get_end_cursor()
1707 self._append_before_prompt_pos = cursor.position()
1707 self._append_before_prompt_pos = cursor.position()
1708
1708
1709 # Insert a preliminary newline, if necessary.
1709 # Insert a preliminary newline, if necessary.
1710 if newline and cursor.position() > 0:
1710 if newline and cursor.position() > 0:
1711 cursor.movePosition(QtGui.QTextCursor.Left,
1711 cursor.movePosition(QtGui.QTextCursor.Left,
1712 QtGui.QTextCursor.KeepAnchor)
1712 QtGui.QTextCursor.KeepAnchor)
1713 if cursor.selection().toPlainText() != '\n':
1713 if cursor.selection().toPlainText() != '\n':
1714 self._append_plain_text('\n')
1714 self._append_plain_text('\n')
@@ -103,7 +103,7 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):'
103
103
104 # Emitted when an exit request has been received from the kernel.
104 # Emitted when an exit request has been received from the kernel.
105 exit_requested = QtCore.Signal()
105 exit_requested = QtCore.Signal()
106
106
107 # Protected class variables.
107 # Protected class variables.
108 _CallTipRequest = namedtuple('_CallTipRequest', ['id', 'pos'])
108 _CallTipRequest = namedtuple('_CallTipRequest', ['id', 'pos'])
109 _CompletionRequest = namedtuple('_CompletionRequest', ['id', 'pos'])
109 _CompletionRequest = namedtuple('_CompletionRequest', ['id', 'pos'])
@@ -115,7 +115,7 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):'
115 #---------------------------------------------------------------------------
115 #---------------------------------------------------------------------------
116 # 'object' interface
116 # 'object' interface
117 #---------------------------------------------------------------------------
117 #---------------------------------------------------------------------------
118
118
119 def __init__(self, *args, **kw):
119 def __init__(self, *args, **kw):
120 super(FrontendWidget, self).__init__(*args, **kw)
120 super(FrontendWidget, self).__init__(*args, **kw)
121
121
@@ -151,9 +151,9 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):'
151 # Connect signal handlers.
151 # Connect signal handlers.
152 document = self._control.document()
152 document = self._control.document()
153 document.contentsChange.connect(self._document_contents_change)
153 document.contentsChange.connect(self._document_contents_change)
154
154
155 # Set flag for whether we are connected via localhost.
155 # Set flag for whether we are connected via localhost.
156 self._local_kernel = kw.get('local_kernel',
156 self._local_kernel = kw.get('local_kernel',
157 FrontendWidget._local_kernel)
157 FrontendWidget._local_kernel)
158
158
159 #---------------------------------------------------------------------------
159 #---------------------------------------------------------------------------
@@ -193,7 +193,7 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):'
193 self._hidden = hidden
193 self._hidden = hidden
194 if not hidden:
194 if not hidden:
195 self.executing.emit(source)
195 self.executing.emit(source)
196
196
197 def _prompt_started_hook(self):
197 def _prompt_started_hook(self):
198 """ Called immediately after a new prompt is displayed.
198 """ Called immediately after a new prompt is displayed.
199 """
199 """
@@ -394,7 +394,7 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):'
394 # to spaces so that output looks as expected regardless of this
394 # to spaces so that output looks as expected regardless of this
395 # widget's tab width.
395 # widget's tab width.
396 text = msg['content']['data'].expandtabs(8)
396 text = msg['content']['data'].expandtabs(8)
397
397
398 self._append_plain_text(text, before_prompt=True)
398 self._append_plain_text(text, before_prompt=True)
399 self._control.moveCursor(QtGui.QTextCursor.End)
399 self._control.moveCursor(QtGui.QTextCursor.End)
400
400
@@ -432,7 +432,7 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):'
432 self.reset()
432 self.reset()
433
433
434 def _started_channels(self):
434 def _started_channels(self):
435 """ Called when the KernelManager channels have started listening or
435 """ Called when the KernelManager channels have started listening or
436 when the frontend is assigned an already listening KernelManager.
436 when the frontend is assigned an already listening KernelManager.
437 """
437 """
438 self.reset()
438 self.reset()
@@ -467,7 +467,7 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):'
467 def reset(self):
467 def reset(self):
468 """ Resets the widget to its initial state. Similar to ``clear``, but
468 """ Resets the widget to its initial state. Similar to ``clear``, but
469 also re-writes the banner and aborts execution if necessary.
469 also re-writes the banner and aborts execution if necessary.
470 """
470 """
471 if self._executing:
471 if self._executing:
472 self._executing = False
472 self._executing = False
473 self._request_info['execute'] = None
473 self._request_info['execute'] = None
@@ -550,7 +550,7 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):'
550 '.'.join(context), # text
550 '.'.join(context), # text
551 self._get_input_buffer_cursor_line(), # line
551 self._get_input_buffer_cursor_line(), # line
552 self._get_input_buffer_cursor_column(), # cursor_pos
552 self._get_input_buffer_cursor_column(), # cursor_pos
553 self.input_buffer) # block
553 self.input_buffer) # block
554 pos = self._get_cursor().position()
554 pos = self._get_cursor().position()
555 info = self._CompletionRequest(msg_id, pos)
555 info = self._CompletionRequest(msg_id, pos)
556 self._request_info['complete'] = info
556 self._request_info['complete'] = info
@@ -561,7 +561,7 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):'
561 """
561 """
562 if cursor is None:
562 if cursor is None:
563 cursor = self._get_cursor()
563 cursor = self._get_cursor()
564 cursor.movePosition(QtGui.QTextCursor.StartOfBlock,
564 cursor.movePosition(QtGui.QTextCursor.StartOfBlock,
565 QtGui.QTextCursor.KeepAnchor)
565 QtGui.QTextCursor.KeepAnchor)
566 text = cursor.selection().toPlainText()
566 text = cursor.selection().toPlainText()
567 return self._completion_lexer.get_context(text)
567 return self._completion_lexer.get_context(text)
@@ -17,7 +17,7 b' class HistoryConsoleWidget(ConsoleWidget):'
17 # an edit is made to a multi-line input buffer. To override the lock, use
17 # an edit is made to a multi-line input buffer. To override the lock, use
18 # Shift in conjunction with the standard history cycling keys.
18 # Shift in conjunction with the standard history cycling keys.
19 history_lock = Bool(False, config=True)
19 history_lock = Bool(False, config=True)
20
20
21 #---------------------------------------------------------------------------
21 #---------------------------------------------------------------------------
22 # 'object' interface
22 # 'object' interface
23 #---------------------------------------------------------------------------
23 #---------------------------------------------------------------------------
@@ -45,7 +45,7 b' class HistoryConsoleWidget(ConsoleWidget):'
45 source, hidden, interactive)
45 source, hidden, interactive)
46
46
47 if executed and not hidden:
47 if executed and not hidden:
48 # Save the command unless it was an empty string or was identical
48 # Save the command unless it was an empty string or was identical
49 # to the previous command.
49 # to the previous command.
50 history = history.rstrip()
50 history = history.rstrip()
51 if history and (not self._history or self._history[-1] != history):
51 if history and (not self._history or self._history[-1] != history):
@@ -90,7 +90,7 b' class HistoryConsoleWidget(ConsoleWidget):'
90 # search.
90 # search.
91 cursor = self._get_prompt_cursor()
91 cursor = self._get_prompt_cursor()
92 if self._history_prefix:
92 if self._history_prefix:
93 cursor.movePosition(QtGui.QTextCursor.Right,
93 cursor.movePosition(QtGui.QTextCursor.Right,
94 n=len(self._history_prefix))
94 n=len(self._history_prefix))
95 else:
95 else:
96 cursor.movePosition(QtGui.QTextCursor.EndOfLine)
96 cursor.movePosition(QtGui.QTextCursor.EndOfLine)
@@ -111,7 +111,7 b' class HistoryConsoleWidget(ConsoleWidget):'
111 return False
111 return False
112
112
113 # Perform the search.
113 # Perform the search.
114 replaced = self.history_next(self._history_prefix,
114 replaced = self.history_next(self._history_prefix,
115 as_prefix=not shift_modifier)
115 as_prefix=not shift_modifier)
116
116
117 # Emulate readline: keep the cursor position fixed for a prefix
117 # Emulate readline: keep the cursor position fixed for a prefix
@@ -120,7 +120,7 b' class HistoryConsoleWidget(ConsoleWidget):'
120 # input buffer is set.)
120 # input buffer is set.)
121 if self._history_prefix and replaced:
121 if self._history_prefix and replaced:
122 cursor = self._get_prompt_cursor()
122 cursor = self._get_prompt_cursor()
123 cursor.movePosition(QtGui.QTextCursor.Right,
123 cursor.movePosition(QtGui.QTextCursor.Right,
124 n=len(self._history_prefix))
124 n=len(self._history_prefix))
125 self._set_cursor(cursor)
125 self._set_cursor(cursor)
126
126
@@ -155,7 +155,7 b' class HistoryConsoleWidget(ConsoleWidget):'
155 or (not as_prefix and substring in history):
155 or (not as_prefix and substring in history):
156 replace = True
156 replace = True
157 break
157 break
158
158
159 if replace:
159 if replace:
160 self._store_edits()
160 self._store_edits()
161 self._history_index = index
161 self._history_index = index
@@ -186,7 +186,7 b' class HistoryConsoleWidget(ConsoleWidget):'
186 or (not as_prefix and substring in history):
186 or (not as_prefix and substring in history):
187 replace = True
187 replace = True
188 break
188 break
189
189
190 if replace:
190 if replace:
191 self._store_edits()
191 self._store_edits()
192 self._history_index = index
192 self._history_index = index
@@ -203,7 +203,7 b' class HistoryConsoleWidget(ConsoleWidget):'
203 The (maximum) number of history items to get.
203 The (maximum) number of history items to get.
204 """
204 """
205 return self._history[-n:]
205 return self._history[-n:]
206
206
207 #---------------------------------------------------------------------------
207 #---------------------------------------------------------------------------
208 # 'HistoryConsoleWidget' protected interface
208 # 'HistoryConsoleWidget' protected interface
209 #---------------------------------------------------------------------------
209 #---------------------------------------------------------------------------
@@ -211,8 +211,8 b' class HistoryConsoleWidget(ConsoleWidget):'
211 def _history_locked(self):
211 def _history_locked(self):
212 """ Returns whether history movement is locked.
212 """ Returns whether history movement is locked.
213 """
213 """
214 return (self.history_lock and
214 return (self.history_lock and
215 (self._get_edited_history(self._history_index) !=
215 (self._get_edited_history(self._history_index) !=
216 self.input_buffer) and
216 self.input_buffer) and
217 (self._get_prompt_cursor().blockNumber() !=
217 (self._get_prompt_cursor().blockNumber() !=
218 self._get_end_cursor().blockNumber()))
218 self._get_end_cursor().blockNumber()))
@@ -81,7 +81,7 b' class IPythonWidget(FrontendWidget):'
81 2. Pygments: .c, .k, .o, etc. (see PygmentsHighlighter)
81 2. Pygments: .c, .k, .o, etc. (see PygmentsHighlighter)
82 3. IPython: .error, .in-prompt, .out-prompt, etc
82 3. IPython: .error, .in-prompt, .out-prompt, etc
83 """)
83 """)
84
84
85 syntax_style = Unicode(config=True,
85 syntax_style = Unicode(config=True,
86 help="""
86 help="""
87 If not empty, use this Pygments style for syntax highlighting.
87 If not empty, use this Pygments style for syntax highlighting.
@@ -110,12 +110,12 b' class IPythonWidget(FrontendWidget):'
110 #---------------------------------------------------------------------------
110 #---------------------------------------------------------------------------
111 # 'object' interface
111 # 'object' interface
112 #---------------------------------------------------------------------------
112 #---------------------------------------------------------------------------
113
113
114 def __init__(self, *args, **kw):
114 def __init__(self, *args, **kw):
115 super(IPythonWidget, self).__init__(*args, **kw)
115 super(IPythonWidget, self).__init__(*args, **kw)
116
116
117 # IPythonWidget protected variables.
117 # IPythonWidget protected variables.
118 self._payload_handlers = {
118 self._payload_handlers = {
119 self._payload_source_edit : self._handle_payload_edit,
119 self._payload_source_edit : self._handle_payload_edit,
120 self._payload_source_exit : self._handle_payload_exit,
120 self._payload_source_exit : self._handle_payload_exit,
121 self._payload_source_page : self._handle_payload_page,
121 self._payload_source_page : self._handle_payload_page,
@@ -151,7 +151,7 b' class IPythonWidget(FrontendWidget):'
151 # but the last component and then suitably decreasing the offset
151 # but the last component and then suitably decreasing the offset
152 # between the current cursor position and the start of completion.
152 # between the current cursor position and the start of completion.
153 if len(matches) > 1 and matches[0][:offset] == text:
153 if len(matches) > 1 and matches[0][:offset] == text:
154 parts = re.split(r'[./\\]', text)
154 parts = re.split(r'[./\\]', text)
155 sep_count = len(parts) - 1
155 sep_count = len(parts) - 1
156 if sep_count:
156 if sep_count:
157 chop_length = sum(map(len, parts[:sep_count])) + sep_count
157 chop_length = sum(map(len, parts[:sep_count])) + sep_count
@@ -228,7 +228,7 b' class IPythonWidget(FrontendWidget):'
228 """ The base handler for the ``display_data`` message.
228 """ The base handler for the ``display_data`` message.
229 """
229 """
230 self.log.debug("display: %s", msg.get('content', ''))
230 self.log.debug("display: %s", msg.get('content', ''))
231 # For now, we don't display data from other frontends, but we
231 # For now, we don't display data from other frontends, but we
232 # eventually will as this allows all frontends to monitor the display
232 # eventually will as this allows all frontends to monitor the display
233 # data. But we need to figure out how to handle this in the GUI.
233 # data. But we need to figure out how to handle this in the GUI.
234 if not self._hidden and self._is_from_this_session(msg):
234 if not self._hidden and self._is_from_this_session(msg):
@@ -302,13 +302,13 b' class IPythonWidget(FrontendWidget):'
302 # text field. Readline-based frontends do get a real text field which
302 # text field. Readline-based frontends do get a real text field which
303 # they can use.
303 # they can use.
304 text = ''
304 text = ''
305
305
306 # Send the completion request to the kernel
306 # Send the completion request to the kernel
307 msg_id = self.kernel_manager.shell_channel.complete(
307 msg_id = self.kernel_manager.shell_channel.complete(
308 text, # text
308 text, # text
309 self._get_input_buffer_cursor_line(), # line
309 self._get_input_buffer_cursor_line(), # line
310 self._get_input_buffer_cursor_column(), # cursor_pos
310 self._get_input_buffer_cursor_column(), # cursor_pos
311 self.input_buffer) # block
311 self.input_buffer) # block
312 pos = self._get_cursor().position()
312 pos = self._get_cursor().position()
313 info = self._CompletionRequest(msg_id, pos)
313 info = self._CompletionRequest(msg_id, pos)
314 self._request_info['complete'] = info
314 self._request_info['complete'] = info
@@ -332,7 +332,7 b' class IPythonWidget(FrontendWidget):'
332 self._append_html(traceback)
332 self._append_html(traceback)
333 else:
333 else:
334 # This is the fallback for now, using plain text with ansi escapes
334 # This is the fallback for now, using plain text with ansi escapes
335 self._append_plain_text(traceback)
335 self._append_plain_text(traceback)
336
336
337 def _process_execute_payload(self, item):
337 def _process_execute_payload(self, item):
338 """ Reimplemented to dispatch payloads to handler methods.
338 """ Reimplemented to dispatch payloads to handler methods.
@@ -344,7 +344,7 b' class IPythonWidget(FrontendWidget):'
344 else:
344 else:
345 handler(item)
345 handler(item)
346 return True
346 return True
347
347
348 def _show_interpreter_prompt(self, number=None):
348 def _show_interpreter_prompt(self, number=None):
349 """ Reimplemented for IPython-style prompts.
349 """ Reimplemented for IPython-style prompts.
350 """
350 """
@@ -383,7 +383,7 b' class IPythonWidget(FrontendWidget):'
383 # Remove the old prompt and insert a new prompt.
383 # Remove the old prompt and insert a new prompt.
384 cursor = QtGui.QTextCursor(block)
384 cursor = QtGui.QTextCursor(block)
385 cursor.movePosition(QtGui.QTextCursor.Right,
385 cursor.movePosition(QtGui.QTextCursor.Right,
386 QtGui.QTextCursor.KeepAnchor,
386 QtGui.QTextCursor.KeepAnchor,
387 self._previous_prompt_obj.length)
387 self._previous_prompt_obj.length)
388 prompt = self._make_in_prompt(previous_prompt_number)
388 prompt = self._make_in_prompt(previous_prompt_number)
389 self._prompt = self._insert_html_fetching_plain_text(
389 self._prompt = self._insert_html_fetching_plain_text(
@@ -485,7 +485,7 b' class IPythonWidget(FrontendWidget):'
485 space_count = len(prompt.lstrip('\n')) - len(end_chars)
485 space_count = len(prompt.lstrip('\n')) - len(end_chars)
486 body = '&nbsp;' * space_count + end_chars
486 body = '&nbsp;' * space_count + end_chars
487 return '<span class="in-prompt">%s</span>' % body
487 return '<span class="in-prompt">%s</span>' % body
488
488
489 def _make_out_prompt(self, number):
489 def _make_out_prompt(self, number):
490 """ Given a prompt number, returns an HTML Out prompt.
490 """ Given a prompt number, returns an HTML Out prompt.
491 """
491 """
@@ -14,7 +14,7 b' from IPython.external.qt import QtCore, QtGui'
14 class KillRing(object):
14 class KillRing(object):
15 """ A generic Emacs-style kill ring.
15 """ A generic Emacs-style kill ring.
16 """
16 """
17
17
18 def __init__(self):
18 def __init__(self):
19 self.clear()
19 self.clear()
20
20
@@ -41,7 +41,7 b' class KillRing(object):'
41
41
42 def rotate(self):
42 def rotate(self):
43 """ Rotate the kill ring, then yank back the new top.
43 """ Rotate the kill ring, then yank back the new top.
44
44
45 Returns:
45 Returns:
46 --------
46 --------
47 A text string or None.
47 A text string or None.
@@ -50,7 +50,7 b' class KillRing(object):'
50 if self._index >= 0:
50 if self._index >= 0:
51 return self._ring[self._index]
51 return self._ring[self._index]
52 return None
52 return None
53
53
54 class QtKillRing(QtCore.QObject):
54 class QtKillRing(QtCore.QObject):
55 """ A kill ring attached to Q[Plain]TextEdit.
55 """ A kill ring attached to Q[Plain]TextEdit.
56 """
56 """
@@ -109,12 +109,12 b' class QtKillRing(QtCore.QObject):'
109 if text:
109 if text:
110 self._skip_cursor = True
110 self._skip_cursor = True
111 cursor = self._text_edit.textCursor()
111 cursor = self._text_edit.textCursor()
112 cursor.movePosition(QtGui.QTextCursor.Left,
112 cursor.movePosition(QtGui.QTextCursor.Left,
113 QtGui.QTextCursor.KeepAnchor,
113 QtGui.QTextCursor.KeepAnchor,
114 n = len(self._prev_yank))
114 n = len(self._prev_yank))
115 cursor.insertText(text)
115 cursor.insertText(text)
116 self._prev_yank = text
116 self._prev_yank = text
117
117
118 #--------------------------------------------------------------------------
118 #--------------------------------------------------------------------------
119 # Protected interface
119 # Protected interface
120 #--------------------------------------------------------------------------
120 #--------------------------------------------------------------------------
@@ -79,7 +79,7 b' class PygmentsBlockUserData(QtGui.QTextBlockUserData):'
79
79
80 def __repr__(self):
80 def __repr__(self):
81 attrs = ['syntax_stack']
81 attrs = ['syntax_stack']
82 kwds = ', '.join([ '%s=%r' % (attr, getattr(self, attr))
82 kwds = ', '.join([ '%s=%r' % (attr, getattr(self, attr))
83 for attr in attrs ])
83 for attr in attrs ])
84 return 'PygmentsBlockUserData(%s)' % kwds
84 return 'PygmentsBlockUserData(%s)' % kwds
85
85
@@ -172,7 +172,7 b' class PygmentsHighlighter(QtGui.QSyntaxHighlighter):'
172 return result
172 return result
173
173
174 def _get_format_from_document(self, token, document):
174 def _get_format_from_document(self, token, document):
175 """ Returns a QTextCharFormat for token by
175 """ Returns a QTextCharFormat for token by
176 """
176 """
177 code, html = self._formatter._format_lines([(token, 'dummy')]).next()
177 code, html = self._formatter._format_lines([(token, 'dummy')]).next()
178 self._document.setHtml(html)
178 self._document.setHtml(html)
@@ -56,7 +56,7 b' class RichIPythonWidget(IPythonWidget):'
56 if svg is not None:
56 if svg is not None:
57 menu.addSeparator()
57 menu.addSeparator()
58 menu.addAction('Copy SVG', lambda: svg_to_clipboard(svg))
58 menu.addAction('Copy SVG', lambda: svg_to_clipboard(svg))
59 menu.addAction('Save SVG As...',
59 menu.addAction('Save SVG As...',
60 lambda: save_svg(svg, self._control))
60 lambda: save_svg(svg, self._control))
61 else:
61 else:
62 menu = super(RichIPythonWidget, self)._context_menu_make(pos)
62 menu = super(RichIPythonWidget, self)._context_menu_make(pos)
@@ -209,7 +209,7 b' class RichIPythonWidget(IPythonWidget):'
209 # Chop stand-alone header from matplotlib SVG
209 # Chop stand-alone header from matplotlib SVG
210 offset = svg.find("<svg")
210 offset = svg.find("<svg")
211 assert(offset > -1)
211 assert(offset > -1)
212
212
213 return svg[offset:]
213 return svg[offset:]
214
214
215 else:
215 else:
@@ -51,20 +51,20 b' class QtShellSocketChannel(SocketChannelQObject, ShellSocketChannel):'
51 # Emitted when the first reply comes back.
51 # Emitted when the first reply comes back.
52 first_reply = QtCore.Signal()
52 first_reply = QtCore.Signal()
53
53
54 # Used by the first_reply signal logic to determine if a reply is the
54 # Used by the first_reply signal logic to determine if a reply is the
55 # first.
55 # first.
56 _handlers_called = False
56 _handlers_called = False
57
57
58 #---------------------------------------------------------------------------
58 #---------------------------------------------------------------------------
59 # 'ShellSocketChannel' interface
59 # 'ShellSocketChannel' interface
60 #---------------------------------------------------------------------------
60 #---------------------------------------------------------------------------
61
61
62 def call_handlers(self, msg):
62 def call_handlers(self, msg):
63 """ Reimplemented to emit signals instead of making callbacks.
63 """ Reimplemented to emit signals instead of making callbacks.
64 """
64 """
65 # Emit the generic signal.
65 # Emit the generic signal.
66 self.message_received.emit(msg)
66 self.message_received.emit(msg)
67
67
68 # Emit signals for specialized message types.
68 # Emit signals for specialized message types.
69 msg_type = msg['header']['msg_type']
69 msg_type = msg['header']['msg_type']
70 signal = getattr(self, msg_type, None)
70 signal = getattr(self, msg_type, None)
@@ -115,7 +115,7 b' class QtSubSocketChannel(SocketChannelQObject, SubSocketChannel):'
115 #---------------------------------------------------------------------------
115 #---------------------------------------------------------------------------
116 # 'SubSocketChannel' interface
116 # 'SubSocketChannel' interface
117 #---------------------------------------------------------------------------
117 #---------------------------------------------------------------------------
118
118
119 def call_handlers(self, msg):
119 def call_handlers(self, msg):
120 """ Reimplemented to emit signals instead of making callbacks.
120 """ Reimplemented to emit signals instead of making callbacks.
121 """
121 """
@@ -153,7 +153,7 b' class QtStdInSocketChannel(SocketChannelQObject, StdInSocketChannel):'
153 """
153 """
154 # Emit the generic signal.
154 # Emit the generic signal.
155 self.message_received.emit(msg)
155 self.message_received.emit(msg)
156
156
157 # Emit signals for specialized message types.
157 # Emit signals for specialized message types.
158 msg_type = msg['header']['msg_type']
158 msg_type = msg['header']['msg_type']
159 if msg_type == 'input_request':
159 if msg_type == 'input_request':
@@ -208,7 +208,7 b' class QtKernelManager(KernelManager, SuperQObject):'
208 super(QtKernelManager, self).start_kernel(*args, **kw)
208 super(QtKernelManager, self).start_kernel(*args, **kw)
209
209
210 #------ Channel management -------------------------------------------------
210 #------ Channel management -------------------------------------------------
211
211
212 def start_channels(self, *args, **kw):
212 def start_channels(self, *args, **kw):
213 """ Reimplemented to emit signal.
213 """ Reimplemented to emit signal.
214 """
214 """
@@ -217,7 +217,7 b' class QtKernelManager(KernelManager, SuperQObject):'
217
217
218 def stop_channels(self):
218 def stop_channels(self):
219 """ Reimplemented to emit signal.
219 """ Reimplemented to emit signal.
220 """
220 """
221 super(QtKernelManager, self).stop_channels()
221 super(QtKernelManager, self).stop_channels()
222 self.stopped_channels.emit()
222 self.stopped_channels.emit()
223
223
@@ -233,7 +233,7 b' class QtKernelManager(KernelManager, SuperQObject):'
233 #---------------------------------------------------------------------------
233 #---------------------------------------------------------------------------
234 # Protected interface
234 # Protected interface
235 #---------------------------------------------------------------------------
235 #---------------------------------------------------------------------------
236
236
237 def _first_reply(self):
237 def _first_reply(self):
238 """ Unpauses the heartbeat channel when the first reply is received on
238 """ Unpauses the heartbeat channel when the first reply is received on
239 the execute channel. Note that this will *not* start the heartbeat
239 the execute channel. Note that this will *not* start the heartbeat
@@ -87,7 +87,7 b' class HtmlExporter(object):'
87 ib.setShortcut('I')
87 ib.setShortcut('I')
88 eb = QtGui.QPushButton("&External")
88 eb = QtGui.QPushButton("&External")
89 eb.setShortcut('E')
89 eb.setShortcut('E')
90 box = QtGui.QMessageBox(QtGui.QMessageBox.Question,
90 box = QtGui.QMessageBox(QtGui.QMessageBox.Question,
91 dialog.windowTitle(), msg)
91 dialog.windowTitle(), msg)
92 box.setInformativeText(info)
92 box.setInformativeText(info)
93 box.addButton(ib, QtGui.QMessageBox.NoRole)
93 box.addButton(ib, QtGui.QMessageBox.NoRole)
@@ -190,12 +190,12 b' def default_image_tag(match, path = None, format = "png"):'
190 """ Return (X)HTML mark-up for the image-tag given by match.
190 """ Return (X)HTML mark-up for the image-tag given by match.
191
191
192 This default implementation merely removes the image, and exists mostly
192 This default implementation merely removes the image, and exists mostly
193 for documentation purposes. More information than is present in the Qt
193 for documentation purposes. More information than is present in the Qt
194 HTML is required to supply the images.
194 HTML is required to supply the images.
195
195
196 Parameters
196 Parameters
197 ----------
197 ----------
198 match : re.SRE_Match
198 match : re.SRE_Match
199 A match to an HTML image tag as exported by Qt, with match.group("Name")
199 A match to an HTML image tag as exported by Qt, with match.group("Name")
200 containing the matched image ID.
200 containing the matched image ID.
201
201
@@ -212,7 +212,7 b' def default_image_tag(match, path = None, format = "png"):'
212
212
213 def fix_html(html):
213 def fix_html(html):
214 """ Transforms a Qt-generated HTML string into a standards-compliant one.
214 """ Transforms a Qt-generated HTML string into a standards-compliant one.
215
215
216 Parameters:
216 Parameters:
217 -----------
217 -----------
218 html : str,
218 html : str,
@@ -53,7 +53,7 b" def kill_embedded(self,parameter_s=''):"
53 figured out what you needed from it, you may then kill it and the program
53 figured out what you needed from it, you may then kill it and the program
54 will then continue to run without the interactive shell interfering again.
54 will then continue to run without the interactive shell interfering again.
55 """
55 """
56
56
57 kill = ask_yes_no("Are you sure you want to kill this embedded instance "
57 kill = ask_yes_no("Are you sure you want to kill this embedded instance "
58 "(y/n)? [y/N] ",'n')
58 "(y/n)? [y/N] ",'n')
59 if kill:
59 if kill:
@@ -206,7 +206,7 b' class InteractiveShellEmbed(TerminalInteractiveShell):'
206
206
207 with nested(self.builtin_trap, self.display_trap):
207 with nested(self.builtin_trap, self.display_trap):
208 self.interact(display_banner=display_banner)
208 self.interact(display_banner=display_banner)
209
209
210 # now, purge out the user namespace from anything we might have added
210 # now, purge out the user namespace from anything we might have added
211 # from the caller's local namespace
211 # from the caller's local namespace
212 delvar = self.user_ns.pop
212 delvar = self.user_ns.pop
@@ -234,7 +234,7 b' def embed(**kwargs):'
234 d = 40
234 d = 40
235 embed
235 embed
236
236
237 Full customization can be done by passing a :class:`Struct` in as the
237 Full customization can be done by passing a :class:`Struct` in as the
238 config argument.
238 config argument.
239 """
239 """
240 config = kwargs.get('config')
240 config = kwargs.get('config')
@@ -117,7 +117,7 b' class TerminalInteractiveShell(InteractiveShell):'
117 self.system = self.system_piped
117 self.system = self.system_piped
118 else:
118 else:
119 self.system = self.system_raw
119 self.system = self.system_raw
120
120
121 self.init_term_title()
121 self.init_term_title()
122 self.init_usage(usage)
122 self.init_usage(usage)
123 self.init_banner(banner1, banner2, display_banner)
123 self.init_banner(banner1, banner2, display_banner)
@@ -214,13 +214,13 b' class TerminalInteractiveShell(InteractiveShell):'
214 If an optional banner argument is given, it will override the
214 If an optional banner argument is given, it will override the
215 internally created default banner.
215 internally created default banner.
216 """
216 """
217
217
218 with nested(self.builtin_trap, self.display_trap):
218 with nested(self.builtin_trap, self.display_trap):
219
219
220 while 1:
220 while 1:
221 try:
221 try:
222 self.interact(display_banner=display_banner)
222 self.interact(display_banner=display_banner)
223 #self.interact_with_readline()
223 #self.interact_with_readline()
224 # XXX for testing of a readline-decoupled repl loop, call
224 # XXX for testing of a readline-decoupled repl loop, call
225 # interact_with_readline above
225 # interact_with_readline above
226 break
226 break
@@ -232,23 +232,23 b' class TerminalInteractiveShell(InteractiveShell):'
232 def interact(self, display_banner=None):
232 def interact(self, display_banner=None):
233 """Closely emulate the interactive Python console."""
233 """Closely emulate the interactive Python console."""
234
234
235 # batch run -> do not interact
235 # batch run -> do not interact
236 if self.exit_now:
236 if self.exit_now:
237 return
237 return
238
238
239 if display_banner is None:
239 if display_banner is None:
240 display_banner = self.display_banner
240 display_banner = self.display_banner
241
241
242 if isinstance(display_banner, basestring):
242 if isinstance(display_banner, basestring):
243 self.show_banner(display_banner)
243 self.show_banner(display_banner)
244 elif display_banner:
244 elif display_banner:
245 self.show_banner()
245 self.show_banner()
246
246
247 more = False
247 more = False
248
248
249 # Mark activity in the builtins
249 # Mark activity in the builtins
250 __builtin__.__dict__['__IPYTHON__active'] += 1
250 __builtin__.__dict__['__IPYTHON__active'] += 1
251
251
252 if self.has_readline:
252 if self.has_readline:
253 self.readline_startup_hook(self.pre_readline)
253 self.readline_startup_hook(self.pre_readline)
254 # exit_now is set by a call to %Exit or %Quit, through the
254 # exit_now is set by a call to %Exit or %Quit, through the
@@ -263,7 +263,7 b' class TerminalInteractiveShell(InteractiveShell):'
263 self.showtraceback()
263 self.showtraceback()
264 if self.autoindent:
264 if self.autoindent:
265 self.rl_do_indent = True
265 self.rl_do_indent = True
266
266
267 else:
267 else:
268 try:
268 try:
269 prompt = self.hooks.generate_prompt(False)
269 prompt = self.hooks.generate_prompt(False)
@@ -276,7 +276,7 b' class TerminalInteractiveShell(InteractiveShell):'
276 break
276 break
277 if self.autoindent:
277 if self.autoindent:
278 self.rl_do_indent = False
278 self.rl_do_indent = False
279
279
280 except KeyboardInterrupt:
280 except KeyboardInterrupt:
281 #double-guard against keyboardinterrupts during kbdint handling
281 #double-guard against keyboardinterrupts during kbdint handling
282 try:
282 try:
@@ -310,7 +310,7 b' class TerminalInteractiveShell(InteractiveShell):'
310 if not more:
310 if not more:
311 source_raw = self.input_splitter.source_raw_reset()[1]
311 source_raw = self.input_splitter.source_raw_reset()[1]
312 self.run_cell(source_raw)
312 self.run_cell(source_raw)
313
313
314 # We are off again...
314 # We are off again...
315 __builtin__.__dict__['__IPYTHON__active'] -= 1
315 __builtin__.__dict__['__IPYTHON__active'] -= 1
316
316
@@ -335,7 +335,7 b' class TerminalInteractiveShell(InteractiveShell):'
335
335
336 if self.has_readline:
336 if self.has_readline:
337 self.set_readline_completer()
337 self.set_readline_completer()
338
338
339 try:
339 try:
340 line = py3compat.str_to_unicode(self.raw_input_original(prompt))
340 line = py3compat.str_to_unicode(self.raw_input_original(prompt))
341 except ValueError:
341 except ValueError:
@@ -351,7 +351,7 b' class TerminalInteractiveShell(InteractiveShell):'
351 if num_ini_spaces(line) > self.indent_current_nsp:
351 if num_ini_spaces(line) > self.indent_current_nsp:
352 line = line[self.indent_current_nsp:]
352 line = line[self.indent_current_nsp:]
353 self.indent_current_nsp = 0
353 self.indent_current_nsp = 0
354
354
355 return line
355 return line
356
356
357 #-------------------------------------------------------------------------
357 #-------------------------------------------------------------------------
@@ -378,7 +378,7 b' class TerminalInteractiveShell(InteractiveShell):'
378 try:
378 try:
379 f = file(err.filename)
379 f = file(err.filename)
380 try:
380 try:
381 # This should be inside a display_trap block and I
381 # This should be inside a display_trap block and I
382 # think it is.
382 # think it is.
383 sys.displayhook(f.read())
383 sys.displayhook(f.read())
384 finally:
384 finally:
@@ -392,10 +392,10 b' class TerminalInteractiveShell(InteractiveShell):'
392 if e.filename in ('<ipython console>','<input>','<string>',
392 if e.filename in ('<ipython console>','<input>','<string>',
393 '<console>','<BackgroundJob compilation>',
393 '<console>','<BackgroundJob compilation>',
394 None):
394 None):
395
395
396 return False
396 return False
397 try:
397 try:
398 if (self.autoedit_syntax and
398 if (self.autoedit_syntax and
399 not self.ask_yes_no('Return to editor to correct syntax error? '
399 not self.ask_yes_no('Return to editor to correct syntax error? '
400 '[Y/n] ','y')):
400 '[Y/n] ','y')):
401 return False
401 return False
@@ -468,7 +468,7 b' class TerminalInteractiveShell(InteractiveShell):'
468 self.ask_exit()
468 self.ask_exit()
469 else:
469 else:
470 self.ask_exit()
470 self.ask_exit()
471
471
472 #------------------------------------------------------------------------
472 #------------------------------------------------------------------------
473 # Magic overrides
473 # Magic overrides
474 #------------------------------------------------------------------------
474 #------------------------------------------------------------------------
@@ -486,38 +486,38 b' class TerminalInteractiveShell(InteractiveShell):'
486 @skip_doctest
486 @skip_doctest
487 def magic_cpaste(self, parameter_s=''):
487 def magic_cpaste(self, parameter_s=''):
488 """Paste & execute a pre-formatted code block from clipboard.
488 """Paste & execute a pre-formatted code block from clipboard.
489
489
490 You must terminate the block with '--' (two minus-signs) alone on the
490 You must terminate the block with '--' (two minus-signs) alone on the
491 line. You can also provide your own sentinel with '%paste -s %%' ('%%'
491 line. You can also provide your own sentinel with '%paste -s %%' ('%%'
492 is the new sentinel for this operation)
492 is the new sentinel for this operation)
493
493
494 The block is dedented prior to execution to enable execution of method
494 The block is dedented prior to execution to enable execution of method
495 definitions. '>' and '+' characters at the beginning of a line are
495 definitions. '>' and '+' characters at the beginning of a line are
496 ignored, to allow pasting directly from e-mails, diff files and
496 ignored, to allow pasting directly from e-mails, diff files and
497 doctests (the '...' continuation prompt is also stripped). The
497 doctests (the '...' continuation prompt is also stripped). The
498 executed block is also assigned to variable named 'pasted_block' for
498 executed block is also assigned to variable named 'pasted_block' for
499 later editing with '%edit pasted_block'.
499 later editing with '%edit pasted_block'.
500
500
501 You can also pass a variable name as an argument, e.g. '%cpaste foo'.
501 You can also pass a variable name as an argument, e.g. '%cpaste foo'.
502 This assigns the pasted block to variable 'foo' as string, without
502 This assigns the pasted block to variable 'foo' as string, without
503 dedenting or executing it (preceding >>> and + is still stripped)
503 dedenting or executing it (preceding >>> and + is still stripped)
504
504
505 '%cpaste -r' re-executes the block previously entered by cpaste.
505 '%cpaste -r' re-executes the block previously entered by cpaste.
506
506
507 Do not be alarmed by garbled output on Windows (it's a readline bug).
507 Do not be alarmed by garbled output on Windows (it's a readline bug).
508 Just press enter and type -- (and press enter again) and the block
508 Just press enter and type -- (and press enter again) and the block
509 will be what was just pasted.
509 will be what was just pasted.
510
510
511 IPython statements (magics, shell escapes) are not supported (yet).
511 IPython statements (magics, shell escapes) are not supported (yet).
512
512
513 See also
513 See also
514 --------
514 --------
515 paste: automatically pull code from clipboard.
515 paste: automatically pull code from clipboard.
516
516
517 Examples
517 Examples
518 --------
518 --------
519 ::
519 ::
520
520
521 In [8]: %cpaste
521 In [8]: %cpaste
522 Pasting code; enter '--' alone on the line to stop.
522 Pasting code; enter '--' alone on the line to stop.
523 :>>> a = ["world!", "Hello"]
523 :>>> a = ["world!", "Hello"]
@@ -525,13 +525,13 b' class TerminalInteractiveShell(InteractiveShell):'
525 :--
525 :--
526 Hello world!
526 Hello world!
527 """
527 """
528
528
529 opts,args = self.parse_options(parameter_s,'rs:',mode='string')
529 opts,args = self.parse_options(parameter_s,'rs:',mode='string')
530 par = args.strip()
530 par = args.strip()
531 if opts.has_key('r'):
531 if opts.has_key('r'):
532 self._rerun_pasted()
532 self._rerun_pasted()
533 return
533 return
534
534
535 sentinel = opts.get('s','--')
535 sentinel = opts.get('s','--')
536
536
537 block = self._strip_pasted_lines_for_code(
537 block = self._strip_pasted_lines_for_code(
@@ -541,7 +541,7 b' class TerminalInteractiveShell(InteractiveShell):'
541
541
542 def magic_paste(self, parameter_s=''):
542 def magic_paste(self, parameter_s=''):
543 """Paste & execute a pre-formatted code block from clipboard.
543 """Paste & execute a pre-formatted code block from clipboard.
544
544
545 The text is pulled directly from the clipboard without user
545 The text is pulled directly from the clipboard without user
546 intervention and printed back on the screen before execution (unless
546 intervention and printed back on the screen before execution (unless
547 the -q flag is given to force quiet mode).
547 the -q flag is given to force quiet mode).
@@ -552,18 +552,18 b' class TerminalInteractiveShell(InteractiveShell):'
552 doctests (the '...' continuation prompt is also stripped). The
552 doctests (the '...' continuation prompt is also stripped). The
553 executed block is also assigned to variable named 'pasted_block' for
553 executed block is also assigned to variable named 'pasted_block' for
554 later editing with '%edit pasted_block'.
554 later editing with '%edit pasted_block'.
555
555
556 You can also pass a variable name as an argument, e.g. '%paste foo'.
556 You can also pass a variable name as an argument, e.g. '%paste foo'.
557 This assigns the pasted block to variable 'foo' as string, without
557 This assigns the pasted block to variable 'foo' as string, without
558 dedenting or executing it (preceding >>> and + is still stripped)
558 dedenting or executing it (preceding >>> and + is still stripped)
559
559
560 Options
560 Options
561 -------
561 -------
562
562
563 -r: re-executes the block previously entered by cpaste.
563 -r: re-executes the block previously entered by cpaste.
564
564
565 -q: quiet mode: do not echo the pasted text back to the terminal.
565 -q: quiet mode: do not echo the pasted text back to the terminal.
566
566
567 IPython statements (magics, shell escapes) are not supported (yet).
567 IPython statements (magics, shell escapes) are not supported (yet).
568
568
569 See also
569 See also
@@ -586,9 +586,9 b' class TerminalInteractiveShell(InteractiveShell):'
586 if not block.endswith('\n'):
586 if not block.endswith('\n'):
587 write('\n')
587 write('\n')
588 write("## -- End pasted text --\n")
588 write("## -- End pasted text --\n")
589
589
590 self._execute_block(block, par)
590 self._execute_block(block, par)
591
591
592 def showindentationerror(self):
592 def showindentationerror(self):
593 super(TerminalInteractiveShell, self).showindentationerror()
593 super(TerminalInteractiveShell, self).showindentationerror()
594 print("If you want to paste code into IPython, try the %paste magic function.")
594 print("If you want to paste code into IPython, try the %paste magic function.")
@@ -201,7 +201,7 b' class TerminalIPythonApp(BaseIPythonApplication, InteractiveShellApp):'
201 PlainTextFormatter,
201 PlainTextFormatter,
202 Completer,
202 Completer,
203 ]
203 ]
204
204
205 subcommands = Dict(dict(
205 subcommands = Dict(dict(
206 qtconsole=('IPython.frontend.qt.console.qtconsoleapp.IPythonQtConsoleApp',
206 qtconsole=('IPython.frontend.qt.console.qtconsoleapp.IPythonQtConsoleApp',
207 """Launch the IPython Qt Console."""
207 """Launch the IPython Qt Console."""
@@ -216,7 +216,7 b' class TerminalIPythonApp(BaseIPythonApplication, InteractiveShellApp):'
216 "Start a kernel without an attached frontend."
216 "Start a kernel without an attached frontend."
217 ),
217 ),
218 ))
218 ))
219
219
220 # *do* autocreate requested profile, but don't create the config file.
220 # *do* autocreate requested profile, but don't create the config file.
221 auto_create=Bool(True)
221 auto_create=Bool(True)
222 # configurables
222 # configurables
@@ -253,7 +253,7 b' class TerminalIPythonApp(BaseIPythonApplication, InteractiveShellApp):'
253 def _force_interact_changed(self, name, old, new):
253 def _force_interact_changed(self, name, old, new):
254 if new:
254 if new:
255 self.interact = True
255 self.interact = True
256
256
257 def _file_to_run_changed(self, name, old, new):
257 def _file_to_run_changed(self, name, old, new):
258 if new and not self.force_interact:
258 if new and not self.force_interact:
259 self.interact = False
259 self.interact = False
@@ -283,7 +283,7 b' class TerminalIPythonApp(BaseIPythonApplication, InteractiveShellApp):'
283 sub = '--pylab='+gui
283 sub = '--pylab='+gui
284 argv.pop(idx+1)
284 argv.pop(idx+1)
285 argv[idx] = sub
285 argv[idx] = sub
286
286
287 return super(TerminalIPythonApp, self).parse_command_line(argv)
287 return super(TerminalIPythonApp, self).parse_command_line(argv)
288
288
289 def initialize(self, argv=None):
289 def initialize(self, argv=None):
@@ -313,7 +313,7 b' class TerminalIPythonApp(BaseIPythonApplication, InteractiveShellApp):'
313 sys.path.insert(0, '')
313 sys.path.insert(0, '')
314
314
315 # Create an InteractiveShell instance.
315 # Create an InteractiveShell instance.
316 # shell.display_banner should always be False for the terminal
316 # shell.display_banner should always be False for the terminal
317 # based app, because we call shell.show_banner() by hand below
317 # based app, because we call shell.show_banner() by hand below
318 # so the banner shows *before* all extension loading stuff.
318 # so the banner shows *before* all extension loading stuff.
319 self.shell = TerminalInteractiveShell.instance(config=self.config,
319 self.shell = TerminalInteractiveShell.instance(config=self.config,
@@ -18,10 +18,10 b' def win32_clipboard_get():'
18 message = ("Getting text from the clipboard requires the pywin32 "
18 message = ("Getting text from the clipboard requires the pywin32 "
19 "extensions: http://sourceforge.net/projects/pywin32/")
19 "extensions: http://sourceforge.net/projects/pywin32/")
20 raise TryNext(message)
20 raise TryNext(message)
21 win32clipboard.OpenClipboard()
21 win32clipboard.OpenClipboard()
22 text = win32clipboard.GetClipboardData(win32clipboard.CF_TEXT)
22 text = win32clipboard.GetClipboardData(win32clipboard.CF_TEXT)
23 # FIXME: convert \r\n to \n?
23 # FIXME: convert \r\n to \n?
24 win32clipboard.CloseClipboard()
24 win32clipboard.CloseClipboard()
25 return text
25 return text
26
26
27 def osx_clipboard_get():
27 def osx_clipboard_get():
@@ -9,11 +9,11 b' To enable it type::'
9 You can then disable it with::
9 You can then disable it with::
10
10
11 __builtin__.reload = deepreload.original_reload
11 __builtin__.reload = deepreload.original_reload
12
12
13 Alternatively, you can add a dreload builtin alongside normal reload with::
13 Alternatively, you can add a dreload builtin alongside normal reload with::
14
14
15 __builtin__.dreload = deepreload.reload
15 __builtin__.dreload = deepreload.reload
16
16
17 This code is almost entirely based on knee.py from the standard library.
17 This code is almost entirely based on knee.py from the standard library.
18 """
18 """
19
19
@@ -30,7 +30,7 b' import sys'
30
30
31 # Replacement for __import__()
31 # Replacement for __import__()
32 def deep_import_hook(name, globals=None, locals=None, fromlist=None, level=-1):
32 def deep_import_hook(name, globals=None, locals=None, fromlist=None, level=-1):
33 # For now level is ignored, it's just there to prevent crash
33 # For now level is ignored, it's just there to prevent crash
34 # with from __future__ import absolute_import
34 # with from __future__ import absolute_import
35 parent = determine_parent(globals)
35 parent = determine_parent(globals)
36 q, tail = find_head_package(parent, name)
36 q, tail = find_head_package(parent, name)
@@ -94,7 +94,7 b' def load_tail(q, tail):'
94 # to:
94 # to:
95 mname = m.__name__
95 mname = m.__name__
96 # This needs more testing!!! (I don't understand this module too well)
96 # This needs more testing!!! (I don't understand this module too well)
97
97
98 #print '** head,tail=|%s|->|%s|, mname=|%s|' % (head,tail,mname) # dbg
98 #print '** head,tail=|%s|->|%s|, mname=|%s|' % (head,tail,mname) # dbg
99 m = import_module(head, mname, m)
99 m = import_module(head, mname, m)
100 if not m:
100 if not m:
@@ -125,25 +125,25 b' def import_module(partname, fqname, parent):'
125 global found_now
125 global found_now
126 if found_now.has_key(fqname):
126 if found_now.has_key(fqname):
127 try:
127 try:
128 return sys.modules[fqname]
128 return sys.modules[fqname]
129 except KeyError:
129 except KeyError:
130 pass
130 pass
131
131
132 print 'Reloading', fqname #, sys.excepthook is sys.__excepthook__, \
132 print 'Reloading', fqname #, sys.excepthook is sys.__excepthook__, \
133 #sys.displayhook is sys.__displayhook__
133 #sys.displayhook is sys.__displayhook__
134
134
135 found_now[fqname] = 1
135 found_now[fqname] = 1
136 try:
136 try:
137 fp, pathname, stuff = imp.find_module(partname,
137 fp, pathname, stuff = imp.find_module(partname,
138 parent and parent.__path__)
138 parent and parent.__path__)
139 except ImportError:
139 except ImportError:
140 return None
140 return None
141
141
142 try:
142 try:
143 m = imp.load_module(fqname, fp, pathname, stuff)
143 m = imp.load_module(fqname, fp, pathname, stuff)
144 finally:
144 finally:
145 if fp: fp.close()
145 if fp: fp.close()
146
146
147 if parent:
147 if parent:
148 setattr(parent, partname, m)
148 setattr(parent, partname, m)
149
149
@@ -168,14 +168,14 b' except AttributeError:'
168 def reload(module, exclude=['sys', '__builtin__', '__main__']):
168 def reload(module, exclude=['sys', '__builtin__', '__main__']):
169 """Recursively reload all modules used in the given module. Optionally
169 """Recursively reload all modules used in the given module. Optionally
170 takes a list of modules to exclude from reloading. The default exclude
170 takes a list of modules to exclude from reloading. The default exclude
171 list contains sys, __main__, and __builtin__, to prevent, e.g., resetting
171 list contains sys, __main__, and __builtin__, to prevent, e.g., resetting
172 display, exception, and io hooks.
172 display, exception, and io hooks.
173 """
173 """
174 global found_now
174 global found_now
175 for i in exclude:
175 for i in exclude:
176 found_now[i] = 1
176 found_now[i] = 1
177 original_import = __builtin__.__import__
177 original_import = __builtin__.__import__
178 __builtin__.__import__ = deep_import_hook
178 __builtin__.__import__ = deep_import_hook
179 try:
179 try:
180 ret = deep_reload_hook(module)
180 ret = deep_reload_hook(module)
181 finally:
181 finally:
@@ -44,7 +44,7 b' subclassing more convenient. Their docstrings below have some more details:'
44
44
45 - post_cmd(): run right after the execution of each block. If the block
45 - post_cmd(): run right after the execution of each block. If the block
46 raises an exception, this is NOT called.
46 raises an exception, this is NOT called.
47
47
48
48
49 Operation
49 Operation
50 =========
50 =========
@@ -72,14 +72,14 b' The supported tags are:'
72 word 'stop', to help visually distinguish the blocks in a text editor:
72 word 'stop', to help visually distinguish the blocks in a text editor:
73
73
74 # <demo> --- stop ---
74 # <demo> --- stop ---
75
75
76
76
77 # <demo> silent
77 # <demo> silent
78
78
79 Make a block execute silently (and hence automatically). Typically used in
79 Make a block execute silently (and hence automatically). Typically used in
80 cases where you have some boilerplate or initialization code which you need
80 cases where you have some boilerplate or initialization code which you need
81 executed but do not want to be seen in the demo.
81 executed but do not want to be seen in the demo.
82
82
83 # <demo> auto
83 # <demo> auto
84
84
85 Make a block execute automatically, but still being printed. Useful for
85 Make a block execute automatically, but still being printed. Useful for
@@ -116,7 +116,7 b' been added to the "docs/examples/core" directory. Just cd to this directory in'
116 an IPython session, and type::
116 an IPython session, and type::
117
117
118 %run demo-exercizer.py
118 %run demo-exercizer.py
119
119
120 and then follow the directions.
120 and then follow the directions.
121
121
122 Example
122 Example
@@ -200,14 +200,14 b' class Demo(object):'
200 IPython.Demo? in IPython to see it).
200 IPython.Demo? in IPython to see it).
201
201
202 Inputs:
202 Inputs:
203
203
204 - src is either a file, or file-like object, or a
204 - src is either a file, or file-like object, or a
205 string that can be resolved to a filename.
205 string that can be resolved to a filename.
206
206
207 Optional inputs:
207 Optional inputs:
208
208
209 - title: a string to use as the demo name. Of most use when the demo
209 - title: a string to use as the demo name. Of most use when the demo
210 you are making comes from an object that has no filename, or if you
210 you are making comes from an object that has no filename, or if you
211 want an alternate denotation distinct from the filename.
211 want an alternate denotation distinct from the filename.
212
212
213 - arg_str(''): a string of arguments, internally converted to a list
213 - arg_str(''): a string of arguments, internally converted to a list
@@ -238,7 +238,7 b' class Demo(object):'
238 self.sys_argv = [src] + shlex.split(arg_str)
238 self.sys_argv = [src] + shlex.split(arg_str)
239 self.auto_all = auto_all
239 self.auto_all = auto_all
240 self.src = src
240 self.src = src
241
241
242 # get a few things from ipython. While it's a bit ugly design-wise,
242 # get a few things from ipython. While it's a bit ugly design-wise,
243 # it ensures that things like color scheme and the like are always in
243 # it ensures that things like color scheme and the like are always in
244 # sync with the ipython mode being used. This class is only meant to
244 # sync with the ipython mode being used. This class is only meant to
@@ -268,7 +268,7 b' class Demo(object):'
268 def reload(self):
268 def reload(self):
269 """Reload source from disk and initialize state."""
269 """Reload source from disk and initialize state."""
270 self.fload()
270 self.fload()
271
271
272 self.src = self.fobj.read()
272 self.src = self.fobj.read()
273 src_b = [b.strip() for b in self.re_stop.split(self.src) if b]
273 src_b = [b.strip() for b in self.re_stop.split(self.src) if b]
274 self._silent = [bool(self.re_silent.findall(b)) for b in src_b]
274 self._silent = [bool(self.re_silent.findall(b)) for b in src_b]
@@ -315,7 +315,7 b' class Demo(object):'
315 """Get the current block index, validating and checking status.
315 """Get the current block index, validating and checking status.
316
316
317 Returns None if the demo is finished"""
317 Returns None if the demo is finished"""
318
318
319 if index is None:
319 if index is None:
320 if self.finished:
320 if self.finished:
321 print >>io.stdout, 'Demo finished. Use <demo_name>.reset() if you want to rerun it.'
321 print >>io.stdout, 'Demo finished. Use <demo_name>.reset() if you want to rerun it.'
@@ -369,7 +369,7 b' class Demo(object):'
369 # that the default demo.edit() call opens up the sblock we've last run
369 # that the default demo.edit() call opens up the sblock we've last run
370 if index>0:
370 if index>0:
371 index -= 1
371 index -= 1
372
372
373 filename = self.shell.mktempfile(self.src_blocks[index])
373 filename = self.shell.mktempfile(self.src_blocks[index])
374 self.shell.hooks.editor(filename,1)
374 self.shell.hooks.editor(filename,1)
375 new_block = file_read(filename)
375 new_block = file_read(filename)
@@ -379,7 +379,7 b' class Demo(object):'
379 self.block_index = index
379 self.block_index = index
380 # call to run with the newly edited index
380 # call to run with the newly edited index
381 self()
381 self()
382
382
383 def show(self,index=None):
383 def show(self,index=None):
384 """Show a single block on screen"""
384 """Show a single block on screen"""
385
385
@@ -414,7 +414,7 b' class Demo(object):'
414 """Execute a string with one or more lines of code"""
414 """Execute a string with one or more lines of code"""
415
415
416 exec source in self.user_ns
416 exec source in self.user_ns
417
417
418 def __call__(self,index=None):
418 def __call__(self,index=None):
419 """run a block of the demo.
419 """run a block of the demo.
420
420
@@ -452,7 +452,7 b' class Demo(object):'
452 self.post_cmd()
452 self.post_cmd()
453 finally:
453 finally:
454 sys.argv = save_argv
454 sys.argv = save_argv
455
455
456 except:
456 except:
457 self.ip_showtb(filename=self.fname)
457 self.ip_showtb(filename=self.fname)
458 else:
458 else:
@@ -499,7 +499,7 b' class IPythonDemo(Demo):'
499 """Execute a string with one or more lines of code"""
499 """Execute a string with one or more lines of code"""
500
500
501 self.shell.run_cell(source)
501 self.shell.run_cell(source)
502
502
503 class LineDemo(Demo):
503 class LineDemo(Demo):
504 """Demo where each line is executed as a separate block.
504 """Demo where each line is executed as a separate block.
505
505
@@ -513,7 +513,7 b' class LineDemo(Demo):'
513 Note: the input can not have *any* indentation, which means that only
513 Note: the input can not have *any* indentation, which means that only
514 single-lines of input are accepted, not even function definitions are
514 single-lines of input are accepted, not even function definitions are
515 valid."""
515 valid."""
516
516
517 def reload(self):
517 def reload(self):
518 """Reload source from disk and initialize state."""
518 """Reload source from disk and initialize state."""
519 # read data and parse into blocks
519 # read data and parse into blocks
@@ -542,26 +542,26 b' class IPythonLineDemo(IPythonDemo,LineDemo):'
542
542
543 class ClearMixin(object):
543 class ClearMixin(object):
544 """Use this mixin to make Demo classes with less visual clutter.
544 """Use this mixin to make Demo classes with less visual clutter.
545
545
546 Demos using this mixin will clear the screen before every block and use
546 Demos using this mixin will clear the screen before every block and use
547 blank marquees.
547 blank marquees.
548
548
549 Note that in order for the methods defined here to actually override those
549 Note that in order for the methods defined here to actually override those
550 of the classes it's mixed with, it must go /first/ in the inheritance
550 of the classes it's mixed with, it must go /first/ in the inheritance
551 tree. For example:
551 tree. For example:
552
552
553 class ClearIPDemo(ClearMixin,IPythonDemo): pass
553 class ClearIPDemo(ClearMixin,IPythonDemo): pass
554
554
555 will provide an IPythonDemo class with the mixin's features.
555 will provide an IPythonDemo class with the mixin's features.
556 """
556 """
557
557
558 def marquee(self,txt='',width=78,mark='*'):
558 def marquee(self,txt='',width=78,mark='*'):
559 """Blank marquee that returns '' no matter what the input."""
559 """Blank marquee that returns '' no matter what the input."""
560 return ''
560 return ''
561
561
562 def pre_cmd(self):
562 def pre_cmd(self):
563 """Method called before executing each block.
563 """Method called before executing each block.
564
564
565 This one simply clears the screen."""
565 This one simply clears the screen."""
566 from IPython.utils.terminal import term_clear
566 from IPython.utils.terminal import term_clear
567 term_clear()
567 term_clear()
@@ -5,30 +5,30 b' Authors : MinRK'
5
5
6 class YouTubeVideo(object):
6 class YouTubeVideo(object):
7 """Class for embedding a YouTube Video in an IPython session, based on its video id.
7 """Class for embedding a YouTube Video in an IPython session, based on its video id.
8
8
9 e.g. to embed the video on this page:
9 e.g. to embed the video on this page:
10
10
11 http://www.youtube.com/watch?v=foo
11 http://www.youtube.com/watch?v=foo
12
12
13 you would do:
13 you would do:
14
14
15 vid = YouTubeVideo("foo")
15 vid = YouTubeVideo("foo")
16 display(vid)
16 display(vid)
17 """
17 """
18
18
19 def __init__(self, id, width=400, height=300):
19 def __init__(self, id, width=400, height=300):
20 self.id = id
20 self.id = id
21 self.width = width
21 self.width = width
22 self.height = height
22 self.height = height
23
23
24 def _repr_html_(self):
24 def _repr_html_(self):
25 """return YouTube embed iframe for this video id"""
25 """return YouTube embed iframe for this video id"""
26 return """
26 return """
27 <iframe
27 <iframe
28 width="%i"
28 width="%i"
29 height="%i"
29 height="%i"
30 src="http://www.youtube.com/embed/%s"
30 src="http://www.youtube.com/embed/%s"
31 frameborder="0"
31 frameborder="0"
32 allowfullscreen
32 allowfullscreen
33 ></iframe>
33 ></iframe>
34 """%(self.width, self.height, self.id)
34 """%(self.width, self.height, self.id)
@@ -8,11 +8,11 b' session. IPython has two different types of GUI integration:'
8 1. The terminal based IPython supports GUI event loops through Python's
8 1. The terminal based IPython supports GUI event loops through Python's
9 PyOS_InputHook. PyOS_InputHook is a hook that Python calls periodically
9 PyOS_InputHook. PyOS_InputHook is a hook that Python calls periodically
10 whenever raw_input is waiting for a user to type code. We implement GUI
10 whenever raw_input is waiting for a user to type code. We implement GUI
11 support in the terminal by setting PyOS_InputHook to a function that
11 support in the terminal by setting PyOS_InputHook to a function that
12 iterates the event loop for a short while. It is important to note that
12 iterates the event loop for a short while. It is important to note that
13 in this situation, the real GUI event loop is NOT run in the normal
13 in this situation, the real GUI event loop is NOT run in the normal
14 manner, so you can't use the normal means to detect that it is running.
14 manner, so you can't use the normal means to detect that it is running.
15 2. In the two process IPython kernel/frontend, the GUI event loop is run in
15 2. In the two process IPython kernel/frontend, the GUI event loop is run in
16 the kernel. In this case, the event loop is run in the normal manner by
16 the kernel. In this case, the event loop is run in the normal manner by
17 calling the function or method of the GUI toolkit that starts the event
17 calling the function or method of the GUI toolkit that starts the event
18 loop.
18 loop.
@@ -47,7 +47,7 b' we proposed the following informal protocol:'
47 *must* use its value. If it has not been set, you can query the toolkit
47 *must* use its value. If it has not been set, you can query the toolkit
48 in the normal manner.
48 in the normal manner.
49 * If you want GUI support and no one else has created an application or
49 * If you want GUI support and no one else has created an application or
50 started the event loop you *must* do this. We don't want projects to
50 started the event loop you *must* do this. We don't want projects to
51 attempt to defer these things to someone else if they themselves need it.
51 attempt to defer these things to someone else if they themselves need it.
52
52
53 The functions below implement this logic for each GUI toolkit. If you need
53 The functions below implement this logic for each GUI toolkit. If you need
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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