<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Valentin's Lab &#187; distutils2</title>
	<atom:link href="https://vaab.blog.kal.fr/tag/distutils2/feed/" rel="self" type="application/rss+xml" />
	<link>https://vaab.blog.kal.fr</link>
	<description>Ratiocination of an opensource techie</description>
	<lastBuildDate>Thu, 15 Nov 2018 08:04:35 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=4.1.1</generator>
	<atom:link rel="payment" title="Flattr this!" href="https://flattr.com/submit/auto?user_id=vaab&amp;popout=1&amp;url=https%3A%2F%2Fvaab.blog.kal.fr%2F&amp;language=en_US&amp;category=text&amp;title=Valentin%27s+Lab&amp;description=Ratiocination+of+an+opensource+techie&amp;tags=blog" type="text/html" />
	<item>
		<title>comparison of minimal packaging between distribute and distutils2</title>
		<link>https://vaab.blog.kal.fr/2013/02/22/comparison-of-minimal-packaging-between-distribute-and-distutils2/</link>
		<comments>https://vaab.blog.kal.fr/2013/02/22/comparison-of-minimal-packaging-between-distribute-and-distutils2/#comments</comments>
		<pubDate>Fri, 22 Feb 2013 15:27:14 +0000</pubDate>
		<dc:creator><![CDATA[vaab]]></dc:creator>
				<category><![CDATA[dev]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[distribute]]></category>
		<category><![CDATA[distutils2]]></category>
		<category><![CDATA[packaging]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://vaab.blog.kal.fr/?p=382</guid>
		<description><![CDATA[In a pythonic mind, we shoud keep things simple as possible. But when having to deal with distribution of your code, especially if it's ONE small python file, you'll might cringe when facing the boilerplate that is required. Even with &#8230;<p class="read-more"><a href="https://vaab.blog.kal.fr/2013/02/22/comparison-of-minimal-packaging-between-distribute-and-distutils2/">Read more &#187;</a></p>]]></description>
				<content:encoded><![CDATA[
<div class="document">


<!-- -*- mode: rst -*- -->
<p>In a pythonic mind, we shoud keep things simple as possible.</p>
<p>But when having to deal with distribution of your code,
especially if it's ONE small python file, you'll might cringe
when facing the boilerplate that is required. Even with
<a class="reference external" href="http://pythonhosted.org/distribute/setuptools.html">distribute</a> in place of setuptools.</p>
<p>And speaking of packaging system, python has a very complex
history of them (between distutils, setuptools, distribute,
distutils2), adding a considerable burden to get a clear
idea of what system you should use, and get a complete
documentation of one system. Especially when whole part of each
system share code, ideas, compatibility but aims to be better in
some obscure part for a newcomer.</p>
<p>Notice how this
<a class="reference external" href="http://stackoverflow.com/questions/6344076/differences-between-distribute-distutils-setuptools-and-distutils2">stackoverflow question about python packaging systems</a> gets
answered brilliantly and how concrete differences between all
these packaging solutions weren't mentioned.</p>
<p>However, I wanted a dead simple way to distribute my single file package. And I
found 2 ways:</p>
<blockquote>
<ul class="simple">
<li>one with <tt class="docutils literal">distribute</tt> (the actually recommended packaging
system),</li>
<li>one with <tt class="docutils literal">distutils2</tt> (the upcoming-but-not-finished replacement
of <tt class="docutils literal">distribute</tt>).</li>
</ul>
</blockquote>
<p>I realized that I could illustrate some simple differences for newcomers
when facing the need to package a simple python file.</p>
<div class="section" id="the-goal">
<h3>The goal</h3>
<p>You have a file <tt class="docutils literal">foo.py</tt> holding whatever python code you
want. <tt class="docutils literal">foo.py</tt> is alone in a directory.</p>
<div class="section" id="install-ability">
<h4>Install-ability</h4>
<p>You need to be able to type <tt class="docutils literal">python setup.py install</tt> (or something similar)
in the source directory and all the magic required will fire out to set things
how they are supposed to be in your python libraries, allowing you to invoke
<tt class="docutils literal">import foo</tt> in any of your python file without any unfriendly exception
being cast.</p>
</div>
<div class="section" id="distributability">
<h4>distributability</h4>
<p>Next, you should be able to type <tt class="docutils literal">python setup.py sdist register upload</tt> (or
something similar) to build a source distribution, register the package to the PyPI,
and send it. So that, finally, from any computer having access to internet, you
could cast a <tt class="docutils literal">pip install foo</tt> (or something similar) to get your package
downloaded from the PyPI, and installed.</p>
</div>
</div>
<div class="section" id="distribute-way">
<h3>Distribute way</h3>
<p>This is the simplest way I found to distribute
a ONE small python file using <tt class="docutils literal">distribute</tt>, which
seems to be the current best solution waiting
for <tt class="docutils literal">distutils2</tt>.</p>
<div class="section" id="requirements">
<h4>Requirements</h4>
<p>Make sure you have the last <tt class="docutils literal">distribute</tt> installed.
You can install it with this command:</p>
<pre class="literal-block">
curl -O http://python-distribute.org/distribute_setup.py
python distribute_setup.py
</pre>
</div>
<div class="section" id="setup-py-file">
<h4>setup.py file</h4>
<p>Then create a <tt class="docutils literal">setup.py</tt> file in the same directory than <tt class="docutils literal">foo.py</tt>, containing:</p>
<pre class="literal-block">
from setuptools import setup
setup(
    ## Required for ``python setup.py install``
    name=&quot;foo_utils&quot;,
    version=&quot;0.1&quot;,
    py_modules=[&quot;foo&quot;]

    ## Required for ``python setup.py sdist upload install``
)
</pre>
<p>The <tt class="docutils literal">name</tt> will be your package name and <tt class="docutils literal">version</tt> will be its version, these
are used for naming the <tt class="docutils literal">.egg</tt> and PyPI references.</p>
<p>The following is a less documented option and makes the solution I have found so small:
<tt class="docutils literal">py_modules</tt> is the python module you want to distribute. Typing <tt class="docutils literal">foo</tt> targets
the <tt class="docutils literal">foo.py</tt> file.</p>
<p>Actually, complete reference of this trick can be found in <a class="reference external" href="http://docs.python.org/2/distutils/examples.html">distutils
documentation</a>, I couldn't find any reference to <tt class="docutils literal">py_modules</tt>
anywhere in the <a class="reference external" href="http://pythonhosted.org/distribute/setuptools.html">distribute documentation</a>.</p>
</div>
<div class="section" id="tada">
<h4>Tada !</h4>
<p>The small <tt class="docutils literal">setup.py</tt> you've written should allow you to type:</p>
<pre class="literal-block">
python setup.py install
</pre>
<!-- to reach the "install-ability" goal. -->
<p>To send it to PyPI, you'll need some other metadata as the author, summary,
licence and maybe a small description. These are to be added in your <tt class="docutils literal">setup.py</tt>
file, and then:</p>
<pre class="literal-block">
python setup.py sdist register upload
</pre>
<p>... will send it to PyPI.</p>
<p>At last you'll then be able to install it from anywhere with:</p>
<pre class="literal-block">
pip install foo_utils
</pre>
</div>
</div>
<div class="section" id="distutils2-way">
<h3>Distutils2 way</h3>
<p>The major modification that you'll notice here is the fact that the
configuration is not executable code anymore: <tt class="docutils literal">setup.py</tt> is replaced
by <tt class="docutils literal">setup.cfg</tt>.</p>
<div class="section" id="id1">
<h4>Requirements</h4>
<p>You need to install <tt class="docutils literal">distutils2</tt>:</p>
<pre class="literal-block">
pip install distutils2
</pre>
<p>If you have any trouble installing <tt class="docutils literal">distutils2</tt>, you might be interested in
the ending section about <tt class="docutils literal">the truth about distutils2</tt>. You could also try
something like that (adapt the version of course !):</p>
<pre class="literal-block">
cd /tmp
wget https://pypi.python.org/packages/source/D/Distutils2/Distutils2-1.0a4.tar.gz
tar xvzf Distutils2-1.0a4.tar.gz
cd Distutils2-1.0a4
python setup.py install
</pre>
</div>
<div class="section" id="setup-cfg">
<h4>setup.cfg</h4>
<p>In the same directory than <tt class="docutils literal">foo.py</tt>, you can create <tt class="docutils literal">setup.cfg</tt>
containing:</p>
<pre class="literal-block">
[metadata]
name = foo_utils
version = 0.1

[files]
modules = foo
</pre>
<p>Notice that <tt class="docutils literal">py_modules</tt> is in a <tt class="docutils literal">files</tt> section and has been renamed
to <tt class="docutils literal">modules</tt>.</p>
<p>This first version of <tt class="docutils literal">setup.cfg</tt> will allow you to achieve first goal of
&quot;install-ability&quot;. But you'll need more to get your code sent to PyPI:</p>
<pre class="literal-block">
[metadata]
name = foo_utils
version = 0.1.0
summary = A Simple example Foo program
description-file = README.rst CHANGELOG.rst

## sdist info
author = John Doe
author_email = john.doe&#64;example.com
classifier =
    Development Status :: 3 - Alpha
    License :: OSI Approved :: GNU General Public License (GPL)

[files]
modules = foo_utils
extra_files =
    README.rst
    CHANGELOG.rst
</pre>
<p>Well, it's not that small, but I'm not sure what is actually really required, and
I think a small summary or description won't hurt. Notice that we have to repeat our
selves for the inclusion of the <tt class="docutils literal">README.rst</tt> and <tt class="docutils literal">CHANGELOG.rst</tt> files that are used in
the description.</p>
<p>Of course, all details given hear are subject to changes in the upcoming releases of
<tt class="docutils literal">distutils2</tt>.</p>
</div>
<div class="section" id="id2">
<h4>Tada !</h4>
<p>The small <tt class="docutils literal">setup.cfg</tt> you've written should allow you to type:</p>
<pre class="literal-block">
pysetup install
</pre>
<p>To reach the &quot;install-ability&quot; goal. And:</p>
<pre class="literal-block">
pysetup run sdist register upload
</pre>
<p>To send it to PyPI. Then you should be able to install it from anywhere with:</p>
<pre class="literal-block">
pysetup install foo_utils
</pre>
<div class="note">
<p class="first admonition-title">Note</p>
<p class="last">packages made with <tt class="docutils literal">distutils2</tt> won't be compatible with <tt class="docutils literal">pip install PACKAGE</tt> commands as
they do not provide any <tt class="docutils literal">setup.py</tt>. You'll receive <tt class="docutils literal">IOError: [Errno 2] No such file or directory</tt>.</p>
</div>
<p>If any of these commands don't work, jump ahead to the next section !.</p>
</div>
<div class="section" id="the-truth-about-distutils2">
<h4>The truth about distutils2</h4>
<p>Before getting something actually working, I ran in multiple issues, and these are some of
the trick I did to make it work.</p>
<p>First, get it installed:</p>
<pre class="literal-block">
cd /tmp
wget https://pypi.python.org/packages/source/D/Distutils2/Distutils2-1.0a4.tar.gz
tar xvzf Distutils2-1.0a4.tar.gz
cd Distutils2-1.0a4
python setup.py install
</pre>
<p>Then, I proceeded towards the distribute installation:</p>
<pre class="literal-block">
$ pysetup foo_utils
No handlers could be found for logger &quot;distutils2&quot;
</pre>
<p>Hum, after hacking into the <tt class="docutils literal">distutils2</tt> code, I've found that distutils hadn't
any default logger, once one set, it was only to realize that it wanted to display
a simple error to tell me that I messed with my arguments. The correct command is:</p>
<pre class="literal-block">
root&#64;myhost$ pysetup install foo_utils
Checking the installation location...
Unable to write in &quot;/usr/lib/python2.7/site-packages&quot;. Do you have the permissions ?
root&#64;myhost$
</pre>
<p>What are you talking about ?! I'm root ! After looking around, I found there were no such
directory <tt class="docutils literal"><span class="pre">site-packages</span></tt> in my testing VM, which should mimick an Ubuntu 12.04 standard
install. I pursued by:</p>
<pre class="literal-block">
root&#64;myhost$ mkdir /usr/lib/python2.7/site-packages
root&#64;myhost$ pysetup install foo_utils
Checking the installation location...
Getting information about 'foo_utils'...
u'python-debian': u'0.1.21ubuntu1' is not a valid version (field 'Version')
u'python-apt': u'0.8.3ubuntu7' is not a valid version (field 'Version')
u'ufw': u'0.31.1-1' is not a valid version (field 'Version')
u'Landscape Client': u'12.05' is not a valid version (field 'Version')
Installing u'foo_utils' 0.1.0...
running install_dist
running build
running build_py
running install_lib
byte-compiling /usr/lib/python2.7/site-packages/foo.py to foo.pyc
running install_distinfo
creating /usr/lib/python2.7/site-packages/foo-utils-0.1.0.dist-info
creating /usr/lib/python2.7/site-packages/foo-utils-0.1.0.dist-info/METADATA
creating /usr/lib/python2.7/site-packages/foo-utils-0.1.0.dist-info/INSTALLER
creating /usr/lib/python2.7/site-packages/foo-utils-0.1.0.dist-info/REQUESTED
creating /usr/lib/python2.7/site-packages/foo-utils-0.1.0.dist-info/RECORD
root&#64;myhost$
</pre>
<p>Success ! I then did the test to see if I could &quot;import&quot; my lib:</p>
<pre class="literal-block">
root&#64;myhost$ python
Python 2.7.3 (default, Aug  1 2012, 05:14:39)
[GCC 4.6.3] on linux2
Type &quot;help&quot;, &quot;copyright&quot;, &quot;credits&quot; or &quot;license&quot; for more information.
&gt;&gt;&gt; import foo
Traceback (most recent call last):
  File &quot;&lt;stdin&gt;&quot;, line 1, in &lt;module&gt;
ImportError: No module named foo
&gt;&gt;&gt;
</pre>
<p>Failure ! A quick check to <tt class="docutils literal">sys.path</tt> will confirm that if the &quot;site-package&quot; was not
existent, it wasn't included in the <tt class="docutils literal">sys.path</tt>... which makes sense. I'm not aware of
all these details, but why <tt class="docutils literal">distutils2</tt> then tries to install packages in this directory ?</p>
<p>Anyway, if I want to make sure that <tt class="docutils literal"><span class="pre">site-packages</span></tt> gets in <tt class="docutils literal">sys.path</tt>, I can follow <a class="reference external" href="http://superuser.com/questions/247620/how-to-globally-modify-the-default-pythonpath-sys-path">superuser advice</a>:</p>
<pre class="literal-block">
echo ../site-packages &gt; /usr/lib/python2.7/dist-packages/site-packages.pth
</pre>
<p>This will easily add <tt class="docutils literal"><span class="pre">site-packages</span></tt> directory system wide.</p>
</div>
</div>
<div class="section" id="conclusion">
<h3>Conclusion</h3>
<p>Is the packaging system of python dead-simple for one file ? Well, yes, once a straightforward recipe was discovered painfully.</p>
<p>Is it easy to find clear and unambiguous documentation ? Not really.</p>
<p>Is <tt class="docutils literal">distutils2</tt> finished ? Nope.
Did you try with <a class="reference external" href="http://hg.python.org/distutils2/">last available code from hg.python.org</a> ? Yes.</p>
<p>Do you still need to use <tt class="docutils literal">distribute</tt> ? Yes.</p>
<p>Any comments ?</p>
</div>
</div>
 <p><a href="https://vaab.blog.kal.fr/?flattrss_redirect&amp;id=382&amp;md5=b1ad1bba5169dd4715c5a089b8fe888b" title="Flattr" target="_blank"><img src="https://vaab.blog.kal.fr/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>https://vaab.blog.kal.fr/2013/02/22/comparison-of-minimal-packaging-between-distribute-and-distutils2/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<atom:link rel="payment" title="Flattr this!" href="https://flattr.com/submit/auto?user_id=vaab&amp;popout=1&amp;url=https%3A%2F%2Fvaab.blog.kal.fr%2F2013%2F02%2F22%2Fcomparison-of-minimal-packaging-between-distribute-and-distutils2%2F&amp;language=en_GB&amp;category=text&amp;title=comparison+of+minimal+packaging+between+distribute+and+distutils2&amp;description=In+a+pythonic+mind%2C+we+shoud+keep+things+simple+as+possible.+But+when+having+to+deal+with+distribution+of+your+code%2C+especially+if+it%27s+ONE+small+python+file%2C+you%27ll+might...&amp;tags=distribute%2Cdistutils2%2Cpackaging%2Cpython%2Cblog" type="text/html" />
	</item>
	</channel>
</rss>
