Problem
Distutils requires that you manually specify each directory and data-file to be included in the distribution. For packages with large and deep sub-package hierarchies it can be a pain to keep this list in sync with the code, particularly as forgetting an entry is not noticable until a user happens to report that a resource is missing.
Solution
Use an automatic scanning mechanism to generate the data_files parameter for setup:
import os
def npFilesFor( dirname ):
"""Return all non-python-file filenames in dir"""
result = []
allResults = []
for name in os.listdir(dirname):
path = os.path.join( dirname, name )
if (
os.path.isfile( path) and
os.path.splitext( name )[1] not in
('.py','.pyc','.pyo')
):
result.append( path )
elif os.path.isdir( path ) and name.lower() !='cvs':
allResults.extend( npFilesFor(path))
if result:
allResults.append( (dirname, result))
return allResultsThen call it for the directories which contain data-files you want to include.
dataFiles = (
npFilesFor( 'pytable') +
npFilesFor( os.path.join('pytable','doc'))
)and pass the result to setup:
setup (
name = "pytable",
version = "0.7.7a",
data_files = dataFiles,
cmdclass = {'install_data':smart_install_data},
**extraArguments
)(See DistutilsInstallDataScattered for the smart_install_data command.)
Discussion
Again, there should be some way to do this with a distutils template processing call or something, but this direct processing approach works well enough. This approach is very similar to DistutilsAutoPackageDiscovery.
