Let's take the following project layout:
$ ls -R .
.:
package setup.py
./package:
__init__.py dir file.dat module.py
./package/dir:
tool1.dat tool2.dat
And the following content for setup.py
:
$ cat setup.py
from distutils.core import setup
setup(name='pyproj',
version='0.1',
packages=[
'package',
],
package_data={
'package': [
'*',
'dir/*',
],
},
)
As you can see, I want to include all non-Python files in package/
and package/dir/
directories. However, running setup.py install
would raise the following error:
$ python setup.py install
running install
running build
running build_py
creating build
creating build/lib
creating build/lib/package
copying package/module.py -> build/lib/package
copying package/__init__.py -> build/lib/package
error: can't copy 'package/dir': doesn't exist or not a regular file
What gives?
I created a function that gives me all the files that I need
And used that as arugment for
package_data
In your
package_data
, your'*'
glob will matchpackage/dir
itself, and try to copy that dir as a file, resulting in a failure. Find a glob that won't match the directorypackage/dir
, rewriting yoursetup.py
along these lines:Given your example, that's just changing
'*'
to'*.dat'
, although you'd probably need to refine your glob more than that, just ensure it won't match'dir'
Not quite sure why, but after some troubleshooting I realised that renaming the directories that had dots in their names solved the problem. E.g.
Note: I'm using Python 2.7.10, SetupTools 12.2
You could use Distribute instead of distutils. It works basically the same (for the most part, you will not have to change your setup.py) and it gives you the exclude_package_data option: