[Distutils] setuptools-0.4a2: Eggs, scripts, and __file__

Ryan Tomayko rtomayko at gmail.com
Mon Jun 13 06:16:39 CEST 2005

 From "[Distutils] A plan for scripts (in EasyInstall)"

On Mon Jun 6 16:44:19 CEST 2005, Phillip J. Eby wrote:
 > The 'run_main' function would do several things:
 >   * Clear everything but __name__ from the __main__ namespace
 >   * exec the script in __main__, using something like:
 >      maindict['__file__'] = pseudo_filename code =
 >      compile(script_source, pseudo_filename, "exec") exec code in
 >      maindict, maindict

It seems that bullet one is happening but not bullet two? I have  
scripts that are attempting to use __file__ but failing with:

     NameError: name '__file__' is not defined

The script looks like it would work properly if it was given a pseudo  
filename but this has me thinking about what the best way to detect  
development environments in scripts will look like in an eggified  
environment. My wrapper scripts generally look something like the  
following to detect whether the script is being run from a  
development location or a deployed location::

     import sys
     from os.path import dirname, abspath, join, exists
     devel_dir = dirname(dirname(abspath(__file__)))
     if exists(join(devel_dir, 'support')):
          sys.path.insert(1, join(devel_dir, 'support'))
          sys.path.insert(1, devel_dir)
     from package.module import main

Assuming a directory layout of:

     [devel-dir]/bin (scripts in here)
     [devel-dir]/support (packages/modules)

At first I thought I should switch from using path operations on  
__file__ to using `pkg_resources.resource_isdir` and  
`resource_filename` but that doesn't make any sense - if the script  
is running from within a deployed egg, I'm not using it from a  
development environment and the resource_*** functions don't make  
sense in __main__ context anyway. So my current thinking is that the  
existing idiom should remain and that a pseudo filename shouldn't  
pose any problems in the scenarios I'm dealing with:

  * Deployed egg: don't tamper with sys.path
  * Deployed site-packages: don't tamper with sys.path
  * Development environment: insert development paths

At any rate, I'm guessing that __file__ appears in a good percentage  
of scripts in the wild. I've switched mine to use sys.argv[0] in  
place of __file__ but I'll see if I can get a patch together for  
getting a psuedo __file__ into the exec dict (but don't wait up - I'm  
not familiar with the code and figuring out how to get the psuedo  
filename will take me infinite orders of magnitude longer than you ;)

Ryan Tomayko
                                  rtomayko at gmail.com

More information about the Distutils-SIG mailing list