[Pythonmac-SIG] Re: [Tutor] sitecustomize and pythonstartup

Danny Yoo dyoo@hkn.eecs.berkeley.edu
Sat, 2 Feb 2002 02:38:05 -0800 (PST)


On Sat, 2 Feb 2002, Jack Jansen wrote:
> > Yes, it's possible.  If we add the following fragment to our
> > sitecustomize.py:
> >
> > ###
> > import math
> > import __builtin__
> > __builtin__.math = math
> > del math
> > ###
> 
> But this will not only make it show up in interactive 
> interpreters, it will also make it show up globally, in every 
> module. I'm not sure this is a good idea...


Good point!  Yikes..., ok if we want this automatic math import to work on
interactive sessions without completely munging every other library in
Python, perhaps we can employ a variation of the tricky code that
pydoc.help() uses to try detecting if a session is interactive:


###
import inspect
def isInteractive():
    """Returns 1 if we're running in an interpreter window, and false
    otherwise.  At least, it tries to.  This is a variation of what
    pydoc.help() tries."""
    return inspect.stack()[-1][1:4] == (None, 1, "?")
###

The idea of this is to look at the very end of the frame stack, and if the
following three characteristics hold:

    1.  The "file" part of the frame is None.
    2.  We're on line number 1.
    3.  We have no clue what function we're in. ("?")

then we're probably in interactive mode.


And speaking of no clue... I have NO clue if this will work on an IDE.  I
think that other IDE's actually set the "file name" to something other
than "None", so perhaps this heuristic needs to be relaxed.  Does anyone
know a better way of testing if we're in interactive mode or not?


If we have something like this like this, we might be able to limit the
extent of the math import to just interactive shells:

###
## Within sitecustomize.py

import inspect
def isInteractive():
    """Returns 1 if we're running in an interpreter window, and false
    otherwise.  At least, it tries to.  This is a variation of what
    pydoc.help() tries."""
    return inspect.stack()[-1][1:4] == (None, 1, "?")

class _InteractiveMath:
    def __repr__(self):
        if isInteractive():
            import math
            return repr(math)
        else:
            raise NameError, 'name "math" is not defined'

    def __getattr__(self, attr):
        if isInteractive():
            import math
            return getattr(math, attr)
        else:
            raise NameError, 'name "math" is not defined'

import __builtin__
__builtin__.math = _InteractiveMath()
###

To tell the truth, I feel very somewhat ashamed about this code, as it
doesn't quite work perfectly.  It tries to simulate the NameErrors that
should occur in a noninteractive Python program --- the _InteractiveMath()
instance tries to pretend that it's not there if the right person doesn't
knock --- but either way, we can still hear some strange shuffling behind
the door.  *sigh*


This is what I could cook up in thirty minutes, and I'm sure there's a
better way to do this.