2008-07-30

Orson Scott Card is a dick


The first and greatest threat from court decisions in California and Massachusetts, giving legal recognition to "gay marriage," is that it marks the end of democracy in America.

So says Orson Scott Card. Shame; I enjoyed the "Ender" books.

2008-07-29

Another victory for superstition

Sikh girl wins bangle law battle

I'm sure there's some legal argument that makes banning all
jewelry, religious or not, "discrimination", but I doubt it's a sensible one.
I wonder if they could add a watch face to it instead.

Hah

This one for the doubters (you know who you are): Likelihood of me being MALE is 100%

2008-07-12

Writing Python Properly

What are people's approaches to writing Python correctly? The library documentation basically doesn't document the set of exceptions the routines can throw, which makes it very difficult to catch the right things, and do the right thing[1] (for example). What do people do to deal with this problem?

[1] on that note, if you're writing a command line tool in Python, please catch KeyboardInterrupt and exit quietly. Drives me crazy!

2008-07-10

Bubble calendar

These are cool:





2008-07-08

Nice bookends

Nice bookends:


2008-07-07

Mercurial corruption (again)

It's somewhat disappoint that Mercurial is still corrupting repositories when you interrupt MQ operations.

Relatively easily recoverable for me this time, thankfully. I'd still like to see hg backup from the OpenSolaris SCM project get merged upstream though :)

2008-07-02

Pure Python Plugins

After some searching and asking around I didn't find any good explanation of the simplest way to implement plugins in Python. So, for posterity's sake, here's my solution. I'm sure there's a better way: I'd love to hear your suggestions.

First, the requirements. The code cannot have knowledge of how the plugins are named (.so files, .py, package dirs, etc.). I don't want to hard-code the list of plugins, as this defeats its dynamic nature altogether. I have to be able to iterate across all plugins. Any user should be able to use the module without knowing that it's got plugins. Finally, it's got to be as simple as possible.

First up, we have whatever/__init__.py:


import pkgutil
import imp
import os

plugin_path = [os.path.join(__path__[0], "plugins/")]

for loader, name, ispkg in pkgutil.iter_modules(plugin_path):
file, pathname, desc = imp.find_module(name, plugin_path)
imp.load_module(name, file, pathname, desc)


This basically uses Python's module search to find all contents of the plugins sub-directory and load them. Now we have some more scaffolding in the same directory, as whatever/whatever.py:


plugins = []

class plugin(object):
"""Abstract plugin base class."""
...

def register_plugin(plugin)
global plugins
plugins += [ plugin ]

# utility functions to iterate across and use plugins...


Finally, each plugin looks something like this, in plugins/foo.py:


from whatever/whatever import *

class fooplugin(plugin):
"""Concrete class for foo plugin."""
...

register_plugin(fooplugin)


Simple enough, but it took a while to work it out. Unfortunately, it doesn't seem possible to merge whatever.py into __init__.py as we have a recursive import problem.