[Distutils] requiring python 2.5

Rick Ratzel rlratzel at enthought.com
Fri Jun 15 07:50:25 CEST 2007


>    Date: Thu, 14 Jun 2007 22:05:43 -0400
>    From: "Phillip J. Eby" <pje at telecommunity.com>
> 
>    It sounds like the other paths are being added (again) to __path__ 
>    later.  This should only happen if new eggs get require()'d or 
>    otherwise added to the working set.  Can you narrow down where this 
>    is happening?
> 
>    Is it possible, for example, that enstaller is being imported while 
>    pkg_resources is being imported?  If you could raise an exception at 
>    the point of setting __path__, what is the full traceback?  Likewise, 
>    what is the full traceback of the import errors you're getting?
> 
>    (Also, perhaps you could try setting __path__ to a tuple instead of a 
>    list?  I'm not sure if that would work, but if it does, then an 
>    exception would occur when any other code modifies the __path__, so 
>    that might be another way to track it down.  Full traceback, please, 
>    if this works...)
> 


   Well, I do make one more require() call, but it's to add the enstaller.gui
egg.  enstaller is the command-line tool, and enstaller.gui adds the GUI.  Both
are "bundled" eggs, where enstaller has a few packages and enstaller.gui has
many more.  When I print the value of enthought.__path__ after that last require
though, it only contains the path to the enstaller egg, and the path to
enstaller.gui.  I hope that's not the problem...


   So I tried to get an exception raised when enthought.__path__ is modified,
but I could not.  It appeared that it never did.  Here is the traceback from the
ImportError when using setuptools 0.6:


Error: No module named app_data_locator.api

  File c:\python25\lib\site-packages\enstaller-2.1.0b1-py2.5-win32.egg\enthought\enstaller\launcher.py, line 72, in launch
     from enthought.enstaller.main import main

  File c:\python25\lib\site-packages\enstaller-2.1.0b1-py2.5-win32.egg\enthought\enstaller\main.py, line 65, in <module>
     from enthought.enstaller.session import \

  File c:\python25\lib\site-packages\enstaller-2.1.0b1-py2.5-win32.egg\enthought\enstaller\session.py, line 33, in <module>
     from enthought.traits.api import \

  File c:\python25\lib\site-packages\enthought.traits-2.0b2.dev_r12224-py2.5-win32.egg\enthought\traits\api.py, line 20, in <module>
     from trait_base \

  File c:\python25\lib\site-packages\enthought.traits-2.0b2.dev_r12224-py2.5-win32.egg\enthought\traits\trait_base.py, line 38, in <module>
     from enthought.app_data_locator.api import AppDataLocator



   Not terribly helpful, but you can see that in enstaller\session.py line 33,
it tries to import enthought.traits.api.  Next line shows enthought.traits.api
coming from the enthought.traits egg when it should be coming from the traits
package in the enstaller egg.

   So, I put a breakpoint in session.py at line 32 to inspect, and here is what that looked like:


Z:\>enstaller -l setuptools
IN INIT:  ('c:\\python25\\lib\\site-packages\\enstaller-2.1.0b1-py2.5-win32.egg\\enthought',)

> c:\python25\lib\site-packages\enstaller-2.1.0b1-py2.5-win32.egg\enthought\enstaller\session.py(33)<module>()
-> from enthought.traits.api import \

(Pdb) l
 28     import xmlrpclib
 29
 30     import pdb
 31     pdb.set_trace()
 32
 33  -> from enthought.traits.api import \
 34          Trait, HasTraits, Str, List, Instance, Property
 35
 36     from enthought.enstaller.enstaller_traits import \
 37          CreatableDir, Url
 38     from enthought.enstaller.api import \

(Pdb) import enthought

(Pdb) p enthought.__path__
('c:\\python25\\lib\\site-packages\\enstaller-2.1.0b1-py2.5-win32.egg\\enthought',)

(Pdb) s
--Call--
> c:\python25\lib\site-packages\enthought.traits-2.0b2.dev_r12224-py2.5-win32.egg\enthought\traits\api.py(16)<module>()
-> """

(Pdb) import enthought

(Pdb) p enthought.__path__
('c:\\python25\\lib\\site-packages\\enstaller-2.1.0b1-py2.5-win32.egg\\enthought',)

(Pdb) import setuptools

(Pdb) setuptools
<module 'setuptools' from 'c:\Python25\lib\site-packages\setuptools-0.6c6-py2.5.egg\setuptools\__init__.py'>

(Pdb) c

The Enstaller package could not be imported...this means Enstaller is not
installed or is broken or missing.

Internal Error: <type 'exceptions.ImportError'>: No module named app_data_locator.api

Please submit the following postmortem file to the authors:
Z:\ENSTALLER_POSTMORTEM.txt


   I break right before the import of enthought.traits.api and print out the
value of enthought.__path__.  I set it to a tuple early on like you suggested to
hopefully get an exception on modification, and you can see that it's still set
that way.  The value is still correct with only the single path to the enthought
package in the enstaller egg.  I step into the next line which is the import,
and you can see that I'm somehow taken to the enthought.traits egg, and it's all
downhill from there.  I also print out where python is finding setuptools, which
is in the 0.6 egg.



   Here is where things get interesting...the same pdb session when I use
setuptools 0.7:

Z:\>enstaller -l setuptools
IN INIT:  ('c:\\python25\\lib\\site-packages\\enstaller-2.1.0b1-py2.5-win32.egg\\enthought',)

> c:\python25\lib\site-packages\enstaller-2.1.0b1-py2.5-win32.egg\enthought\enstaller\session.py(33)<module>()
-> from enthought.traits.api import \

(Pdb) import enthought

(Pdb) p enthought.__path__
('c:\\python25\\lib\\site-packages\\enstaller-2.1.0b1-py2.5-win32.egg\\enthought',)

(Pdb) s
ImportError: 'No module named traits.api'
> c:\python25\lib\site-packages\enstaller-2.1.0b1-py2.5-win32.egg\enthought\enstaller\session.py(33)<module>()
-> from enthought.traits.api import \


   I get a different ImportError now.  Now here is the pdb session when I set
enthought.__path__ back to a list instead of a tuple using 0.7:


Z:\>enstaller -l setuptools
IN INIT:  ['c:\\python25\\lib\\site-packages\\enstaller-2.1.0b1-py2.5-win32.egg\\enthought']

> c:\python25\lib\site-packages\enstaller-2.1.0b1-py2.5-win32.egg\enthought\enstaller\session.py(33)<module>()
-> from enthought.traits.api import \

(Pdb) import enthought

(Pdb) p enthought.__path__
['c:\\python25\\lib\\site-packages\\enstaller-2.1.0b1-py2.5-win32.egg\\enthought']

(Pdb) s
--Call--
> c:\python25\lib\site-packages\enstaller-2.1.0b1-py2.5-win32.egg\enthought\traits\__init__.py(22)<module>()
-> try:

(Pdb) import enthought

(Pdb) p enthought.__path__
['c:\\python25\\lib\\site-packages\\enstaller-2.1.0b1-py2.5-win32.egg\\enthought']

(Pdb) import setuptools

(Pdb) setuptools
<module 'setuptools' from 'c:\Python25\lib\site-packages\setuptools-0.7a1dev_r53614-py2.5.egg\setuptools\__init__.pyc'>

(Pdb) c
------------------------------------------------------------
name       | version         | act | location
------------------------------------------------------------
setuptools | 0.6c6           |  n  | c:\python25\lib\site-packages
setuptools | 0.7a1dev_r53614 |  Y  | c:\python25\lib\site-packages


   Works fine when using setuptools 0.7, and enthought.__path__ appears correct
all the way through.  Here's the code where __path__ gets set and the only other
require() is:

------------------------------------------------------------------------------
from os import path

#
# Set the path to enthought to be this standalone enstaller egg.  This
# prevents any other eggs which contribute to the enthought namespace from
# being found instead of the enthought packages bundled in this egg, which
# are known to be compatible.
#
import enthought
enthought.__path__ = [path.dirname( path.dirname( __file__ ) )]

HAVE_GUI = True

#
# Try to activate the GUI...if found, this will enable GUI features.
#
try :
    require( "enstaller.gui" )

except :
    HAVE_GUI = False

print "IN INIT: ", enthought.__path__
------------------------------------------------------------------------------


   I'd be happy to provide any additional details...thanks again,


-- 
Rick Ratzel - Enthought, Inc.
515 Congress Avenue, Suite 2100 - Austin, Texas 78701
512-536-1057 x229 - Fax: 512-536-1059
http://www.enthought.com



More information about the Distutils-SIG mailing list