From 82a945d8b8e7d705ae9e0af16f4799f615008edd 2010-09-03 08:12:45 From: Fernando Perez Date: 2010-09-03 08:12:45 Subject: [PATCH] Continue restructuring info system, move some standalone code to utils. --- diff --git a/IPython/core/interactiveshell.py b/IPython/core/interactiveshell.py index da3bc70..8cf8824 100644 --- a/IPython/core/interactiveshell.py +++ b/IPython/core/interactiveshell.py @@ -61,7 +61,7 @@ from IPython.utils.path import get_home_dir, get_ipython_dir, HomeDirError from IPython.utils.process import system, getoutput from IPython.utils.strdispatch import StrDispatch from IPython.utils.syspathcontext import prepended_to_syspath -from IPython.utils.text import num_ini_spaces +from IPython.utils.text import num_ini_spaces, format_screen from IPython.utils.traitlets import (Int, Str, CBool, CaselessStrEnum, Enum, List, Unicode, Instance, Type) from IPython.utils.warn import warn, error, fatal @@ -1036,7 +1036,15 @@ class InteractiveShell(Configurable, Magic): Has special code to detect magic functions. """ - oname = oname.strip() + #oname = oname.strip() + #print '1- oname: <%r>' % oname # dbg + try: + oname = oname.strip().encode('ascii') + #print '2- oname: <%r>' % oname # dbg + except UnicodeEncodeError: + print 'Python identifiers can only contain ascii characters.' + return dict(found=False) + alias_ns = None if namespaces is None: # Namespaces to search in: @@ -1105,32 +1113,13 @@ class InteractiveShell(Configurable, Magic): obj = eval(oname_head) found = True ospace = 'Interactive' - + return {'found':found, 'obj':obj, 'namespace':ospace, 'ismagic':ismagic, 'isalias':isalias, 'parent':parent} - def _inspect(self,meth,oname,namespaces=None,**kw): - """Generic interface to the inspector system. - - This function is meant to be called by pdef, pdoc & friends.""" - - #oname = oname.strip() - #print '1- oname: <%r>' % oname # dbg - try: - oname = oname.strip().encode('ascii') - #print '2- oname: <%r>' % oname # dbg - except UnicodeEncodeError: - print 'Python identifiers can only contain ascii characters.' - return 'not found' - - info = Struct(self._ofind(oname, namespaces)) - + def _ofind_property(self, oname, info): + """Second part of object finding, to look for property details.""" if info.found: - try: - IPython.utils.generics.inspect_object(info.obj) - return - except TryNext: - pass # Get the docstring of the class property if it exists. path = oname.split('.') root = '.'.join(path[:-1]) @@ -1146,18 +1135,36 @@ class InteractiveShell(Configurable, Magic): info = Struct(self._ofind(oname)) except AttributeError: pass except AttributeError: pass - - pmethod = getattr(self.inspector,meth) - formatter = info.ismagic and self.format_screen or None + + # We return either the new info or the unmodified input if the object + # hadn't been found + return info + + def _object_find(self, oname, namespaces=None): + """Find an object and return a struct with info about it.""" + inf = Struct(self._ofind(oname, namespaces)) + return Struct(self._ofind_property(oname, inf)) + + def _inspect(self, meth, oname, namespaces=None, **kw): + """Generic interface to the inspector system. + + This function is meant to be called by pdef, pdoc & friends.""" + info = self._object_find(oname) + if info.found: + pmethod = getattr(self.inspector, meth) + formatter = format_screen if info.ismagic else None if meth == 'pdoc': - pmethod(info.obj,oname,formatter) + pmethod(info.obj, oname, formatter) elif meth == 'pinfo': - pmethod(info.obj,oname,formatter,info,**kw) + pmethod(info.obj, oname, formatter, info, **kw) else: - pmethod(info.obj,oname) + pmethod(info.obj, oname) else: print 'Object `%s` not found.' % oname return 'not found' # so callers can take other action + + def object_inspect(self, oname): + info = self._object_find(oname) #------------------------------------------------------------------------- # Things related to history management diff --git a/IPython/core/magic.py b/IPython/core/magic.py index d72a4f0..f86443f 100644 --- a/IPython/core/magic.py +++ b/IPython/core/magic.py @@ -62,7 +62,7 @@ import IPython.utils.io from IPython.utils.path import get_py_filename from IPython.utils.process import arg_split, abbrev_cwd from IPython.utils.terminal import set_term_title -from IPython.utils.text import LSString, SList, StringTypes +from IPython.utils.text import LSString, SList, StringTypes, format_screen from IPython.utils.timing import clock, clock2 from IPython.utils.warn import warn, error from IPython.utils.ipstruct import Struct @@ -240,15 +240,6 @@ python-profiler package from non-free.""") strng = newline_re.sub(r'\\textbackslash{}n',strng) return strng - def format_screen(self,strng): - """Format a string for screen printing. - - This removes some latex-type format codes.""" - # Paragraph continue - par_re = re.compile(r'\\$',re.MULTILINE) - strng = par_re.sub('',strng) - return strng - def parse_options(self,arg_str,opt_str,*long_opts,**kw): """Parse options passed to an argument string. @@ -387,7 +378,7 @@ python-profiler package from non-free.""") print self.format_latex(magic_docs) return else: - magic_docs = self.format_screen(magic_docs) + magic_docs = format_screen(magic_docs) if mode == 'brief': return magic_docs @@ -585,8 +576,8 @@ Currently the magic system has the following functions:\n""" if "*" in oname: self.magic_psearch(oname) else: - self._inspect('pinfo', oname, detail_level=detail_level, - namespaces=namespaces) + self.shell._inspect('pinfo', oname, detail_level=detail_level, + namespaces=namespaces) def magic_pdef(self, parameter_s='', namespaces=None): """Print the definition header for any callable object. diff --git a/IPython/core/oinspect.py b/IPython/core/oinspect.py index 5d19236..463d0f4 100644 --- a/IPython/core/oinspect.py +++ b/IPython/core/oinspect.py @@ -200,7 +200,7 @@ class Inspector: self.str_detail_level = str_detail_level self.set_active_scheme(scheme) - def __getdef(self,obj,oname=''): + def _getdef(self,obj,oname=''): """Return the definition header for any callable object. If any exception is generated, None is returned instead and the @@ -245,7 +245,7 @@ class Inspector: elif type(obj) is types.InstanceType: obj = obj.__call__ - output = self.__getdef(obj,oname) + output = self._getdef(obj,oname) if output is None: self.noinfo('definition header',oname) else: @@ -438,7 +438,7 @@ class Inspector: binary_file = True # reconstruct the function definition and print it: - defln = self.__getdef(obj,oname) + defln = self._getdef(obj,oname) if defln: out.write(header('Definition:\t')+self.format(defln)) @@ -478,7 +478,7 @@ class Inspector: except AttributeError: init_def = init_ds = None else: - init_def = self.__getdef(obj_init,oname) + init_def = self._getdef(obj_init,oname) init_ds = getdoc(obj_init) # Skip Python's auto-generated docstrings if init_ds and \ @@ -532,7 +532,7 @@ class Inspector: # Call form docstring for callable instances if hasattr(obj,'__call__'): #out.writeln(header('Callable:\t')+'Yes') - call_def = self.__getdef(obj.__call__,oname) + call_def = self._getdef(obj.__call__,oname) #if call_def is None: # out.writeln(header('Call def:\t')+ # 'Calling definition not available.') diff --git a/IPython/utils/text.py b/IPython/utils/text.py index 45ec602..38825d8 100644 --- a/IPython/utils/text.py +++ b/IPython/utils/text.py @@ -487,3 +487,13 @@ def num_ini_spaces(strng): else: return 0 + +def format_screen(strng): + """Format a string for screen printing. + + This removes some latex-type format codes.""" + # Paragraph continue + par_re = re.compile(r'\\$',re.MULTILINE) + strng = par_re.sub('',strng) + return strng +