A small performance improvement on startup may be possible by replacing len(key('',0,0)) with struct.calcsize(self.fmt):

python -m timeit -s \
  'import struct; checksum_length = 32; fmt = "!%dsQQ" % checksum_length'\
  'struct.calcsize(fmt)'
1000000 loops, best of 3: 0.201 usec per loop

vs

python -m timeit -s \
  'import struct; checksum_length = 32; fmt = "!%dsQQ" % checksum_length'\
  'len(struct.pack(fmt,"",0,0))'
1000000 loops, best of 3: 0.753 usec per loop

I can't attach files, so I can't attach the bundle I think you prefer, but here's the diff, and I'll email you the bundle as an attachment.

=== modified file 'obnamlib/checksumtree.py'
--- obnamlib/checksumtree.py        2011-07-26 13:23:55 +0000
+++ obnamlib/checksumtree.py        2013-02-08 07:09:22 +0000
@@ -33,7 +33,7 @@
                  upload_queue_size, lru_size, hooks):
         tracing.trace('new ChecksumTree name=%s' % name)
         self.fmt = '!%dsQQ' % checksum_length
-        key_bytes = len(self.key('', 0, 0))
+        key_bytes = struct.calcsize(self.fmt)
         obnamlib.RepositoryTree.__init__(self, fs, name, key_bytes, node_size, 
                                          upload_queue_size, lru_size, hooks)
         self.keep_just_one_tree = True

=== modified file 'obnamlib/chunklist.py'
--- obnamlib/chunklist.py   2011-07-26 13:23:55 +0000
+++ obnamlib/chunklist.py   2013-02-08 07:09:22 +0000
@@ -35,14 +35,15 @@

     def __init__(self, fs, node_size, upload_queue_size, lru_size, hooks):
         tracing.trace('new ChunkList')
-        self.key_bytes = len(self.key(0))
+        self.fmt = '!Q'
+        self.key_bytes = struct.calcsize(self.fmt)
         obnamlib.RepositoryTree.__init__(self, fs, 'chunklist', self.key_bytes, 
                                          node_size, upload_queue_size, 
                                          lru_size, hooks)
         self.keep_just_one_tree = True

     def key(self, chunk_id):
-        return struct.pack('!Q', chunk_id)
+        return struct.pack(self.fmt, chunk_id)

     def add(self, chunk_id, checksum):
         tracing.trace('chunk_id=%s', chunk_id)

=== modified file 'obnamlib/clientlist.py'
--- obnamlib/clientlist.py  2011-07-26 13:23:55 +0000
+++ obnamlib/clientlist.py  2013-02-08 07:09:22 +0000
@@ -49,7 +49,7 @@
         tracing.trace('new ClientList')
         self.hash_len = len(self.hashfunc(''))
         self.fmt = '!%dsQB' % self.hash_len
-        self.key_bytes = len(self.key('', 0, 0))
+        self.key_bytes = struct.calcsize(self.fmt)
         self.minkey = self.hashkey('\x00' * self.hash_len, 0, 0)
         self.maxkey = self.hashkey('\xff' * self.hash_len, obnamlib.MAX_ID, 
                                    self.SUBKEY_MAX)

Thank you. This has been merged now. done --liw