Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Move object inspection machinery out of the magics code.

Later we'll put this into a standalone object, but the least intrusive
change for now is to put it in the main interactive shell object.  At
least now it's not embedded in the magics code, and we can start using
this programatically via the messaging api.
  • Loading branch information...
commit 4e3685be1b53680b1894da6bba96141ed582b123 1 parent 2be9133
Fernando Perez fperez authored
Showing with 136 additions and 132 deletions.
  1. +136 −2 IPython/core/interactiveshell.py
  2. +0 −130 IPython/core/magic.py
138 IPython/core/interactiveshell.py
View
@@ -18,6 +18,7 @@
from __future__ import absolute_import
import __builtin__
+import __future__
import abc
import codeop
import exceptions
@@ -40,7 +41,7 @@
from IPython.core.builtin_trap import BuiltinTrap
from IPython.core.display_trap import DisplayTrap
from IPython.core.displayhook import DisplayHook
-from IPython.core.error import UsageError
+from IPython.core.error import TryNext, UsageError
from IPython.core.extensions import ExtensionManager
from IPython.core.fakemodule import FakeModule, init_fakemod_dict
from IPython.core.inputlist import InputList
@@ -48,7 +49,7 @@
from IPython.core.magic import Magic
from IPython.core.payload import PayloadManager
from IPython.core.plugin import PluginManager
-from IPython.core.prefilter import PrefilterManager
+from IPython.core.prefilter import PrefilterManager, ESC_MAGIC
from IPython.external.Itpl import ItplNS
from IPython.utils import PyColorize
from IPython.utils import io
@@ -1026,6 +1027,139 @@ def push(self, variables, interactive=True):
config_ns[name] = val
#-------------------------------------------------------------------------
+ # Things related to object introspection
+ #-------------------------------------------------------------------------
+ def _ofind(self, oname, namespaces=None):
+ """Find an object in the available namespaces.
+
+ self._ofind(oname) -> dict with keys: found,obj,ospace,ismagic
+
+ Has special code to detect magic functions.
+ """
+ oname = oname.strip()
+ alias_ns = None
+ if namespaces is None:
+ # Namespaces to search in:
+ # Put them in a list. The order is important so that we
+ # find things in the same order that Python finds them.
+ namespaces = [ ('Interactive', self.shell.user_ns),
+ ('IPython internal', self.shell.internal_ns),
+ ('Python builtin', __builtin__.__dict__),
+ ('Alias', self.shell.alias_manager.alias_table),
+ ]
+ alias_ns = self.shell.alias_manager.alias_table
+
+ # initialize results to 'null'
+ found = False; obj = None; ospace = None; ds = None;
+ ismagic = False; isalias = False; parent = None
+
+ # We need to special-case 'print', which as of python2.6 registers as a
+ # function but should only be treated as one if print_function was
+ # loaded with a future import. In this case, just bail.
+ if (oname == 'print' and not (self.shell.compile.compiler.flags &
+ __future__.CO_FUTURE_PRINT_FUNCTION)):
+ return {'found':found, 'obj':obj, 'namespace':ospace,
+ 'ismagic':ismagic, 'isalias':isalias, 'parent':parent}
+
+ # Look for the given name by splitting it in parts. If the head is
+ # found, then we look for all the remaining parts as members, and only
+ # declare success if we can find them all.
+ oname_parts = oname.split('.')
+ oname_head, oname_rest = oname_parts[0],oname_parts[1:]
+ for nsname,ns in namespaces:
+ try:
+ obj = ns[oname_head]
+ except KeyError:
+ continue
+ else:
+ #print 'oname_rest:', oname_rest # dbg
+ for part in oname_rest:
+ try:
+ parent = obj
+ obj = getattr(obj,part)
+ except:
+ # Blanket except b/c some badly implemented objects
+ # allow __getattr__ to raise exceptions other than
+ # AttributeError, which then crashes IPython.
+ break
+ else:
+ # If we finish the for loop (no break), we got all members
+ found = True
+ ospace = nsname
+ if ns == alias_ns:
+ isalias = True
+ break # namespace loop
+
+ # Try to see if it's magic
+ if not found:
+ if oname.startswith(ESC_MAGIC):
+ oname = oname[1:]
+ obj = getattr(self,'magic_'+oname,None)
+ if obj is not None:
+ found = True
+ ospace = 'IPython internal'
+ ismagic = True
+
+ # Last try: special-case some literals like '', [], {}, etc:
+ if not found and oname_head in ["''",'""','[]','{}','()']:
+ 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))
+
+ 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])
+ if info.parent is not None:
+ try:
+ target = getattr(info.parent, '__class__')
+ # The object belongs to a class instance.
+ try:
+ target = getattr(target, path[-1])
+ # The class defines the object.
+ if isinstance(target, property):
+ oname = root + '.__class__.' + path[-1]
+ info = Struct(self._ofind(oname))
+ except AttributeError: pass
+ except AttributeError: pass
+
+ pmethod = getattr(self.shell.inspector,meth)
+ formatter = info.ismagic and self.format_screen or None
+ if meth == 'pdoc':
+ pmethod(info.obj,oname,formatter)
+ elif meth == 'pinfo':
+ pmethod(info.obj,oname,formatter,info,**kw)
+ else:
+ pmethod(info.obj,oname)
+ else:
+ print 'Object `%s` not found.' % oname
+ return 'not found' # so callers can take other action
+
+ #-------------------------------------------------------------------------
# Things related to history management
#-------------------------------------------------------------------------
130 IPython/core/magic.py
View
@@ -207,87 +207,7 @@ def extract_input_slices(self,slices,raw=False):
fin = ini+1
cmds.append(hist[ini:fin])
return cmds
-
- def _ofind(self, oname, namespaces=None):
- """Find an object in the available namespaces.
-
- self._ofind(oname) -> dict with keys: found,obj,ospace,ismagic
-
- Has special code to detect magic functions.
- """
- oname = oname.strip()
- alias_ns = None
- if namespaces is None:
- # Namespaces to search in:
- # Put them in a list. The order is important so that we
- # find things in the same order that Python finds them.
- namespaces = [ ('Interactive', self.shell.user_ns),
- ('IPython internal', self.shell.internal_ns),
- ('Python builtin', __builtin__.__dict__),
- ('Alias', self.shell.alias_manager.alias_table),
- ]
- alias_ns = self.shell.alias_manager.alias_table
-
- # initialize results to 'null'
- found = False; obj = None; ospace = None; ds = None;
- ismagic = False; isalias = False; parent = None
-
- # We need to special-case 'print', which as of python2.6 registers as a
- # function but should only be treated as one if print_function was
- # loaded with a future import. In this case, just bail.
- if (oname == 'print' and not (self.shell.compile.compiler.flags &
- __future__.CO_FUTURE_PRINT_FUNCTION)):
- return {'found':found, 'obj':obj, 'namespace':ospace,
- 'ismagic':ismagic, 'isalias':isalias, 'parent':parent}
-
- # Look for the given name by splitting it in parts. If the head is
- # found, then we look for all the remaining parts as members, and only
- # declare success if we can find them all.
- oname_parts = oname.split('.')
- oname_head, oname_rest = oname_parts[0],oname_parts[1:]
- for nsname,ns in namespaces:
- try:
- obj = ns[oname_head]
- except KeyError:
- continue
- else:
- #print 'oname_rest:', oname_rest # dbg
- for part in oname_rest:
- try:
- parent = obj
- obj = getattr(obj,part)
- except:
- # Blanket except b/c some badly implemented objects
- # allow __getattr__ to raise exceptions other than
- # AttributeError, which then crashes IPython.
- break
- else:
- # If we finish the for loop (no break), we got all members
- found = True
- ospace = nsname
- if ns == alias_ns:
- isalias = True
- break # namespace loop
-
- # Try to see if it's magic
- if not found:
- if oname.startswith(ESC_MAGIC):
- oname = oname[1:]
- obj = getattr(self,'magic_'+oname,None)
- if obj is not None:
- found = True
- ospace = 'IPython internal'
- ismagic = True
-
- # Last try: special-case some literals like '', [], {}, etc:
- if not found and oname_head in ["''",'""','[]','{}','()']:
- obj = eval(oname_head)
- found = True
- ospace = 'Interactive'
- return {'found':found, 'obj':obj, 'namespace':ospace,
- 'ismagic':ismagic, 'isalias':isalias, 'parent':parent}
-
def arg_err(self,func):
"""Print docstring if incorrect arguments were passed"""
print 'Error in arguments:'
@@ -708,56 +628,6 @@ def magic_pfile(self, parameter_s=''):
return
page.page(self.shell.inspector.format(file(filename).read()))
- 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))
-
- 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])
- if info.parent is not None:
- try:
- target = getattr(info.parent, '__class__')
- # The object belongs to a class instance.
- try:
- target = getattr(target, path[-1])
- # The class defines the object.
- if isinstance(target, property):
- oname = root + '.__class__.' + path[-1]
- info = Struct(self._ofind(oname))
- except AttributeError: pass
- except AttributeError: pass
-
- pmethod = getattr(self.shell.inspector,meth)
- formatter = info.ismagic and self.format_screen or None
- if meth == 'pdoc':
- pmethod(info.obj,oname,formatter)
- elif meth == 'pinfo':
- pmethod(info.obj,oname,formatter,info,**kw)
- else:
- pmethod(info.obj,oname)
- else:
- print 'Object `%s` not found.' % oname
- return 'not found' # so callers can take other action
-
def magic_psearch(self, parameter_s=''):
"""Search for object in namespaces by wildcard.
Please sign in to comment.
Something went wrong with that request. Please try again.