##// END OF EJS Templates
Namespace fixes for embedded instances, as well as tab-complete enhancements...
fperez -
Show More
@@ -78,31 +78,40 b' used, and this module (and the readline module) are silently inactive.'
78 78 #
79 79 #*****************************************************************************
80 80
81 import readline
82 81 import __builtin__
83 82 import __main__
83 import readline
84 import keyword
85 import types
84 86
85 87 __all__ = ["Completer"]
86 88
87 89 class Completer:
88 def __init__(self, namespace = None):
90 def __init__(self,namespace=None,global_namespace=None):
89 91 """Create a new completer for the command line.
90 92
91 Completer([namespace]) -> completer instance.
93 Completer([namespace,global_namespace]) -> completer instance.
92 94
93 95 If unspecified, the default namespace where completions are performed
94 96 is __main__ (technically, __main__.__dict__). Namespaces should be
95 97 given as dictionaries.
96 98
99 An optional second namespace can be given. This allows the completer
100 to handle cases where both the local and global scopes need to be
101 distinguished.
102
97 103 Completer instances should be used as the completion mechanism of
98 104 readline via the set_completer() call:
99 105
100 106 readline.set_completer(Completer(my_namespace).complete)
101 107 """
102 108
103 if namespace and type(namespace) != type({}):
109 if namespace and type(namespace) != types.DictType:
104 110 raise TypeError,'namespace must be a dictionary'
105 111
112 if global_namespace and type(global_namespace) != types.DictType:
113 raise TypeError,'global_namespace must be a dictionary'
114
106 115 # Don't bind to namespace quite yet, but flag whether the user wants a
107 116 # specific namespace or to use __main__.__dict__. This will allow us
108 117 # to bind to __main__.__dict__ at completion time, not now.
@@ -112,6 +121,12 b' class Completer:'
112 121 self.use_main_ns = 0
113 122 self.namespace = namespace
114 123
124 # The global namespace, if given, can be bound directly
125 if global_namespace is None:
126 self.global_namespace = {}
127 else:
128 self.global_namespace = global_namespace
129
115 130 def complete(self, text, state):
116 131 """Return the next possible completion for 'text'.
117 132
@@ -136,27 +151,29 b' class Completer:'
136 151 """Compute matches when text is a simple name.
137 152
138 153 Return a list of all keywords, built-in functions and names currently
139 defined in self.namespace that match.
154 defined in self.namespace or self.global_namespace that match.
140 155
141 156 """
142 import keyword
143 157 matches = []
158 match_append = matches.append
144 159 n = len(text)
145 for list in [keyword.kwlist,
146 __builtin__.__dict__.keys(),
147 self.namespace.keys()]:
148 for word in list:
160 for lst in [keyword.kwlist,
161 __builtin__.__dict__.keys(),
162 self.namespace.keys(),
163 self.global_namespace.keys()]:
164 for word in lst:
149 165 if word[:n] == text and word != "__builtins__":
150 matches.append(word)
166 match_append(word)
151 167 return matches
152 168
153 169 def attr_matches(self, text):
154 170 """Compute matches when text contains a dot.
155 171
156 172 Assuming the text is of the form NAME.NAME....[NAME], and is
157 evaluatable in self.namespace, it will be evaluated and its attributes
158 (as revealed by dir()) are used as possible completions. (For class
159 instances, class members are are also considered.)
173 evaluatable in self.namespace or self.global_namespace, it will be
174 evaluated and its attributes (as revealed by dir()) are used as
175 possible completions. (For class instances, class members are are
176 also considered.)
160 177
161 178 WARNING: this can still invoke arbitrary C code, if an object
162 179 with a __getattr__ hook is evaluated.
@@ -170,7 +187,12 b' class Completer:'
170 187 if not m:
171 188 return []
172 189 expr, attr = m.group(1, 3)
173 object = eval(expr, self.namespace)
190 print 'expr:',expr # dbg
191 try:
192 object = eval(expr, self.namespace)
193 except:
194 object = eval(expr, self.global_namespace)
195 print 'obj:',object # dbg
174 196 words = [w for w in dir(object) if isinstance(w, basestring)]
175 197 if hasattr(object,'__class__'):
176 198 words.append('__class__')
@@ -4,7 +4,7 b''
4 4 All the matplotlib support code was co-developed with John Hunter,
5 5 matplotlib's author.
6 6
7 $Id: Shell.py 927 2005-12-08 23:19:59Z fperez $"""
7 $Id: Shell.py 952 2005-12-26 17:51:33Z fperez $"""
8 8
9 9 #*****************************************************************************
10 10 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
@@ -212,8 +212,8 b' class IPShellEmbed:'
212 212
213 213 If you need to manually"""
214 214
215 if dummy not in [0,1]:
216 raise ValueError,'dummy parameter must be 0 or 1'
215 if dummy not in [0,1,False,True]:
216 raise ValueError,'dummy parameter must be boolean'
217 217 self.__dummy_mode = dummy
218 218
219 219 def get_dummy_mode(self):
@@ -874,12 +874,13 b' def start():'
874 874
875 875 global USE_TK
876 876 # Crude sys.argv hack to extract the threading options.
877 if len(sys.argv) > 1:
878 if len(sys.argv) > 2:
879 arg2 = sys.argv[2]
877 argv = sys.argv
878 if len(argv) > 1:
879 if len(argv) > 2:
880 arg2 = argv[2]
880 881 if arg2.endswith('-tk'):
881 882 USE_TK = True
882 arg1 = sys.argv[1]
883 arg1 = argv[1]
883 884 if arg1.endswith('-gthread'):
884 885 shell = IPShellGTK
885 886 elif arg1.endswith( '-qthread' ):
@@ -6,7 +6,7 b' Requires Python 2.1 or newer.'
6 6
7 7 This file contains all the classes and helper functions specific to IPython.
8 8
9 $Id: iplib.py 951 2005-12-25 00:57:24Z fperez $
9 $Id: iplib.py 952 2005-12-26 17:51:33Z fperez $
10 10 """
11 11
12 12 #*****************************************************************************
@@ -171,7 +171,8 b' try:'
171 171 class MagicCompleter(FlexCompleter.Completer):
172 172 """Extension of the completer class to work on %-prefixed lines."""
173 173
174 def __init__(self,shell,namespace=None,omit__names=0,alias_table=None):
174 def __init__(self,shell,namespace=None,global_namespace=None,
175 omit__names=0,alias_table=None):
175 176 """MagicCompleter() -> completer
176 177
177 178 Return a completer object suitable for use by the readline library
@@ -184,6 +185,10 b' try:'
184 185 only be accessed via the ipython instance.
185 186
186 187 - namespace: an optional dict where completions are performed.
188
189 - global_namespace: secondary optional dict for completions, to
190 handle cases (such as IPython embedded inside functions) where
191 both Python scopes are visible.
187 192
188 193 - The optional omit__names parameter sets the completer to omit the
189 194 'magic' names (__magicname__) for python objects unless the text
@@ -225,13 +230,14 b' try:'
225 230 """Return all possible completions for the benefit of emacs."""
226 231
227 232 completions = []
233 comp_append = completions.append
228 234 try:
229 235 for i in xrange(sys.maxint):
230 236 res = self.complete(text, i)
231 237
232 238 if not res: break
233 239
234 completions.append(res)
240 comp_append(res)
235 241 #XXX workaround for ``notDefined.<tab>``
236 242 except NameError:
237 243 pass
@@ -622,13 +628,22 b' class InteractiveShell(code.InteractiveConsole, Logger, Magic):'
622 628 # instance has its own private namespace, so we can't go shoving
623 629 # everything into __main__.
624 630
625 try:
626 main_name = self.user_ns['__name__']
627 except KeyError:
628 raise KeyError,'user_ns dictionary MUST have a "__name__" key'
629 else:
630 #print "pickle hack in place" # dbg
631 sys.modules[main_name] = FakeModule(self.user_ns)
631 # note, however, that we should only do this for non-embedded
632 # ipythons, which really mimic the __main__.__dict__ with their own
633 # namespace. Embedded instances, on the other hand, should not do
634 # this because they need to manage the user local/global namespaces
635 # only, but they live within a 'normal' __main__ (meaning, they
636 # shouldn't overtake the execution environment of the script they're
637 # embedded in).
638
639 if not embedded:
640 try:
641 main_name = self.user_ns['__name__']
642 except KeyError:
643 raise KeyError,'user_ns dictionary MUST have a "__name__" key'
644 else:
645 #print "pickle hack in place" # dbg
646 sys.modules[main_name] = FakeModule(self.user_ns)
632 647
633 648 # List of input with multi-line handling.
634 649 # Fill its zero entry, user counter starts at 1
@@ -972,11 +987,11 b' class InteractiveShell(code.InteractiveConsole, Logger, Magic):'
972 987
973 988 def set_completer_frame(self, frame):
974 989 if frame:
975 ns = frame.f_globals.copy()
976 ns.update(frame.f_locals)
977 self.Completer.namespace = ns
990 self.Completer.namespace = frame.f_locals
991 self.Completer.global_namespace = frame.f_globals
978 992 else:
979 993 self.Completer.namespace = self.user_ns
994 self.Completer.global_namespace = self.user_global_ns
980 995
981 996 def post_config_initialization(self):
982 997 """Post configuration init method
@@ -1234,6 +1249,7 b' want to merge them back into the new files.""" % locals()'
1234 1249 import readline
1235 1250 self.Completer = MagicCompleter(self,
1236 1251 self.user_ns,
1252 self.user_global_ns,
1237 1253 self.rc.readline_omit__names,
1238 1254 self.alias_table)
1239 1255 except ImportError,NameError:
@@ -1427,6 +1443,10 b' want to merge them back into the new files.""" % locals()'
1427 1443 if local_ns is None and global_ns is None:
1428 1444 self.user_global_ns.update(__main__.__dict__)
1429 1445
1446 # make sure the tab-completer has the correct frame information, so it
1447 # actually completes using the frame's locals/globals
1448 self.set_completer_frame(call_frame)
1449
1430 1450 self.interact(header)
1431 1451
1432 1452 def interact(self, banner=None):
@@ -1914,7 +1934,7 b' want to merge them back into the new files.""" % locals()'
1914 1934 cmd = '%sipmagic("%s")' % (pre,esc_quotes('%s %s' % (iFun,theRest)))
1915 1935 self.log(cmd,continue_prompt)
1916 1936 self.update_cache(line)
1917 #print 'in handle_magic, cmd=<%s>' % cmd # dbg
1937 print 'in handle_magic, cmd=<%s>' % cmd # dbg
1918 1938 return cmd
1919 1939
1920 1940 def handle_auto(self, line, continue_prompt=None,
@@ -1,3 +1,26 b''
1 2005-12-26 Fernando Perez <Fernando.Perez@colorado.edu>
2
3 * IPython/FlexCompleter.py (Completer.__init__): Added support for
4 distinct local and global namespaces in the completer API. This
5 change allows us top properly handle completion with distinct
6 scopes, including in embedded instances (this had never really
7 worked correctly).
8
9 Note: this introduces a change in the constructor for
10 MagicCompleter, as a new global_namespace parameter is now the
11 second argument (the others were bumped one position).
12
13 2005-12-25 Fernando Perez <Fernando.Perez@colorado.edu>
14
15 * IPython/iplib.py (embed_mainloop): fix tab-completion in
16 embedded instances (which can be done now thanks to Vivian's
17 frame-handling fixes for pdb).
18 (InteractiveShell.__init__): Fix namespace handling problem in
19 embedded instances. We were overwriting __main__ unconditionally,
20 and this should only be done for 'full' (non-embedded) IPython;
21 embedded instances must respect the caller's __main__. Thanks to
22 a bug report by Yaroslav Bulatov <yaroslavvb-AT-gmail.com>
23
1 24 2005-12-24 Fernando Perez <Fernando.Perez@colorado.edu>
2 25
3 26 * setup.py: added download_url to setup(). This registers the
General Comments 0
You need to be logged in to leave comments. Login now