MANIFEST.in ignored on "python setup.py install" - no data files installed?

Viewed 42193

Here's my stripped-down setup.py script with non-code stuff removed:

#!/usr/bin/env python

from distutils.core import setup
from whyteboard.misc import meta


setup(
    name = 'Whyteboard',
    version = meta.version,

    packages = ['whyteboard', 'whyteboard.gui', 'whyteboard.lib', 'whyteboard.lib.pubsub',
                'whyteboard.lib.pubsub.core', 'whyteboard.lib.pubsub.utils', 'whyteboard.misc'],

    py_modules = ['whyteboard'],
    scripts = ['whyteboard.py'],
)

MANIFEST.in:

include *.txt
include whyteboard-help/*.*
recursive-include locale *.mo
recursive-include images *.png

When I run "python setup.py install sdist" I get a nice .tar.gz with a "whyteboard-0.41" root folder, with my locale/ images/ and whyteboard-help/ folders inside. This also has my whyteboard.py script that launches my program from inside the whyteboard source package.

So:

whyteboard/
 ├── locale/
 ├── images
 ├── whyteboard-help/
 ├── whyteboard/
 │  ├── __init__.py
 │  └── other packages etc
 ├── whyteboard.py
 ├── README
 ├── setup.py
 └── CHANGELOG

This mirrors the source of my program, is how everything should be, and is correct.

However when I run "python setup.py install" none of my data files are written - only the "whyteboard" source package, and the whyteboard.py is placed in /usr/local/lib/python2.6/dist-packages/.

Ideally, I'd like the same directory structure as what's been generated in the .tar.gz file to be created in dist-packages, as this is how my program expects to look for its resources.

How can I get "install" to create this directory structure? It seems to be ignoring my manifest file, as far as I can tell.

6 Answers

Minimal published runnable example

Key takeaway: only MANIFEST.in worked for me, package_data did not.

Tested on Ubuntu 19.10, Python 3.7.5, wheel==0.32.3, setuptools==41.1.0, twine==3.1.1.

How end users use the package from https://pypi.org/project/python-sample-package-with-data/:

python3 -m pip install --user python-sample-package-with-data
python-sample-package-with-data

Expected output:

hello data

How maintainers publish it:

# One time setup.
python3 -m pip install --user setuptools wheel twine

# Every time you want to publish.
python setup.py sdist bdist_wheel
twine upload dist/*
rm -rf build dist *.egg-info

The actual files:

MANIFEST.in

# Or else pip install cannot find README.md on the setup.py under certain conditions.
include README.md

# This actually adds the data file.
include python_sample_package_with_data/mydata.txt

python-sample-package-with-data

#!/usr/bin/env python3

import python_sample_package_with_data

print(python_sample_package_with_data.get_data(), end='')

python_sample_package_with_data/__init__.py

try:
    import importlib.resources as importlib_resources
except ImportError:
    # In PY<3.7 fall-back to backported `importlib_resources`.
    import importlib_resources

def get_data():
    return importlib_resources.read_text(__name__, 'mydata.txt')

python_sample_package_with_data/mydata.txt

hello data

setup.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from setuptools import setup, find_packages

from os import path
this_directory = path.abspath(path.dirname(__file__))
with open(path.join(this_directory, 'README.md')) as f:
    long_description = f.read()

setup(
    name='python-sample-package-with-data',
    version='0.0.3',
    description='My short description',
    long_description=long_description,
    long_description_content_type='text/markdown',
    url='https://github.com/cirosantilli/python-sample-package-with-data',
    author='Ciro Santilli',
    author_email='ciro.santilli.contact@gmail.com',
    packages=find_packages(),
    include_package_data=True,
    scripts=['python-sample-package-with-data'],
)

Bibliography:

Related