<br><div class="gmail_quote">On Thu, Dec 29, 2011 at 10:04 AM, Jonathan Ballet <span dir="ltr">&lt;<a href="mailto:jon@multani.info">jon@multani.info</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Hi,<br>
<br>
I hav a desktop application which currently runs only on Linux using<br>
pyGtk, and is packaged using setuptools/distribute.<br>
<br>
It ships with a number of non-Python files:<br>
<br>
* documentation (README, Changelog, Authors, etc.)<br>
* .desktop file<br>
* application specific&#39;s icons<br>
* one man file<br>
* translation files<br>
* and one executable script<br>
<br>
The setup.py file looks like this so far:<br>
<br>
    setup(<br>
        name=&#39;myapp&#39;,<br>
        ...<br>
        packages=[&quot;myapp&quot;],<br>
        package_dir={&quot;myapp&quot;: &quot;myapp/&quot;},<br>
        data_files=[<br>
            (&#39;share/myapp&#39;, [&#39;README&#39;, &#39;Changelog&#39;, &#39;Authors&#39;]),<br>
            (&#39;share/applications&#39;, [&#39;myapp.desktop&#39;]),<br>
            (&#39;share/pixmaps&#39;, glob.glob(&#39;myapp/pixmaps/*&#39;)),<br>
            (&#39;share/man/man1&#39;, [&#39;myapp.1&#39;]),<br>
            (&#39;share/locale/fr/LC_MESSAGES&#39;, [&#39;mo/fr/myapp.mo&#39;]),<br>
            ... numerous other translation files ...<br>
<br>
        ],<br>
        entry_points={&#39;console_scripts&#39;: [&#39;myapp=myapp:run&#39;]},<br>
    )<br>
<br>
but I somehow have a bad feeling about this, except for the entry point<br>
(which does a great job).<br>
<br>
When I run ``python setup.py install --prefix=&quot;local&quot;``, everything gets<br>
installed into ``site-packages/myapp/``, Python files and data files,<br>
which seems to be a feature of setuptools/distribute over plain<br>
Distutils, whereas it seems to be &quot;cleaner&quot; to split things as described<br>
by the ``data_files`` setting (and AFAIK, Distutils does just that).<br>
<br>
To be clear, I end up with<br>
<br>
    install/lib/python2.7/site-packages/myapp.egg/myapp.py<br>
    ...<br>
    install/lib/python2.7/site-packages/myapp.egg/share/myapp/README<br>
    ...<br>
    install/lib/python2.7/site-packages/myapp.egg/share/pixmaps/myapp.png<br>
    ...<br>
    install/lib/python2.7/site-packages/myapp.egg/share/locale/fr/LC_MESSAGES/myapp.mo<br>
    ...<br>
<br>
Whereas I &quot;think&quot; I would like to have this instead, which looks more<br>
organized to me:<br>
<br>
    install/lib/python2.7/site-packages/myapp.egg/myapp.py<br>
    ...<br>
    install/share/myapp/README<br>
    ...<br>
    install/share/pixmaps/myapp.png<br>
    ...<br>
    install/share/locale/fr/LC_MESSAGES/myapp.mo<br>
    ...<br>
<br>
Actually, someone reported this &quot;bug&quot; to me, as he was expecting the<br>
latter whereas he got the former.<br>
<br>
<br>
Also, the application currently uses a custom method to find the<br>
location of those data files (mainly the icons which are used at<br>
run-time). It does a &quot;terrible&quot; job of trying several well-known<br>
locations until it either reaches the file or fails with a laconic<br>
error. I guess using ``pkg_resources`` data-access API would be much<br>
better, right?<br></blockquote><div><br></div><div>Well, it&#39;d certainly be One Obvious Way to do it.  ;-)</div><div><br></div><div>The way I look at it is, if the &quot;data&quot; file is really just a code constant (i.e., not user-modifiable, nor modified by the program), then it&#39;s not really data, it&#39;s part of the code.  A &quot;resource&quot; rather than data.  That&#39;s what the pkg_resources API is for: resources.</div>
<div><br></div><div>Now, if it&#39;s data or configuration -- something the user or program will touch -- then resources don&#39;t cut it.  You need a way to set that stuff up.  Same for documentation, unless it&#39;s a program-served resource.</div>
<div><br></div><div>Setuptools doesn&#39;t handle those so well; eggs and easy_install were designed for application *plugins* more than applications; it was assumed that when you install the self-contained .egg, the application platform would provide documentation browsing and configuration support.  So, there was no real provision for installing things to multiple places; even scripts were a bit of an afterthought.</div>
<div> </div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Finally, I&#39;m also concerned about Linux distribution packagers, and I<br>
would like to package the application so that it also useful and easy<br>
for them to repackage and distribute it.<br></blockquote><div><br></div><div>If you actually build a system package (e.g. via bdist_rpm), you&#39;ll notice that your package will actually be installed the way you want: the data files will go to the right place.  That&#39;s because &quot;setup.py install --root /somepath&quot; or &quot;setup.py install --single-version-externally-managed&quot; will use distutils conventions for installation.  So, don&#39;t worry about the system packagers, you&#39;re doing it right (enough) with your current mechanism.</div>
<div> </div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">After reading setuptools/distribute and distutils documentations, I&#39;m<br>
still not what is the best way to proceed. Any hints would be greatly<br>
appreciated.<br></blockquote><div><br></div><div>Based on what you&#39;re trying to accomplish, I&#39;d suggest:</div><div><br></div><div>1. Use pkg_resources to access constant &quot;resource&quot; files that are not user-changeable</div>
<div>2. Leave configuration, data, or documentation files as &#39;data_files&#39; in your setup.py</div><div>3. If your package doesn&#39;t need easy_install support (i.e., it has no dependencies to download), add a setup.cfg with:</div>
<div><br></div><div>[install]</div><div>single_version_externally_managed = 1</div><div>record = RECORD</div><div><br></div><div>And tell people to install it using &quot;setup.py install&quot;.  This will install it in a flat (no .egg subdirectory) fashion, and with data files to the share/ location you expect.</div>
<div><br></div><div>If you *do* need easy_install support, then it&#39;s a bit more complex, so I&#39;m not going to spell that out unless you first say that you do need it.  ;-)</div><div><br></div></div>