From 430fdd30d015eeca6dbe87fbcd7cfd52df79b436 Mon Sep 17 00:00:00 2001 From: helmutm Date: Wed, 22 Nov 2006 11:46:10 +0000 Subject: [PATCH] MultiKeyDict re-implemented git-svn-id: svn://svn.cy55.de/Zope3/src/cybertools/trunk@1514 fd906abe-77d9-0310-91a1-e0d9ade77398 --- index/README.txt | 14 +++++++------- index/multikey.py | 13 +++++++++---- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/index/README.txt b/index/README.txt index 89370a2..146ab73 100644 --- a/index/README.txt +++ b/index/README.txt @@ -12,18 +12,15 @@ A MultiKeyDict is a dictionary that expects its keys to be tuples. >>> from cybertools.index.multikey import MultiKeyDict >>> registry = MultiKeyDict() - >>> registry[('index.html',)] = 'global index.html' + >>> registry[('index.html', None, None, None)] = 'global index.html' - >>> registry[('index.html',)] + >>> registry[('index.html', None, None, None)] 'global index.html' So this would be nothing special - any dictionary is able to provide this functionality; but a MultiKeyDict has some fallback mechanisms for retrieving objects only partly fitting the requested key: - >>> registry.get(('index.html', 'topic', 'zope3', 'Custom')) - 'global index.html' - >>> registry[('index.html', 'topic', 'zope3', 'Custom')] 'global index.html' @@ -45,14 +42,13 @@ The more on the left a matching key part is the higher is its priority: >>> registry[('index.html', 'task', 'bugfixes', 'Custom')] 'Global index.html for Custom skin' +Index entries that are present in the stored dictionaries must always match: >>> registry[('edit.html', 'topic', 'zope3', 'Custom')] = 'very special edit.html' >>> registry[('index.html', 'task', 'bugfixes', 'Custom')] 'Global index.html for Custom skin' -Index entries that are present in the stored dictionaries must always match: - >>> registry[('index.html', 'topic', 'zope3', 'Custom')] 'index.html for type "topic"' @@ -63,3 +59,7 @@ Index entries that are present in the stored dictionaries must always match: >>> registry.get(('edit.html', 'task', 'bugfixes', '')) is None True + + >>> registry[('edit.html', 'task', 'bugfixes', 'Custom')] + 'edit.html for Custom skin' + diff --git a/index/multikey.py b/index/multikey.py index cf732e5..6ce1e47 100644 --- a/index/multikey.py +++ b/index/multikey.py @@ -26,12 +26,16 @@ _not_found = object() class MultiKeyDict(dict): - def __init__(self, **kw): + def __init__(self, keylen=None, **kw): super(MultiKeyDict, self).__init__(**kw) self.submapping = {} + self.keylen = keylen def __setitem__(self, key, value): assert type(key) is tuple + if self.keylen is None: + self.keylen = len(key) + assert len(key) == self.keylen k0 = key[0] if len(key) > 1: sub = self.submapping.setdefault(k0, MultiKeyDict()) @@ -46,6 +50,7 @@ class MultiKeyDict(dict): def get(self, key, default=None): assert type(key) is tuple + assert len(key) == self.keylen k0 = key[0] rsub = _not_found r0 = super(MultiKeyDict, self).get(k0, _not_found) @@ -57,12 +62,12 @@ class MultiKeyDict(dict): sub = self.submapping.get(k0, _not_found) if sub is _not_found: sub = self.getSubmappingFallback(key) - if sub is not _not_found: + if sub is _not_found: + rsub = _not_found + else: rsub = sub.get(key[1:], _not_found) if rsub is _not_found: return default - else: - rsub = _not_found result = rsub is _not_found and r0 or rsub return result is _not_found and default or result