def p_top(self, p): """top : section_content""" section = ConfigSection('__top__') for child in p[1]: if isinstance(child, ConfigSection): child.parent = section section.register(child) p[0] = section
def p_section(self, p): """section : NAME LBRACE section_content RBRACE | NAME section_args LBRACE section_content RBRACE""" name = p[1] if len(p) == 5: args = None section_content = p[3] else: args = p[2] section_content = p[4] column = p.lexer.column(p.lexpos(1)) position = Position(self._input_name, p.lineno(1), column) section = ConfigSection(name, args=args, position=position) for child in section_content: if isinstance(child, ConfigSection): child.parent = section section.register(child) p[0] = section
def validate(self, section): if not isinstance(section, ConfigSection): raise ValidationError('Not a section') # Rebuild the section using schema: validated_section = ConfigSection(section.name, section.parent, position=section.position) # Validate the section's argument: if self.meta['args'] is None and section.args is not None: raise ValidationError('section %s, this section does not take ' 'any argument' % section.name, position=section.position) elif self.meta['args'] is not None: try: validated_args = self.meta['args'].validate(section.args_raw) except ValidationError as err: msg = 'section %s, arguments, %s' % (section.name, err) raise ValidationError(msg, position=err.position) else: validated_section.args = validated_args # Validate the section's children: for name, container in self.keys.items(): if isinstance(container, Section): # Validate subsections of this section: subsections = list(section.subsections(name)) # Check for repeat option: rmin, rmax = container.meta['repeat'] if rmax is not None and rmin > rmax: raise ValidationError('section %s, rmin > rmax' % name) if len(subsections) < rmin: raise ValidationError('section %s, section must be defined' ' at least %d times' % (name, rmin)) if rmax is not None and len(subsections) > rmax: raise ValidationError('section %s, section must be defined' ' at max %d times' % (name, rmax)) # Do the children validation: args = set() # Store the already seen args for subsection in subsections: # Check for unique option: if container.meta['unique']: args_value = None if subsection.args is None else tuple(subsection.args) if args_value in args: msg = 'section %s, section must be unique' % name raise ValidationError(msg, position=subsection.position) else: args.add(args_value) # Container validation: validated_subsection = container.validate(subsection) validated_section.register(validated_subsection, name=name) elif isinstance(container, Container): # Validate all other types of containers: try: validated_value = container.validate(section.get(name, raw=False)) except ValidationError as err: raise ValidationError('section %s, key %s, %s' % (section.name, name, err), position=err.position) else: validated_section.register(validated_value, name=name) # Handle the allow_unknown meta option: for name, child in section.iteritems(): if name not in validated_section: if self.meta['allow_unknown']: validated_section.register(child, name=name) else: msg = 'section %s, unknown key %s' % (section.name, name) raise ValidationError(msg, position=child.position) return validated_section