Search code examples
cerberus

Python Cerberus dependencies on nested list level


Does Cerberus 1.2 support dependency validation on a list?

For instance the schema looks as follows:

schema = {
   'list_1': {
     'type': 'list',
     'schema': {
       'type': 'dict',
       'schema': {
         'simple_field': {'type': 'boolean'},
         'not_simple_field': {
           'type': 'dict',
           'schema': {
              'my_field': {'dependencies': {'simple_field': True}}
           }
         }
       }
     }
   }
 }

The rule that I'd like to check is that my_field should only exist when simple_field is True. How would I translate that in Cerberus?


Solution

  • As of now Cerberus 1.2 does not support this feature. I've overridden the Validator class method _lookup_field in order to implement this functionality.

    Here's the link to a feature request on GitHub

    Here's my implementation:

    def _lookup_field(self, path: str) -> Tuple:
        """
        Implement relative paths with dot (.) notation as used 
        in Python relative imports
        - A single leading dot indicates a relative import
        starting with the current package.
        - Two or more leading dots give a relative import to the parent(s)
        of the current package, one level per dot after the first
        Return: Tuple(dependency_name: str, dependency_value: Any)
        """
        # Python relative imports use a single leading dot
        # for the current level, however no dot in Cerberus
        # does the same thing, thus we need to check 2 or more dots
        if path.startswith('..'):
            parts = path.split('.')
            dot_count = self.path.count('.')
            context = self.root_document
    
            for key in self.document_path[:dot_count]:
                context = context[key]
    
            context = context.get(parts[-1])
    
            return parts[-1], context
    
        else:
            return super()._lookup_field(path)