While working on one project I've met a problem that I can't to specify to not touch my configuration files for python package that uses setup.py technique. To solve this problem I've implemented the following solution that works for me. If this idea worths it, I can make a patch relative needed version of python. Here is the patch I've done for that project (inlined here to show the idea). # HG changeset patch # Node ID 286864b5c6a30d0ebba5fc99876013c85c06ab59 # Parent fc4dfd9ad64f477a0326995bea7cda12e33ddb39 Add 'preserve files' functionality to setup() while installation. (clean version) diff -r fc4dfd9ad64f -r 286864b5c6a3 setup.py --- a/setup.py Wed Dec 13 12:50:46 2006 +0300 +++ b/setup.py Mon Dec 18 14:01:34 2006 +0300 @@ -26,17 +26,66 @@ # POSSIBILITY OF SUCH DAMAGE. from distutils.core import setup +from distutils.command.install_data import install_data +from distutils.util import change_root, convert_path +from types import StringType -import sys +import sys,os pyver = "%d.%d" % sys.version_info[0:2] + +class smart_install_data(install_data): + def run(self): + # Use revers order for safe removal + for i in range(len(self.data_files)-1, -1, -1): + f = self.data_files[i] + if type(f) is StringType: + continue + if len(f) <= 2: + continue + # Ok, we have additional value, do some magick according it. + if f[2] != "preserve": + # Nope, we do not know it. Just ignore for now. + # Should we scream about it? + continue + # Check a tuple with path to install to and a list of files + dir = convert_path(f[0]) + if not os.path.isabs(dir): + dir = os.path.join(self.install_dir, dir) + elif self.root: + dir = change_root(self.root, dir) + + if f[1] == []: + # If there are no files listed, the user must be + # trying to create an empty directory, so just ignore + # it. + # Should we scream in this case? + continue + + # Check files one by one. + # Use revers order for safe removal + for j in range(len(f[1])-1, -1, -1): + data=f[1][j] + data = convert_path(data) + if not os.path.isfile(data): + # Again skip dirs. + continue + dst = os.path.join(dir, os.path.basename(data)) + if not os.path.exists(dst): + continue + del f[1][j] + if len(f[1]) == 0: + del self.data_files[i] + + return install_data.run(self) setup(name = 'usher', version = '0.1', package_dir = { 'usher':'python' }, packages = ['usher', 'usher.ushercli', 'usher.usherlnm', 'usher.utils', 'usher.usherctrl'], + cmdclass = {'install_data':smart_install_data}, data_files = [ ('/etc/init.d', ['initscripts/usherctrl', 'initscripts/usherlnm']), - ('/etc/usher', ['configs/usherctrl.config', 'configs/usherlnm.config', 'configs/ushercli.config']), + ('/etc/usher', ['configs/usherctrl.config', 'configs/usherlnm.config', 'configs/ushercli.config'], "preserve"), ("/usr/lib/python%s/site-packages/usher/usherctrl" % pyver, ['python/usherctrl/app.tac']), ("/usr/lib/python%s/site-packages/usher/usherlnm" % pyver, ['python/usherlnm/app.tac']) ]