Published 31st December 2008
Installing additional files with distutils in Python 2.3 isn't as easy as one expects it to be because the "data_files" attribute installs directly into "sys.prefix" and not the package specific directory in "site-packages", where one would expect such data.
Python 2.4 introduced the "package_data" attribute in distutils which should be used instead, as it installs the data in the correct directory. However, since there are still many packages around which support Python 2.3, I thought I would write down this little advice.
To include additional files with distutils in Python 2.3, the "data_files" argument must be used in the setup script:
from distutils.core import setup
setup(name='foobar',
version='1.0',
data_files=[('docs', ['README']),],
)
The sequence consists of pairs that specify the target directory and files that should be installed there. So in the above example, the "README" file would be installed into the "docs" directory.
Executing the above script in a virtual environment called "testenv" will result in the following:
copying README-> /Users/arthurk/.virtualenvs/testenv/docs
If other setup scripts would install a "README" file the same way, the file would be overwritten with each successive installation.
The problem, of course, isn't new. Lonnie Princehouse has posted a simple solution to this problem over four years ago.
Distutils has a variable called "INSTALL_SCHEMES" where the paths of the target directories for each platform are specified.
INSTALL_SCHEMES: ['mac', 'unix_prefix', 'os2', 'nt', 'unix_home']
INSTALL_SCHEMES['mac']: {'purelib': '$base/Lib/site-packages',
'headers': '$base/Include/$dist_name',
'scripts': '$base/Scripts',
'data': '$base',
'platlib': '$base/Lib/site-packages'}
The proposed solution sets the installation path of data files to to the path of packages e.g. the "site-packages" directory.
That and the addition of a package specific identifier (can be the same value as the "name" attribute, otherwise a "docs" directory would be created in "site-packages") result in the following setup script.
from distutils.core import setup
from distutils.command.install import INSTALL_SCHEMES
for scheme in INSTALL_SCHEMES.values():
scheme['data'] = scheme['purelib']
setup(name='foobar',
version='1.0',
data_files=[('foobar/docs', ['README']),],
)
Executing the above script will copy the data into the proper directory.
copying README-> /Users/arthurk/.virtualenvs/testenv/lib/python2.5/site-packages/foobar/docs