views:

382

answers:

3

How do I make setup.py include a file that isn't part of the code? (Specifically, it's a license file, but it could be any other thing.)

I want to be able to control the location of the file. In the original source folder, the file is in the root of the package. (i.e. on the same level as the topmost __init__.py.) I want it to stay exactly there when the package is installed, regardless of operating system. How do I do that?

A: 

Figured out a workaround: I renamed my lgpl2.1_license.txt to lgpl2.1_license.txt.py, and put some triple quotes around the text. Now I don't need to use the data_files option nor to specify any absolute paths. Making it a Python module is ugly, I know, but I consider it less ugly than specifying absolute paths.

cool-RR
@cool-RR See my post. It doesn't have to be ugly. It's just hard to find a good example on the net because good documentation to setup packages is hard to find.
Evan Plaice
+2  A: 

Probably the best way to do this is to use the setuptools package_data directive. This does mean using setuptools (or distribute) instead of distutils, but this is a very seamless "upgrade".

Here's a full (but untested) example:

from setuptools import setup, find_packages

setup(
    name='your_project_name',
    version='0.1',
    description='A description.',
    packages=find_packages(exclude=['ez_setup', 'tests', 'tests.*']),
    package_data={'': ['license.txt']},
    include_package_data=True,
    install_requires=[],
)

Note the specific line that's critical here:

package_data={'': ['license.txt']}

This is a dict of package names (empty = all packages) to a list of patterns (can include globs). For example, if you want to only specify files within your package, you can do that too:

package_data={'yourpackage': ['*.txt', 'path/to/resources/*.txt']}

The solution here is definitely not to rename your non-py files with a .py extension.

See Ian Bicking's presentation for more info.

Hans L
+1  A: 

Create a MANIFEST template in the folder that contains setup.py

Here's an example of the MANIFEST for my project:

CHANGELOG.txt
INSTALL.txt
LICENSE.txt
pypreprocessor.py
README.txt
setup.py
test.py
TODO.txt

Note: Mine are included in the root folder for simplicity, I don't include LICENSE.txt in the project folder because I insert it directly into the project's egg file by specifying the following line in my setup.py file.

license = open('LICENSE.txt').read(),

I also import the README.txt directly into setup.py by specifying:

long_description = open('README.txt').read(),

If you release/upload your package to PYPI you'll see that the README.txt (written in ReST) becomes the project's info and the LICENSE.txt shows up in full at the bottom with the rest of the project info, the same as it does in the .egg file after installation.

EDIT: To get an idea of the folder structure I use see this. The MANIFEST file is missing from the root because I don't keep it under version control.

Evan Plaice