##// END OF EJS Templates
Move object inspection machinery out of the magics code....
Fernando Perez -
Show More
@@ -18,6 +18,7 b' from __future__ import with_statement'
18 from __future__ import absolute_import
18 from __future__ import absolute_import
19
19
20 import __builtin__
20 import __builtin__
21 import __future__
21 import abc
22 import abc
22 import codeop
23 import codeop
23 import exceptions
24 import exceptions
@@ -40,7 +41,7 b' from IPython.core.alias import AliasManager'
40 from IPython.core.builtin_trap import BuiltinTrap
41 from IPython.core.builtin_trap import BuiltinTrap
41 from IPython.core.display_trap import DisplayTrap
42 from IPython.core.display_trap import DisplayTrap
42 from IPython.core.displayhook import DisplayHook
43 from IPython.core.displayhook import DisplayHook
43 from IPython.core.error import UsageError
44 from IPython.core.error import TryNext, UsageError
44 from IPython.core.extensions import ExtensionManager
45 from IPython.core.extensions import ExtensionManager
45 from IPython.core.fakemodule import FakeModule, init_fakemod_dict
46 from IPython.core.fakemodule import FakeModule, init_fakemod_dict
46 from IPython.core.inputlist import InputList
47 from IPython.core.inputlist import InputList
@@ -48,7 +49,7 b' from IPython.core.logger import Logger'
48 from IPython.core.magic import Magic
49 from IPython.core.magic import Magic
49 from IPython.core.payload import PayloadManager
50 from IPython.core.payload import PayloadManager
50 from IPython.core.plugin import PluginManager
51 from IPython.core.plugin import PluginManager
51 from IPython.core.prefilter import PrefilterManager
52 from IPython.core.prefilter import PrefilterManager, ESC_MAGIC
52 from IPython.external.Itpl import ItplNS
53 from IPython.external.Itpl import ItplNS
53 from IPython.utils import PyColorize
54 from IPython.utils import PyColorize
54 from IPython.utils import io
55 from IPython.utils import io
@@ -1026,6 +1027,139 b' class InteractiveShell(Configurable, Magic):'
1026 config_ns[name] = val
1027 config_ns[name] = val
1027
1028
1028 #-------------------------------------------------------------------------
1029 #-------------------------------------------------------------------------
1030 # Things related to object introspection
1031 #-------------------------------------------------------------------------
1032 def _ofind(self, oname, namespaces=None):
1033 """Find an object in the available namespaces.
1034
1035 self._ofind(oname) -> dict with keys: found,obj,ospace,ismagic
1036
1037 Has special code to detect magic functions.
1038 """
1039 oname = oname.strip()
1040 alias_ns = None
1041 if namespaces is None:
1042 # Namespaces to search in:
1043 # Put them in a list. The order is important so that we
1044 # find things in the same order that Python finds them.
1045 namespaces = [ ('Interactive', self.shell.user_ns),
1046 ('IPython internal', self.shell.internal_ns),
1047 ('Python builtin', __builtin__.__dict__),
1048 ('Alias', self.shell.alias_manager.alias_table),
1049 ]
1050 alias_ns = self.shell.alias_manager.alias_table
1051
1052 # initialize results to 'null'
1053 found = False; obj = None; ospace = None; ds = None;
1054 ismagic = False; isalias = False; parent = None
1055
1056 # We need to special-case 'print', which as of python2.6 registers as a
1057 # function but should only be treated as one if print_function was
1058 # loaded with a future import. In this case, just bail.
1059 if (oname == 'print' and not (self.shell.compile.compiler.flags &
1060 __future__.CO_FUTURE_PRINT_FUNCTION)):
1061 return {'found':found, 'obj':obj, 'namespace':ospace,
1062 'ismagic':ismagic, 'isalias':isalias, 'parent':parent}
1063
1064 # Look for the given name by splitting it in parts. If the head is
1065 # found, then we look for all the remaining parts as members, and only
1066 # declare success if we can find them all.
1067 oname_parts = oname.split('.')
1068 oname_head, oname_rest = oname_parts[0],oname_parts[1:]
1069 for nsname,ns in namespaces:
1070 try:
1071 obj = ns[oname_head]
1072 except KeyError:
1073 continue
1074 else:
1075 #print 'oname_rest:', oname_rest # dbg
1076 for part in oname_rest:
1077 try:
1078 parent = obj
1079 obj = getattr(obj,part)
1080 except:
1081 # Blanket except b/c some badly implemented objects
1082 # allow __getattr__ to raise exceptions other than
1083 # AttributeError, which then crashes IPython.
1084 break
1085 else:
1086 # If we finish the for loop (no break), we got all members
1087 found = True
1088 ospace = nsname
1089 if ns == alias_ns:
1090 isalias = True
1091 break # namespace loop
1092
1093 # Try to see if it's magic
1094 if not found:
1095 if oname.startswith(ESC_MAGIC):
1096 oname = oname[1:]
1097 obj = getattr(self,'magic_'+oname,None)
1098 if obj is not None:
1099 found = True
1100 ospace = 'IPython internal'
1101 ismagic = True
1102
1103 # Last try: special-case some literals like '', [], {}, etc:
1104 if not found and oname_head in ["''",'""','[]','{}','()']:
1105 obj = eval(oname_head)
1106 found = True
1107 ospace = 'Interactive'
1108
1109 return {'found':found, 'obj':obj, 'namespace':ospace,
1110 'ismagic':ismagic, 'isalias':isalias, 'parent':parent}
1111
1112 def _inspect(self,meth,oname,namespaces=None,**kw):
1113 """Generic interface to the inspector system.
1114
1115 This function is meant to be called by pdef, pdoc & friends."""
1116
1117 #oname = oname.strip()
1118 #print '1- oname: <%r>' % oname # dbg
1119 try:
1120 oname = oname.strip().encode('ascii')
1121 #print '2- oname: <%r>' % oname # dbg
1122 except UnicodeEncodeError:
1123 print 'Python identifiers can only contain ascii characters.'
1124 return 'not found'
1125
1126 info = Struct(self._ofind(oname, namespaces))
1127
1128 if info.found:
1129 try:
1130 IPython.utils.generics.inspect_object(info.obj)
1131 return
1132 except TryNext:
1133 pass
1134 # Get the docstring of the class property if it exists.
1135 path = oname.split('.')
1136 root = '.'.join(path[:-1])
1137 if info.parent is not None:
1138 try:
1139 target = getattr(info.parent, '__class__')
1140 # The object belongs to a class instance.
1141 try:
1142 target = getattr(target, path[-1])
1143 # The class defines the object.
1144 if isinstance(target, property):
1145 oname = root + '.__class__.' + path[-1]
1146 info = Struct(self._ofind(oname))
1147 except AttributeError: pass
1148 except AttributeError: pass
1149
1150 pmethod = getattr(self.shell.inspector,meth)
1151 formatter = info.ismagic and self.format_screen or None
1152 if meth == 'pdoc':
1153 pmethod(info.obj,oname,formatter)
1154 elif meth == 'pinfo':
1155 pmethod(info.obj,oname,formatter,info,**kw)
1156 else:
1157 pmethod(info.obj,oname)
1158 else:
1159 print 'Object `%s` not found.' % oname
1160 return 'not found' # so callers can take other action
1161
1162 #-------------------------------------------------------------------------
1029 # Things related to history management
1163 # Things related to history management
1030 #-------------------------------------------------------------------------
1164 #-------------------------------------------------------------------------
1031
1165
@@ -207,87 +207,7 b' python-profiler package from non-free.""")'
207 fin = ini+1
207 fin = ini+1
208 cmds.append(hist[ini:fin])
208 cmds.append(hist[ini:fin])
209 return cmds
209 return cmds
210
211 def _ofind(self, oname, namespaces=None):
212 """Find an object in the available namespaces.
213
214 self._ofind(oname) -> dict with keys: found,obj,ospace,ismagic
215
216 Has special code to detect magic functions.
217 """
218 oname = oname.strip()
219 alias_ns = None
220 if namespaces is None:
221 # Namespaces to search in:
222 # Put them in a list. The order is important so that we
223 # find things in the same order that Python finds them.
224 namespaces = [ ('Interactive', self.shell.user_ns),
225 ('IPython internal', self.shell.internal_ns),
226 ('Python builtin', __builtin__.__dict__),
227 ('Alias', self.shell.alias_manager.alias_table),
228 ]
229 alias_ns = self.shell.alias_manager.alias_table
230
231 # initialize results to 'null'
232 found = False; obj = None; ospace = None; ds = None;
233 ismagic = False; isalias = False; parent = None
234
235 # We need to special-case 'print', which as of python2.6 registers as a
236 # function but should only be treated as one if print_function was
237 # loaded with a future import. In this case, just bail.
238 if (oname == 'print' and not (self.shell.compile.compiler.flags &
239 __future__.CO_FUTURE_PRINT_FUNCTION)):
240 return {'found':found, 'obj':obj, 'namespace':ospace,
241 'ismagic':ismagic, 'isalias':isalias, 'parent':parent}
242
243 # Look for the given name by splitting it in parts. If the head is
244 # found, then we look for all the remaining parts as members, and only
245 # declare success if we can find them all.
246 oname_parts = oname.split('.')
247 oname_head, oname_rest = oname_parts[0],oname_parts[1:]
248 for nsname,ns in namespaces:
249 try:
250 obj = ns[oname_head]
251 except KeyError:
252 continue
253 else:
254 #print 'oname_rest:', oname_rest # dbg
255 for part in oname_rest:
256 try:
257 parent = obj
258 obj = getattr(obj,part)
259 except:
260 # Blanket except b/c some badly implemented objects
261 # allow __getattr__ to raise exceptions other than
262 # AttributeError, which then crashes IPython.
263 break
264 else:
265 # If we finish the for loop (no break), we got all members
266 found = True
267 ospace = nsname
268 if ns == alias_ns:
269 isalias = True
270 break # namespace loop
271
272 # Try to see if it's magic
273 if not found:
274 if oname.startswith(ESC_MAGIC):
275 oname = oname[1:]
276 obj = getattr(self,'magic_'+oname,None)
277 if obj is not None:
278 found = True
279 ospace = 'IPython internal'
280 ismagic = True
281
282 # Last try: special-case some literals like '', [], {}, etc:
283 if not found and oname_head in ["''",'""','[]','{}','()']:
284 obj = eval(oname_head)
285 found = True
286 ospace = 'Interactive'
287
210
288 return {'found':found, 'obj':obj, 'namespace':ospace,
289 'ismagic':ismagic, 'isalias':isalias, 'parent':parent}
290
291 def arg_err(self,func):
211 def arg_err(self,func):
292 """Print docstring if incorrect arguments were passed"""
212 """Print docstring if incorrect arguments were passed"""
293 print 'Error in arguments:'
213 print 'Error in arguments:'
@@ -708,56 +628,6 b' Currently the magic system has the following functions:\\n"""'
708 return
628 return
709 page.page(self.shell.inspector.format(file(filename).read()))
629 page.page(self.shell.inspector.format(file(filename).read()))
710
630
711 def _inspect(self,meth,oname,namespaces=None,**kw):
712 """Generic interface to the inspector system.
713
714 This function is meant to be called by pdef, pdoc & friends."""
715
716 #oname = oname.strip()
717 #print '1- oname: <%r>' % oname # dbg
718 try:
719 oname = oname.strip().encode('ascii')
720 #print '2- oname: <%r>' % oname # dbg
721 except UnicodeEncodeError:
722 print 'Python identifiers can only contain ascii characters.'
723 return 'not found'
724
725 info = Struct(self._ofind(oname, namespaces))
726
727 if info.found:
728 try:
729 IPython.utils.generics.inspect_object(info.obj)
730 return
731 except TryNext:
732 pass
733 # Get the docstring of the class property if it exists.
734 path = oname.split('.')
735 root = '.'.join(path[:-1])
736 if info.parent is not None:
737 try:
738 target = getattr(info.parent, '__class__')
739 # The object belongs to a class instance.
740 try:
741 target = getattr(target, path[-1])
742 # The class defines the object.
743 if isinstance(target, property):
744 oname = root + '.__class__.' + path[-1]
745 info = Struct(self._ofind(oname))
746 except AttributeError: pass
747 except AttributeError: pass
748
749 pmethod = getattr(self.shell.inspector,meth)
750 formatter = info.ismagic and self.format_screen or None
751 if meth == 'pdoc':
752 pmethod(info.obj,oname,formatter)
753 elif meth == 'pinfo':
754 pmethod(info.obj,oname,formatter,info,**kw)
755 else:
756 pmethod(info.obj,oname)
757 else:
758 print 'Object `%s` not found.' % oname
759 return 'not found' # so callers can take other action
760
761 def magic_psearch(self, parameter_s=''):
631 def magic_psearch(self, parameter_s=''):
762 """Search for object in namespaces by wildcard.
632 """Search for object in namespaces by wildcard.
763
633
General Comments 0
You need to be logged in to leave comments. Login now