Skip to content

Instantly share code, notes, and snippets.

@kirpit
Last active December 16, 2015 16:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kirpit/5460564 to your computer and use it in GitHub Desktop.
Save kirpit/5460564 to your computer and use it in GitHub Desktop.
python dictionary with key requirements
#! /usr/bin/env python
from abc import ABCMeta
class FieldsDict(dict):
__metaclass__ = ABCMeta
FIELDS = None
REQUIRED = None
def __init__(self, seq=None, **kwargs):
# create a single dict
seq = seq or {}
mapping = dict(seq, **kwargs)
# make sure all fields are expected
try:
unexpected = next(key for key in mapping if key not in self.FIELDS)
except StopIteration:
pass
else:
raise ValueError("The field '%s' was not expected" % unexpected)
# and check the required fields
if self.REQUIRED:
try:
req = next(r for r in self.REQUIRED if r not in mapping)
except StopIteration:
pass
else:
raise ValueError("The field '%s' is required" % req)
super(FieldsDict, self).__init__(mapping)
# use as:
class Person(FieldsDict):
FIELDS = (
'title',
'first_name',
'last_name',
'email',
'phone',
'birthday',
)
REQUIRED = (
'title',
'first_name',
'last_name',
)
# should give ValueError("The field 'title' is required")
me = Person(first_name='Roy')
# should give ValueError("The field 'last_name' is required")
me = Person({'title': 'MR', 'first_name': 'Roy'})
# should give ValueError("The field 'level' was not expected")
me = Person({'level': 'PRO', 'first_name': 'Roy'})
# should be fine
me = Person({'title': 'MR', 'first_name': 'Roy', 'last_name': 'Enjoy', 'email': 'roy@example.com'})
# or that is fine too
me = Person(title='MR', first_name='Roy', last_name='Enjoy', phone=123456)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment