##// 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 import __builtin__
81 import __builtin__
83 import __main__
82 import __main__
83 import readline
84 import keyword
85 import types
84
86
85 __all__ = ["Completer"]
87 __all__ = ["Completer"]
86
88
87 class Completer:
89 class Completer:
88 def __init__(self, namespace = None):
90 def __init__(self,namespace=None,global_namespace=None):
89 """Create a new completer for the command line.
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 If unspecified, the default namespace where completions are performed
95 If unspecified, the default namespace where completions are performed
94 is __main__ (technically, __main__.__dict__). Namespaces should be
96 is __main__ (technically, __main__.__dict__). Namespaces should be
95 given as dictionaries.
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 Completer instances should be used as the completion mechanism of
103 Completer instances should be used as the completion mechanism of
98 readline via the set_completer() call:
104 readline via the set_completer() call:
99
105
100 readline.set_completer(Completer(my_namespace).complete)
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 raise TypeError,'namespace must be a dictionary'
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 # Don't bind to namespace quite yet, but flag whether the user wants a
115 # Don't bind to namespace quite yet, but flag whether the user wants a
107 # specific namespace or to use __main__.__dict__. This will allow us
116 # specific namespace or to use __main__.__dict__. This will allow us
108 # to bind to __main__.__dict__ at completion time, not now.
117 # to bind to __main__.__dict__ at completion time, not now.
@@ -112,6 +121,12 b' class Completer:'
112 self.use_main_ns = 0
121 self.use_main_ns = 0
113 self.namespace = namespace
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 def complete(self, text, state):
130 def complete(self, text, state):
116 """Return the next possible completion for 'text'.
131 """Return the next possible completion for 'text'.
117
132
@@ -136,27 +151,29 b' class Completer:'
136 """Compute matches when text is a simple name.
151 """Compute matches when text is a simple name.
137
152
138 Return a list of all keywords, built-in functions and names currently
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 matches = []
157 matches = []
158 match_append = matches.append
144 n = len(text)
159 n = len(text)
145 for list in [keyword.kwlist,
160 for lst in [keyword.kwlist,
146 __builtin__.__dict__.keys(),
161 __builtin__.__dict__.keys(),
147 self.namespace.keys()]:
162 self.namespace.keys(),
148 for word in list:
163 self.global_namespace.keys()]:
164 for word in lst:
149 if word[:n] == text and word != "__builtins__":
165 if word[:n] == text and word != "__builtins__":
150 matches.append(word)
166 match_append(word)
151 return matches
167 return matches
152
168
153 def attr_matches(self, text):
169 def attr_matches(self, text):
154 """Compute matches when text contains a dot.
170 """Compute matches when text contains a dot.
155
171
156 Assuming the text is of the form NAME.NAME....[NAME], and is
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
173 evaluatable in self.namespace or self.global_namespace, it will be
158 (as revealed by dir()) are used as possible completions. (For class
174 evaluated and its attributes (as revealed by dir()) are used as
159 instances, class members are are also considered.)
175 possible completions. (For class instances, class members are are
176 also considered.)
160
177
161 WARNING: this can still invoke arbitrary C code, if an object
178 WARNING: this can still invoke arbitrary C code, if an object
162 with a __getattr__ hook is evaluated.
179 with a __getattr__ hook is evaluated.
@@ -170,7 +187,12 b' class Completer:'
170 if not m:
187 if not m:
171 return []
188 return []
172 expr, attr = m.group(1, 3)
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 words = [w for w in dir(object) if isinstance(w, basestring)]
196 words = [w for w in dir(object) if isinstance(w, basestring)]
175 if hasattr(object,'__class__'):
197 if hasattr(object,'__class__'):
176 words.append('__class__')
198 words.append('__class__')
@@ -4,7 +4,7 b''
4 All the matplotlib support code was co-developed with John Hunter,
4 All the matplotlib support code was co-developed with John Hunter,
5 matplotlib's author.
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 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
10 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
@@ -212,8 +212,8 b' class IPShellEmbed:'
212
212
213 If you need to manually"""
213 If you need to manually"""
214
214
215 if dummy not in [0,1]:
215 if dummy not in [0,1,False,True]:
216 raise ValueError,'dummy parameter must be 0 or 1'
216 raise ValueError,'dummy parameter must be boolean'
217 self.__dummy_mode = dummy
217 self.__dummy_mode = dummy
218
218
219 def get_dummy_mode(self):
219 def get_dummy_mode(self):
@@ -874,12 +874,13 b' def start():'
874
874
875 global USE_TK
875 global USE_TK
876 # Crude sys.argv hack to extract the threading options.
876 # Crude sys.argv hack to extract the threading options.
877 if len(sys.argv) > 1:
877 argv = sys.argv
878 if len(sys.argv) > 2:
878 if len(argv) > 1:
879 arg2 = sys.argv[2]
879 if len(argv) > 2:
880 arg2 = argv[2]
880 if arg2.endswith('-tk'):
881 if arg2.endswith('-tk'):
881 USE_TK = True
882 USE_TK = True
882 arg1 = sys.argv[1]
883 arg1 = argv[1]
883 if arg1.endswith('-gthread'):
884 if arg1.endswith('-gthread'):
884 shell = IPShellGTK
885 shell = IPShellGTK
885 elif arg1.endswith( '-qthread' ):
886 elif arg1.endswith( '-qthread' ):
@@ -6,7 +6,7 b' Requires Python 2.1 or newer.'
6
6
7 This file contains all the classes and helper functions specific to IPython.
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 class MagicCompleter(FlexCompleter.Completer):
171 class MagicCompleter(FlexCompleter.Completer):
172 """Extension of the completer class to work on %-prefixed lines."""
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 """MagicCompleter() -> completer
176 """MagicCompleter() -> completer
176
177
177 Return a completer object suitable for use by the readline library
178 Return a completer object suitable for use by the readline library
@@ -184,6 +185,10 b' try:'
184 only be accessed via the ipython instance.
185 only be accessed via the ipython instance.
185
186
186 - namespace: an optional dict where completions are performed.
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 - The optional omit__names parameter sets the completer to omit the
193 - The optional omit__names parameter sets the completer to omit the
189 'magic' names (__magicname__) for python objects unless the text
194 'magic' names (__magicname__) for python objects unless the text
@@ -225,13 +230,14 b' try:'
225 """Return all possible completions for the benefit of emacs."""
230 """Return all possible completions for the benefit of emacs."""
226
231
227 completions = []
232 completions = []
233 comp_append = completions.append
228 try:
234 try:
229 for i in xrange(sys.maxint):
235 for i in xrange(sys.maxint):
230 res = self.complete(text, i)
236 res = self.complete(text, i)
231
237
232 if not res: break
238 if not res: break
233
239
234 completions.append(res)
240 comp_append(res)
235 #XXX workaround for ``notDefined.<tab>``
241 #XXX workaround for ``notDefined.<tab>``
236 except NameError:
242 except NameError:
237 pass
243 pass
@@ -622,13 +628,22 b' class InteractiveShell(code.InteractiveConsole, Logger, Magic):'
622 # instance has its own private namespace, so we can't go shoving
628 # instance has its own private namespace, so we can't go shoving
623 # everything into __main__.
629 # everything into __main__.
624
630
625 try:
631 # note, however, that we should only do this for non-embedded
626 main_name = self.user_ns['__name__']
632 # ipythons, which really mimic the __main__.__dict__ with their own
627 except KeyError:
633 # namespace. Embedded instances, on the other hand, should not do
628 raise KeyError,'user_ns dictionary MUST have a "__name__" key'
634 # this because they need to manage the user local/global namespaces
629 else:
635 # only, but they live within a 'normal' __main__ (meaning, they
630 #print "pickle hack in place" # dbg
636 # shouldn't overtake the execution environment of the script they're
631 sys.modules[main_name] = FakeModule(self.user_ns)
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 # List of input with multi-line handling.
648 # List of input with multi-line handling.
634 # Fill its zero entry, user counter starts at 1
649 # Fill its zero entry, user counter starts at 1
@@ -972,11 +987,11 b' class InteractiveShell(code.InteractiveConsole, Logger, Magic):'
972
987
973 def set_completer_frame(self, frame):
988 def set_completer_frame(self, frame):
974 if frame:
989 if frame:
975 ns = frame.f_globals.copy()
990 self.Completer.namespace = frame.f_locals
976 ns.update(frame.f_locals)
991 self.Completer.global_namespace = frame.f_globals
977 self.Completer.namespace = ns
978 else:
992 else:
979 self.Completer.namespace = self.user_ns
993 self.Completer.namespace = self.user_ns
994 self.Completer.global_namespace = self.user_global_ns
980
995
981 def post_config_initialization(self):
996 def post_config_initialization(self):
982 """Post configuration init method
997 """Post configuration init method
@@ -1234,6 +1249,7 b' want to merge them back into the new files.""" % locals()'
1234 import readline
1249 import readline
1235 self.Completer = MagicCompleter(self,
1250 self.Completer = MagicCompleter(self,
1236 self.user_ns,
1251 self.user_ns,
1252 self.user_global_ns,
1237 self.rc.readline_omit__names,
1253 self.rc.readline_omit__names,
1238 self.alias_table)
1254 self.alias_table)
1239 except ImportError,NameError:
1255 except ImportError,NameError:
@@ -1427,6 +1443,10 b' want to merge them back into the new files.""" % locals()'
1427 if local_ns is None and global_ns is None:
1443 if local_ns is None and global_ns is None:
1428 self.user_global_ns.update(__main__.__dict__)
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 self.interact(header)
1450 self.interact(header)
1431
1451
1432 def interact(self, banner=None):
1452 def interact(self, banner=None):
@@ -1914,7 +1934,7 b' want to merge them back into the new files.""" % locals()'
1914 cmd = '%sipmagic("%s")' % (pre,esc_quotes('%s %s' % (iFun,theRest)))
1934 cmd = '%sipmagic("%s")' % (pre,esc_quotes('%s %s' % (iFun,theRest)))
1915 self.log(cmd,continue_prompt)
1935 self.log(cmd,continue_prompt)
1916 self.update_cache(line)
1936 self.update_cache(line)
1917 #print 'in handle_magic, cmd=<%s>' % cmd # dbg
1937 print 'in handle_magic, cmd=<%s>' % cmd # dbg
1918 return cmd
1938 return cmd
1919
1939
1920 def handle_auto(self, line, continue_prompt=None,
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 2005-12-24 Fernando Perez <Fernando.Perez@colorado.edu>
24 2005-12-24 Fernando Perez <Fernando.Perez@colorado.edu>
2
25
3 * setup.py: added download_url to setup(). This registers the
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