Monthly Archives: December 2009

Merry Christmas

Thank you to the varied shop staff in London this past week for being without exception polite, enthusiastic and helpful when I asked for help. Especially the girl in [HMV Bond Street][hmv] who spelt [Zappa][zappa] as “zapper” – she was cute. It made tedious shopping joyful.

Let’s do it again next year! Love Dave

[zappa]: http://www.zappa.com/
[hmv]: http://hmv.com

Context managers

I was re-writing the exellent [watchedinstall][watchedinstall] tool and needed to simplify a particularly gnarly chunk of code that required three sub-proceses to be started and then killed after invoking another process. It occurred to me I could make these into context managers.

Previously the code was something like…

start(program1)
try:
start(program2)
except:
stop(program1)
raise

try:
start(program3)
except:
stop(program2)
stop(program1)
raise

try:
mainprogram()
finally:
stop(program3)
stop(program2)
stop(program1)

Of course that could have been written with nested try / except / else / finally blocks as well, which I did start with but found not much shorter while almost incomprehensible.

[With context managers][ctxt] the whole thing was written as…

# from __future__ import with_statement, Python 2.5

with start(program1):
with start(program2):
with start(program3):
mainprogram()

So much more comprehensible! Here’s the implementation of the context manager (using the `contextlib.contextmanager` decorator for a triple word score):

import contextlib
import os
import signal
import subprocess

@contextlib.contextmanager
def start(program_args):
prog = subprocess.Popen(program_args)
if prog.poll(): # Anything other than None or 0 is BAD
raise subprocess.CalledProcessError(prog.returncode, program_args[0])

try:
yield
finally:
if prog.poll() is None:
os.kill(prog.pid, signal.SIGTERM)

For bonus points I might have used [`contexlib.nested()`][ctxtlib] to put the three `start()` calls on one line but then what would I do for the rest of the day?

[watchedinstall]: http://bitbucket.org/ptone/watchedinstall/
[ctxt]: http://docs.python.org/library/stdtypes.html#typecontextmanager
[ctxtlib]: http://docs.python.org/library/contextlib.html

Snow Leopard: a reactionary writes

Things I like about [Mac OS X version 10.6][sl]:

(Mac OS X 10.6 is also known as Snow Leopard, although I dislike Apple’s use of the operating system codename in their publicity material because it leads to conversations where people talk about “Leopard” and “Tiger” and one has to stop for a second to translate those to actual operating system versions and no-one is ever going to refer to [Mac OS X 10.3 as Panther][panther] these days, let alone [10.2 being Jagwire][jaguar] or heaven forbid [Puma][puma] and [Cheetah][cheetah]. What are the chances I’ll have to look up the codename for 10.5 by the time we reach 10.10? Version numbers are not so evocative but are less confusing than codenames. This doesn’t mean I will stop naming hard disks after Mac OS codenames – my desktop has [Veronica, Gershwin, Harmony and Sonata][codenames] connected at the moment, with [Copland][copland] and [Pink][pink] sitting on the shelf as appropriate…)

Things I like about Mac OS X Snow Leopard:

– Apple’s drivers for my Epson all-in-one printer / scanner actually work. Epson’s drivers for the same printer / scanner only worked if you never used the scanner and promised to attend church more often.
– Significantly snappier.
– QuickTime Player’s minimal interface.

Things I dislike about Mac OS X Snow Leopard:

– By default the Finder does not show internal disks on the Desktop.
– The Finder [ignores type / creator codes][typecreator] on files.

Everything else in 10.6 is good. However it strikes me that the de-emphasizing of old-style Mac metadata (type / creator codes) and the default of not showing your computer’s hard drive icon on the desktop are evidence of the triumph of old-school Next-ies within Apple.

I think the decision to cover-up the hierarchical filesystem is a bad thing.

P.S. Wouldn’t it have been awesome if, having released Mac OS X Cheetah, Apple had continued with naming their releases after other famous Hollywood animal actors? Why they stopped naming releases after [disappointing Sylvester Stallone movies][sly] is beyond me – most any version of System 7 could have been named [Lock Up][lockup].

[sl]: http://www.apple.com/macosx/
[leopard]: http://www.apple.com/support/leopard/
[panther]: http://www.apple.com/support/panther/
[jaguar]: http://www.apple.com/support/jaguar/
[puma]: http://en.wikipedia.org/wiki/Mac_OS_X_v10.1
[cheetah]: http://en.wikipedia.org/wiki/Mac_OS_X_v10.0
[codenames]: http://www.mackido.com/CodeNames/MacOSSoftware.html
[copland]: http://lowendmac.com/orchard/05/1108.html
[pink]: http://lowendmac.com/orchard/05/1026.html
[lockup]: http://www.imdb.com/title/tt0097770/
[sly]: http://www.imdb.com/title/tt0118887/
[typecreator]: http://arstechnica.com/staff/fatbits/2009/09/metadata-madness.ars

Serving custom Django admin media in development

I’ve just discovered [Django][django]’s development server always serves admin media. This is tremendously useful because it means you don’t need to configure a static serve view in your project `urls.py` during development.

However what bit me was I wanted to use a customised set of admin media and had configured a view for the `ADMIN_MEDIA_URL` path and was going batty trying to work out why Django was ignoring it. It used to be that as long as you had `DEBUG = False` in `settings.py` then the development server did not try to help serve the admin media automatically.

[Changeset 6075][6075] added a switch to the runserver command for over-riding the admin media directory.

python manage.py runserver –adminmedia /path/to/custom/media

That change was made more than two years ago. It is [right there in the documentation][docs]. A little bit of magic that wasted fifteen minutes of my frantic schedule (except for the fact I do not have a frantic schedule).

[django]: http://www.djangoproject.com/
[6075]: http://code.djangoproject.com/changeset/6075
[docs]: http://docs.djangoproject.com/en/dev/ref/django-admin/#djadminopt—adminmedia