Nested scopes hitch

Fernando Pérez fperez528 at yahoo.com
Mon Apr 8 22:13:11 EDT 2002


Jeff Shannon wrote:

> I obviously can't speak to your specific designs, not having seen
> them, but I can't imagine how globals()/locals() would be
> necessary unless you have a large amount of interdependencies in
> your code, and it is generally accepted that interdependent code
> is not a good thing.  If you can explain to me how you can
> require access to large portions of another scope's namespace
> without having large interdependencies, then perhaps I'll change
> my mind about this method.

Here's an example:

    def __call__(self,header='',local_ns=None,global_ns=None,dummy=None):
        """Activate the interactive interpreter.

        __call__(self,header='',local_ns=None,global_ns,dummy=None) -> Start
        the interpreter shell with the given local and global namespaces, and
        optionally print a header string at startup.

        The shell can be globally activated/deactivated using the
        set/get_dummy_mode methods. This allows you to turn off a shell used
        for debugging globally.

        However, *each* time you call the shell you can override the current
        state of dummy_mode with the optional keyword parameter 'dummy'. For
        example, if you set dummy mode on with IPShell.set_dummy_mode(1), you
        can still have a specific call work by making it as IPShell(dummy=0).

        The optional keyword parameter dummy controls whether the call
        actually does anything.  """


        # Allow the dummy parameter to override the global __dummy_mode
        if dummy:
            return
        else:
            if dummy != 0 and self.__dummy_mode:
                return

        # Set global subsystems (display,completions) to our values
        sys.displayhook = self.sys_displayhook_embed
        try:
            import readline
            readline.set_completer(self.IP.Completer.complete)
        except:
            pass

        # Get locals and globals from caller
        call_frame = sys._getframe().f_back

        if local_ns is None:
            local_ns = call_frame.f_locals
        if global_ns is None:
            global_ns = call_frame.f_globals

        try:
            if self.banner:
                if header:
                    self.IP.embed_mainloop('%s\n%s' % (self.banner,header),
                                           local_ns,global_ns)
                else:
                    self.IP.embed_mainloop(self.banner,local_ns,global_ns)
            else:
                self.IP.embed_mainloop(self.banner,local_ns,global_ns)
                pass
        except SystemExit:
            pass

        if self.exit_msg:
            print self.exit_msg
            
        # Restore global systems (display, completion)
        sys.displayhook = self.sys_displayhook_ori
        try:
            readline.set_completer(self.sys_ipcompleter_ori)
        except:
            pass # not embedded, or not using readline.


This is an embedded interpreter, which _needs_ to know the namespace structure 
of where it's being called, but can't expect to be passed parameters (since 
it simply needs to know _all_ of the caller's namespace). This discussion has 
made me realize that in fact this system fails to properly recongize nested 
scopes. 

So tell me how such a system could be built otherwise and I'll be happy to 
change my design.

Cheers,

f.



More information about the Python-list mailing list