Skip to content

Commit

Permalink
Fix mutually required fields
Browse files Browse the repository at this point in the history
Save a set of required fields, and ensure at least one of them is
present in the end
  • Loading branch information
calve committed Aug 25, 2015
1 parent 5746872 commit 7504fc8
Showing 1 changed file with 21 additions and 0 deletions.
21 changes: 21 additions & 0 deletions cerberus/cerberus.py
Expand Up @@ -416,6 +416,7 @@ class instantiation.
self.update = update
self.__init_processing(document, schema)
self.__prepare_document(document, normalize)
self._required_excluded = set()

for field in self.document:
if self.ignore_none_values and self.document[field] is None:
Expand Down Expand Up @@ -707,13 +708,23 @@ def _validate_required_fields(self, document):
"""
required = set(field for field, definition in self.schema.items()
if definition.get('required') is True)
required -= self._required_excluded
missing = required - set(field for field in document
if document.get(field) is not None or
not self.ignore_none_values)

for field in missing:
self._error(field, errors.ERROR_REQUIRED_FIELD)

# At least on field from self._required_excluded should be
# present in document
if len(self._required_excluded) > 0:
fields = set(field for field in document
if document.get(field) is not None)
if self._required_excluded.isdisjoint(fields):
for field in self._required_excluded - fields:
self._error(field, errors.ERROR_REQUIRED_FIELD)

def _validate_schema(self, definition, field, value):
schema = definition.get('schema')
if schema is None:
Expand Down Expand Up @@ -822,6 +833,16 @@ def _validate_excludes(self, excludes, field, value):
if isinstance(excludes, Hashable):
excludes = [excludes]

# Save required field to be checked latter
if 'required' in self.schema[field] and self.schema[field]['required']:
self._required_excluded.add(field)
for exclude in excludes:
if (exclude in self.schema
and 'required' in self.schema[exclude]
and self.schema[exclude]['required']):

self._required_excluded.add(exclude)

if [True for key in excludes if key in self.document]:
# Wrap each field in `excludes` list between quotes
exclusion_str = ', '.join("'{0}'"
Expand Down

0 comments on commit 7504fc8

Please sign in to comment.