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
<
In your package_data
, your '*'
glob will match package/dir
itself, and try to copy that dir as a file, resulting in a failure. Find a glob that won't match the directory package/dir
, rewriting your setup.py
along these lines:
from distutils.core import setup
setup(name='pyproj',
version='0.1',
packages=[
'package',
],
package_data={
'package': [
'*.dat',
'dir/*'
],
},
)
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'
I created a function that gives me all the files that I need
def find_files(directory, strip):
"""
Using glob patterns in ``package_data`` that matches a directory can
result in setuptools trying to install that directory as a file and
the installation to fail.
This function walks over the contents of *directory* and returns a list
of only filenames found. The filenames will be stripped of the *strip*
directory part.
"""
result = []
for root, dirs, files in os.walk(directory):
for filename in files:
filename = os.path.join(root, filename)
result.append(os.path.relpath(filename, strip))
return result
And used that as arugment for package_data
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:
from distribute_setup import use_setuptools
use_setuptools()
from setuptools import setup
setup(name='pyproj',
version='0.1',
packages=[
'package',
],
package_data={
'package': [
'*.dat',
'dir/*'
],
},
exclude_package_data={
'package': [
'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.
chart.js-2.4.0 => chart_js-2_4_0
Note: I'm using Python 2.7.10, SetupTools 12.2