Skip to content

Instantly share code, notes, and snippets.

@kirpit
Last active December 16, 2015 16:08
Show Gist options
  • 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, **kwargs):
# clear empty fields
mapping = dict([(k, v) for k, v in dict(seq, **kwargs).iteritems()])
# 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[0] not in mapping)
except StopIteration:
pass
else:
raise ValueError(req[1])
super(FieldsDict, self).__init__(mapping)
# use as:
class Person(FieldsDict):
FIELDS = (
'title',
'first_name',
'last_name',
'email',
'phone',
'birthday',
)
REQUIRED = (
('title', "Title is required"),
('first_name', "First name is required"),
('last_name', "Last name is required"),
)
# should give ValueError("Title is required")
me = Person(first_name='Roy')
# should give ValueError("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': '[email protected]'})
# 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