From 4708461471f8a68ba9dbab0e566c6f8a11f9ff2f 2005-11-15 08:51:15 From: fperez Date: 2005-11-15 08:51:15 Subject: [PATCH] Wildcard system cleanup, ipmaker speedups, bugfix in globals handling (previous fix had introduced a problem). Changelog has more details. --- diff --git a/IPython/Magic.py b/IPython/Magic.py index bad50e7..e53207d 100644 --- a/IPython/Magic.py +++ b/IPython/Magic.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """Magic functions for InteractiveShell. -$Id: Magic.py 922 2005-11-13 10:21:08Z fperez $""" +$Id: Magic.py 923 2005-11-15 08:51:15Z fperez $""" #***************************************************************************** # Copyright (C) 2001 Janko Hauser and @@ -296,10 +296,9 @@ license. To use profiling, please install"python2.3-profiler" from non-free.""") Struct with the options as keys and the stripped argument string still as a string. - arg_str is quoted as a true sys.argv vector by calling on the fly a - python process in a subshell. This allows us to easily expand - variables, glob files, quote arguments, etc, with all the power and - correctness of the underlying system shell. + arg_str is quoted as a true sys.argv vector by using shlex.split. + This allows us to easily expand variables, glob files, quote + arguments, etc. Options: -mode: default 'string'. If given as 'list', the argument string is @@ -665,55 +664,109 @@ Currently the magic system has the following functions:\n""" def magic_psearch(self, parameter_s=''): """Search for object in namespaces by wildcard. - %psearch PATTERN [OBJECT TYPE] [-NAMESPACE]* [+NAMESPACE]* [-a] [-c] + %psearch [options] PATTERN [OBJECT TYPE] Note: ? can be used as a synonym for %psearch, at the beginning or at - the end: both a*? and ?a* are equivalent to '%psearch a*'. - - PATTERN - - where PATTERN is a string containing * as a wildcard similar to its - use in a shell. The pattern is matched in all namespaces on the - search path. By default objects starting with a single _ are not - matched, many IPython generated objects have a single underscore. The - default is case insensitive matching. Matching is also done on the - attributes of objects and not only on the objects in a module. - - [OBJECT TYPE] - Is the name of a python type from the types module. The name is given - in lowercase without the ending type, ex. StringType is written - string. By adding a type here only objects matching the given type are - matched. Using all here makes the pattern match all types (this is the - default). - - [-NAMESPACE]* [+NAMESPACE]* - The possible namespaces are builtin, user, internal, alias. Where - builtin and user are default. Builtin contains the python module - builtin, user contains all imported namespaces, alias only contain the - shell aliases and no python objects, internal contains objects used by - IPython. The namespaces on the search path are removed by -namespace - and added by +namespace. - - [-a] makes the pattern match even objects with a single underscore. - [-c] makes the pattern case sensitive. + the end: both a*? and ?a* are equivalent to '%psearch a*'. Still, the + rest of the command line must be unchanged (options come first), so + for example the following forms are equivalent + + %psearch -i a* function + -i a* function? + ?-i a* function + + Arguments: + + PATTERN + + where PATTERN is a string containing * as a wildcard similar to its + use in a shell. The pattern is matched in all namespaces on the + search path. By default objects starting with a single _ are not + matched, many IPython generated objects have a single + underscore. The default is case insensitive matching. Matching is + also done on the attributes of objects and not only on the objects + in a module. + + [OBJECT TYPE] + + Is the name of a python type from the types module. The name is + given in lowercase without the ending type, ex. StringType is + written string. By adding a type here only objects matching the + given type are matched. Using all here makes the pattern match all + types (this is the default). + + Options: + + -a: makes the pattern match even objects whose names start with a + single underscore. These names are normally ommitted from the + search. + + -i/-c: make the pattern case insensitive/sensitive. If neither of + these options is given, the default is read from your ipythonrc + file. The option name which sets this value is + 'wildcards_case_sensitive'. If this option is not specified in your + ipythonrc file, IPython's internal default is to do a case sensitive + search. + + -e/-s NAMESPACE: exclude/search a given namespace. The pattern you + specifiy can be searched in any of the following namespaces: + 'builtin', 'user', 'user_global','internal', 'alias', where + 'builtin' and 'user' are the search defaults. Note that you should + not use quotes when specifying namespaces. + + 'Builtin' contains the python module builtin, 'user' contains all + user data, 'alias' only contain the shell aliases and no python + objects, 'internal' contains objects used by IPython. The + 'user_global' namespace is only used by embedded IPython instances, + and it contains module-level globals. You can add namespaces to the + search with -s or exclude them with -e (these options can be given + more than once). Examples: - %psearch a* list objects beginning with an a - %psearch a* function list all functions beginning with an a - %psearch re.e* list objects beginning with an e in module re - %psearch r*.e* list objects that starts with e in modules starting in r - %psearch r*.* string list all strings in modules beginning with r + %psearch a* -> objects beginning with an a + %psearch -e builtin a* -> objects NOT in the builtin space starting in a + %psearch a* function -> all functions beginning with an a + %psearch re.e* -> objects beginning with an e in module re + %psearch r*.e* -> objects that start with e in modules starting in r + %psearch r*.* string -> all strings in modules beginning with r Case sensitve search: - %psearch a* -c list all object beginning with lower case a + %psearch -c a* list all object beginning with lower case a Show objects beginning with a single _: - %psearch _* -a list objects beginning with underscore""" + %psearch -a _* list objects beginning with a single underscore""" + + # default namespaces to be searched + def_search = ['user','builtin'] + + # Process options/args + opts,args = self.parse_options(parameter_s,'cias:e:',list_all=True) + opt = opts.get + shell = self.shell + psearch = shell.inspector.psearch - self.shell.inspector.psearch(parameter_s,shell=self.shell) + # select case options + if opts.has_key('i'): + ignore_case = True + elif opts.has_key('c'): + ignore_case = False + else: + ignore_case = not shell.rc.wildcards_case_sensitive + + # Build list of namespaces to search from user options + def_search.extend(opt('s',[])) + ns_exclude = ns_exclude=opt('e',[]) + ns_search = [nm for nm in def_search if nm not in ns_exclude] + + # Call the actual search + try: + psearch(args,shell.ns_table,ns_search, + show_all=opt('a'),ignore_case=ignore_case) + except: + shell.showtraceback() def magic_who_ls(self, parameter_s=''): """Return a sorted list of all interactive variables. diff --git a/IPython/OInspect.py b/IPython/OInspect.py index 6cd81b7..aa7b5c0 100644 --- a/IPython/OInspect.py +++ b/IPython/OInspect.py @@ -6,7 +6,7 @@ Uses syntax highlighting for presenting the various information elements. Similar in spirit to the inspect module, but all calls take a name argument to reference the name under which an object is being read. -$Id: OInspect.py 922 2005-11-13 10:21:08Z fperez $ +$Id: OInspect.py 923 2005-11-15 08:51:15Z fperez $ """ #***************************************************************************** @@ -23,13 +23,14 @@ __license__ = Release.license __all__ = ['Inspector','InspectColors'] # stdlib modules +import __builtin__ import inspect,linecache,types,StringIO,string # IPython's own from IPython import PyColorize from IPython.Itpl import itpl -from IPython.wildcard import choose_namespaces,list_namespace -from IPython.genutils import page,indent,Term +from IPython.wildcard import list_namespace +from IPython.genutils import page,indent,Term,mkdict from IPython.ColorANSI import * #**************************************************************************** @@ -398,44 +399,56 @@ class Inspector: page(output) # end pinfo - def psearch(self,oname='',formatter=None,shell=None): + def psearch(self,pattern,ns_table,ns_search=[], + ignore_case=False,show_all=False): """Search namespaces with wildcards for objects. + Arguments: + + - pattern: string containing shell-like wildcards to use in namespace + searches and optionally a type specification to narrow the search to + objects of that type. + + - ns_table: dict of name->namespaces for search. + Optional arguments: - - oname: rest of the commandline containging pattern and options. + - ns_search: list of namespace names to include in search. - - formatter: Not used. + - ignore_case(False): make the search case-insensitive. - - shell: The shell object from the Magic class. Needed to access - the namespaces. + - show_all(False): show all names, including those starting with + underscores. """ - option_list = ['-c','-a'] - cmds = oname.split() - filter = '' + # defaults type_pattern = 'all' - options = [x for x in cmds if x in option_list] - ignorecase = '-c' not in options - showhidden = '-a' in options - ns_cmds = [x for x in cmds if x[0] in '-+' and x not in option_list] - cmds = [x for x in cmds if x[0] not in '-+'] + filter = '' + + cmds = pattern.split() len_cmds = len(cmds) if len_cmds == 1: - filter = cmds[0].strip() + # Only filter pattern given + filter = cmds[0] elif len_cmds == 2: + # Both filter and type specified filter,type_pattern = cmds - elif len_cmds>2: - # assume we want to choose name spaces. Rather poor design forces - #the use of a typepattern in order to choose name spaces - cmds = cmds[:2] + else: + raise ValueError('invalid argument string for psearch: <%s>' % + pattern) - do_list = choose_namespaces(shell,ns_cmds) + # filter search namespaces + for name in ns_search: + if name not in ns_table: + raise ValueError('invalid namespace <%s>. Valid names: %s' % + (name,ns_table.keys())) + #print 'type_pattern:',type_pattern # dbg search_result = [] - for ns in do_list: + for ns_name in ns_search: + ns = ns_table[ns_name] tmp_res = list(list_namespace(ns,type_pattern,filter, - ignorecase=ignorecase, - showhidden=showhidden)) + ignore_case=ignore_case, + show_all=show_all)) search_result.extend(tmp_res) search_result.sort() diff --git a/IPython/Shell.py b/IPython/Shell.py index 1ecf931..d8f0570 100644 --- a/IPython/Shell.py +++ b/IPython/Shell.py @@ -4,7 +4,7 @@ All the matplotlib support code was co-developed with John Hunter, matplotlib's author. -$Id: Shell.py 921 2005-11-13 06:51:34Z fperez $""" +$Id: Shell.py 923 2005-11-15 08:51:15Z fperez $""" #***************************************************************************** # Copyright (C) 2001-2004 Fernando Perez @@ -132,9 +132,6 @@ class IPShellEmbed: #self.IP = make_IPython(argv,user_ns=__main__.__dict__) self.IP = make_IPython(argv,rc_override=rc_override,embedded=True) - # mark this as an embedded instance so we know if we get a crash - # post-mortem - self.IP.rc.embedded = 1 # copy our own displayhook also self.sys_displayhook_embed = sys.displayhook # and leave the system's display hook clean diff --git a/IPython/UserConfig/ipythonrc b/IPython/UserConfig/ipythonrc index 19358bd..a500846 100644 --- a/IPython/UserConfig/ipythonrc +++ b/IPython/UserConfig/ipythonrc @@ -1,5 +1,5 @@ # -*- Mode: Shell-Script -*- Not really, but shows comments correctly -# $Id: ipythonrc 633 2005-07-17 01:03:15Z tzanko $ +# $Id: ipythonrc 923 2005-11-15 08:51:15Z fperez $ #*************************************************************************** # @@ -262,6 +262,14 @@ separate_out2 0 # Simply removes all input/output separators, overriding the choices above. nosep 0 +# Wildcard searches - IPython has a system for searching names using +# shell-like wildcards; type %psearch? for details. This variables sets +# whether by default such searches should be case sensitive or not. You can +# always override the default at the system command line or the IPython +# prompt. + +wildcards_case_sensitive 1 + # xmode - Exception reporting mode. # Valid modes: Plain, Context and Verbose. diff --git a/IPython/iplib.py b/IPython/iplib.py index 3dca034..23038ca 100644 --- a/IPython/iplib.py +++ b/IPython/iplib.py @@ -6,7 +6,7 @@ Requires Python 2.1 or newer. This file contains all the classes and helper functions specific to IPython. -$Id: iplib.py 921 2005-11-13 06:51:34Z fperez $ +$Id: iplib.py 923 2005-11-15 08:51:15Z fperez $ """ #***************************************************************************** @@ -508,7 +508,7 @@ class InteractiveShell(code.InteractiveConsole, Logger, Magic): def __init__(self,name,usage=None,rc=Struct(opts=None,args=None), user_ns = None,user_global_ns=None,banner2='', - custom_exceptions=((),None)): + custom_exceptions=((),None),embedded=False): # Put a reference to self in builtins so that any form of embedded or # imported code can test for being inside IPython. @@ -532,6 +532,10 @@ class InteractiveShell(code.InteractiveConsole, Logger, Magic): __builtin__.exit += _exit __builtin__.quit += _exit + # We need to know whether the instance is meant for embedding, since + # global/local namespaces need to be handled differently in that case + self.embedded = embedded + # compiler command self.compile = CommandCompiler() @@ -584,9 +588,29 @@ class InteractiveShell(code.InteractiveConsole, Logger, Magic): if user_global_ns is None: user_global_ns = {} - # assign namespaces + # Assign namespaces + # This is the namespace where all normal user variables live self.user_ns = user_ns + # Embedded instances require a separate namespace for globals. + # Normally this one is unused by non-embedded instances. self.user_global_ns = user_global_ns + # A namespace to keep track of internal data structures to prevent + # them from cluttering user-visible stuff. Will be updated later + self.internal_ns = {} + + # Namespace of system aliases. Each entry in the alias + # table must be a 2-tuple of the form (N,name), where N is the number + # of positional arguments of the alias. + self.alias_table = {} + + # A table holding all the namespaces IPython deals with, so that + # introspection facilities can search easily. + self.ns_table = {'user':user_ns, + 'user_global':user_global_ns, + 'alias':self.alias_table, + 'internal':self.internal_ns, + 'builtin':__builtin__.__dict__ + } # The user namespace MUST have a pointer to the shell itself. self.user_ns[name] = self @@ -619,11 +643,6 @@ class InteractiveShell(code.InteractiveConsole, Logger, Magic): # dict of output history self.output_hist = {} - # dict of names to be treated as system aliases. Each entry in the - # alias table must be a 2-tuple of the form (N,name), where N is the - # number of positional arguments of the alias. - self.alias_table = {} - # dict of things NOT to alias (keywords, builtins and some special magics) no_alias = {} no_alias_magics = ['cd','popd','pushd','dhist','alias','unalias'] @@ -956,7 +975,15 @@ class InteractiveShell(code.InteractiveConsole, Logger, Magic): This is called after the configuration files have been processed to 'finalize' the initialization.""" - + + # Load readline proper + if self.rc.readline: + self.init_readline() + + # Set user colors (don't do it in the constructor above so that it doesn't + # crash if colors option is invalid) + self.magic_colors(self.rc.colors) + # dynamic data that survives through sessions # XXX make the filename a config option? persist_base = 'persist' @@ -1629,7 +1656,16 @@ want to merge them back into the new files.""" % locals() outflag = 1 # happens in more places, so it's easier as default try: try: - exec code_obj in self.user_global_ns, self.user_ns + # Embedded instances require separate global/local namespaces + # so they can see both the surrounding (local) namespace and + # the module-level globals when called inside another function. + if self.embedded: + exec code_obj in self.user_global_ns, self.user_ns + # Normal (non-embedded) instances should only have a single + # namespace for user code execution, otherwise functions won't + # see interactive top-level globals. + else: + exec code_obj in self.user_ns finally: # Reset our crash handler in place sys.excepthook = old_excepthook diff --git a/IPython/ipmaker.py b/IPython/ipmaker.py index fc2b295..b2a8d38 100644 --- a/IPython/ipmaker.py +++ b/IPython/ipmaker.py @@ -6,7 +6,7 @@ Requires Python 2.1 or better. This file contains the main make_IPython() starter function. -$Id: ipmaker.py 911 2005-10-08 07:59:40Z fperez $""" +$Id: ipmaker.py 923 2005-11-15 08:51:15Z fperez $""" #***************************************************************************** # Copyright (C) 2001-2004 Fernando Perez. @@ -82,7 +82,7 @@ def make_IPython(argv=None,user_ns=None,debug=1,rc_override=None, # __IP.name. We set its name via the first parameter passed to # InteractiveShell: - IP = shell_class('__IP',user_ns=user_ns,**kw) + IP = shell_class('__IP',user_ns=user_ns,embedded=embedded,**kw) # Put 'help' in the user namespace from site import _Helper @@ -155,7 +155,7 @@ object? -> Details about 'object'. ?object also works, ?? prints more. 'readline! readline_merge_completions! ' 'readline_omit__names! ' 'rcfile=s separate_in|si=s separate_out|so=s ' - 'separate_out2|so2=s xmode=s ' + 'separate_out2|so2=s xmode=s wildcards_case_sensitive! ' 'magic_docstrings system_verbose! ' 'multi_line_specials!') @@ -218,6 +218,7 @@ object? -> Details about 'object'. ?object also works, ?? prints more. upgrade = 0, Version = 0, xmode = 'Verbose', + wildcards_case_sensitive = 1, magic_docstrings = 0, # undocumented, for doc generation ) @@ -281,7 +282,7 @@ object? -> Details about 'object'. ?object also works, ?? prints more. except: print cmd_line_usage warn('\nError in Arguments: ' + `sys.exc_value`) - sys.exit() + sys.exit(1) # convert the options dict to a struct for much lighter syntax later opts = Struct(getopt.optionValues) @@ -445,73 +446,72 @@ object? -> Details about 'object'. ?object also works, ?? prints more. # Execute user config # first, create a valid config structure with the right precedence order: - # defaults < rcfile < command line - IP.rc = rc_def.copy() - IP.rc.update(opts_def) + # defaults < rcfile < command line. We make it as a local (IP_rc) to + # avoid a zillion attribute accesses. Right before returning, this will + # be set as IP.rc. + IP_rc = rc_def.copy() + IP_rc.update(opts_def) if rcfiledata: # now we can update - IP.rc.update(rcfiledata) - IP.rc.update(opts) - IP.rc.update(rc_override) + IP_rc.update(rcfiledata) + IP_rc.update(opts) + IP_rc.update(rc_override) # Store the original cmd line for reference: - IP.rc.opts = opts - IP.rc.args = args + IP_rc.opts = opts + IP_rc.args = args # create a *runtime* Struct like rc for holding parameters which may be # created and/or modified by runtime user extensions. IP.runtime_rc = Struct() - # from this point on, all config should be handled through IP.rc, + # from this point on, all config should be handled through IP_rc, # opts* shouldn't be used anymore. # add personal .ipython dir to sys.path so that users can put things in # there for customization - sys.path.append(IP.rc.ipythondir) + sys.path.append(IP_rc.ipythondir) sys.path.insert(0, '') # add . to sys.path. Fix from Prabhu Ramachandran - # update IP.rc with some special things that need manual + # update IP_rc with some special things that need manual # tweaks. Basically options which affect other options. I guess this # should just be written so that options are fully orthogonal and we # wouldn't worry about this stuff! - if IP.rc.classic: - IP.rc.quick = 1 - IP.rc.cache_size = 0 - IP.rc.pprint = 0 - IP.rc.prompt_in1 = '>>> ' - IP.rc.prompt_in2 = '... ' - IP.rc.prompt_out = '' - IP.rc.separate_in = IP.rc.separate_out = IP.rc.separate_out2 = '0' - IP.rc.colors = 'NoColor' - IP.rc.xmode = 'Plain' + if IP_rc.classic: + IP_rc.quick = 1 + IP_rc.cache_size = 0 + IP_rc.pprint = 0 + IP_rc.prompt_in1 = '>>> ' + IP_rc.prompt_in2 = '... ' + IP_rc.prompt_out = '' + IP_rc.separate_in = IP_rc.separate_out = IP_rc.separate_out2 = '0' + IP_rc.colors = 'NoColor' + IP_rc.xmode = 'Plain' # configure readline # Define the history file for saving commands in between sessions - if IP.rc.profile: - histfname = 'history-%s' % IP.rc.profile + if IP_rc.profile: + histfname = 'history-%s' % IP_rc.profile else: histfname = 'history' IP.histfile = os.path.join(opts_all.ipythondir,histfname) - # Load readline proper - if IP.rc.readline: - IP.init_readline() # update exception handlers with rc file status otrap.trap_out() # I don't want these messages ever. - IP.magic_xmode(IP.rc.xmode) + IP.magic_xmode(IP_rc.xmode) otrap.release_out() # activate logging if requested and not reloading a log - if IP.rc.logplay: - IP.magic_logstart(IP.rc.logplay + ' append') - elif IP.rc.logfile: - IP.magic_logstart(IP.rc.logfile) - elif IP.rc.log: + if IP_rc.logplay: + IP.magic_logstart(IP_rc.logplay + ' append') + elif IP_rc.logfile: + IP.magic_logstart(IP_rc.logfile) + elif IP_rc.log: IP.magic_logstart() # find user editor so that it we don't have to look it up constantly - if IP.rc.editor.strip()=='0': + if IP_rc.editor.strip()=='0': try: ed = os.environ['EDITOR'] except KeyError: @@ -519,12 +519,16 @@ object? -> Details about 'object'. ?object also works, ?? prints more. ed = 'vi' # the only one guaranteed to be there! else: ed = 'notepad' # same in Windows! - IP.rc.editor = ed + IP_rc.editor = ed + + # Keep track of whether this is an embedded instance or not (useful for + # post-mortems). + IP_rc.embedded = IP.embedded # Recursive reload try: from IPython import deep_reload - if IP.rc.deep_reload: + if IP_rc.deep_reload: __builtin__.reload = deep_reload.reload else: __builtin__.dreload = deep_reload.reload @@ -538,25 +542,25 @@ object? -> Details about 'object'. ?object also works, ?? prints more. # defining things on the command line, and %who works as expected. # DON'T do anything that affects the namespace beyond this point! - IP.internal_ns = __main__.__dict__.copy() + IP.internal_ns.update(__main__.__dict__) #IP.internal_ns.update(locals()) # so our stuff doesn't show up in %who # Now run through the different sections of the users's config - if IP.rc.debug: + if IP_rc.debug: print 'Trying to execute the following configuration structure:' print '(Things listed first are deeper in the inclusion tree and get' print 'loaded first).\n' - pprint(IP.rc.__dict__) + pprint(IP_rc.__dict__) - for mod in IP.rc.import_mod: + for mod in IP_rc.import_mod: try: exec 'import '+mod in IP.user_ns except : IP.InteractiveTB() import_fail_info(mod) - for mod_fn in IP.rc.import_some: + for mod_fn in IP_rc.import_some: if mod_fn == []: break mod,fn = mod_fn[0],','.join(mod_fn[1:]) try: @@ -565,14 +569,14 @@ object? -> Details about 'object'. ?object also works, ?? prints more. IP.InteractiveTB() import_fail_info(mod,fn) - for mod in IP.rc.import_all: + for mod in IP_rc.import_all: try: exec 'from '+mod+' import *' in IP.user_ns except : IP.InteractiveTB() import_fail_info(mod) - for code in IP.rc.execute: + for code in IP_rc.execute: try: exec code in IP.user_ns except: @@ -580,7 +584,7 @@ object? -> Details about 'object'. ?object also works, ?? prints more. warn('Failure executing code: ' + `code`) # Execute the files the user wants in ipythonrc - for file in IP.rc.execfile: + for file in IP_rc.execfile: try: file = filefind(file,sys.path+[IPython_dir]) except IOError: @@ -589,12 +593,12 @@ object? -> Details about 'object'. ?object also works, ?? prints more. IP.safe_execfile(os.path.expanduser(file),IP.user_ns) # Load user aliases - for alias in IP.rc.alias: + for alias in IP_rc.alias: IP.magic_alias(alias) # release stdout and stderr and save config log into a global summary msg.config.release_all() - if IP.rc.messages: + if IP_rc.messages: msg.summary += msg.config.summary_all() #------------------------------------------------------------------------ @@ -612,7 +616,7 @@ object? -> Details about 'object'. ?object also works, ?? prints more. if load_logplay: print 'Replaying log...' try: - if IP.rc.debug: + if IP_rc.debug: logplay_quiet = 0 else: logplay_quiet = 1 @@ -621,7 +625,7 @@ object? -> Details about 'object'. ?object also works, ?? prints more. IP.safe_execfile(load_logplay,IP.user_ns, islog = 1, quiet = logplay_quiet) msg.logplay.release_all() - if IP.rc.messages: + if IP_rc.messages: msg.summary += msg.logplay.summary_all() except: warn('Problems replaying logfile %s.' % load_logplay) @@ -639,7 +643,7 @@ object? -> Details about 'object'. ?object also works, ?? prints more. # ipython prompt. This would also give them the benefit of ipython's # nice tracebacks. - if not embedded and IP.rc.args: + if not embedded and IP_rc.args: name_save = IP.user_ns['__name__'] IP.user_ns['__name__'] = '__main__' try: @@ -655,40 +659,36 @@ object? -> Details about 'object'. ?object also works, ?? prints more. IP.user_ns['__name__'] = name_save msg.user_exec.release_all() - if IP.rc.messages: + if IP_rc.messages: msg.summary += msg.user_exec.summary_all() # since we can't specify a null string on the cmd line, 0 is the equivalent: - if IP.rc.nosep: - IP.rc.separate_in = IP.rc.separate_out = IP.rc.separate_out2 = '0' - if IP.rc.separate_in == '0': IP.rc.separate_in = '' - if IP.rc.separate_out == '0': IP.rc.separate_out = '' - if IP.rc.separate_out2 == '0': IP.rc.separate_out2 = '' - IP.rc.separate_in = IP.rc.separate_in.replace('\\n','\n') - IP.rc.separate_out = IP.rc.separate_out.replace('\\n','\n') - IP.rc.separate_out2 = IP.rc.separate_out2.replace('\\n','\n') + if IP_rc.nosep: + IP_rc.separate_in = IP_rc.separate_out = IP_rc.separate_out2 = '0' + if IP_rc.separate_in == '0': IP_rc.separate_in = '' + if IP_rc.separate_out == '0': IP_rc.separate_out = '' + if IP_rc.separate_out2 == '0': IP_rc.separate_out2 = '' + IP_rc.separate_in = IP_rc.separate_in.replace('\\n','\n') + IP_rc.separate_out = IP_rc.separate_out.replace('\\n','\n') + IP_rc.separate_out2 = IP_rc.separate_out2.replace('\\n','\n') # Determine how many lines at the bottom of the screen are needed for # showing prompts, so we can know wheter long strings are to be printed or # paged: - num_lines_bot = IP.rc.separate_in.count('\n')+1 - IP.rc.screen_length = IP.rc.screen_length - num_lines_bot + num_lines_bot = IP_rc.separate_in.count('\n')+1 + IP_rc.screen_length = IP_rc.screen_length - num_lines_bot # Initialize cache, set in/out prompts and printing system - IP.outputcache = CachedOutput(IP.rc.cache_size, - IP.rc.pprint, - input_sep = IP.rc.separate_in, - output_sep = IP.rc.separate_out, - output_sep2 = IP.rc.separate_out2, - ps1 = IP.rc.prompt_in1, - ps2 = IP.rc.prompt_in2, - ps_out = IP.rc.prompt_out, + IP.outputcache = CachedOutput(IP_rc.cache_size, + IP_rc.pprint, + input_sep = IP_rc.separate_in, + output_sep = IP_rc.separate_out, + output_sep2 = IP_rc.separate_out2, + ps1 = IP_rc.prompt_in1, + ps2 = IP_rc.prompt_in2, + ps_out = IP_rc.prompt_out, user_ns = IP.user_ns, input_hist = IP.input_hist, - pad_left = IP.rc.prompts_pad_left) - - # Set user colors (don't do it in the constructor above so that it doesn't - # crash if colors option is invalid) - IP.magic_colors(IP.rc.colors) + pad_left = IP_rc.prompts_pad_left) # user may have over-ridden the default print hook: try: @@ -697,7 +697,7 @@ object? -> Details about 'object'. ?object also works, ?? prints more. pass # Set calling of pdb on exceptions - IP.InteractiveTB.call_pdb = IP.rc.pdb + IP.InteractiveTB.call_pdb = IP_rc.pdb # I don't like assigning globally to sys, because it means when embedding # instances, each embedded instance overrides the previous choice. But @@ -709,18 +709,25 @@ object? -> Details about 'object'. ?object also works, ?? prints more. IP.do_full_cache = IP.outputcache.do_full_cache # configure startup banner - if IP.rc.c: # regular python doesn't print the banner with -c - IP.rc.banner = 0 - if IP.rc.banner: - IP.BANNER = '\n'.join(IP.BANNER_PARTS) + if IP_rc.c: # regular python doesn't print the banner with -c + IP_rc.banner = 0 + if IP_rc.banner: + BANN_P = IP.BANNER_PARTS else: - IP.BANNER = '' + BANN_P = [] - if IP.rc.profile: IP.BANNER += '\nIPython profile: '+IP.rc.profile+'\n' + if IP_rc.profile: BANN_P.append('IPython profile: %s\n' % IP_rc.profile) # add message log (possibly empty) - IP.BANNER += msg.summary + if msg.summary: BANN_P.append(msg.summary) + # Final banner is a string + IP.BANNER = '\n'.join(BANN_P) + + # Assign the IP_rc object as an attribute of IP + IP.rc = IP_rc + # Finalize the IPython instance. This assumes the rc structure is fully + # in place. IP.post_config_initialization() return IP diff --git a/IPython/wildcard.py b/IPython/wildcard.py index 617d14c..c7fb2ff 100644 --- a/IPython/wildcard.py +++ b/IPython/wildcard.py @@ -21,7 +21,6 @@ import re import pprint import exceptions import pdb -import IPython.genutils as genutils def create_typestr2type_dicts(dont_include_in_type2type2str=["lambda"]): """Return dictionaries mapping lower case typename to type objects, from @@ -59,21 +58,21 @@ def is_type(obj,typestr_or_type): else: return False -def show_hidden(str,showhidden=False): - """Return true for strings starting with single _ if showhidden is true.""" - return showhidden or str.startswith("__") or not str.startswith("_") +def show_hidden(str,show_all=False): + """Return true for strings starting with single _ if show_all is true.""" + return show_all or str.startswith("__") or not str.startswith("_") class NameSpace(object): """NameSpace holds the dictionary for a namespace and implements filtering on name and types""" - def __init__(self,obj,namepattern="*",typepattern="all",ignorecase=True, - showhidden=True): - self.showhidden = showhidden #Hide names beginning with single _ + def __init__(self,obj,name_pattern="*",type_pattern="all",ignore_case=True, + show_all=True): + self.show_all = show_all #Hide names beginning with single _ self.object = obj - self.namepattern = namepattern - self.typepattern = typepattern - self.ignorecase = ignorecase + self.name_pattern = name_pattern + self.type_pattern = type_pattern + self.ignore_case = ignore_case # We should only match EXACT dicts here, so DON'T use isinstance() if type(obj) == types.DictType: @@ -84,7 +83,7 @@ class NameSpace(object): def get_ns(self): """Return name space dictionary with objects matching type and name patterns.""" - return self.filter(self.namepattern,self.typepattern) + return self.filter(self.name_pattern,self.type_pattern) ns=property(get_ns) def get_ns_names(self): @@ -93,64 +92,47 @@ class NameSpace(object): ns_names=property(get_ns_names,doc="List of objects in name space that " "match the type and name patterns.") - def filter(self,namepattern,typepattern): + def filter(self,name_pattern,type_pattern): """Return dictionary of filtered namespace.""" - def glob_filter(lista,namepattern,hidehidden,ignorecase): + def glob_filter(lista,name_pattern,hidehidden,ignore_case): """Return list of elements in lista that match pattern.""" - pattern=namepattern.replace("*",".*") - if ignorecase: + pattern=name_pattern.replace("*",".*") + if ignore_case: reg=re.compile(pattern+"$",re.I) else: reg=re.compile(pattern+"$") result=[x for x in lista if reg.match(x) and show_hidden(x,hidehidden)] return result ns=self._ns - #Filter namespace by the namepattern - all=[(x,ns[x]) for x in glob_filter(ns.keys(),namepattern, - self.showhidden,self.ignorecase)] - #Filter namespace by typepattern - all=[(key,obj) for key,obj in all if is_type(obj,typepattern)] + #Filter namespace by the name_pattern + all=[(x,ns[x]) for x in glob_filter(ns.keys(),name_pattern, + self.show_all,self.ignore_case)] + #Filter namespace by type_pattern + all=[(key,obj) for key,obj in all if is_type(obj,type_pattern)] all=dict(all) return all #TODO: Implement dictionary like access to filtered name space? -def list_namespace(namespace,typepattern,filter,ignorecase=False,showhidden=False): - """Return dictionary of all objects in namespace that matches typepattern +def list_namespace(namespace,type_pattern,filter,ignore_case=False,show_all=False): + """Return dictionary of all objects in namespace that matches type_pattern and filter.""" - patternlist=filter.split(".") - if len(patternlist)==1: - ns=NameSpace(namespace,namepattern=patternlist[0],typepattern=typepattern, - ignorecase=ignorecase,showhidden=showhidden) + pattern_list=filter.split(".") + if len(pattern_list)==1: + ns=NameSpace(namespace,name_pattern=pattern_list[0],type_pattern=type_pattern, + ignore_case=ignore_case,show_all=show_all) return ns.ns - if len(patternlist)>1: - #This is where we can change if all objects should be searched or only moduleas - #Just change the typepattern to module to search only modules - ns=NameSpace(namespace, - namepattern=patternlist[0], - typepattern="all",ignorecase=ignorecase,showhidden=showhidden) + else: + # This is where we can change if all objects should be searched or + # only modules. Just change the type_pattern to module to search only + # modules + ns=NameSpace(namespace,name_pattern=pattern_list[0],type_pattern="all", + ignore_case=ignore_case,show_all=show_all) res={} nsdict=ns.ns for name,obj in nsdict.iteritems(): - ns=list_namespace(obj,typepattern,".".join(patternlist[1:]), - ignorecase=ignorecase,showhidden=showhidden) + ns=list_namespace(obj,type_pattern,".".join(pattern_list[1:]), + ignore_case=ignore_case,show_all=show_all) for inner_name,inner_obj in ns.iteritems(): res["%s.%s"%(name,inner_name)]=inner_obj return res - -def choose_namespaces(shell,cmds): - """Returns a list of namespaces modified by arguments.""" - nslist=genutils.mkdict(user=shell.user_ns,internal=shell.internal_ns, - builtin=__builtin__.__dict__,alias=shell.alias_table) - default_list=["user","builtin"] # Should this list be a user option?? - for cmd in cmds: - if cmd[0]=="-": #remove from defaultlist - if cmd[1:] in default_list: - default_list.remove(cmd[1:]) - elif cmd[0]=="+": - if cmd[1:] not in default_list and cmd[1:]in nslist: - default_list.append(cmd[1:]) - else: - if cmd in nslist: - default_list.append(cmd[1:]) - return [nslist[x] for x in default_list] diff --git a/doc/ChangeLog b/doc/ChangeLog index e30fdc6..b69e029 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,18 @@ +2005-11-15 + + * IPython/ipmaker.py (make_IPython): cleanups which should improve + startup time. + + * IPython/iplib.py (runcode): my globals 'fix' for embedded + instances had introduced a bug with globals in normal code. Now + it's working in all cases. + + * IPython/Magic.py (magic_psearch): Finish wildcard cleanup and + API changes. A new ipytonrc option, 'wildcards_case_sensitive' + has been introduced to set the default case sensitivity of the + searches. Users can still select either mode at runtime on a + per-search basis. + 2005-11-13 * IPython/wildcard.py (NameSpace.__init__): fix resolution of