<?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>Bluehorn's Blog &#187; Python</title>
	<atom:link href="http://www.landschoff.net/blog/tag/python/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.landschoff.net/blog</link>
	<description>Ramblings of Torsten Landschoff</description>
	<lastBuildDate>Thu, 08 Jul 2010 10:43:01 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>How to run a single unit test/unit test module with py.test</title>
		<link>http://www.landschoff.net/blog/2010/07/how-to-run-a-single-unit-testunit-test-module-with-py-test/</link>
		<comments>http://www.landschoff.net/blog/2010/07/how-to-run-a-single-unit-testunit-test-module-with-py-test/#comments</comments>
		<pubDate>Thu, 08 Jul 2010 10:43:01 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[How-To]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[py.test]]></category>

		<guid isPermaLink="false">http://www.landschoff.net/blog/?p=203</guid>
		<description><![CDATA[Note to self: It is actually possible to select a single test module or a single test function in py.test.
But passing the file name as argument to a py.test invocation selects only the doctest from that file (wtf!?). Instead, you need to call it like this:
12$ py.test -k test_module &#160; &#160;# to run the tests [...]]]></description>
			<content:encoded><![CDATA[<p>Note to self: It is actually possible to select a single test module or a single test function in <a href="http://pytest.org/">py.test</a>.</p>
<p>But passing the file name as argument to a py.test invocation selects only the doctest from that file (wtf!?). Instead, you need to call it like this:</p>
<div class="codecolorer-container bash mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ py.test <span style="color: #660033;">-k</span> test_module &nbsp; &nbsp;<span style="color: #666666; font-style: italic;"># to run the tests from test_module.py</span><br />
$ py.test <span style="color: #660033;">-k</span> test_func &nbsp; &nbsp; &nbsp;<span style="color: #666666; font-style: italic;"># to run tests having the function name test_func</span></div></td></tr></tbody></table></div>
<p>This is documented in the section <a href="http://codespeak.net/py/dist/test/features.html#advanced-test-selection-and-running-modes">advanced test selection and running modes</a> of the py.test documentation, although I fail to see how this is advanced.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.landschoff.net/blog/2010/07/how-to-run-a-single-unit-testunit-test-module-with-py-test/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Postprocessing conference videos</title>
		<link>http://www.landschoff.net/blog/2010/07/postprocessing-conference-videos/</link>
		<comments>http://www.landschoff.net/blog/2010/07/postprocessing-conference-videos/#comments</comments>
		<pubDate>Sun, 04 Jul 2010 22:03:06 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Debian]]></category>
		<category><![CDATA[How-To]]></category>
		<category><![CDATA[mlt]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[video]]></category>

		<guid isPermaLink="false">http://www.landschoff.net/blog/?p=167</guid>
		<description><![CDATA[I was planning to attend DebConf New York this year, but for a number of reasons I decided not to go. Fortunately, Ferdinand Thommes organized a MiniDebConf in Berlin at LinuxTag and I managed to attend. Thanks, Ferdinand!
There were a number of interesting Talks. I especially liked the talk of our DPL, and those about [...]]]></description>
			<content:encoded><![CDATA[<p>I was planning to attend <a href="http://debconf10.debconf.org/">DebConf New York</a> this year, but for a number of reasons I decided not to go. Fortunately, Ferdinand Thommes organized a <a href="http://www.minidebconf.de/2010/berlin/">MiniDebConf</a> in Berlin at <a href="http://www.linuxtag.org/">LinuxTag</a> and I managed to attend. Thanks, Ferdinand!</p>
<p>There were a number of interesting <a href="http://wiki.debconf.org/wiki/Miniconf-LT-Berlin/2010#Schedule">Talks</a>. I especially liked the talk of our DPL, and those about piuparts and git-buildpackage. In contrast to the other LinuxTag talks, we had a livestream of our talks and recorded (most) of them. The kudos for setting this up goes to Alexander Wirt, who spent quite a few hours to get it up and running.</p>
<p>I have to apologize for being late in bringing my Notebook, which was intended to do the theora encoding of the livestream. This was a misunderstanding on my part, I should have known that this is not going to be setup in the night before show time&#8230; So to compensate the extra hours he had to put in for me, I offered to do the post processing of the videos.</p>
<h2>Basic approach for post processing</h2>
<p>The main goal of post processing the videos was (of course) to compress them to a usable size from the original 143 GB. I also wanted to have a title on each video, and show the sponsors at the end of the video.</p>
<p>My basic idea to implement that consisted of the following steps:</p>
<ol>
<li>Create a title animation template.</li>
<li>Generate title animations from template for all talks.</li>
<li>Use a video editor to create a playlist of the parts title &#8211; talk &#8211; epilogue.</li>
<li>Run the video editor in batch mode to generate the combined video.</li>
<li>Encode the resulting video as ogg theora.</li>
</ol>
<p>As always with technology, it turned out that the original plan needed a few modifications.</p>
<h2>Title animations</h2>
<div style="float:right; border:1px dashed; padding:3px;"><video width="360 "height="288" src="http://www.landschoff.net/blog/uploads/2010/07/mdc2010_title_anim1.ogv" controls="controls"></video></div>
<p>Originally I wanted to use <a href="http://www.blender.org/">Blender</a> for the title animation, but I knew it is quite a complicated bit of software. So I looked for something simpler, and stumbled across an <a href="https://www.lwn.net/Articles/377939/">article</a> that pointed me towards <a href="http://www.synfig.org/">Synfig Studio</a> for 2D animation. This is also in Debian, so I gave it a try.</p>
<p>I was delighted that Synfig Studio has a command line renderer which is just called <tt>synfig</tt> and that the file format is XML, which would make it simple to batch-create the title animations. My title template can be found in <a href="http://landschoff.net/git/?p=mdc-video.git;a=summary">this git repository</a>.</p>
<h3>Batch creation of title animations</h3>
<p>I used a combination of <tt>make</tt> and a simple <a href="http://landschoff.net/git/?p=mdc-video.git;a=blob;f=doit.py;h=2601eac32d653056e6f516ce148bb8a7bda70dd5;hb=18026583d915c166b19fd26535cb49019d1158af">python script</a> to replace the author name and the title of the talk into the synfig XML file. The data for all talks is another XML file <tt>talks.xml</tt>. Basically, I used a simple <a href="http://www.w3.org/TR/xpath/">XPath</a> expression to find the relevant text node and change the data using the ElementTree API of <a href="http://codespeak.net/lxml/">lxml python module</a>.</p>
<p>The same could be done using <a href="http://www.w3.org/TR/xslt">XSLT</a> of course (for a constant replacement, see <a href="http://landschoff.net/git/?p=mdc-video.git;a=blob;f=test.xsl;h=ba2a20d545c5076ea1b78707ab5e585ffa219262;hb=18026583d915c166b19fd26535cb49019d1158af">this file</a>) but I found it easier to combine two XML files in python.</p>
<p>Note that I create PNG files with synfig and use <a href="http://www.ffmpeg.org/">ffmpeg</a> to generate a DV file from those. Originally, I had synfig create DV files directly but those turned out quite gray for some reason. I am now unable to reproduce this problem.</p>
<h2>Combining the title animation with the talk</h2>
<p>For joining the title animation with the talk, I originally went with <a href="http://www.openshotvideo.com/">OpenShot</a>, which somebody of the video team had running at the conference. My idea was to mix a single video manually and just replace the underlying data files for each talk. I expected that this would be easy using the <tt>openshot-render</tt> command, which renders the output video from the input clips and the <a href="http://landschoff.net/git/?p=mdc-video.git;a=blob;f=master/master.osp;h=f32c0c2dc5e8ca88c69eff88fd46f70318064beb;hb=18026583d915c166b19fd26535cb49019d1158af">OpenShot project file</a>. However, OpenShot stores the video lengths in the project file and will take those literally, so this did not work for talks of different play times&#8230;</p>
<p>I considered working with <a href="http://www.kinodv.org/">Kino</a> or <a href="http://kdenlive.org/">Kdenlive</a> but they did not look more appropriate for this use case. I noticed that OpenShot and Kdenlive both use the <a href="http://www.mltframework.org/">Media Lovin&#8217; Toolkit</a> under the hood, and OpenShot actually serializes the MLT configuration to <tt>$HOME/.openshot/sequence.xml</tt> when rendering. I first tried to read that XML file from python (using the mlt python bindings from the <tt>python-mlt2</tt> package) but did not find an API function to do that. So I just hard coded the <a href="http://landschoff.net/git/?p=mdc-video.git;a=blob;f=sequence.py;h=030ea9e2b2cfcb279d0baa19d03f09397583d644;hb=18026583d915c166b19fd26535cb49019d1158af">video sequence</a> in python.</p>
<p>I ran into a few gotchas on the way:</p>
<ul>
<li>it&#8217;s easy to segfault MLT from Python (something is wrong with the refcounting)</li>
<li>generating ogg theora using MLT from Python (which uses libavformat) resulted in a bad audio/video synchronisation of the output (more than 1 second for 1 hour of video)</li>
<li>generating dv from MLT and running <a href="http://v2v.cc/~j/ffmpeg2theora/">ffmpeg2theora</a> on the result is disk-bound on my quad core system &#8211; so use a pipe to ffmpeg2theora</li>
</ul>
<h2>Things to improve</h2>
<p>While the results look quite okay for me now, there is a lot of room for improvement.</p>
<ul>
<li>What bothers me the most is the unequal audio volume between talks. We should apply something like <a href="http://replaygain.hydrogenaudio.org/">replay gain</a> for normalization. I did not find an easy way to add this to the processing pipeline, otherwise it would have been included already.</li>
<li>Original recordings have different aspect ratios, so after combining them, there is a letterbox added. This is the case for <a href="http://meetings-archive.debian.net/pub/debian-meetings/2010/minidebconf-berlin/MDC2010_Brederlow_MultiArch.ogv">Goswin&#8217;s talk on Multiarch</a> for example. I&#8217;d rather have the title distorted or letter boxed, if I get around to it, I will fix it in the script.</li>
<li>Most of the recordings concentrate on showing the slides. As we did not keep the raw camera data, but recorded the <a href="http://dvswitch.alioth.debian.org/wiki/">DVswitch</a> output, we missed the opportunity to show the speaker more often in full screen. Looking at the same slide becomes quite boring after half a minute, so it would be better<br />
to show the speaker more often. That would require quite a bit of man power for post processing though, I have to admit that I did not watch all the hours of video.</li>
<li>We could cut a bit off the talk at start and end, when the speaker discusses where he is available for questions. It is not of interest anymore after the conference is over.</li>
</ul>
<h2>Availability</h2>
<ul>
<li>git repo (browsing): <a href="http://www.landschoff.net/git/?p=mdc-video.git;a=summary">http://www.landschoff.net/git/?p=mdc-video.git;a=summary</a></li>
<li>git repo (clone): <a href="git://landschoff.net/mdc-video">git://landschoff.net/mdc-video</a></li>
<li>Videos: <a href="http://meetings-archive.debian.net/pub/debian-meetings/2010/minidebconf-berlin/">http://meetings-archive.debian.net/pub/debian-meetings/2010/minidebconf-berlin/</a> (<strong>note:</strong> most of these are in german, apart from the DPL and the LXDE talk)</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.landschoff.net/blog/2010/07/postprocessing-conference-videos/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="http://www.landschoff.net/blog/uploads/2010/07/mdc2010_title_anim1.ogv" length="369157" type="video/ogg" />
<enclosure url="http://meetings-archive.debian.net/pub/debian-meetings/2010/minidebconf-berlin/MDC2010_Brederlow_MultiArch.ogv" length="426287215" type="video/ogg" />
		</item>
		<item>
		<title>Hitting the dynamic linker wall&#8230;</title>
		<link>http://www.landschoff.net/blog/2009/12/hitting-the-dynamic-linker-wall/</link>
		<comments>http://www.landschoff.net/blog/2009/12/hitting-the-dynamic-linker-wall/#comments</comments>
		<pubDate>Wed, 23 Dec 2009 17:01:27 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[dlopen]]></category>
		<category><![CDATA[dynamic linker]]></category>

		<guid isPermaLink="false">http://www.landschoff.net/blog/?p=127</guid>
		<description><![CDATA[I was working on replacing some mockup code for testing an internal library with python. Basically, the C code is incredibly big and I would rather mock the 3rd party API we are using in python. I wrote a generator to create wrapping code that forwards the C API calls to my python module.
Now that [...]]]></description>
			<content:encoded><![CDATA[<p>I was working on replacing some mockup code for testing an internal library with python. Basically, the C code is incredibly big and I would rather mock the 3rd party API we are using in python. I wrote a generator to create wrapping code that forwards the C API calls to my python module.</p>
<p>Now that most of the work is finished, I get the following error message from my python mock:</p>
<div class="codecolorer-container python mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Traceback <span style="color: black;">&#40;</span>most recent call last<span style="color: black;">&#41;</span>:<br />
&nbsp; File <span style="color: #483d8b;">&quot;simple_mockup.py&quot;</span>, line 2, <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #66cc66;">&lt;</span>module<span style="color: #66cc66;">&gt;</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">threading</span><br />
&nbsp; File <span style="color: #483d8b;">&quot;/usr/lib/python2.5/threading.py&quot;</span>, line 11, <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #66cc66;">&lt;</span>module<span style="color: #66cc66;">&gt;</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">time</span> <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">time</span> <span style="color: #ff7700;font-weight:bold;">as</span> _time, sleep <span style="color: #ff7700;font-weight:bold;">as</span> _sleep<br />
<span style="color: #008000;">ImportError</span>: /usr/lib/python2.5/lib-dynload/<span style="color: #dc143c;">time</span>.<span style="color: black;">so</span>: undefined <span style="color: #dc143c;">symbol</span>: PyExc_ValueError</div></td></tr></tbody></table></div>
<p>What&#8217;s going on here? This issue reminds me of a <a href="http://lists.debian.org/debian-gtk-gnome/1999/05/msg00095.html">bug of my ancient Debian times</a> which affected loading of GTK theme engines from python-gtk. The bug (#38138) is so old, it&#8217;s not even in the BTS archive anymore&#8230;</p>
<p>The problem is illustrated by the following example program (consisting of three files):</p>
<dl>
<dt>demo.c</dt>
<dd>
<div class="codecolorer-container c mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br /></div></td><td><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #339933;">#include &lt;Python.h&gt;</span><br />
<br />
<span style="color: #993333;">void</span> test_python<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; Py_Initialize<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; PyRun_SimpleString<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;import threading<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
</dd>
<dt>main.c</dt>
<dd>
<div class="codecolorer-container c mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;height:350px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br /></div></td><td><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #339933;">#include &lt;stdio.h&gt;</span><br />
<span style="color: #339933;">#include &lt;dlfcn.h&gt;</span><br />
<br />
<span style="color: #993333;">int</span> main<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span><span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #993333;">const</span> <span style="color: #993333;">char</span> <span style="color: #339933;">*</span>error<span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #993333;">void</span> <span style="color: #339933;">*</span>handle <span style="color: #339933;">=</span> dlopen<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;./demo.so&quot;</span><span style="color: #339933;">,</span> RTLD_LAZY <span style="color: #339933;">|</span> EXTRA_RTLD_FLAGS<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #993333;">void</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span>test_python<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #339933;">*</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span><span style="color: #339933;">**</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;</span>test_python <span style="color: #339933;">=</span> dlsym<span style="color: #009900;">&#40;</span>handle<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;test_python&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>error <span style="color: #339933;">=</span> dlerror<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; fprintf<span style="color: #009900;">&#40;</span>stderr<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;%s<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> error<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color: #000066;">printf</span></a><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Calling test_python @ %p in shared object @ %p.<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> test_python<span style="color: #339933;">,</span> handle<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span>test_python<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; dlclose<span style="color: #009900;">&#40;</span>handle<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color: #000066;">printf</span></a><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Feels fine, finishing.<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
</dd>
<dt>run_it.sh</dt>
<div class="codecolorer-container bash mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br /></div></td><td><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #666666; font-style: italic;">#! /bin/sh</span><br />
<br />
<span style="color: #c20cb9; font-weight: bold;">gcc</span> <span style="color: #660033;">-shared</span> <span style="color: #000000; font-weight: bold;">`</span>python-config --includes<span style="color: #000000; font-weight: bold;">`</span> <span style="color: #660033;">-o</span> demo.so demo.c <span style="color: #000000; font-weight: bold;">`</span>python-config --ldflags<span style="color: #000000; font-weight: bold;">`</span><br />
<br />
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Running example with default RTLD flags:&quot;</span><br />
<span style="color: #c20cb9; font-weight: bold;">gcc</span> -DEXTRA_RTLD_FLAGS=0 <span style="color: #660033;">-o</span> main main.c <span style="color: #660033;">-ldl</span><br />
.<span style="color: #000000; font-weight: bold;">/</span>main<br />
<span style="color: #7a0874; font-weight: bold;">echo</span><br />
<br />
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Passing RTLD_GLOBAL in addition:&quot;</span><br />
<span style="color: #c20cb9; font-weight: bold;">gcc</span> -DEXTRA_RTLD_FLAGS=RTLD_GLOBAL <span style="color: #660033;">-o</span> main main.c <span style="color: #660033;">-ldl</span><br />
.<span style="color: #000000; font-weight: bold;">/</span>main<br />
<span style="color: #7a0874; font-weight: bold;">echo</span></div></td></tr></tbody></table></div>
</dl>
<p>On my system, this results in the following output:</p>
<pre>
torsten@pulsar:~/sh_bug$ ./run_it.sh
Running example with default RTLD flags:
Calling test_python @ 0xb77084bc in shared object @ 0x96bc018.
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/usr/lib/python2.5/threading.py", line 11, in <module>
    from time import time as _time, sleep as _sleep
ImportError: /usr/lib/python2.5/lib-dynload/time.so: undefined symbol: PyExc_ValueError
Feels fine, finishing.

Passing RTLD_GLOBAL in addition:
Calling test_python @ 0xb783f4bc in shared object @ 0x95e1018.
Feels fine, finishing.
</pre>
<p>Sucky. So embedding Python into an application is easy but if you want to use the interpreter and its modules from a plugin, you are out of luck. Somebody knows a way around this problem? The only solution I can think of is to link libpython.so into each of the python plugins.</p>
<h3>Update: Work around</h3>
<p>Small update: For my current problem, the work around is to run the application with the python library preloaded: <tt>LD_PRELOAD=/usr/lib/libpython2.5.so.1.0 app</tt>. Back to adding functionality&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.landschoff.net/blog/2009/12/hitting-the-dynamic-linker-wall/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Passing optparse results as keyword arguments</title>
		<link>http://www.landschoff.net/blog/2009/10/passing-optparse-results-as-keyword-arguments/</link>
		<comments>http://www.landschoff.net/blog/2009/10/passing-optparse-results-as-keyword-arguments/#comments</comments>
		<pubDate>Fri, 16 Oct 2009 14:12:14 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.landschoff.net/blog/?p=50</guid>
		<description><![CDATA[The python optparse package is really handy for parsing command line arguments. When combining this with an extra main function idiom (to allow interactive usage or use as a module), I ran into a small problem &#8211; the following code does not run:
123456789def main&#40;foo, bar&#41;:
&#160; &#160; print&#40;&#34;foo: %s, bar: %s\n&#34; % &#40;foo, bar&#41;&#41;
if __name__ == [...]]]></description>
			<content:encoded><![CDATA[<p>The python <a href="http://docs.python.org/2.6/library/optparse.html">optparse package</a> is really handy for parsing command line arguments. When combining this with an <a href="http://docs.python.org/2.6/library/__main__.html">extra <tt>main</tt> function</a> idiom (to allow interactive usage or use as a module), I ran into a small problem &#8211; the following code does not run:</p>
<div class="codecolorer-container python mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">def</span> main<span style="color: black;">&#40;</span>foo, bar<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;foo: %s, bar: %s<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>foo, bar<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><br />
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">&quot;__main__&quot;</span>:<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">optparse</span> <span style="color: #ff7700;font-weight:bold;">import</span> OptionParser<br />
&nbsp; &nbsp; <span style="color: #dc143c;">parser</span> = OptionParser<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #dc143c;">parser</span>.<span style="color: black;">add_option</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;--foo&quot;</span>, dest=<span style="color: #483d8b;">&quot;foo&quot;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #dc143c;">parser</span>.<span style="color: black;">add_option</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;--bar&quot;</span>, dest=<span style="color: #483d8b;">&quot;bar&quot;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: black;">&#40;</span>options, args<span style="color: black;">&#41;</span> = <span style="color: #dc143c;">parser</span>.<span style="color: black;">parse_args</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; main<span style="color: black;">&#40;</span><span style="color: #66cc66;">**</span>options<span style="color: black;">&#41;</span></div></td></tr></tbody></table></div>
<p>This is the error message:</p>
<pre>
Traceback (most recent call last):
  File "foobar.py", line 9, in <module>
    main(**options)
TypeError: main() argument after ** must be a dictionary
</pre>
<p>The problem here is that the options result from OptionParser is instead of type <tt>optparse.Values</tt>, which is not derived from dict (huh?!). Quoting the <a href="http://docs.python.org/2.6/reference/expressions.html#calls">Python language reference</a>:<br />
<blockquote>If the syntax **expression appears in the function call, expression must evaluate to a mapping, the contents of which are treated as additional keyword arguments.</p></blockquote>
<p>Here are two ways to fix the problem:</p>
<div class="codecolorer-container python mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;"># &nbsp; ...</span><br />
&nbsp; &nbsp; <span style="color: black;">&#40;</span>options, args<span style="color: black;">&#41;</span> = <span style="color: #dc143c;">parser</span>.<span style="color: black;">parse_args</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; main<span style="color: black;">&#40;</span>foo=options.<span style="color: black;">foo</span>, bar=options.<span style="color: black;">bar</span><span style="color: black;">&#41;</span> &nbsp;<span style="color: #808080; font-style: italic;"># Fix (a)</span><br />
&nbsp; &nbsp; main<span style="color: black;">&#40;</span><span style="color: #66cc66;">**</span>options.<span style="color: #0000cd;">__dict__</span><span style="color: black;">&#41;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #808080; font-style: italic;"># Fix (b)</span></div></td></tr></tbody></table></div>
<p>I know I prefer (b), especially if there are many options to pass on. Another work around is used by the <a href="http://pylit.berlios.de/examples/pylit.py.html#optionvalues">pylit</a> project (extending the <tt>optparse.Values<tt> class).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.landschoff.net/blog/2009/10/passing-optparse-results-as-keyword-arguments/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Reading an arbitrary file as python module source</title>
		<link>http://www.landschoff.net/blog/2009/02/reading-an-arbitrary-file-as-python-module-source/</link>
		<comments>http://www.landschoff.net/blog/2009/02/reading-an-arbitrary-file-as-python-module-source/#comments</comments>
		<pubDate>Fri, 20 Feb 2009 16:34:55 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.landschoff.net/blog/?p=20</guid>
		<description><![CDATA[Not sure if anybody will ever need this. I just found out because I did not accept that I can&#8217;t load my Subversion pre-commit hook as a module.
Of course it is actually quite simple:

import imp
hook = imp.load_source("hook", "pre-commit")

It&#8217;s that easy. Now I can test the internal functions from ipython before letting it wreck our repository. [...]]]></description>
			<content:encoded><![CDATA[<p>Not sure if anybody will ever need this. I just found out because I did not accept that I can&#8217;t load my Subversion <tt>pre-commit</tt> hook as a module.</p>
<p>Of course it is actually quite simple:</p>
<pre>
import imp
hook = imp.load_source("hook", "pre-commit")
</pre>
<p>It&#8217;s that easy. Now I can test the internal functions from ipython before letting it wreck our repository. <img src='http://www.landschoff.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.landschoff.net/blog/2009/02/reading-an-arbitrary-file-as-python-module-source/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
