23
votes

I have a python application that has a fixed layout which I cannot change. I would like to wrap it up using setuptools, e.g. write a setup.py script.

Using the official documentation, I was able to write a first template. However, the application in question uses a lot of additional data files that are not explicitly part of any package. Here's an example source tree:

somepackage
   __init__.py
   something.py
   data.txt
additionalstuff
   moredata.txt
INFO.txt

Here's the trouble: The code in something.py reads the files moredata.txt and INFO.txt. For the former, I can monkeypatch the problem by adding an empty additionalstuff/__init__.py file to promote additionalstuff to a package and have it picked up by setuptools. But how could I possibly add INFO.txt to my .egg?

Edit

The proposed solutions using something along the lines of

package_data = { '' : ['moredata.txt','INFO.txt']}

does not work for me because the files moredata and INFO.txt do not belong to a package, but are part of a separate folder that is only part of the module as a whole, not of any individual package. As explained above, this could be fixed in the case of moredata.txt by adding a __init__.py file to additionpythonalstuff, thus promoting it to a package. However, this is not an elegant solution and does not work at all for INFO.txt, which lives in the top-level directory.

Solution

Based on the accepted answer, here's the solution

This is the setup.py:

from setuptools import setup, find_packages

setup(
    name='mytest',
    version='1.0.0',
    description='A sample Python project',
    author='Test',
    zip_safe=False,
    author_email='[email protected]',
    keywords='test',
    packages=find_packages(),
    package_data={'': ['INFO.txt', 'moredata.txt'],
                  'somepackage':['data.txt']},
    data_files=[('.',['INFO.txt']),
                ('additionalstuff',['additionalstuff/moredata.txt'])],
    include_package_data=True,
)

And this is the MANIFEST.in:

include INFO.txt
graft additionalstuff
include somepackage/*.txt
2
It is not a duplicate. In the given question, the accepted solution is to use package_data. This I have already done. Please take note that the given solution to use '' (empty string) does not work for me since it explicitly refers to "all packages", which does not apply to me, since the file I want to add does not belong to any package, which is precisely the problem I'm facing. - carsten

2 Answers

7
votes

There is also data_files

data_files=[("yourdir",
             ["additionalstuff/moredata.txt", "INFO.txt"])],

Have a think about where you want to put those files. More info in the docs.

1
votes

You need to use package_data. Put your setup.py in the root directory, then you just need to:

package_data={'': [
    'somepackage/*.txt',
    'additionalstuff/*.txt',
    '*.txt',
]