44

How can I write setup.py so that:

  1. The binary egg distribution (bdist_egg) includes a sample configuration file and
  2. Upon installation puts it into the {prefix}/etc directory?

A sample project source directory looks like this:

bin/
   myapp
etc/
   myapp.cfg
myapp/
    __init__.py
    [...]
setup.py

The setup.py looks like this:

from distutils.command.install_data import install_data

packages = ['myapp', ]
scripts = ['bin/myapp',]
cmdclasses = {'install_data': install_data}
data_files = [('etc', ['etc/myapp.cfg'])]

setup_args = {
    'name': 'MyApp',
    'version': '0.1',
    'packages': packages,
    'cmdclass': cmdclasses,
    'data_files': data_files,
    'scripts': scripts,
#    'include_package_data': True,
    'test_suite': 'nose.collector'
}

try:
    from setuptools import setup
except ImportError:
    from distutils.core import setup

setup(**setup_args)

setuptools are installed in both the build environment and in the installation environment.

The 'include_package_data' commented out or not does not help.

Michael Currie
  • 13,721
  • 9
  • 42
  • 58
Victor Olex
  • 1,458
  • 1
  • 13
  • 28

2 Answers2

21

I was doing some research on this issue and I think the answer is in the setuptools documentation: http://peak.telecommunity.com/DevCenter/setuptools#non-package-data-files

Next, I quote the extract that I think has the answer:

Non-Package Data Files

The distutils normally install general "data files" to a platform-specific location (e.g. /usr/share). This feature intended to be used for things like documentation, example configuration files, and the like. setuptools does not install these data files in a separate location, however. They are bundled inside the egg file or directory, alongside the Python modules and packages. The data files can also be accessed using the Resource Management API [...]

Note, by the way, that this encapsulation of data files means that you can't actually install data files to some arbitrary location on a user's machine; this is a feature, not a bug. You can always include a script in your distribution that extracts and copies your the documentation or data files to a user-specified location, at their discretion. If you put related data files in a single directory, you can use resource_filename() with the directory name to get a filesystem directory that then can be copied with the shutil module. [...]

Akhorus
  • 2,233
  • 20
  • 24
  • 9
    Why is it a feature, not a bug? – Flimm Feb 05 '13 at 20:14
  • 3
    @Flimm , it is a feature because it is intended to work like that. The API has been specifically designed to present such behavior. It is even documented and properly explained. A [bug](http://en.wikipedia.org/wiki/Software_bug) is an error, flaw, mistake, failure, or fault in a computer program or system that produces an incorrect or unexpected result, or causes it to behave in unintended ways. – Akhorus Feb 18 '13 at 13:19
  • 7
    I meant, why did they intend it to work that way? It seems to me like one would want to be able to install data files to arbitrary locations on a user's machine. – Flimm Feb 18 '13 at 13:55
  • @Flimm The `resource_filename()` api provides increased flexibility for platforms that wouldn't let an application install its files to arbitrary locations. It also allows for packaging everything into a single egg file, with data files being decompressed on demand. – Tobu Feb 19 '13 at 12:01
  • 12
    @Flimm We often view the inconveniences created by security measures to be bugs. We also view lack of security to be a bug. That said... As you can see from https://docs.python.org/2/distutils/setupscript.html#installing-additional-files that feature/bug has been eliminated. Congratulations, you can now replace a victims '/bin/bash' when they pip install your json library. ;-) – Bruno Bronosky Mar 18 '15 at 16:51
1

Please note that the recommendations regarding config files outside the package have been updated since the question was originally asked.

PyPa now recommends that all configuration/python setup files for distribution be included within the package.

Please read here the relevant excerpt from the setuptools documentation (own highlights):

Non-Package Data Files
Historically, setuptools by way of easy_install would encapsulate data files from the distribution into the egg (see the old docs). As eggs are deprecated and pip-based installs fall back to the platform-specific location for installing data files, there is no supported facility to reliably retrieve these resources.
Instead, the PyPA recommends that any data files you wish to be accessible at run time be included inside the package.

Helmut
  • 311
  • 1
  • 9