##// END OF EJS Templates
ENH: Allow non-dict namespaces. This involves a change in the ipapi for setting user namespaces.
Robert Kern -
Show More
@@ -566,17 +566,7 b' def make_user_ns(user_ns = None):'
566 classes in ipython.
566 classes in ipython.
567 """
567 """
568
568
569 if user_ns is None:
569 raise NotImplementedError
570 # Set __name__ to __main__ to better match the behavior of the
571 # normal interpreter.
572 user_ns = {'__name__' :'__main__',
573 '__builtins__' : __builtin__,
574 }
575 else:
576 user_ns.setdefault('__name__','__main__')
577 user_ns.setdefault('__builtins__',__builtin__)
578
579 return user_ns
580
570
581
571
582 def make_user_global_ns(ns = None):
572 def make_user_global_ns(ns = None):
@@ -586,8 +576,56 b' def make_user_global_ns(ns = None):'
586 embedded applications, where there is a distinction between the user's
576 embedded applications, where there is a distinction between the user's
587 interactive namespace and the global one where ipython is running."""
577 interactive namespace and the global one where ipython is running."""
588
578
589 if ns is None: ns = {}
579 raise NotImplementedError
590 return ns
580
581 # Record the true objects in order to be able to test if the user has overridden
582 # these API functions.
583 _make_user_ns = make_user_ns
584 _make_user_global_ns = make_user_global_ns
585
586
587 def make_user_namespaces(user_ns = None,user_global_ns = None):
588 """Return a valid local and global user interactive namespaces.
589
590 This builds a dict with the minimal information needed to operate as a
591 valid IPython user namespace, which you can pass to the various embedding
592 classes in ipython. The default implementation returns the same dict for
593 both the locals and the globals to allow functions to refer to variables in
594 the namespace. Customized implementations can return different dicts. The
595 locals dictionary can actually be anything following the basic mapping
596 protocol of a dict, but the globals dict must be a true dict, not even
597 a subclass. It is recommended that any custom object for the locals
598 namespace synchronize with the globals dict somehow.
599
600 Raises TypeError if the provided globals namespace is not a true dict.
601 """
602
603 if user_ns is None:
604 if make_user_ns is not _make_user_ns:
605 # Old API overridden.
606 # FIXME: Issue DeprecationWarning, or just let the old API live on?
607 user_ns = make_user_ns(user_ns)
608 else:
609 # Set __name__ to __main__ to better match the behavior of the
610 # normal interpreter.
611 user_ns = {'__name__' :'__main__',
612 '__builtins__' : __builtin__,
613 }
614 else:
615 user_ns.setdefault('__name__','__main__')
616 user_ns.setdefault('__builtins__',__builtin__)
617
618 if user_global_ns is None:
619 if make_user_global_ns is not _make_user_global_ns:
620 # Old API overridden.
621 user_global_ns = make_user_global_ns(user_global_ns)
622 else:
623 user_global_ns = user_ns
624 if type(user_global_ns) is not dict:
625 raise TypeError("user_global_ns must be a true dict; got %r"
626 % type(user_global_ns))
627
628 return user_ns, user_global_ns
591
629
592
630
593 def make_session(user_ns = None, shellclass = None):
631 def make_session(user_ns = None, shellclass = None):
@@ -207,7 +207,7 b' class InteractiveShell(object,Magic):'
207 isthreaded = False
207 isthreaded = False
208
208
209 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
209 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
210 user_ns = None,user_global_ns=None,banner2='',
210 user_ns=None,user_global_ns=None,banner2='',
211 custom_exceptions=((),None),embedded=False):
211 custom_exceptions=((),None),embedded=False):
212
212
213 # log system
213 # log system
@@ -215,10 +215,11 b' class InteractiveShell(object,Magic):'
215
215
216 # some minimal strict typechecks. For some core data structures, I
216 # some minimal strict typechecks. For some core data structures, I
217 # want actual basic python types, not just anything that looks like
217 # want actual basic python types, not just anything that looks like
218 # one. This is especially true for namespaces.
218 # one. This is especially true for the global namespace.
219 for ns in (user_ns,user_global_ns):
219 if user_global_ns is not None and type(user_global_ns) is not dict:
220 if ns is not None and type(ns) != types.DictType:
220 raise TypeError('global namespace must be a true dict; got %r'
221 raise TypeError,'namespace must be a dictionary'
221 % type(user_global_ns))
222
222 # Job manager (for jobs run as background threads)
223 # Job manager (for jobs run as background threads)
223 self.jobs = BackgroundJobManager()
224 self.jobs = BackgroundJobManager()
224
225
@@ -260,7 +261,8 b' class InteractiveShell(object,Magic):'
260 # the locals argument. But we do carry a user_global_ns namespace
261 # the locals argument. But we do carry a user_global_ns namespace
261 # given as the exec 'globals' argument, This is useful in embedding
262 # given as the exec 'globals' argument, This is useful in embedding
262 # situations where the ipython shell opens in a context where the
263 # situations where the ipython shell opens in a context where the
263 # distinction between locals and globals is meaningful.
264 # distinction between locals and globals is meaningful. For
265 # non-embedded contexts, it is just the same object as the user_ns dict.
264
266
265 # FIXME. For some strange reason, __builtins__ is showing up at user
267 # FIXME. For some strange reason, __builtins__ is showing up at user
266 # level as a dict instead of a module. This is a manual fix, but I
268 # level as a dict instead of a module. This is a manual fix, but I
@@ -290,14 +292,12 b' class InteractiveShell(object,Magic):'
290 # These routines return properly built dicts as needed by the rest of
292 # These routines return properly built dicts as needed by the rest of
291 # the code, and can also be used by extension writers to generate
293 # the code, and can also be used by extension writers to generate
292 # properly initialized namespaces.
294 # properly initialized namespaces.
293 user_ns = IPython.ipapi.make_user_ns(user_ns)
295 user_ns, user_global_ns = IPython.ipapi.make_user_namespaces(user_ns,
294 user_global_ns = IPython.ipapi.make_user_global_ns(user_global_ns)
296 user_global_ns)
295
297
296 # Assign namespaces
298 # Assign namespaces
297 # This is the namespace where all normal user variables live
299 # This is the namespace where all normal user variables live
298 self.user_ns = user_ns
300 self.user_ns = user_ns
299 # Embedded instances require a separate namespace for globals.
300 # Normally this one is unused by non-embedded instances.
301 self.user_global_ns = user_global_ns
301 self.user_global_ns = user_global_ns
302 # A namespace to keep track of internal data structures to prevent
302 # A namespace to keep track of internal data structures to prevent
303 # them from cluttering user-visible stuff. Will be updated later
303 # them from cluttering user-visible stuff. Will be updated later
@@ -2066,16 +2066,7 b' want to merge them back into the new files.""" % locals()'
2066 try:
2066 try:
2067 try:
2067 try:
2068 self.hooks.pre_runcode_hook()
2068 self.hooks.pre_runcode_hook()
2069 # Embedded instances require separate global/local namespaces
2069 exec code_obj in self.user_global_ns, self.user_ns
2070 # so they can see both the surrounding (local) namespace and
2071 # the module-level globals when called inside another function.
2072 if self.embedded:
2073 exec code_obj in self.user_global_ns, self.user_ns
2074 # Normal (non-embedded) instances should only have a single
2075 # namespace for user code execution, otherwise functions won't
2076 # see interactive top-level globals.
2077 else:
2078 exec code_obj in self.user_ns
2079 finally:
2070 finally:
2080 # Reset our crash handler in place
2071 # Reset our crash handler in place
2081 sys.excepthook = old_excepthook
2072 sys.excepthook = old_excepthook
General Comments 0
You need to be logged in to leave comments. Login now