[Edu-sig] PEPTALK: path sanity and newbie mental health -- please help

Leif Johnson leif@ambient.2y.net
Mon, 7 Jul 2003 02:29:58 -0400


Hi Jason -

> Q: How to see PYTHONPATH?
> 
> >>> PYTHONPATH
> Traceback (most recent call last):
>   File "<pyshell#2>", line 1, in ?
>     PYTHONPATH
> NameError: name 'PYTHONPATH' is not defined
> >>> $PYTHONPATH
> SyntaxError: invalid syntax
> >>>
> 
> nope :-((
> Since PYTHONPATH  is so essential to using Python, surely it would make
> sense to make that permanently available to people?
> To my mind an intuitive interface would allow direct typing any of the
> environment variables in idle shell.

Well, being able to set environment variables directly from the Python
command line would make it more like shell script, and thus more like Perl,
so that's bad.

... just kidding. :-)

You pointed this out in your email, though I don't think you realized it.
There is indeed a nice, Pythonesque way to check your environment
variables, namely the os.environ dictionary :

  >>> import os
  >>> for pair in os.environ.items(): print '%s --> %s' % pair

In my mind, environment variables are necessarily an operating system
service (they are manipulated differently on different platforms), so they
should be accessed somehow under the `os' module. You can even set these
values using the os.environ dictionary.

> If "sys.path" is so essential, then why do I have to import sys all the
> time?

I think one of the issues is that most of the time you shouldn't need to
know what your sys.path is ; it's more of a system administration variable.
The fact that you're worried about it implies that you're installing things
in nonstandard locations, which is usually assumed to be a power user or
system administrator activity.

> And why do so many texts talk about PYTHONPATH when what they really mean
> is sys.path?

The following will never raise an exception, as far as I understand it :

  >>> for pth in os.environ[PYTHONPATH].split(os.pathsep):
  ...     if pth not in sys.path: raise

That is, the value of the sys.path list contains---at the very least---all
the values in the PYTHONPATH environment variable. There can be additional
values, which are determined by the global Python configuration file
(site.py and whatever files it loads).

So PYTHONPATH is an environment variable, available to all programs running
in the operating system environment, whereas sys.path is a list of strings
used internally by the Python interpreter. Actually, the Python interpreter
really only uses sys.path ; PYTHONPATH is used as a seed for initializing
the elements in the sys.path list when the interpreter starts up.

But this is why setting the PYTHONPATH variable is so handy, because you
don't have to configure Python to add these paths for you, you can just do
it using your operating system and then run Python normally.

Or you could modify your Python site configuration file (site.py and
sitecustomize.py, as mentioned below).

There's more than one way to do it, some guy said once. (Is it illegal to
use Larry Wall quotes on a Python mailing list ? :-)

> And how do I customize my environment so I don't have to jump through
> these hoops every time?

It seems like IDLE should provide some way for you to do this, but I looked
over the docs and couldn't find a nice solution. So, it looks like you're
left with a few options :

- Set your PYTHONPATH variable using your operating system. This entails
  editing your registry, messing with autoexec.bat, or setting your local
  variables using an obscure dialog. (Try right clicking `My Computer' or
  the Start menu, and going to `Properties' ... it's a tab somewhere in
  there.)

- Run a script each time you start up IDLE. Based on the IDLE docs
  <http://www.python.org/idle/doc/idle2.html>, it looks like you could use
  F5 when you start up IDLE, and then load whatever file you want to run.

  So you could write up a wee script containing the code you mentioned,
  which sets up your path :

    import sys
    sys.path.append('C:\\PYTHON22\\lib\\site-packages\\jabber')
    del sys

- Alter your site customization files. I'd personally do this by putting
  the above Python code in C:\PYTHON22\lib\site-packages\sitecustomize.py.

> DS #0 -- Display PYTHONPATH when Python boots.  Make this a default, which
> pros can disable via config value.

I kind of like the current default, so that normally your path doesn't show
up. (What if your path happens to be really long ? Seems like it would get
annoying.) Anyway, you could enable such behavior by putting the following
in C:\PYTHON22\lib\site-packages\sitecustomize.py :

  import sys
  sys.path.append('C:\\PYTHON22\\lib\\site-packages\\jabber')
  for p in sys.path: print p
  del p, sys

> DS #2   -- To be able to add to that by setting like this:
> 
> PYTHONPATH = ['C:\\PYTHON22\\Tools\\idle', 'M:\\jasonic\\python',
> 'C:\\Python22', 'C:\\PYTHON22\\DLLs', 'C:\\PYTHON22\\lib',
> 'C:\\PYTHON22\\lib\\lib-tk', 'C:\\PYTHON22\\lib\\site-packages',
> 'C:\\PYTHON22\\lib\\site-packages\\jabber']  <<< the last entry is my
> addition
> 
> or by adding or appending:
> 
> PYTHONPATH.add('C:\\PYTHON22\\lib\\site-packages\\jabber')
> PYTHONPATH.append('C:\\PYTHON22\\lib\\site-packages\\jabber')

I'd definitely use sys.path for this type of manipulation. Doing this is
perfectly valid :

  >>> import sys
  >>> sys.path = ['foo', 'bar', 'baz'] # not a very functional path ...
  >>> sys.path.append('C:\\PYTHON22\\lib\\site-packages\\jabber')

You could even do this type of manipulation in your sitecustomize.py file
so you don't have to remember to do it each time you start IDLE. Again, I
think IDLE should have its own `exec this file on startup' configurability,
but that's a separate issue.

As you point out, there's no direct parallel like this for any other
environment variables. But that's ok, because Python only uses the one
variable, PYTHONPATH ... all others are pretty much irrelevant.

> Ideally there is a single dict which holds all of these and can be easily
> viewed and edited anytime on any system the same way and will always be
> accessible in the Python shell. Perhaps there already is and I'm too dumb
> to have found it.

  >>> import os
  >>> os.environ['PYTHONPATH'] = os.pathsep.join(['foo', 'bar', 'baz'])
  >>> os.environ['PYTHONPATH']
  'foo:bar:baz'
  >>> os.environ['MYVARIABLE'] = 'myvalue'

Use the force, Luke. Or the os.environ dictionary. But good luck, either
way. Hope this long message helps.

leif

--
Leif Morgan Johnson : http://ambient.2y.net/leif/