3

I am using setuptools to build a number of data files (compiled translations, icons resized and converted into different formats, etc.) and I would like to include the sources of these data files in to sdist and the build results but not their sources and and intermediary files into bdist_wheel.

When I use package_data both sources, intermediary files and built files will be included into bdist_wheel. E.g. translation sources (.ts) are compiled into .qm files then included as part of a rcc bundle, so bdist includes three copies of the translations in different formats and the same happens with icons.

Is there any way to prevent this when using setuptools, i.e. have sdist include data files in their source format and bdist_wheel include only the built results without the sources?

D.Herrman
  • 33
  • 3

2 Answers2

3

Further down is a minimal example showing how to achieve both:

  • packaging a data file file.src in sdist only;
  • and packaging another data file file.bin in bdist only;
  • additionally it shows how file.all is packaged in both distribution packages and file.not in none of them.

The gist of it is:

  • first and foremost, always thoroughly clean up the working directory between two packaging attempts while tweaking these packaging options (in particular empty the src/Thing.egg-info directory containing the SOURCES.txt file as well as the build, and dist directories) or the results will be inconsistent;
  • set the include_package_data option to True;
  • file.all and files that belong in both sdist and bdist are specified in MANIFEST.in;
  • file.bin and files that belong in bdist only are specified in package_data;
  • file.src and files that belong in sdist only are specified in both MANIFEST.in and exclude_package_data;
  • file.not and files that do not belong in any distribution package are not specified anywhere.

The directory structure for our example:

    .
    ├── MANIFEST.in
    ├── setup.py
    └── src
        └── thing
            ├── __init__.py
            └── data
                ├── __init__.py
                ├── file.all
                ├── file.bin
                ├── file.not
                └── file.src

In MANIFEST.in:

recursive-include src/thing *.all
recursive-include src/thing *.src

In setup.py:

#!/usr/bin/env python3

import setuptools

setuptools.setup(
    package_data={'thing': ['data/*.bin']},
    exclude_package_data={'thing': ['data/*.src']},
    include_package_data=True,
    #
    name='Thing',
    version='1.0.0',
    package_dir={'': 'src'},
    packages=setuptools.find_packages(where='src'),
)

This has been tested with:

  • Python 3.6.7
  • setuptools 39.0.1
  • wheel 0.33.1
sinoroc
  • 18,409
  • 2
  • 39
  • 70
-1

Include your directories in MANIFEST.in (see the docs), it's exactly for sdist distribution. Don't use include_package_data = True in setup.py because that includes files from MANIFEST.in into bdist distributions.

phd
  • 82,685
  • 13
  • 120
  • 165
  • Thanks, that's almost perfect. Is there an equivalent for bdist that only includes the built files in bdist_wheel but not sdist? Using `package_data` also includes listed files in sdist if they happen to be built. – D.Herrman Feb 25 '19 at 20:48
  • I don't think there is an easy way for it. – phd Feb 25 '19 at 20:54