[Distutils] resource_filename() breaks cxfreeze (py2exe?)

Phillip J. Eby pje at telecommunity.com
Thu Oct 13 01:37:49 CEST 2005


At 07:14 PM 10/12/2005 -0400, Robby Dermody wrote:
>Hi guys,
>
>The subject line no doubt tells you all something you already know. This
>morning, I didn't even know that setuputils existed, so excuse my
>ignorance on the topic.
>
>Basically, I have an application that makes use of a python web
>application development library called nevow. The current version of
>nevow (0.5.0) makes use of resource_filename() to get the paths of
>certain static files that it uses. Things work fine when my app is not
>frozen, but after I freeze it with cx_freeze resource_filename() turns
>out to be a breakage point. I would think the same kind of thing would
>happen with py2exe. See the traceback at the end of this message for
>more info.
>
>Once I freeze the application and run it, my sys.path is set to
>['/home/robbyd/dev/inquest/dist/inquest-director-0.7.0-1/inquest-director',
>'/home/robbyd/dev/inquest/dist/inquest-director-0.7.0-1']
>(Meaning the frozen zip file executable, 'inquest-director', and its
>parent path.)
>
>Normally this works fine, due to zipimporter. However, with the static
>files nevow is attempting to locate with resource_filename(), it seems
>that the problem is that, resource_filename() wants to look into the zip
>file but it doesn't know how to do so. (I have not done too much
>research into how this function works, so I may be missing the point
>here.) What I'd like to know is why this is the case, and what may
>happen when resource_filename() gets used in more libraries whose users
>freeze their applications with cxfreeze/py2exe/macmillian/etc.  Is this
>a move by setuptools to take over the world (of python packaging
>utilities)? ;)
>
>Thanks in advance for any feedback that is offered. At this point I'm
>just unsure if this is more of a setuptools issue, or more of a
>cx_Freeze issue. I did take a look at setuptools and I was impressed
>with it, but my app has certain requirements that make cx_freeze a good
>choice.

You could say that it's a collision between the program's desire to use the 
more convenient resource_filename() function in place of the more-portable 
resource_stream() and resource_string() functions.  The latter two 
functions will work just fine with arbitrary importable zip files, but 
resource_filename() requires either an extracted zipfile or a zipped egg.

The issue here is that resource_filename() requires the static file to be 
extracted to the filesystem.  To be extracted to the filesystem, there 
needs to be a place to extract.  For eggs, the extract location is partly 
determined by the egg's project name and version number, which are assumed 
to be "relatively unique", allowing the resource to be extracted to a 
unique location.  The runtime complains in this case because it doesn't 
find any data that tells it what the name of the egg is that it's doing the 
extraction on behalf of, so it doesn't know where it should extract to.

There are two possible solutions:

1. Lobby the nevow author(s) to use resource_stream() or resource_string() 
instead
2. Package the .egg in the zipfile as a subdirectory

The first one is self-explanatory; it will make the package work even if 
it's not packaged as an egg.  I suggest submitting a patch, if you can.

The second one is straightforward in principle, but perhaps not in 
practice, depending on the constraints of your tools.  What you want to do 
is have a subdirectory *in your zipfile* that is named 
'nevow-0.5.0-py2.4.egg', or whatever the correct name is.  Inside that 
subdirectory, you include the original contents of the egg.  Then, 
pkg_resources will know what egg contains the package, and thus do the 
extraction correctly.  A zipfile that contains multiple eggs is sometimes 
called a "basket", as in "putting all your eggs in one basket".  :)

In general, pkg_resources tries to treat zipfiles and directories inside 
zipfiles as equivalents to "real" directories, which means that if you have 
a .zip on sys.path (or even an executable with a zipfile appended to it), 
then pkg_resources will happily search the zipfile's root for .egg 
subdirectories when it's trying to resolve dependencies.

As for your world domination question, I suspect that eventually most 
freezing tools will just dump all the necessary eggs into a basket, since 
this is simpler and less likely to break than scouting out individual 
module dependencies.  There's also an opportunity for installation-oriented 
tools to create "download only the bits I need" web installers, etc.



More information about the Distutils-SIG mailing list