<?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>Labix Blog &#187; Python</title>
	<atom:link href="http://blog.labix.org/tag/python/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.labix.org</link>
	<description>by Gustavo Niemeyer</description>
	<lastBuildDate>Fri, 09 Jul 2010 19:15:49 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Python has a GIL, and lots of complainers</title>
		<link>http://blog.labix.org/2010/07/09/python-has-a-gil-and-lots-of-complainers</link>
		<comments>http://blog.labix.org/2010/07/09/python-has-a-gil-and-lots-of-complainers#comments</comments>
		<pubDate>Fri, 09 Jul 2010 19:15:49 +0000</pubDate>
		<dc:creator>Gustavo Niemeyer</dc:creator>
				<category><![CDATA[Erlang]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://blog.labix.org/?p=381</guid>
		<description><![CDATA[I&#8217;ve just read a post by Brett Cannon where, basically, he complains about complainers. If you don&#8217;t know who Brett is, you&#8217;re probably not a heavy Python user. Brett is a very important Python core developer which has been around &#8230; <a href="http://blog.labix.org/2010/07/09/python-has-a-gil-and-lots-of-complainers">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve just read <a href="http://sayspy.blogspot.com/2010/07/two-types-of-people-who-cause-biggest.html">a post by Brett Cannon</a> where, basically, he complains about complainers.</p>
<p>If you don&#8217;t know who Brett is, you&#8217;re probably not a heavy Python user.  Brett is a very important Python core developer which has been around for a while and who does a great job at it.  His post, though, makes me a bit sad.</p>
<p><span id="more-381"></span>Brett points out that there are two types of personalities which do not contribute to open source.  The first one he defines as:</p>
<blockquote><p>
The first type is the &#8220;complainer&#8221;. This is someone who finds something they don&#8217;t like, points out that the thing they don&#8217;t like is suboptimal, but then offers no solutions.
</p></blockquote>
<p>And the second one is defined as:</p>
<blockquote><p>
(&#8230;) This is someone who, upon finding out about a decision that they think was sub-optimal, decides to bring up new ideas and solutions. The person is obviously trying to be helpful by bringing up new ideas and solutions, thinking that the current one is simply going to flop and they need to stop people from making a big mistake.  The thing is, this person is not helping. (&#8230;)
</p></blockquote>
<p>This, on itself, is already shortsighted. If you&#8217;re tired of hearing the same arguments again and again for 10 years, from completely different people, there&#8217;s a pretty good chance that there&#8217;s an actual issue with your project, and your users are trying in their way to contribute and interact with you in the hope that it might get fixed.</p>
<p>This is really important:  They are <i>people</i>, which <i>use your project</i>, and are trying to <i>improve it</i>. If you can&#8217;t stand that, you should stop maintaining an open source project now, or pick something which no one cares about.</p>
<p>The other issue which took my attention in his post is his example: the Python GIL.  Look at the way in which Brett dismisses the problem:</p>
<blockquote><p>
(I am ignoring the fact that few people write CPU-intensive code requiring true threading support, that there is the multiprocessing library, true power users have extension  modules which do operate with full threading, and that there are multiple VMs out there with a solution that have other concurrency solutions)
</p></blockquote>
<p>Brett, we can understand that <a href="http://www.artima.com/weblogs/viewpost.jsp?thread=214235">the GIL is hard to remove</a>, but it&#8217;s a <a href="http://www.dabeaz.com/GIL/">fundamental flaw in the most important Python implementation</a>, and being dismissive about it will either draw further complaints at you, or will simply drive users away from the language entirely.</p>
<p>I can understand why you think this way, though.  Guido presents the same kind of feeling about the GIL for a very long time.  Here is one excerpt from a <a href="http://mail.python.org/pipermail/python-3000/2007-May/007414.html">mail thread about it</a>:</p>
<blockquote><p>
Nevertheless, you&#8217;re right the GIL is not as bad as you would initially think: you just have to undo the brainwashing you got from Windows and Java proponents who seem to consider threads as the only way to approach concurrent activities.</p>
<p>Just Say No to the combined evils of locking, deadlocks, lock granularity, livelocks, nondeterminism and race conditions.
</p></blockquote>
<p>I apologize, but I have a very hard time reading this and not complaining.</p>
<p>In my world, the golden days of geometric growth in vertical processing power is over, multi-processed machines are here to stay, and the amount of traffic flowing through networks is just increasing.  It feels reasonable to desire a less naïve approach to deal with real world problems, such as executing tasks concurrently.</p>
<p>I actually would love to not worry about things like non-determinism and race conditions, and would love even more to have a <i>programming language</i> which helps me with that!</p>
<p>Python, though, has a Global Interpreter Lock (yes, I&#8217;m talking about CPython, the most important interpreter).  Python programs execute in sequence.  No <a href="http://www.infoq.com/interviews/doug-lea-fork-join">Fork/Join frameworks</a>, no <a href="http://golang.org">coroutines</a>, no <a href="http://erlang.org">lightweight processes</a>, nothing.  Your <i>Python</i> code <i>will execute in sequence</i> if it lives in the same process space.</p>
<p>The answer from Brett and Guido to concurrency?  Develop your code in C, or write your code to execute in multiple processes.  If they really want people to get rid of non-determinism, locking issues, race conditions, and so on, they&#8217;re not helping at all.</p>
<p>I know this is just yet another complaint, though. I honestly cannot fix the problem either, and rather just talk about it in the hope that someone who&#8217;s able to do it will take care of it.  That said, I wish that the language maintainers would <i>do the same</i>, and tell the world that it&#8217;s an unfortunate problem, and that they wished someone else would go there and fix it!  If, instead, maintainers behave in a ridiculously dismissive way, like Guido did in that mail thread, and like Brett is doing in his post, the smart people that could solve the problem get turned down.  People like to engage with motivated maintainers.. they like to solve problems that others are interested in seeing solved.</p>
<p>Perhaps agreeing with the shortcomings won&#8217;t help, though, and no one will show up to fix the problem either. But then, at least users will know that the maintainers are on the same side of the fence, and the hope that it will get fixed survives.  If the maintainers just complain about the users which complain, and dismiss the problem, users are put in an awkward position.  I can&#8217;t complain.. I can&#8217;t provide ideas or solutions.. I can&#8217;t fix the problem.. they don&#8217;t even <i>care</i> about the problem.  Why am I using this thing at all?</p>
<p>Would you rather have users, or have no complainers?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.labix.org/2010/07/09/python-has-a-gil-and-lots-of-complainers/feed</wfw:commentRss>
		<slash:comments>31</slash:comments>
		</item>
		<item>
		<title>Mocker 1.0 for Python released!</title>
		<link>http://blog.labix.org/2010/06/20/mocker-1-0-for-python-released</link>
		<comments>http://blog.labix.org/2010/06/20/mocker-1-0-for-python-released#comments</comments>
		<pubDate>Mon, 21 Jun 2010 00:09:02 +0000</pubDate>
		<dc:creator>Gustavo Niemeyer</dc:creator>
				<category><![CDATA[Project]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Test]]></category>

		<guid isPermaLink="false">http://blog.labix.org/?p=323</guid>
		<description><![CDATA[After a few years in development, version 1.0 of Mocker is now available! Check out the changes since 0.10.1, the supported features, or go straight to the download page.]]></description>
			<content:encoded><![CDATA[<p>After a few years in development, version 1.0 of <a href="http://bit.ly/dm0GGy" _href="http://labix.org/mocker">Mocker</a> is now <a href="http://bit.ly/dez9jQ" _href="https://launchpad.net/mocker/trunk/1.0">available</a>!  Check out the <a href="http://bit.ly/czhiru " _href="http://bazaar.launchpad.net/~niemeyer/mocker/trunk/annotate/head:/NEWS">changes since 0.10.1</a>, the <a href="http://bit.ly/dm0GGy" _href="http://labix.org/mocker">supported features</a>, or go straight to the <a href="http://bit.ly/9Wszmp" _href="https://launchpad.net/mocker/+download">download page</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.labix.org/2010/06/20/mocker-1-0-for-python-released/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Integrating IRC with LDAP and two-way SMSing</title>
		<link>http://blog.labix.org/2010/06/19/integrating-irc-with-ldap-and-two-way-smsing</link>
		<comments>http://blog.labix.org/2010/06/19/integrating-irc-with-ldap-and-two-way-smsing#comments</comments>
		<pubDate>Sat, 19 Jun 2010 21:56:07 +0000</pubDate>
		<dc:creator>Gustavo Niemeyer</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[Erlang]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Project]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://blog.labix.org/?p=296</guid>
		<description><![CDATA[A bit of history I don&#8217;t know exactly why, but I&#8217;ve always enjoyed IRC bots. Perhaps it&#8217;s the fact that it emulates a person in an easy-to-program way, or maybe it&#8217;s about having a flexible and shared &#8220;command line&#8221; tool, &#8230; <a href="http://blog.labix.org/2010/06/19/integrating-irc-with-ldap-and-two-way-smsing">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><b>A bit of history</b></p>
<p>I don&#8217;t know exactly why, but I&#8217;ve always enjoyed IRC bots.  Perhaps it&#8217;s the fact that it emulates a person in an easy-to-program way, or maybe it&#8217;s about having a flexible and shared &#8220;command line&#8221; tool, or maybe it&#8217;s just the fact that it helps people perceive things in an asynchronous way without much effort.  Probably a bit of everything, actually.</p>
<p><span id="more-296"></span></p>
<p>My bot programming started with <a href="http://labix.org/pybot">pybot</a> many years ago, when I was still working at <a href="http://www.conectiva.com.br">Conectiva</a>.  Besides having many interesting features, this bot eventually got in an abandonware state, since <a href="http://www.canonical.com">Canonical</a> already had pretty much equivalent features available when I joined, and I had other interests which got in the way.  The code was a bit messy as well.. it was a time when I wasn&#8217;t very used to testing software properly (a friend has a great excuse for that kind of messy software: <i>&#8220;I was young, and needed the money!&#8221;</i>).</p>
<p>Then, a couple of years ago, while working in the <a href="http://landscape.canonical.com">Landscape</a> project, there was an opportunity of getting some information more visible to the team.  Coincidently, it was also a time when I wanted to get some practice with the concepts of <a href="http://erlang.org">Erlang</a>, so I decided to write a bot from scratch with some nice support for plugins, just to get a feeling of how the promised stability of Erlang actually took place for real.  This bot is called <a href="https://launchpad.net/mup">mup</a> (Mup Pet, more formally), and its code is available publicly through <a href="https://launchpad.net/mup">Launchpad</a>.</p>
<p>This was a nice experiment indeed, and I did learn quite a bit about the ins and outs of Erlang with it.  Somewhat unexpected, though, was the fact that the bot grew up a few extra features which multiple teams in Canonical started to appreciate.  This was of course very nice, but it also made it more obvious that the egocentric reason for having a bot written in Erlang would now hurt, because most of Canonical&#8217;s own coding is done in Python, and that&#8217;s what internal tools should generally be written in for everyone to contribute and help maintaining the code.</p>
<p>That&#8217;s where the desire of migrating mup into a Python-based brain again came from, and having a new feature to write was the perfect motivator for this.</p>
<p><b>LDAP and two-way SMSing over IRC</b></p>
<p>Canonical is a <i>very</i> distributed company.  Employees are distributed over dozens of countries, literally.  Not only that, but most people also work from their homes, rather than in an office.  Many different countries also means many different timezones, and working from home with people from different timezones means flexible timing.  All of that means communication gets&#8230; well.. interesting.</p>
<p>How do we reach someone that should be in an online meeting and is not?  Or someone that is traveling to get to a sprint?  Or how can someone that has no network connectivity reach an IRC channel to talk to the team?  There are probably several answers to this question, but one of them is of course SMS.  It&#8217;s not exactly cheap if we consider the cost of the data being transfered, but pretty much everyone has a mobile phone which can do SMS, and the model is not that far away from IRC, which is the main communication system used by the company.</p>
<p>So, the itch was itching.  Let&#8217;s scratch it!</p>
<p>Getting the mobile phone of employees was already a solved problem for mup, because it had a plugin which could interact with the LDAP directory, allowing people to do something like this:</p>
<blockquote><p>
&lt;joe&gt; mup: poke gustavo<br />
&lt;mup&gt; joe: niemeyer is Gustavo Niemeyer &lt;&#8230;@canonical.com&gt; &lt;time:&#8230;&gt; &lt;mobile:&#8230;&gt;
</p></blockquote>
<p>This just had to be migrated from Erlang into a Python-based brain for the reasons stated above. This time, though, there was no reason to write something from scratch.  I could even have used pybot itself, but there was also <a href="http://sourceforge.net/projects/supybot/">supybot</a>, an IRC bot which started around the same time I wrote the first version of pybot, and unlike the latter, supybot&#8217;s author was much more diligent in evolving it.  There is quite a comprehensive list of plugins for supybot nowadays, and it includes means for testing plugins and so on.  The choice of using it was straighforward, and getting &#8220;<i>poke</i>&#8221; support ported into a plugin wasn&#8217;t hard at all.</p>
<p>So, on to SMSing.  Canonical already had a contract with an SMS gateway company which we established to test-drive some ideas on <a href="https://landscape.canonical.com">Landscape</a>. With the mobile phone numbers coming out of the LDAP directory in hands and an SMS contract established, all that was needed was a plugin for the bot to talk to the SMS gateway.  That &#8220;conversation&#8221; with the SMS gateway allows not only sending messages, but also receiving SMS messages which were sent to a specific number.</p>
<p>In practice, this means that people which are connected to IRC can very easily deliver an SMS to someone using their nicks.  Something like this:</p>
<blockquote><p>
&lt;joe&gt; @sms niemeyer Where are you?  We&#8217;re waiting!
</p></blockquote>
<p>And this would show up in the mobile screen as:</p>
<blockquote><p>
joe&gt; Where are you?  We&#8217;re waiting!
</p></blockquote>
<p>In addition to this, people which have <i>no connectivity</i> can also contact individuals and channels on IRC, with mup working as a middle man.  The message would show up on IRC in a similar way to:</p>
<blockquote><p>
&lt;mup&gt; [SMS] &lt;niemeyer&gt; Sorry, the flight was delayed. Will be there in 5.
</p></blockquote>
<p>The communication from the bot to the gateway happens via plain HTTPS.  The communication back is a bit more complex, though.  There is a small proxy service deployed in <a href="http://code.google.com/appengine">Google App Engine</a> to receive messages from the SMS gateway.  This was done to avoid losing messages when the bot itself is taken down for maintenance.  The SMS gateway doesn&#8217;t handle this case very well, so it&#8217;s better to have something which will be up most of the time buffering messages.</p>
<p>A picture is worth 2<sup>10</sup> words, so here is a simple diagram explaining how things got linked together:</p>
<p><a href="http://blog.labix.org/wp-content/uploads/2010/06/mup-sms.png"><img src="http://blog.labix.org/wp-content/uploads/2010/06/mup-sms.png" alt="" title="SMS integration diagram" width="449" height="255" class="aligncenter size-full wp-image-308" /></a></p>
<p>This is now up for experimentation, and so far it&#8217;s working nicely.  I&#8217;m hoping that in the next few weeks we&#8217;ll manage to port the rest of mup into the supybot-based brain.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.labix.org/2010/06/19/integrating-irc-with-ldap-and-two-way-smsing/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Released editmoin 1.15</title>
		<link>http://blog.labix.org/2010/06/19/released-editmoin-1-15</link>
		<comments>http://blog.labix.org/2010/06/19/released-editmoin-1-15#comments</comments>
		<pubDate>Sat, 19 Jun 2010 19:15:18 +0000</pubDate>
		<dc:creator>Gustavo Niemeyer</dc:creator>
				<category><![CDATA[Project]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://blog.labix.org/?p=291</guid>
		<description><![CDATA[Version 1.15 of editmoin is now available. The following changes were made: Moin used to work with numerical IDs for identification, and editmoin was still based on this model. This release adds support for direct authentication as available in current &#8230; <a href="http://blog.labix.org/2010/06/19/released-editmoin-1-15">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Version 1.15 of <a href="http://labix.org/editmoin">editmoin</a> is now available.</p>
<p>The following changes were made:</p>
<ul>
<li> Moin used to work with numerical IDs for identification, and editmoin was still based on this model. This release adds support for direct authentication as available in current Moin releases.  This was inspired by Reimar Bauer.
<li> The new file ~/.moin_users is now parsed to obtain usernames, supporting the feature above.  Shortcuts are also supported in this file.
<li> Added support for textcha question handling.
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.labix.org/2010/06/19/released-editmoin-1-15/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The forgotten art of error checking</title>
		<link>http://blog.labix.org/2010/06/17/the-forgotten-art-of-error-checking</link>
		<comments>http://blog.labix.org/2010/06/17/the-forgotten-art-of-error-checking#comments</comments>
		<pubDate>Thu, 17 Jun 2010 15:15:59 +0000</pubDate>
		<dc:creator>Gustavo Niemeyer</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Lua]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Snippet]]></category>
		<category><![CDATA[Test]]></category>

		<guid isPermaLink="false">http://blog.labix.org/?p=275</guid>
		<description><![CDATA[I was just rambling randomly yesterday, in the usual microblogging platforms, about how result checking seems to be ignored or done badly. The precise wording was: It&#8217;s really amazing how little attention error handling receives in most software development. Even &#8230; <a href="http://blog.labix.org/2010/06/17/the-forgotten-art-of-error-checking">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I was just rambling randomly yesterday, in the usual microblogging platforms, about how result checking seems to be ignored or done badly.  The precise wording was:</p>
<blockquote><p>
It&#8217;s really amazing how little attention error handling receives in most software development. Even *tutorials* often ignore it.
</p></blockquote>
<p>It indeed does amaze me.  It sometimes feels like we write code for theoretical perfect worlds.. <i>&#8220;If the processor executes exactly in this order, and the weather is calm, this program will work.&#8221;</i>.  There are countless examples of bad assumptions.. someday I will come with some statistics of the form <i>&#8220;Every N seconds someone forgets to check the result of write().&#8221;</i>.</p>
<p><span id="more-275"></span></p>
<p>If you are a teacher, or a developer that enjoys writing snippets of code to teach people, please join me in the quest of building a better future.  Do <i>not</i> tell us that you&#8217;re &#8220;avoiding result checking for terseness&#8221;, because that&#8217;s exactly what we people will do (terseness is good, right?).  On the contrary, take this chance to make us feel <i>bad</i> about avoiding result checking.  You might do this by putting a comment like &#8220;If you don&#8217;t do this, you&#8217;re a bad programmer.&#8221; right next to the logic which is handling the result, and might take this chance to teach people how proper result handling is done.</p>
<p>Of course, there&#8217;s another forgotten art related to result checking.  It sits on the other side of the fence.  If you are a library author, do think through about how you plan to make us check conditions which happen inside your library, and try to imagine how to make our lives easier.  If we suck at handling results when there are obvious ways to handle it, you can imagine what happens when you structure your result logic badly.</p>
<p>Here is a clear example of what <i>not</i> to do, coming straight from Python&#8217;s standard library, in the <i>imaplib</i> module:</p>
<pre>
    def login(self, user, password):
        typ, dat = self._simple_command('LOGIN', user, self._quote(password))
        if typ != 'OK':
            raise self.error(dat[-1])
        self.state = 'AUTH'
        return typ, dat
</pre>
<p>You see the problem there?  How do you handle errors from this library?  Should we catch the exception, or should we verify the result code? <i>&#8220;Both!&#8221;</i> is the right answer, unfortunately, because the author decided to do us a little favor and check the error condition himself in some arbitrary cases and raise the error, while letting it go through and end up in the result code in a selection of other arbitrary cases.</p>
<p>I may provide some additional advice on result handling in the future, but for now I&#8217;ll conclude with the following suggestion: please check the results from your actions, and help others to check theirs.  That&#8217;s a good life-encompassing recommendation, actually.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.labix.org/2010/06/17/the-forgotten-art-of-error-checking/feed</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Xpresser &#8211; Python library for GUI automation with image matching</title>
		<link>http://blog.labix.org/2010/05/18/xpresser-python-library-for-gui-automation-with-image-matching</link>
		<comments>http://blog.labix.org/2010/05/18/xpresser-python-library-for-gui-automation-with-image-matching#comments</comments>
		<pubDate>Tue, 18 May 2010 20:43:24 +0000</pubDate>
		<dc:creator>Gustavo Niemeyer</dc:creator>
				<category><![CDATA[Project]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Test]]></category>

		<guid isPermaLink="false">http://blog.labix.org/?p=267</guid>
		<description><![CDATA[In a hurry? Go check it out! The context A while ago I found out about Sikuli, a very interesting project which allows people to script actions in GUIs based on screenshot excerpts. The idea is that you basically take &#8230; <a href="http://blog.labix.org/2010/05/18/xpresser-python-library-for-gui-automation-with-image-matching">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><b>In a hurry?</b></p>
<p><a href="http://wiki.ubuntu.com/Xpresser">Go check it out!</a></p>
<p><b>The context</b></p>
<p>A while ago I found out about <a href="http://sikuli.org">Sikuli</a>, a very interesting project which allows people to script actions in GUIs based on screenshot excerpts.  The idea is that you basically take images representing portions of your screen, like a button, or a label, or an icon, and then create a script which can detect a position in the screen which resembles one of these images, and perform actions on them, such as clicking, or hovering.</p>
<p><span id="more-267"></span></p>
<p>I had never imagined something like this, and the idea got me really excited about the possibilities.   Imagine, for instance, what can be done in terms of testing.  Testing of GUIs is unfortunately not yet a trivial task nowadays.  We do have frameworks which are based on accessibility hooks, for instance, but these sometimes can&#8217;t be used because the hook is missing, or is even far off in terms of the context being tested (imagine testing that a browser can open a specific flash site successfully, for instance).</p>
<p>So, Sikuli opened my eyes to the possibility of using image matching technology in a GUI automation context, and I really wanted to play with it.  In the days following the discovery, I fiddled a bit, communicated with the author, and even submitted some changes to make it work well in Ubuntu.</p>
<p>Then, the idea cooled down in my head, and I moved on with life.  Well&#8230; until two weeks ago.</p>
<p>Right before heading to the <a href="http://wiki.ubuntu.com/UDS-M">Ubuntu Developer Summit</a> for the next Ubuntu release, the desire of automating GUIs appeared again in the context of the widely scoped Ubuntu-level testing suite.  Then, over the first few days last week, I was able to catch up with quite a few people which were interested in the concept of automating GUIs, with different purposes (testing, design approval, etc), which of course was all I needed to actually push that old desire forward.</p>
<p>Trying to get Sikuli to work, though, was quite painful.  Even though I had sent patches upstream before, it looks like the build process isn&#8217;t working in Ubuntu again for other reasons (it&#8217;s not a polished build process, honestly), and even if I managed to make it work and contributed that to the upstream, in the end the path to integrate the Java-based tool in the Python-based testing framework which Ubuntu uses (<a href="https://launchpad.net/mago">Mago</a>) wasn&#8217;t entirely straightforward either.</p>
<p><b>Reinventing the wheel</b></p>
<p>So, the the itch was in place, and there was a reason to let the <a href="http://en.wikipedia.org/wiki/Not_Invented_Here">NIH</a> syndrome take over a bit.  Plus, image processing is something I&#8217;d like to get a foot in anyway, so it felt like a good chance to have a closer look and at the same time contribute a small bit to potential quality improvements of Ubuntu.</p>
<p>That&#8217;s when <a href="http://wiki.ubuntu.com/Xpresser">Xpresser</a> was born.  Xpresser is a clean room implementation of the concepts explored by Sikuli, in the form of a Python library which can be used standalone, or embedded into other programs and testing frameworks such as Mago.</p>
<p>The project is sponsored by <a href="http://canonical.com">Canonical</a>, and licensed under the LGPL.</p>
<p>Internally, it makes use of opencv for the image matching, pyatspi for the event generation (mouse clicks, etc), gtk for screen capturing and testing (of itself), and numpy for matrix operations. Clearly, the NIH syndrome, wasn&#8217;t <i>entirely</i> active. <img src='http://blog.labix.org/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />   As a side note, I haven&#8217;t played with numpy and gtk for some time, and I&#8217;m always amazed by the quality of these modules.</p>
<p><b>Contribute code and ideas</b></p>
<p>Concluding this post, which is already longer than I expected, the basics of Xpresser are in place, so go ahead and play with it!  That said, there are quite a few low hanging fruits to get it to a point of being a really compelling GUI-driving library, so if you have any interest in the concept, I invite you to play with the code and submit contributions too.  If you want ideas of what else could be done, let&#8217;s have a chat.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.labix.org/2010/05/18/xpresser-python-library-for-gui-automation-with-image-matching/feed</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>The last 4 years (and the next N?)</title>
		<link>http://blog.labix.org/2009/11/25/the-last-4-years-and-the-next-n</link>
		<comments>http://blog.labix.org/2009/11/25/the-last-4-years-and-the-next-n#comments</comments>
		<pubDate>Wed, 25 Nov 2009 04:16:59 +0000</pubDate>
		<dc:creator>Gustavo Niemeyer</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Project]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://blog.labix.org/?p=190</guid>
		<description><![CDATA[Some interesting changes have been happening in my professional life, so I wanted to share it here to update friends and also for me to keep track of things over time (at some point I will be older and will &#8230; <a href="http://blog.labix.org/2009/11/25/the-last-4-years-and-the-next-n">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Some interesting changes have been happening in my professional life, so I wanted to share it here to update friends and also for me to keep track of things over time (at some point I will be older and will certainly laugh at what I called &#8220;interesting changes&#8221; in the ol&#8217;days).  Given the goal, I apologize but this may come across as more egocentric than usual, so please feel free to jump over to your next blog post at any time.</p>
<p><span id="more-190"></span></p>
<p>It&#8217;s been little more than four years since I left <a href="http://www.conectiva.com.br">Conectiva / Mandriva</a> and joined <a href="http://www.canonical.com">Canonical</a>, in August of 2005.  Shortly after I joined, I had the luck of spending a few months working on the different projects which the company was pushing at the time, including <a href="http://launchpad.net">Launchpad</a>, then <a href="http://bazaar-vcs.org/en/">Bazaar</a>, then a little bit on some projects which didn&#8217;t end up seeing much light. It was a great experience by itself, since all of these projects were abundant in talent.  Following that, in the beginning of 2006, counting on the trust of people which knew more than I did, I was requested/allowed to lead the development of a brand new project the company wanted to attempt.  After a few months of research I had the chance to sit next to Chris Armstrong and Jamu Kakar to bootstrap the development of what is now known as the <a href="https://landscape.canonical.com">Landscape</a> distributed systems management project.</p>
<p>Fast forward three and a half years, in mid 2009, and Landscape became a massive project with hundreds of thousands of very well tested lines, sprawling not only a client branch, but also external child projects such as the <a href="https://storm.canonical.com">Storm Object Relational Mapper</a>, in use also by Launchpad and <a href="https://one.ubuntu.com">Ubuntu One</a>.  In the commercial side of things it looks like Landscape&#8217;s life is just starting, with its hosted and standalone versions getting more and more attention from enterprise customers.  And the three guys which started the project didn&#8217;t do it alone, for sure.  The toy project of early 2006 has grown to become a well structured team, with added talent spreading areas such as development, business and QA.</p>
<p>While I wasn&#8217;t watching, though, something happened.  Facing that great action, my attention was slowly being spread thinly among management, architecture, development, testing, code reviews, meetings, and other tasks, sometimes in areas not entirely related, but very interesting of course.  The net result of increased attention sprawl isn&#8217;t actually good, though.  If it persists, even when the several small tasks may be individually significant, the achievement just doesn&#8217;t feel significant given the invested effort as a whole.  At least not for someone that truly enjoys being a software architect, and loves to feel that the effort invested in the growth of a significant working software is really helping people out in the same magnitude of that investment.  In simpler words, it felt like my position within the team just wasn&#8217;t helping the team out the same way it did before, and thus it was time for a change.</p>
<p>Last July an external factor helped to catapult that change. <a href="http://www.eucalyptus.com">Eucalyptus</a> needed a feature to be released with Ubuntu 9.10, due in October, to greatly simplify the installation of some standard machine images.. an <i>Image Store</i>.  It felt like a very tight schedule, even more considering that I hadn&#8217;t been doing Java for a while, and Eucalyptus uses some sexy (and useful) new technology called  the <a href="http://code.google.com/webtoolkit/">Google Web Toolkit</a>, something I had to get acquainted with.  Two months looked like a tight schedule, and a risky bet overall, but it also felt like a great opportunity to strongly refocus on a task that needed someone&#8217;s attention urgently.  Again I was blessed with trust I&#8217;m thankful for, and by now I&#8217;m relieved to look back and perceive that it went alright, certainly thanks to the help of other people like Sidnei da Silva and Mathias Gug.  Meanwhile, on the Landscape side, my responsibilities were distributed within the team so that I could be fully engaged on the problem.</p>
<p>Moving this forward a little bit we reach the current date.  Right now the Landscape project has a new organizational structure, and it actually feels like it&#8217;s moving along quite well.  Besides the internal changes, a major organizational change also took place around Landscape over that period, and the planned restructuring led me to my current role.  In practice, I&#8217;m now engaging into the research of a new concept which I&#8217;m hoping to publish openly quite soon, if everything goes well.    It&#8217;s challenging, it&#8217;s exciting, and most importantly, allows me to focus strongly on something which has a great potential (I will stop teasing you now).  In addition to this, I&#8217;ll definitely be spending some of that time on the progress of Landscape and the Image Store, but mostly from an architectural point of view, since both of these projects will have bright hands taking care of them more closely.</p>
<p>Sit by the fireside if you&#8217;re interested in the upcoming chapters of that story. <img src='http://blog.labix.org/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.labix.org/2009/11/25/the-last-4-years-and-the-next-n/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Screwing up Python compatibility: unicode(), str(), and bytes()</title>
		<link>http://blog.labix.org/2009/07/02/screwing-up-python-compatibility-unicode-str-bytes</link>
		<comments>http://blog.labix.org/2009/07/02/screwing-up-python-compatibility-unicode-str-bytes#comments</comments>
		<pubDate>Thu, 02 Jul 2009 15:50:17 +0000</pubDate>
		<dc:creator>Gustavo Niemeyer</dc:creator>
				<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://blog.labix.org/?p=133</guid>
		<description><![CDATA[Backwards and forwards compatibility is an art. In the very basic and generic form, it consists in organizing the introduction of new concepts while allowing people to maintain existing assets working. In some cases, the new concepts introduced are disruptive, &#8230; <a href="http://blog.labix.org/2009/07/02/screwing-up-python-compatibility-unicode-str-bytes">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Backwards and forwards compatibility is an art.  In the very basic and generic form, it consists in organizing the introduction of new concepts while allowing people to maintain existing assets working.  In some cases, the new concepts introduced are disruptive, in the sense that they prevent the original form of the asset to be preserved completely, and then some careful consideration has to be done for creating a migration path which is technically viable, and which at the same time helps people keeping the process in mind.  A great example of what <i>not</i> to do when introducing such disruptive changes has happened in Python recently.</p>
<p>Up to Python 2.5, any strings you put within normal quotes (without a leading character marker in front of it) would be considered to be of the type <i>str</i>, which originally was used for both binary data and textual data, but in modern times it was seen as the type to be used for binary data only.  For textual information, the <i>unicode</i> type has been introduced in Python 2.0, and it provides easy access to all the goodness of Unicode.  Besides converting to and from <i>str</i>, it&#8217;s also possible to use Unicode <i>literals</i> in the code by preceding the quotes with a leading <i>u</i> character.</p>
<p>This evolution has happened quite cleanly, but it introduced one problem: these two types were both seen as the main way to input textual data in one point in time, and the language syntax clearly makes it very easy to use either type interchangeably.  Sounds good in theory, but the types are <i>not</i> interchangeable, and what is worse: in many cases the problem is only seen at runtime when incompatible data passes through the code.  This is what gives form to the interminable <a href="http://www.google.com/search?q=UnicodeDecodeError">UnicodeDecodeError problem</a> you may have heard about.  So what can be done about this?  Enter Python 3.0.</p>
<p>In Python 3.0 an attempt is being made to sanitize this, by promoting the <i>unicode</i> type to a more prominent position, removing the original <i>str</i> type, and introducing a similar but incompatible <i>bytes</i> type which is more clearly oriented towards binary data.</p>
<p>So far so good.  The motivation is good, the target goal is a good one too.  As usual, the details may complicate things a bit.  Before we go into what was actually done, let&#8217;s look at an ideal scenario for such an incompatible change.</p>
<p>As mentioned above, when introducing disruptive changes like this, we want a good migration path, and we want to help people keeping the procedure in mind, so that they do the right thing even though they&#8217;re not spending too many brain cycles on it.  Here is a suggested schema of what might have happened to achieve the above goal: in Python 2.6, introduce the <i>bytes</i> type, with exactly the same semantics of what will be seen in Python 3.0.   During 2.6, encourage people to migrate <i>str</i> references in their code to either the previously existent <i>unicode</i> type, when dealing with textual data, or to the new <i>bytes</i> type, when handling binary data.  When 3.0 comes along, simply kill the old <i>str</i> types, and we&#8217;re done.  People can easily write code in 2.6 which supports 3.0, and if they see a reference to <i>str</i> they know something must be done.  No big deal, and apparently quite straightforward.</p>
<p>Now, let&#8217;s see how to do it in a bad way.</p>
<p>Python 2.6 introduces the <i>bytes</i> type, but it&#8217;s not actually a new type.  It&#8217;s simply an alias to the existing <i>str</i> type.  This means that if you write code to support <i>bytes</i> in 2.6, you are actually not writing code which is compatible with Python 3.0.  Why on earth would someone introduce an alias on 2.6 which will generate <i>incompatible</i> code with 3.0 is beyond me.  It must be some kind of anti-migration pattern.  Then, Python 3.0 renames <i>unicode</i> to <i>str</i>, and kills the old <i>str</i>.  So, the result is quite bad: Python 3.0 has both <i>str</i> and <i>bytes</i>, and they both mean something else than they did on 2.6, which is the first version which supposedly should help migration, and not a single one of the three types from 2.6 got their names and semantics preserved in 3.0.  In fact, just <i>unicode</i> exists at all, and it has a different name.</p>
<p>There you go.  I&#8217;ve heard people learn better from counter-examples.  Here we have a good one to keep in mind and avoid repeating.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.labix.org/2009/07/02/screwing-up-python-compatibility-unicode-str-bytes/feed</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>Changing people or changing rules</title>
		<link>http://blog.labix.org/2009/05/16/changing-people-or-changing-rules</link>
		<comments>http://blog.labix.org/2009/05/16/changing-people-or-changing-rules#comments</comments>
		<pubDate>Sat, 16 May 2009 13:02:20 +0000</pubDate>
		<dc:creator>Gustavo Niemeyer</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://blog.labix.org/?p=109</guid>
		<description><![CDATA[In my previous post I made an open statement which I&#8217;d like to clarify a bit further: (&#8230;) when the rules don’t work for people, the rules should be changed, not the people. This leaves a lot of room for &#8230; <a href="http://blog.labix.org/2009/05/16/changing-people-or-changing-rules">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In my previous post I made an open statement which I&#8217;d like to clarify a bit further:</p>
<blockquote><p>(&#8230;) when the rules don’t work for people, the rules should be changed, not the people.</p></blockquote>
<p>This leaves a lot of room for personal interpretation of what was actually meant, and TIm Hoffman pointed that out nicely with the following questioning in a comment:</p>
<blockquote><p>I wonder when the rule is important enough to change the people though. For instance [, if your] development process is oriented to TDD and people don’t write the tests or do the job poorly will you change them then?</p></blockquote>
<p>This is indeed a nice scenario to explore the idea.  If it happens at some point that a team claims to be using TDD, but if in practice no developer actually writes tests first, the rules are clearly not working.  If everyone in the team hates doing TDD, enforcing it most probably won&#8217;t show its intended benefits, and that was the heart of my comment.  You can&#8217;t simply keep the rule as is if no one follows it, unless you don&#8217;t really care about the outcome of the rule.</p>
<p>One interesting point, though, is that when you have a high level of influence over the environment in which people are, it may be possible to tweak the rules <i>or</i> the processes to adapt to reality, and tweaking the processes may change the way that people feel about the rules as a consequence (arguably, <i>changing people</i> as a side effect).</p>
<p>As a more concrete example, if I found myself in the described scenario,  I&#8217;d try to understand why TDD is not working, and would try to discuss with the team to see how we should change the process so that it starts to work for us somehow.  Maybe what would be needed is more discussion to show the value of TDD, and perhaps some pair programming with people that do TDD very well so that the joy of doing it becomes more visible.</p>
<p>In either case, I wouldn&#8217;t be simply asking people &#8220;<i>Everyone has to do TDD from now on!</i>&#8220;, I&#8217;d be tweaking the process so that it feels better and more natural to people.  Then, if nothing similar works either, well, let&#8217;s change the rule.  I&#8217;d try to use more conventional unit testing or some other system which people do follow more naturally and that presents similar benefits.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.labix.org/2009/05/16/changing-people-or-changing-rules/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Class member access control: enforcement vs. convention</title>
		<link>http://blog.labix.org/2009/05/15/class-member-access-control-enforcement-vs-convention</link>
		<comments>http://blog.labix.org/2009/05/15/class-member-access-control-enforcement-vs-convention#comments</comments>
		<pubDate>Fri, 15 May 2009 09:26:06 +0000</pubDate>
		<dc:creator>Gustavo Niemeyer</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://blog.labix.org/?p=99</guid>
		<description><![CDATA[For a long time I&#8217;ve been an advocate of Python&#8217;s notion of controlling access to private and protected members (attributes, methods, etc) with conventions, by simply naming them like &#8220;_name&#8221;, with an initial underline.  Even though Python does support the &#8230; <a href="http://blog.labix.org/2009/05/15/class-member-access-control-enforcement-vs-convention">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>For a long time I&#8217;ve been an advocate of Python&#8217;s notion of controlling access to private and protected members (attributes, methods, etc) with conventions, by simply naming them like &#8220;_name&#8221;, with an initial underline.  Even though Python does support the &#8220;__name&#8221; (with double underscore) for &#8220;private&#8221; members (this actually mangles the name rather than hiding it), you&#8217;ll notice that even this is rarely used in practice, and the largely agreed mantra is that convention should be enough and thus one underscore suffices.  This always resonated quite well with me, since I generally prefer to handle situations by agreement rather than enforcement.  Well, I&#8217;m now changing my opinion.that this works well for this purpose, at least in certain situations.</p>
<p>This methodology may work quite well in situations where the code scope is within a very controlled environment, with one or more teams which follow strictly a single development guideline, and have the power to refactor the affected code base somewhat easily when the original decisions are too limiting.</p>
<p>Having worked on a few major projects now, and some of them being libraries which are used by several teams within the same company or outside, I now perceive that people very often take shortcuts over these decisions for getting their job done quickly.  It&#8217;s way easier to simply read the code and get to the private guts of a library than to try to get agreement over the right way to do something, or sending a patch with a suggested change which was carefully architected.</p>
<p>Many people by now are probably thinking: &#8220;Well, that&#8217;s <i>their</i> problem, isn&#8217;t it?  If their code base breaks on the next upgrade they&#8217;ll get burden and won&#8217;t be able to upgrade cleanly.&#8221;, and I can honestly understand this feeling, since I shared it.  But, for a number of reasons, I now understand that this isn&#8217;t just <i>their</i> problem, it&#8217;s very much <i>my</i> problem too.</p>
<p>Most importantly, on any serious software, these problems will usually come back to the implementors, and many times the problem will have a much larger magnitude by then than they had at the time a change could have been done &#8220;the right way&#8221; on the implementation, because code dependent on the private bits will have settled.</p>
<p>Most people are optimist by nature and believe that the implementation won&#8217;t change, but, of course, one of the reasons why private information is made private in the first place is exactly because the implementor believes that having the freedom to change these details in the future is important, and not rarely there&#8217;s already a plan of evolution in place for these private pieces, which may include revamping the implementation entirely for scalability or for other goals.</p>
<p>In the best case, the careless people will get burden on the upgrade and will ask for support or simply won&#8217;t upgrade silently, and both cases hurt implementors, because providing support for broken software takes time and energy, and amazingly can even hurt the software image. Lack of upgrades also means more ancient versions in the wild to give support for.  Besides these, in the worst case scenario, the careless people have enough influence on the affected project to cause as much burden on it as if the private data was public in the first place.</p>
<p>As much as I&#8217;m a believer in handling situation by agreement rather than enforcement, I&#8217;m also a believer that when the rules don&#8217;t work for people, the rules should be changed, not the people.  So my positioning now is that the language supported access constraints (public, protected, private), as available in languages like Java and C++, are a better alternative when compared to convention as used today in Python, since they provide an additional layer of encouragement for people to not break the rules carelessly, and that helps in the maintenance and reuse of software that has greater visibility.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.labix.org/2009/05/15/class-member-access-control-enforcement-vs-convention/feed</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
	</channel>
</rss>
