Simple Workaround for Py2Exe and .EGG Files

May 7, 2006 on 11:28 pm | In Python |

Py2Exe, along with Freeze are two popular packages for combining multiple files, dependencies, shared objects, and resources into a single relocatable package. Unfortunately, Py2Exe doesn’t handle .egg files very easily, which is what quite a few packages out there are distributed in. Using the Cygwin environment to easily create symbolic links, we’re able to simply include the necessary packages in the final distribution.

In the processes of rolling up my current application to move over to the testuser’s workstation, I encountered a fair bit of difficult with py2exe. My initial attempts at rolling my own <module>.zip file and including that in the archive thwarted by peculiar parameter requirements, I struck a fairly simple solution to the problem. Sadly, it’s not very elegent, but it will suffice in the meantime.

The Py2Exe looks for various files to import, hopefully discovering all the necessary files for your application. In my case, I was trying to import the SQLAlchemy ORM library, which I used extensively on this project, as well as the PsycoPG2 PostgreSQL Python Module for access to my backend database. Both of these modules install as egg’s into the /usr/local/Python.2.4.3/Lib/site-packages/ directory, and neither of them was being properly discovered by Py2Exe.

After trying some schenanigans with the data_files setup.py parameter, I simplified things and simply created shortcuts named properly after the module names to the relevent root directories of each module of the egg itself. This does, of course, require that the egg is installed as a directory (add a zip_safe=False entry to the modules setup.py) and not as a .egg file (essentially a ZIP archive).

ln -s /usr/local/Python.2.4.3/Lib/site-packages/psycopg2 psycopg2
ln -s /usr/local/Python.2.4.3/Lib/site-packages/SQLAlchemy-0.1.7.1419-py2.4.egg/sqlalchemy sqlalchemy

The exact directory you have to link to might change a bit depending on the EGG you’re linking against. You’ll also note that these symlinks are only valid for that particular installation point — it would be possible to parse the site-packages/easy-install.pth file for the correct directory if you are so inclined, but as in the case of SQLAlchemy, an additional directory is needed for things to work properly.

With the symlinks in place, we need a basic setup.py to drive run Py2Exe from. I put this one together as a bare-minimum example with the necessary components:

from distutils.core import setup
import py2exe
 
setup(name='geartrac',
      version='1.0',
      py_modules=['GearTrac'],
      windows=['GearTrac.py']
      )

This is sufficient to tell Py2Exe the name of the program (’GearTrac’), and that it’s a windows-based application, instead of a console or other style application. Now, kick the process off by calling setup.py and including the sqlalchemy and psycopg2 modules in the packages command line option:

python setup.py py2exe --dist-dir=dist/exe --bundle=1 --packages=sqlalchemy,psycopg2

This places the resulting files in the dist/exe directory, bundles them into a minimum of extra files, and includes the two package files. Pay close attention at the end of the process to the lines just above the licenese warning and DLL list that states the missing modules:

The following modules appear to be missing
['MySQLdb', 'adodbapi', 'cx_Oracle', 'dummythread', 'kinterbasdb', 'mx.DateTime.DateTime',
 'psycopg', 'pymssql', 'zLOG']

Since I’m not using any of these databases, I can safely ignore the message. If you see the modules you’re trying to import listed on this line anywhere, then you probably have a problem.

My resulting dist/exe directory contains only the following fouro files: GearTrac.exe MSVCR71.dll library.zip w9xpopen.exe, of which the w9xpopen.exe file I can safely discard since I have no plans to get within arms reach of a Windows 9x machine :)

Cheers!

No Comments yet

Sorry, the comment form is closed at this time.

Entries and comments feeds. ^Top^
18 queries. 0.202 seconds.