Created
July 30, 2015 22:31
-
-
Save effigies/9c64e743f8c60a22bc70 to your computer and use it in GitHub Desktop.
Typed Dictionary
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!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