<?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>Geek at Play &#187; python</title>
	<atom:link href="http://www.kylev.com/tag/python/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.kylev.com</link>
	<description>kylev in text form</description>
	<lastBuildDate>Fri, 12 Mar 2010 07:01:47 +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>Finding my first Python reference cycle</title>
		<link>http://www.kylev.com/2009/11/03/finding-my-first-python-reference-cycle/</link>
		<comments>http://www.kylev.com/2009/11/03/finding-my-first-python-reference-cycle/#comments</comments>
		<pubDate>Tue, 03 Nov 2009 19:31:34 +0000</pubDate>
		<dc:creator>kylev</dc:creator>
				<category><![CDATA[Geekdom]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.kylev.com/?p=479</guid>
		<description><![CDATA[I&#8217;ve worked in Python for nearly six years now and, up to this point, I&#8217;ve not had to deal with the king of memory-related gotchas: the reference cycle.  Simply put, a reference cycle happens when two or more objects create a cyclic directed graph in their path of references (ok, not that simple).  [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve worked in Python for nearly six years now and, up to this point, I&#8217;ve not had to deal with the king of memory-related gotchas: the reference cycle.  Simply put, a reference cycle happens when two or more objects create a cyclic directed graph in their path of references (ok, not that simple).  The simplest form is the &#8220;I point to you, you point to me, neither of our reference counts get to zero&#8221; scenario.</p>
<p>Usually, this isn&#8217;t a big deal.  Although objects don&#8217;t get immediately collected when dereferenced, the garbage collector will eventually notice that there is some wasted memory, do the more expensive cycle detection work, and free the objects.  In many scenarios like single-run scripts, cron jobs, or low-load applications you&#8217;ll never notice; Python does it&#8217;s job, keeps things clean, and stays out of your way.  If, however, you&#8217;re writing a high performance internet server intended to handle the ever increasing demands of the modern Internet, you just might be screwed.  That GC work will cost you desired though-put and scalability.  In the worst case, the GC won&#8217;t be invoked in time and you&#8217;ll hemorrhage memory (or at least gobble it up in competition with other things your system might need to do).  I this case, initial numbers left us with a customer-detectable throughput degradation when a particular security feature was enabled.</p>
<p>Without further ado, here is the distilled pattern that ran us into trouble.</p>
<pre class="brush:py">
class Filter:
    def __init__(self, callback):
        self._callback = callback

    def update(self, data):
        """Override and call parent."""
        self._callback(data)

class AddLF(Filter):
    def update(self, data):
        data = data + '\n'
        Filter.update(self, data)

class AddCRLF(Filter):
    def update(self, data):
        data = data + '\r\n'
        Filter.update(self, data)

class Foo:
    def __init__(self, dos_mode=False):
        if dos_mode:
            self._filter = AddCRLF(self.the_callback)
        else:
            self._filter = AddLF(self.the_callback)
        self._filtered_data = list()

    def update(self, data):
        self._filter.update(data)

    def the_callback(self, data):
        self._filtered_data.append(data)

    def all_data(self):
        return ''.join(self._filtered_data)
</pre>
<p>At a glance, this isn&#8217;t an unreasonable design pattern.  If you&#8217;re writing a cross platform tool, or something that needs to listen on a socket and account for variations and flaws in protocol implementations, passing the input through a filter to clean it up is reasonable.  It&#8217;s even somewhat pythonic in that a call-back is used, allowing for various patterns of code re-use and subclassing in both the filters and the consumer.</p>
<p>The usage pattern is something like this: for each chunk of data you receive, call <code>update()</code>, the main class hands the data off to the filter, the filter does its thing, and uses the callback to pass the data back up.</p>
<pre class="brush:py">
# Many of you will recognize this pattern from crypto digests
f = Foo()
f.update('asdf')
f.update('jkl;')
print f.all_data()
f = None
# At this point ref-counting could have reclaimed the object
</pre>
<p>Pay attention to that last line: when we assign <code>f = None</code>, under normal circumstances the reference count would hit zero, and all objects should be collected.  Here this is not the case!</p>
<p>Once I realized this region of code was the likely culprit, I started playing with the <code><a href="http://docs.python.org/library/gc.html">gc</a></code> module and its debugging abilities.  Most importantly, using the <code>gc.DEBUG_SAVEALL</code> setting causes the garbage collector to (instead of completing collection) store all unreachable objects in a list named <code>gc.garbage</code>.  This can be examined for hints.</p>
<pre class="brush:py">
import gc, pprint

gc.set_debug(gc.DEBUG_SAVEALL)
print gc.get_count()
print gc.collect()
pprint.pprint(gc.garbage)
</pre>
<p>Here is the output from that single object creation.</p>
<pre class="brush:text">
(249, 5, 0)
6
[{'_filter': &lt;__main__.AddLF instance at 0x7f23ec3261b8&gt;,
  '_filtered_data': ['asdf\n', 'jkl;\n']},
 &lt;__main__.Foo instance at 0x7f23ec326170&gt;,
 &lt;bound method Foo.the_callback of &lt;__main__.Foo instance at 0x7f23ec326170&gt;&gt;,
 {'_callback': &lt;bound method Foo.the_callback of &lt;__main__.Foo instance at 0x7f23ec326170&gt;&gt;},
 &lt;__main__.AddLF instance at 0x7f23ec3261b8&gt;,
 ['asdf\n', 'jkl;\n']]
</pre>
<p>You might be able to see the loop already.  We have, left over, a <code>Foo</code> instance, an <code>AddLF</code> instance (which we know is stored as a member variable of <code>Foo</code>), and (most importantly) a reference to a <em>bound method</em> on <code>Foo</code>.  This <em>bound method</em> holds a reference back to the <code>Foo</code> instance, completing the cycle.</p>
<p>What the original designer of this code probably didn&#8217;t realize is that passing that callback when instantiating a Filter would create that loop (via the bound instance method, which has a reference to the instance).  After a minor refactoring, I&#8217;ve gotten rid of the cycle and reference counts hit zero when the last external reference to a <code>Foo</code> object is eliminated.  Most importantly all the related data is freed as well; in this case <code>Foo._filtered_data</code> (which could grow to be very large) will get freed up as well.</p>
<p>This anti-pattern is only one step away from the simplest case reference cycle, but it had real consequences.  With it gone, memory is managed far more efficiently and this feature is usable in a demanding, high-performance environment.</p>
<p><em>I do not host comments due to spam and abuse.  <a href="http://www.reddit.com/r/Python/comments/a0lnu/finding_my_first_python_reference_cycle/">Discuss this post at reddit</a></em>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kylev.com/2009/11/03/finding-my-first-python-reference-cycle/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Start your Python project with optparse and logging</title>
		<link>http://www.kylev.com/2009/07/01/start-your-python-project-with-optparse-and-logging/</link>
		<comments>http://www.kylev.com/2009/07/01/start-your-python-project-with-optparse-and-logging/#comments</comments>
		<pubDate>Wed, 01 Jul 2009 21:15:04 +0000</pubDate>
		<dc:creator>kylev</dc:creator>
				<category><![CDATA[Geekdom]]></category>
		<category><![CDATA[logging]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.kylev.com/?p=432</guid>
		<description><![CDATA[Python continues to be my favorite language to hack in.  It&#8217;s useful for tasks big and small and has the advantage of being more readable and maintainable than a lot of other scripting languages.  I remember when, having learned the basics of Python, I decided to rewrite my home-built CD-to-MP3 script suite from [...]]]></description>
			<content:encoded><![CDATA[<p>Python continues to be my favorite language to hack in.  It&#8217;s useful for tasks big and small and has the advantage of being more readable and maintainable than a lot of other scripting languages.  I remember when, having learned the basics of Python, I decided to rewrite my home-built CD-to-MP3 script suite from its perl incarnation (perl was my previous favorite language for system programming projects).  I knocked that project out in only about 2 hours, including a major redesign made easy by Python&#8217;s object syntax and built in &#8220;pickle&#8221; for serialization.</p>
<p>Since then, I&#8217;ve usually chosen Python for a variety of system programming tasks.  This includes things like making backups, deploying software, configuration file templating, web site scraping, health monitoring, and some bigger data crunching/graphing.  Time after time, these quick projects (often at work) turned into something bigger.  Eventually they get rolled into a product or adopted by the production operations group as standard kit.</p>
<p>At some point I realized that there was something that I was doing that made this transition from &#8220;quick hack&#8221; to &#8220;standard tool&#8221; easy: I always start my projects with <code><a href="http://docs.python.org/library/logging.html">logging</a></code> and <code><a href="http://docs.python.org/library/optparse.html">optparse</a></code> in place from day zero.  During development, this means that I don&#8217;t have to scatter <code>print</code>-style debugging statements throughout the code, I can just use <code>logging.debug()</code> and turn them on and off at will (via command line flags).  Once deployed or passed on, it means other people using it can immediately start interacting with my script just like other familiar Unix utilities.</p>
<p>So, here is a variation on what my typical python script starts out with.</p>
<pre class="brush:py">#!/usr/bin/python

import logging

def foo():
    """These will only get output if you turn up verbosity."""
    logging.debug("This is debug.")
    logging.info("This is info.")

def bar():
    """These will all be output a default logging levels."""
    logging.warn("Warning!  Things are getting scary.")
    logging.error("Uh-oh, something is wrong.")
    try:
        raise Exception("ZOMG tacos.")
    except:
        logging.exception("Just like error, but with a traceback.")

if '__main__' == __name__:
    # Late import, in case this project becomes a library, never to be run as main again.
    import optparse

    # Populate our options, -h/--help is already there for you.
    optp = optparse.OptionParser()
    optp.add_option('-v', '--verbose', dest='verbose', action='count',
                    help="Increase verbosity (specify multiple times for more)")
    # Parse the arguments (defaults to parsing sys.argv).
    opts, args = optp.parse_args()

    # Here would be a good place to check what came in on the command line and
    # call optp.error("Useful message") to exit if all it not well.

    log_level = logging.WARNING # default
    if opts.verbose == 1:
        log_level = logging.INFO
    elif opts.verbose >= 2:
        log_level = logging.DEBUG

    # Set up basic configuration, out to stderr with a reasonable default format.
    logging.basicConfig(level=log_level)

    # Do some actual work.
    foo()
    bar()</pre>
<p>This is obviously a pretty minimal setup, but it achieves what most people need.  You get option parsing and checking along with usage information.  You get warnings and errors spat out to <code>sys.stderr</code> (leaving <code>sys.stdout</code> for actual program output).  You can specify <code>-v</code> to crank up verbosity.</p>
<p>More than once, I&#8217;ve had a pager-frazzled sysadmin ask me how the heck to use the new tool.  I get to reply, &#8220;Just run it with <code>--help</code>, it has full usage instructions built in.&#8221;  This makes sysadmins happy; really happy.  It means they don&#8217;t have to remember odd semantics or dig around for the how-to page on the internal wiki at 3:00am when they need to use it.  Culturally, there is almost nothing more valuable than a sysadmin who has had success with your code, and nothing worse than one that has had trouble with it.  To me, the first step in granting a sysadmin that sort of success is to make your code act like everything else in <code>/usr/bin</code> and that&#8217;s why I&#8217;ll continue starting my projects in this manner.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kylev.com/2009/07/01/start-your-python-project-with-optparse-and-logging/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>A brief Python decorator primer</title>
		<link>http://www.kylev.com/2009/05/28/a-brief-python-decorator-primer/</link>
		<comments>http://www.kylev.com/2009/05/28/a-brief-python-decorator-primer/#comments</comments>
		<pubDate>Fri, 29 May 2009 02:37:34 +0000</pubDate>
		<dc:creator>kylev</dc:creator>
				<category><![CDATA[Geekdom]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.kylev.com/?p=405</guid>
		<description><![CDATA[My last post looked at easing a common database idiom using a decorator.  Interestingly, the brief discussion on reddit regarding the post had a number of people remarking that the coverage of decorators was more interesting than the SQL-related bits.  Curious, that.
It seems I&#8217;m not alone in being occasionally puzzled by the way [...]]]></description>
			<content:encoded><![CDATA[<p>My <a href="/2009/05/22/python-decorators-and-database-idioms/">last post looked at easing a common database idiom using a decorator</a>.  Interestingly, the brief <a href="http://www.reddit.com/r/Python/comments/8np00/python_decorators_and_database_idioms/">discussion on reddit regarding the post</a> had a number of people remarking that the coverage of decorators was more interesting than the SQL-related bits.  Curious, that.</p>
<p>It seems I&#8217;m not alone in being occasionally puzzled by the way decorators work.  It took me a little while to comprehend them.  I&#8217;m still not a huge fan of how they work, but I can see their utility and do use them when appropriate.  Almost without fail I end up heading over to <a href="http://www.python.org/dev/peps/pep-0318/">PEP-318</a> and puzzling over the variations.  The PEP isn&#8217;t terribly helpful since it is dominated by historical discussion rather than examples or instructions.</p>
<p>So let&#8217;s start with the basic no-argument decorator.  It doesn&#8217;t take any declarative arguments when decorating a function; you just type <code>@some_deco</code> without parenthesis when using it.</p>
<pre class="brush:python">def some_deco(f):
    def _inner(*args, **kwargs):
        print "Decorated!"
        return f(*args, **kwargs)

    return _inner

@some_deco
def some_func(a, b):
    return a + b

print some_func(1, 2)</pre>
<p>This will print out:</p>
<blockquote><pre>Decorated!
3</pre>
</blockquote>
</pre>
<p>According to the PEP, if you wrap <code>some_func</code> with <code>@some_deco</code>, it is the equivalent of <code>some_func = some_deco(some_func)</code>.  What it fails to call out is that this happens <em>at load time</em>.  What we're returning from the decorator function is a new function or callable that will be bound to the name <code>some_func</code> when this module is loaded.  Subsequent run-time calls to <code>some_func</code> are actually calling the <code>_inner</code> function we defined on the fly when the decorator was called.  Thanks to Python's scoping rules and closures, we have access to the passed <code>f</code> parameter from the inner function, so we can call it.</p>
<p>Lovely.  Now you have the power to tack on any sort of things you want to around a given function.  Print a log message before or after, spawn a thread, add some exception handling.  Whatever you want.</p>
<p>Things get a little more hairy if we want our decorators themselves to take parameters.  According to the PEP, if was want parameters on the decorator to take parameters it's the equivalent of <code>func = decomaker(argA, argB, ...)(func)</code>.  Again, this happens at load time, so it's worth staring at for a moment.  In plain English, this is saying that decomaker will be called with some arguments, and then the result of <em>that</em> will be called with a function reference.  This is key!  There are actually two invocations happening.  The first will need to return a callable that accepts a function as it's argument.  That will then be called, and the result bound to the name <code>func</code>, so it better be callable as well.  Let's try it.</p>
<pre class="brush:python">def log_wrap(message):
    """Print `message` each time the decorated function is called."""
    def _second(f):
        def _inner(*args, **kwargs):
            print message
            return f(*args, **kwargs) 

        # This is called second, so return a callable that takes arguments
        # like the first example.
        return _inner

    # This is called first, so we want to pass back our inner function that accepts
    # a function as argument
    return _second

@log_wrap("Called it!")
def func(a, b):
    return a + b

print func(1, 2)</pre>
<p>This will output:</p>
<blockquote><pre>Called it!
3</pre>
</blockquote>
<p>Ok, ok, that's not terribly useful, but it illustrates the point (and expands on the first example by being a parameterized version).  It requires that we construct two callable items inside our decorator, and that each will be called in turn during load time.  Let's quick dissect what happens at load time.  When python gets to the declaration of <code>func</code> with the decorator sitting on top of it, it calls the decorator function with its argument (in this case, the string "Called!").  What is returned is a function reference to <code>_second</code>.  Next, that just-returned reference to <code>_second</code> is invoked with a single argument: a function pointer to <code>func</code>, which is what we're actually trying to decorate.  The return value of <code>_second</code> is a reference to <code>_inner</code>, which will be bound to the name <code>func</code>, ready for run-time invocation.</p>
<p>Yeah, I'm a little dizzy, too.  But if you practice this a couple times, it'll start to make sense.  Again, the key to getting this second form working is to recognize that two calls are happening at load time and returning the appropriate callable references at the right time.</p>
<p>Once you have it down, use this new hammer when it serves you, remembering that not every problem is a nail.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kylev.com/2009/05/28/a-brief-python-decorator-primer/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Python, decorators, and database idioms</title>
		<link>http://www.kylev.com/2009/05/22/python-decorators-and-database-idioms/</link>
		<comments>http://www.kylev.com/2009/05/22/python-decorators-and-database-idioms/#comments</comments>
		<pubDate>Fri, 22 May 2009 20:04:43 +0000</pubDate>
		<dc:creator>kylev</dc:creator>
				<category><![CDATA[Geekdom]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.kylev.com/?p=397</guid>
		<description><![CDATA[Now that I&#8217;m a co-maintainer of the MySQL driver for Python I get to see a lot of confused people pop in on the support forums with some elementary problems.  These seem to be mostly young developers who haven&#8217;t quite mastered the &#8220;start transaction, work with the database, commit&#8221; pattern that so many of [...]]]></description>
			<content:encoded><![CDATA[<p>Now that I&#8217;m a co-maintainer of the <a href="https://sourceforge.net/projects/mysql-python/">MySQL driver for Python</a> I get to see a lot of confused people pop in on the support forums with some elementary problems.  These seem to be mostly young developers who haven&#8217;t quite mastered the &#8220;start transaction, work with the database, commit&#8221; pattern that so many of us have become used to after a few years.</p>
<p>I still find the overhead of doing that sort of thing repeatedly to be tiresome.  It doesn&#8217;t take long for your code to become a mess of try/except blocks, making code reading confusing and arduous.  To avoid this, I&#8217;ve been using a Python decorator to wrap my SQL functions.  It goes a little something like this (simplified form):</p>
<pre class="brush:py">def dbwrap(func):
    """Wrap a function in an idomatic SQL transaction.  The wrapped function
    should take a cursor as its first argument; other arguments will be
    preserved.
    """
    def new_func(conn, *args, **kwargs):
        cursor = conn.cursor()
        try:
            cursor.execute("BEGIN")
            retval = func(cursor, *args, **kwargs)
            cursor.execute("COMMIT")
        except:
            cursor.execute("ROLLBACK")
            raise
        finally:
            cursor.close()

        return retval

    # Tidy up the help()-visible docstrings to be nice
    new_func.__name__ = func.__name__
    new_func.__doc__ = func.__doc__

    return new_func

@dbwrap
def do_something(cursor, val1=1, val2=2):
    """Do that database thing."""
    cursor.execute("SELECT %s, %s", (val1, val2))
    return cursor.fetchall()

class SomeClass(object):
    def __init__(self):
        conn = MySQLdb.connect(db='test')
        self.instance_var = SomeClass.get_stuff(conn)
        print self.instance_var
        conn.close()

    @staticmethod
    @dbwrap
    def get_stuff(cursor):
        """Load something meaningful from the database."""
        cursor.execute("SELECT 'blah'")
        return cursor.fetchall()[0][0]

if '__main__' == __name__:
    conn = MySQLdb.connect(db='test')
    print do_something(conn)
    print do_something(conn, 3, 4)
    print do_something(conn, 5)
    print do_something(conn, val2=6)
    #help(do_something)

    s = SomeClass()
    #help(s)</pre>
<p>Now, there are obviously several additions you could make here.  You could add retry/reconnect logic, be a little more careful when closing the cursor (which can throw exceptions), or even attempt some deadlock recovery.  But I think this simple example shows how you can effectively use decorators to implement a useful DB interaction idiom on both functions and object static methods.</p>
<p>And, damn, if it doesn&#8217;t save a lot of typing.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kylev.com/2009/05/22/python-decorators-and-database-idioms/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Django and app-relative static content</title>
		<link>http://www.kylev.com/2009/01/20/django-and-app-relative-static-content/</link>
		<comments>http://www.kylev.com/2009/01/20/django-and-app-relative-static-content/#comments</comments>
		<pubDate>Tue, 20 Jan 2009 21:25:30 +0000</pubDate>
		<dc:creator>kylev</dc:creator>
				<category><![CDATA[Geekdom]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.kylev.com/?p=376</guid>
		<description><![CDATA[This one drove me a little nuts at first, but I finally realized how to do it.  In the process of trying to write a little application using Django and jQuery, I found it to be annoyingly non-obvious how I should serve up a self contained set of graphical assets (like images) and my own [...]]]></description>
			<content:encoded><![CDATA[<p>This one drove me a little nuts at first, but I finally realized how to do it.  In the process of trying to write a little application using <a href="http://www.djangoproject.com/">Django</a> and <a href="http://jquery.com/">jQuery</a>, I found it to be annoyingly non-obvious how I should serve up a self contained set of graphical assets (like images) and my own application-local jQuery distribution.  Sure, I could drop stuff in the same media root as the admin app, or tell people how to create a static mapping, but that kind of defeats modularity.  I <em>really</em> want people to be able to drop my little application into their existing Django project or installation, add a single <code>include()</code> entry into their project&#8217;s <code>urls.py</code> and go.</p>
<p>I tried a couple of things including a manually constructed <code>RegexURLPattern</code>, but it didn&#8217;t feel very clean or pythonic.  Over the weekend I realized I could just write a simple delegating view function in my application&#8217;s <code>views.py</code>:</p>
<pre class="brush:py">import os
import django.views.static

STATIC_ROOT = os.path.dirname(os.path.normpath(__file__)) + '/static'

def static(request, path):
    """Return app-relative static resources and collateral."""
    return django.views.static.serve(request, path, STATIC_ROOT)</pre>
<p>With this trick and the app-relative templates loaded from the <code>templates/</code> directory (if you don&#8217;t waste time on the <a href="http://code.djangoproject.com/ticket/10053">doc bug I found</a>) it is quite possible to write a fully self-contained, drop-in application.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kylev.com/2009/01/20/django-and-app-relative-static-content/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Not a good start</title>
		<link>http://www.kylev.com/2008/12/02/not-a-good-start/</link>
		<comments>http://www.kylev.com/2008/12/02/not-a-good-start/#comments</comments>
		<pubDate>Tue, 02 Dec 2008 20:01:55 +0000</pubDate>
		<dc:creator>kylev</dc:creator>
				<category><![CDATA[Day in the Life]]></category>
		<category><![CDATA[Geekdom]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[tar]]></category>

		<guid isPermaLink="false">http://www.kylev.com/?p=372</guid>
		<description><![CDATA[This is going to be one of those days.  I decided to install a python package called Plex that we use in a few places.  It looked like a coworker was misusing it a little, so I wanted to understand more.  I took a quick look at the tarball contents and was instantly annoyed.
[kylev@kylev-dt tmp]$ [...]]]></description>
			<content:encoded><![CDATA[<p>This is going to be one of those days.  I decided to install a python package called <a href="http://www.cosc.canterbury.ac.nz/greg.ewing/python/Plex/">Plex</a> that we use in a few places.  It looked like a coworker was misusing it a little, so I wanted to understand more.  I took a quick look at the tarball contents and was instantly annoyed.</p>
<pre class="brush:bash">[kylev@kylev-dt tmp]$ tar tzf Plex-1.1.5.tar.gz
[ Bunch of stuff scrolls off]
tests/._test6.py
tests/test6.py
tests/._test7.in
tests/test7.in
tests/._test7.out
tests/test7.out
tests/._test7.py
tests/test7.py
tests/._test8.in
tests/test8.in
tests/._test8.out
tests/test8.out
tests/._test8.py
tests/test8.py
tests/._test9.in
tests/test9.in
tests/._test9.out
tests/test9.out
tests/._test9.py
tests/test9.py</pre>
<p>What jumps out at me is the damn <code>._</code> files everywhere.  Crud, the author did this on a Mac, which in certain cases (and versions of <code>tar</code>) will include these annoying extra empty files.  No big deal, it&#8217;s just annoying.  Maybe I&#8217;ll talk to the maintainer later and have him fix it.</p>
<p>Let&#8217;s get on with it and get this baby installed:</p>
<pre class="brush:bash">[kylev@kylev-dt tmp]$ tar xzf Plex-1.1.5.tar.gz
[kylev@kylev-dt tmp]$ cd Plex-1.1.5.tar.gz</pre>
<p>Wait, what the hell?  Why did tab-completion give me the tarball again?  Oh, damnit!  While being distracted and annoyed with the OSX dot-underscore files, I failed to notice that this tarball doesn&#8217;t have a top level container directory!  Argh, it has just spewed files all over instead of being neatly contained.  No big deal, I&#8217;m in my <code>~/tmp</code> directory so I probably didn&#8217;t over-write anything important.  Time to clean things up:</p>
<pre class="brush:bash">[kylev@kylev-dt tmp]$ tar tzf Plex-1.1.5.tar.gz | xargs rm
rm: cannot remove `./._Iconr': No such file or directory
rm: cannot remove `Iconr': No such file or directory
rm: cannot remove `Plex/': Is a directory
rm: cannot remove `doc/': Is a directory
rm: cannot remove `examples/': Is a directory
rm: cannot remove `tests/': Is a directory</pre>
<p>Bah, I could have used <code>rm -rf</code>, but I didn&#8217;t want to trash the whole <code>examples</code> or <code>doc</code> directories in case I had one not created by this package.  Let&#8217;s just clean up the last bits one by one.</p>
<pre class="brush:bash">[kylev@kylev-dt tmp]$ rmdir ._Icon^M</pre>
<p>What did tab-completion just do with&#8230; <strong>facepalm</strong>!  The tarball contained a directory with a carriage-return in the name!  Time to fire up emacs dired to finish cleaning up.</p>
<p>That was one troublesome tarball.  It can only get better from here, right?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kylev.com/2008/12/02/not-a-good-start/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Pylons on Fedora 8</title>
		<link>http://www.kylev.com/2008/04/11/pylons-on-fedora-8/</link>
		<comments>http://www.kylev.com/2008/04/11/pylons-on-fedora-8/#comments</comments>
		<pubDate>Fri, 11 Apr 2008 23:32:16 +0000</pubDate>
		<dc:creator>kylev</dc:creator>
				<category><![CDATA[Geekdom]]></category>
		<category><![CDATA[fedora]]></category>
		<category><![CDATA[pylons]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.kylev.com/2008/04/11/pylons-on-fedora-8/</guid>
		<description><![CDATA[I&#8217;ve started playing with Pylons and like it so far.  It has the rails-ish routing system, but doesn&#8217;t have some of the nonsense.  Additionally, it&#8217;s designed to be open and adaptable, letting you plug in your own ORM or eschew using one entirely (unlike Django which seems to really want you to use [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve started playing with <a href="http://pylonshq.com/">Pylons</a> and like it so far.  It has the rails-ish routing system, but doesn&#8217;t have some of the nonsense.  Additionally, it&#8217;s designed to be open and adaptable, letting you plug in your own ORM or eschew using one entirely (unlike Django which seems to <em>really</em> want you to use their <a href="http://code.djangoproject.com/ticket/373">badly crippled ORM</a>).</p>
<p>To make things easier for people running Fedora 8 or other RPM-based Linux distros, I&#8217;ve created some <a href="/pylons-rpm/">spec files and F8 RPMs to let you install Pylons in an RPM-friendly way</a>.  The other dependencies (like python-simplejson) can be found already via <code>yum</code>.  Try them, and let me know what you think; I may submit these for F9.</p>
<p><em>Update:</em> These have been <a href="https://bugzilla.redhat.com/show_bug.cgi?id=445028">submitted for review</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kylev.com/2008/04/11/pylons-on-fedora-8/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>All in order</title>
		<link>http://www.kylev.com/2005/01/07/all-in-order/</link>
		<comments>http://www.kylev.com/2005/01/07/all-in-order/#comments</comments>
		<pubDate>Fri, 07 Jan 2005 10:21:20 +0000</pubDate>
		<dc:creator>kylev</dc:creator>
				<category><![CDATA[Geekdom]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.kylev.com/Cms/?p=227</guid>
		<description><![CDATA[I swear I have rare moments of clarity.  I was really happy when I finally realized how a non-recursive in-order binary tree traversal would work.  It&#8217;s a piece of CS trivia that I continually forget.  I&#8217;m also pleased to realize how easy it is to write in python as an iterator class. [...]]]></description>
			<content:encoded><![CDATA[<p>I swear I have rare moments of clarity.  I was really happy when I finally realized how a non-recursive in-order binary tree traversal would work.  It&#8217;s a piece of CS trivia that I continually forget.  I&#8217;m also pleased to realize how easy it is to write in python as an iterator class.  16 lines, with comments and some white space.<br />
<span id="more-230"></span></p>
<pre class="brush:py">class _OrderIterator:
    """An in-order traversal iterator."""
    def __init__(self, head):
        self._stack = [head]

    def next(self):
        cur = self._stack.pop()
        while cur:
            self._stack.append(cur)
            cur = cur.left

        if not len(self._stack):
            raise StopIteration
        cur = self._stack.pop()

        self._stack.append(cur.right)
        return cur.value</pre>
<p>Now that you see it, isn&#8217;t it just freaking <em>obvious</em>?!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kylev.com/2005/01/07/all-in-order/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fun with python properties</title>
		<link>http://www.kylev.com/2004/10/13/fun-with-python-properties/</link>
		<comments>http://www.kylev.com/2004/10/13/fun-with-python-properties/#comments</comments>
		<pubDate>Thu, 14 Oct 2004 01:24:12 +0000</pubDate>
		<dc:creator>kylev</dc:creator>
				<category><![CDATA[Geekdom]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.kylev.com/Cms/?p=219</guid>
		<description><![CDATA[I ran into an oddity of something I wanted to do with python properties while playing with my music server the yesterday.  After a little futzing, I found a way around my problem.  Read on to find out how to do python properties and inheritance.

Assume we have two classes.  The first, Base, [...]]]></description>
			<content:encoded><![CDATA[<p>I ran into an oddity of something I wanted to do with <a href="http://www.python.org/2.2.3/descrintro.html">python properties</a> while playing with my music server the yesterday.  After a little futzing, I found a way around my problem.  Read on to find out how to do python properties and inheritance.<br />
<span id="more-222"></span><br />
Assume we have two classes.  The first, <code>Base</code>, provides property-style access to some attributes.  Straightforward get and set.  The <code>Derived</code> class wants the same thing, but wants to change the default &#8220;unset&#8221; value for property <code>foo</code>.</p>
<p>In the absence of property (dot-style) access, it would just be a matter of overriding <code>getFoo()</code>.  To make property access work right, we must get a little bit clever.</p>
<p>At first it seems simple.  Just point the arguments to <code>property()</code> to the get and set functions and be done with this.  Seems obvious:</p>
<pre class="brush:py">class Base(object):
    def __init__(self):
        self.foo = None

    def getFoo(self):
        return self.__foo

    def setFoo(self, val):
        self.__foo = val

    # Seemingly obvious solution:
    # foo = property(fget=getFoo, fset=setFoo)
    #
    # Actual solution:
    foo = property(fget=lambda self: self.getFoo(),
                   fset=lambda self, v: self.setFoo(v)
                   )

class Derived(Base):
    def getFoo(self):
        """Same as in Base, but default to 0 instead of None."""
        result = super(Derived, self).getFoo()
        if result != None:
            return result
        else:
            return 0

if __name__ == "__main__":
    t1 = Base()
    print t1.foo
    t1.foo = "Something"
    print t1.foo

    print

    t2 = Derived()
    print t2.foo
    t2.foo = "bar"
    print t2.foo</pre>
<p>I was pretty impressed with myself for figuring this out.  So I&#8217;m putting it on my site to pat myself on the back.  Turns out, after my initial bitching, that python is actually pretty cool.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kylev.com/2004/10/13/fun-with-python-properties/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
