Help with Distutils

J

Johan Svedberg

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?
 
J

Jorge Godoy

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?

Could you explain when and why you are trying to do that?
 
J

Johan Svedberg

* Jorge Godoy said:
Could you explain when and why you are trying to do that?

Well, the reason is that I've told setup.py to install a bunch of
templates in <prefix>/share/myapp/templates/ and I want to make sure
that myapp can find these no matter what <prefix> is.
 
D

David M. Cooke

At some point said:
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.
 
J

Jorge Godoy

Well, the reason is that I've told setup.py to install a bunch of
templates in <prefix>/share/myapp/templates/ and I want to make sure
that myapp can find these no matter what <prefix> is.

I see somebody suggested that you use __file__, from the module.

Another option --- I'm using it --- is to have a config file and have
distutils to call a postinstall script (requires Python 2.3+) to update the
directory in such a config file.

You can parse it with ConfigParser in your application. It also adds an
interesting way of putting things in different places and still having them
to work as expected :)
 
D

David M. Cooke

At some point said:
I see somebody suggested that you use __file__, from the module.

Another option --- I'm using it --- is to have a config file and have
distutils to call a postinstall script (requires Python 2.3+) to update the
directory in such a config file.

Of course, you have to able to find the config file, but that's a
smaller kettle of fish. I suppose you could put the config file in
your modules directory (like I suggested), and have your other data
files sitting outside (in /usr/share/whatever).
 
J

Jorge Godoy

Of course, you have to able to find the config file, but that's a
smaller kettle of fish. I suppose you could put the config file in
your modules directory (like I suggested), and have your other data
files sitting outside (in /usr/share/whatever).

If all your concerns are with unix machines, taht would be great. I don't
know if his software should also run on other platforms and OSs. Anyway,
you have basically two points, for Unix and Windows: /etc/something/config
and c:\Windows\something\config. You can check the OS and go to the correct
directory... It makes it harder to find only one file: the config file. The
other way you'd have to check all the other files...
 
J

Johan Svedberg

* Johan Svedberg said:
Well, the reason is that I've told setup.py to install a bunch of
templates in <prefix>/share/myapp/templates/ and I want to make sure
that myapp can find these no matter what <prefix> is.

When I think more about it, the cleanest way would probably be if I
could in some way patch the relevant files so that they point to the
right location. This would ofcourse have to be done after the user has
decided where he wants to install things. Very much like the way
configure and make works together.

I'm going to look around more to see if I can find any good solution by
looking at other peoples projects. I find it really strange that there
isn't some generic way of doing this since application installment is a
pretty central part.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top