Help with Distutils

David M. Cooke cookedm+news at physics.mcmaster.ca
Thu May 13 14:52:38 EDT 2004


At some point, Johan Svedberg <johan at svedberg.pp.se> wrote:

> Hi!
>
> I just started playing around with Distutils and there is one thing I
> could use some help with. I'm wondering if there is some convenient way
> to access the directories where the data_files was installed?

If you're using the data_files argument to setup(), it's behaviour is
described in the manual. Basically, if the specified directory is
absolute, the files go there. Otherwise, the directory is relative to
sys.prefix (or sys.exec_prefix if extension modules are installed).

For example (from the documentation):

### setup.py
setup(...
      py_modules = ['mod'],
      data_files=[('bitmaps', ['bm/b1.gif', 'bm/b2.gif']),
                  ('config', ['cfg/data.cfg']),
                  ('/etc/init.d', ['init-script'])]
     )
###

I'll assume sys.prefix is '/usr'.

b1.gif and b2.gif will installed by default /usr/bitmaps',
and data.cfg in /usr/config. init-script will be installed in /etc/init.d.

Now, there's a difficulty. If I run the setup.py script like this:

$ python setup.py install --prefix=/usr/local

then b1.gif, for instance, gets installed in /usr/local/bitmaps. So
you can't hard-code /usr/bitmaps as the path to look at in your
application. One thing you can do is use the __file__ variable that's
defined in a module to find out where that module is installed, and
work your way up.

With the above call to setup.py, the module 'mod.py' would be
installed in /usr/local/lib/python2.3/site-packages, and within
mod.py, __file__ would be
'/usr/local/lib/python2.3/site-packages/mod.pyc', so you could walk
the tree up.

However, there's more problems. I install somethings in my home
directory like this:

$ python setup.py install --home=~/usr

Now mod.__file__ is '/home/cookedm/usr/lib/python/mod.pyc'. Things can
get more complicated if the --install-lib option is used.

Ugh.

One solution that I've seen used several times is to install data
files in the package directory:

### setup.py
from distutils.core import setup
from distutils.command.install_data import install_data

class my_install_data(install_data):
    def finalize_options(self):
        self.set_undefined_options('install',
                                   ('install_lib', 'install_dir'))
        install_data.finalize_options(self)

setup(...
      packages = ['mypackage', 'mypackage.data'],
      data_files=[('mypackage/data', ['bm/b1.gif', 'bm/b2.gif'])],
      cmdclass = { 'install_data' : my_install_data }
     )
###

b1.gif and b2.gif will now be installed in the same directory as the
modules in mypackage.data. A file mypackage.data.__init.py can look
like this:

### mypackage.data.__init__
import os.path
def data_dir():
    mod_loc = os.path.dirname(__file__)
    return os.path.abspath(mod_loc)
###

Then in your main code,

### mypackage.do_stuff_module
import mypackage.data
...
        data_dir = mypackage.data.data_dir()
        b1gif = open(os.path.join(data_dir, 'b1.gif'))
###

Hope this helps.

-- 
|>|\/|<
/--------------------------------------------------------------------------\
|David M. Cooke
|cookedm(at)physics(dot)mcmaster(dot)ca



More information about the Python-list mailing list