def _validate_type(self, schema):
     """
     Check if the type is available.
     """
     if 'type' not in schema:
         for key in ('arguments', 'elements', 'mapping'):
             if key in schema:
                 message = 'cannot parse {} without specified type'
                 message.format(key)
                 raise SchemaError(message)
     if 'type' in schema:
         if not self._find_type(schema.module, schema.type):
             message = 'type {} not found in module {}'
             message = message.format(schema.type, schema.module)
             raise SchemaError(message)
 def _validate_nested(self, schema):
     """
     Recursively check nested schemas.
     """
     if schema.arguments:
         if not isinstance(schema.arguments, dict):
             raise SchemaError('arguments must be a dict')
         for argument in schema.arguments.values():
             self._validate_schema(argument)
     if schema.mapping:
         if not isinstance(schema.mapping, dict):
             raise SchemaError('mapping must be a dict')
         for value in schema.mapping.values():
             self._validate_schema(value)
     if schema.elements:
         self._validate_schema(schema.elements)
 def _validate_exclusives(schema):
     """
     Mutually exclusive keys.
     """
     exclusives = ('arguments', 'elements', 'mapping')
     if sum(x in schema for x in exclusives) > 1:
         message = '{} are mutually exclusive'.format(', '.join(exclusives))
         raise SchemaError(message)
 def _validate_schema(self, schema):
     if schema is None:
         return
     if not isinstance(schema, dict):
         raise SchemaError('schema must be nested dicts')
     self._validate_type(schema)
     self._validate_exclusives(schema)
     self._validate_nested(schema)