Skip to content

Instantly share code, notes, and snippets.

@effigies
Created July 30, 2015 22:31
Show Gist options
  • Save effigies/9c64e743f8c60a22bc70 to your computer and use it in GitHub Desktop.
Save effigies/9c64e743f8c60a22bc70 to your computer and use it in GitHub Desktop.
Typed Dictionary
#!python3
class TypedDict(dict):
keytype = valtype = keymap = valmap = valid_keys = typemap = None
def __init__(self, mapping=None, **kwargs):
if self.typemap is not None and self.valid_keys is None:
self.valid_keys = set(self.typemap)
super(TypedDict, self).__init__()
if mapping is None:
mapping = kwargs.items()
elif isinstance(mapping, dict):
mapping = mapping.items()
for k, v in mapping:
self[k] = v
def __setitem__(self, key, val):
if self.keytype is not None and type(key) is not self.keytype:
if self.keymap is not None and type(key) in self.keymap:
key = self.keymap[type(key)](key)
else:
try:
key = self.keytype(key)
except TypeError:
raise TypeError('Keys must be of type {!r}'.format(
self.keytype))
if self.valtype is not None and type(val) is not self.valtype:
if self.valmap is not None and type(val) in self.valmap:
val = self.valmap[type(val)](val)
else:
try:
val = self.valtype(val)
except TypeError:
raise TypeError('Values must be of type {!r}'.format(
self.valtype))
if self.typemap is not None and key in self.typemap:
val = self.typemap[key](val)
if self.valid_keys is not None and key not in self.valid_keys:
raise KeyError('Invalid key')
super(TypedDict, self).__setitem__(key, val)
class BytesIntMap(TypedDict):
keytype = bytes
valtype = int
keymap = {str: str.encode}
class ExampleModel(TypedDict):
class File(TypedDict):
class Permission(TypedDict):
valid_keys = {'r', 'w', 'x'}
valtype = bool
keytype = str
typemap = {'mtime': int, 'perm': Permission}
class User(TypedDict):
keytype = str
valid_keys = {'groups'}
valtype = list
typemap = {'files': File, 'users': User}
model = ExampleModel(
files={'/home': {'mtime': 0, 'perm': {'r': True, 'w': False}},
'/tmp': {'mtime': 0, 'perm': {'r': True, 'w': True}}},
users={'root': {'groups': ['root', 'wheel']}})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment