<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 TRANSITIONAL//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; CHARSET=UTF-8">
<META NAME="GENERATOR" CONTENT="GtkHTML/3.10.1">
</HEAD>
<BODY>
On Wed, 2007-07-25 at 18:10 -0400, Phillip J. Eby wrote:
<BLOCKQUOTE TYPE=CITE>
<PRE>
<!--+GtkHTML:<DATA class="ClueFlow" key="orig" value="1">--><FONT COLOR="#000000">At 04:42 PM 7/25/2007 -0400, Stanley A. Klein wrote:</FONT>
<FONT COLOR="#000000">>I've been trying to build rpms of enthought system components. Some of</FONT>
<FONT COLOR="#000000">>them use namespace packages. Those packages have the required __init__.py</FONT>
<FONT COLOR="#000000">>files containing</FONT>
<FONT COLOR="#000000">>"__import__('pkg_resources').declare_namespace(__name__)".</FONT>
<FONT COLOR="#000000">></FONT>
<FONT COLOR="#000000">>According to the Setuptools Guide, these __init__.py files are not to be</FONT>
<FONT COLOR="#000000">>packaged when using "system" packaging (such as bdist_rpm) and when I run</FONT>
<FONT COLOR="#000000">>bdist_rpm they are not included in the rpms. However, there are egg-info</FONT>
<FONT COLOR="#000000">>directories and nspkg.pth files produced, included in the rpms, and</FONT>
<FONT COLOR="#000000">>installed in site-packages.</FONT>
<FONT COLOR="#000000">So far, so good - that's exactly how it's supposed to work.</FONT>
<FONT COLOR="#000000">> When I tried to run the enthought example</FONT>
<FONT COLOR="#000000">>applications, I had various kinds of import failures. I found that fixing</FONT>
<FONT COLOR="#000000">>them required putting the unpackaged __init__.py files into the relevant</FONT>
<FONT COLOR="#000000">>directories in the namespace packages.</FONT>
<FONT COLOR="#000000">></FONT>
<FONT COLOR="#000000">>The various rpms were being placed in the proper locations where they</FONT>
<FONT COLOR="#000000">>should have been found for importing. There were some strange errors,</FONT>
<FONT COLOR="#000000">>such as in one case when I tried to test the imports interactively an</FONT>
<FONT COLOR="#000000">>"import a.b.c" worked, but an "import a.b.c as c" failed.</FONT>
<FONT COLOR="#000000">></FONT>
<FONT COLOR="#000000">>Before putting in the __init__.py files, I tried removing the egg-info and</FONT>
<FONT COLOR="#000000">>nspkg.pth files from site_packages. That did not improve things.</FONT>
<FONT COLOR="#000000">It sure as heck wouldn't. They need to be there, and the nspkg.pth </FONT>
<FONT COLOR="#000000">files need to be processed by Python during its startup.</FONT>
<FONT COLOR="#000000">>I think setuptools is somehow not properly processing bdist_rpm if there</FONT>
<FONT COLOR="#000000">>are namespace packages involved. Also, the setuptools don't seem to have</FONT>
<FONT COLOR="#000000">>an option to not create the egg info and nspkg.pth files and/or to not</FONT>
<FONT COLOR="#000000">>package them if bdist_rpm is being used.</FONT>
<FONT COLOR="#000000">This is by design. It is almost certainly the case that either:</FONT>
<FONT COLOR="#000000">1. the nspkg.pth files are not being processed when Python starts</FONT>
<FONT COLOR="#000000">2. something is deleting the namespace packages from sys.modules </FONT>
<FONT COLOR="#000000">between the time the .pth files are processed, and the time you </FONT>
<FONT COLOR="#000000">attempt to import them.</FONT>
<FONT COLOR="#000000">To verify this, I would say, start Python with the bdist_rpms </FONT>
<FONT COLOR="#000000">installed as directed (i.e., don't mess with what's installed), and </FONT>
<FONT COLOR="#000000">see if there are sys.modules entries for the namespace </FONT>
<FONT COLOR="#000000">package(s). If there are, then the problem is happening later - </FONT>
<FONT COLOR="#000000">i.e., something being done by your code. If the namespace packages </FONT>
<FONT COLOR="#000000">aren't in sys.modules, then there is a problem with the .pth files at </FONT>
<FONT COLOR="#000000">startup; try using "python -v" to see if there are any errors shown.</FONT>
</PRE>
</BLOCKQUOTE>
<!--+GtkHTML:<DATA class="ClueFlow" key="orig" value="0">--><BR>
<!--+GtkHTML:<DATA class="ClueFlow" key="orig" value="0">-->I think the "almost" allows more than the two alternative possibilities you provide, and I think that is the situation. Something else must be going on.<BR>
<!--+GtkHTML:<DATA class="ClueFlow" key="orig" value="0">--><BR>
<!--+GtkHTML:<DATA class="ClueFlow" key="orig" value="0">-->I disabled the __init__.py's on the namespace packages by renaming them. A sys.modules.keys() shows the namespace packages in the list. Then I interactively did the first three statements of the test_traits.py program:<BR>
<!--+GtkHTML:<DATA class="ClueFlow" key="orig" value="0">--><BR>
<!--+GtkHTML:<DATA class="ClueFlow" key="orig" value="0">-->import unittest<BR>
<!--+GtkHTML:<DATA class="ClueFlow" key="orig" value="0">-->from enthought.traits.api import *<BR>
<!--+GtkHTML:<DATA class="ClueFlow" key="orig" value="0">-->import enthought.traits.standard as standard<BR>
<!--+GtkHTML:<DATA class="ClueFlow" key="orig" value="0">--><BR>
<!--+GtkHTML:<DATA class="ClueFlow" key="orig" value="0">-->The last statement failed with an error:<BR>
<!--+GtkHTML:<DATA class="ClueFlow" key="orig" value="0">--><BR>
<!--+GtkHTML:<DATA class="ClueFlow" key="orig" value="0">--><TT>Traceback (most recent call last):</TT><BR>
<!--+GtkHTML:<DATA class="ClueFlow" clear="orig">--><TT> File "test_traits.py", line 23, in ?</TT><BR>
<TT> import enthought.traits.standard as standard</TT><BR>
<TT>AttributeError: 'module' object has no attribute 'traits'</TT><BR>
<!--+GtkHTML:<DATA class="ClueFlow" key="orig" value="0">--><BR>
If I then interactively do "<TT>import enthought.traits.standard", it works without error.</TT><BR>
<BR>
If I redo the same steps using python -v, I get the error message only after a lot of imports. The last output before the error message is <BR>
<BR>
# /usr/lib/python2.4/site-packages/enthought/traits/ui/editors.pyc matches /usr/lib/python2.4/site-packages/enthought/traits/ui/editors.py<BR>
import enthought.traits.ui.editors # precompiled from /usr/lib/python2.4/site-packages/enthought/traits/ui/editors.pyc<BR>
Traceback (most recent call last):<BR>
File "<stdin>", line 1, in ?<BR>
AttributeError: 'module' object has no attribute 'traits'<BR>
<BR>
The file editors.py first does:<BR>
<BR>
from toolkit \<BR>
import toolkit<BR>
<BR>
which points to toolkit.py. That file contains some statements that were the failure point when I tried to run an example from the Traits UI Guide. The relevant statements in toolkit.py are:<BR>
<BR>
<BR>
from enthought.traits.api \<BR>
import HasTraits, HasPrivateTraits, TraitError<BR>
<BR>
from ui_traits \<BR>
import SequenceTypes<BR>
<BR>
#-------------------------------------------------------------------------------# Constants:<BR>
#-------------------------------------------------------------------------------<BR>
<BR>
# List of implemented UI toolkits<BR>
TraitUIToolkits = [ 'wx', 'null' ]<BR>
<BR>
#-------------------------------------------------------------------------------<BR>
# Data:<BR>
#-------------------------------------------------------------------------------<BR>
<BR>
# The current GUI toolkit object being used<BR>
_toolkit = None<BR>
<BR>
#-------------------------------------------------------------------------------<BR>
# Low-level GUI toolkit selection function:<BR>
#-------------------------------------------------------------------------------<BR>
<BR>
def toolkit ( *toolkits ):<BR>
""" Selects and returns a low-level GUI toolkit.<BR>
<BR>
Use this function to get a reference to the current toolkit.<BR>
"""<BR>
global _toolkit<BR>
<BR>
if len( toolkits ) == 0:<BR>
if _toolkit is not None:<BR>
return _toolkit<BR>
toolkits = TraitUIToolkits<BR>
for toolkit_name in toolkits:<BR>
try:<BR>
package = 'enthought.traits.ui.' + toolkit_name<BR>
module = __import__( package )<BR>
_toolkit = getattr( module.traits.ui, toolkit_name ).toolkit<BR>
return _toolkit<BR>
except ImportError:<BR>
pass<BR>
else:<BR>
raise TraitError, ("Could not find any UI toolkit called: %s" %<BR>
', '.join( toolkits ))<BR>
<BR>
When I restart the interactive session as python -v, do the import statements in toolkit.py , and then do <BR>
<BR>
toolkit_name = "wx"<BR>
package = 'enthought.traits.ui.' + toolkit_name<BR>
module = __import__( package )<BR>
_toolkit = getattr( module.traits.ui, toolkit_name ).toolkit<BR>
<BR>
it finds the enthought.traits.ui.wx toolkit, does the imports required by the "module = __import__( package )" statement and then fails on the next statement with an error:<BR>
<BR>
>>> _toolkit = getattr( module.traits.ui, toolkit_name ).toolkit<BR>
Traceback (most recent call last):<BR>
File "<stdin>", line 1, in ?<BR>
AttributeError: 'module' object has no attribute 'traits'<BR>
<BR>
<BR>
If I manually restore the __init__.py files in the three namespace packages, I don't see the namespace packages on python startup when I do the sys.modules.keys(), but I can run the test_traits.py and the examples from the Traits UI Guide without a problem. In particular, I don't get the attribute error that I got without the __init__.py files in place.<BR>
<BR>
Also, I don't know how Ryan May "hand-rolled" his Gentoo packages, but he said he had a similar problem and fixed it by putting in the __init__.py files.<BR>
<BR>
It looks like without the __init__.py files, the imports are being properly found and imported, but some lack of information somewhere is causing the getattr statement to fail. The purpose of the statement appears to be to return which lower level GUI toolkit was found and imported.<BR>
<BR>
I hope this provides everyone enough information to figure out what is happening.<BR>
<BR>
<BR>
Stan Klein
</BODY>
</HTML>