def load(self, context: ILoadingContext, field: IBaseField) -> Any: """See Resolver.resolve for usage.""" if not context.expect_scalar( _("import / try-import must be set on a scalar node") ): return UNDEFINED file_path = self._get_file(context) if file_path is None: node = context.current_node() if node.tag == "!import": context.error( ErrorCode.IMPORT_NOT_FOUND, _("Unable to find {} in any of the configured directories"), node.value, ) return UNDEFINED file_yaml_node = self._load_file(context, file_path) if file_yaml_node is None: return UNDEFINED return context.load(field, file_yaml_node, str(file_path))
def _load(obj: Any, context: ILoadingContext, config: ObjectField.Config) -> Any: fields = config.get_fields(obj) node = context.current_node() set_fields = set() for name_node, value_node in node.value: field_name = context.load(StringField(), name_node) if field_name is UNDEFINED: continue field_name = name_node.value set_fields.add(field_name) if field_name not in fields: context.error(ErrorCode.FIELD_NOT_DECLARED, _("Field {} is not declared."), field_name) continue field = fields[field_name] field_value = context.load(field, value_node) if field_value is UNDEFINED: continue setattr(obj, field_name, field_value) if _validate(obj, fields, set_fields, context, config): post_load = config.get_hook(obj, "post_load") if post_load is not None: post_load() return obj return UNDEFINED
def _convert(self, context: ILoadingContext, value: str) -> Any: try: result = float(value) except ValueError: context.error(ErrorCode.VALUE_ERROR, _('Can\'t convert "{}" to a float'), value) return UNDEFINED return ScalarField._check_in_bounds(context, result, self._minimum, self._maximum)
def _convert(self, context: ILoadingContext, value: str) -> Any: if self._pattern is not None and not self._pattern.match(value): context.error( ErrorCode.VALIDATION_ERROR, _("Value {} doesn't match required pattern {}"), value, self._pattern_str, ) return UNDEFINED return value
def _convert(self, context: ILoadingContext, value: str) -> Any: for member in self._enum_class: if member.name == value: return member context.error( ErrorCode.VALIDATION_ERROR, _("Unkown value {} for enum {}."), value, self._enum_class, ) return UNDEFINED
def _load_file(context: ILoadingContext, path: Path) -> Optional[Node]: """Load a YAML document, emit a MarshPyError on ParseError.""" with open(path, "r", encoding="utf-8") as yaml_file: try: return cast(Node, compose(yaml_file)) # type: ignore except ParserError as error: context.error( ErrorCode.VALUE_ERROR, _("Parse error while loading {} : {}"), path, error, ) return None
def _convert(self, context: ILoadingContext, value: str) -> Any: if value in _TRUE_VALUES: return True if value in _FALSE_VALUES: return False context.error( ErrorCode.VALUE_ERROR, _("Boolean value should be one of {}"), ", ".join(_TRUE_VALUES + _FALSE_VALUES), ) return UNDEFINED
def _convert(self, context: ILoadingContext, value: str) -> Any: result: Optional[int] = None try: result = int(value, self._base) except ValueError: context.error(ErrorCode.VALUE_ERROR, _('Can\'t convert "{}" to an integer'), value) return UNDEFINED return cast( Optional[int], ScalarField._check_in_bounds(context, result, self._minimum, self._maximum), )
def _convert(self, context: ILoadingContext, value: str) -> Any: path = Path(value) if not path.is_absolute() and not path.exists(): location_str = context.current_location() if location_str is not None: location = Path(location_str) parent = location.parent path = parent / path if self._must_exist and not path.exists(): context.error(ErrorCode.VALIDATION_ERROR, _("Cannot find path {}."), path) return UNDEFINED return path
def _validate( obj: Any, fields: Dict[str, IBaseField], set_fields: Set[str], context: ILoadingContext, config: ObjectField.Config, ) -> bool: valid_object = True for name, field in fields.items(): if field.required and name not in set_fields: valid_object = False context.error(ErrorCode.MISSING_REQUIRED_FIELD, _("Missing required field {}"), name) hook = config.get_hook(obj, "validate") if hook is not None: validation_context = ValidationContext(context) hook(validation_context) valid_object = valid_object and not validation_context.has_error() return valid_object
def _load(self, context: ILoadingContext) -> Any: if not context.expect_mapping(): return UNDEFINED config = context.get_config(ObjectField.Config) node = context.current_node() tag = str(node.tag) if tag.startswith("!type"): splitted_tag = tag.split(":") if len(splitted_tag) != 2: context.error(ErrorCode.BAD_TYPE_TAG_FORMAT, _TYPE_FORMAT_MSG, tag) return None type_name = splitted_tag[1] obj = config.create(type_name, context) else: obj = self._object_class() if obj is None: return UNDEFINED return _load(obj, context, config)
def _check_in_bounds( context: ILoadingContext, value: Union[int, float], minimum: Optional[Union[int, float]], maximum: Optional[Union[int, float]], ) -> Any: if minimum is not None and value < minimum: context.error( ErrorCode.VALIDATION_ERROR, _("Value is too small (minimum : {})"), minimum, ) return UNDEFINED if maximum is not None and value > maximum: context.error( ErrorCode.VALIDATION_ERROR, _("Value is too big (maximum : {})"), maximum, ) return UNDEFINED return value
def load(self, context: ILoadingContext, field: IBaseField) -> Any: if not context.expect_sequence(): return UNDEFINED node = context.current_node() result: Optional[Union[Dict[str, Any], List[Any]]] = None for child in node.value: child_result = context.load(field, child) if child_result is UNDEFINED: continue if isinstance(child_result, dict): if result is None: result = {} assert isinstance(result, dict) result.update(child_result) elif isinstance(child_result, list): if result is None: result = [] assert isinstance(result, list) result += child_result else: msg = _("Trying to merge invalid object {}, expected dict or " "list") context.error(ErrorCode.VALUE_ERROR, msg, result) # If nothing it's to merge, return UNDEFINED if result is None: return UNDEFINED return result
def _default_object_factory( type_name: str, context: ILoadingContext) -> Optional[Type[Any]]: splitted_name = type_name.split(".") if len(splitted_name) < 2: context.error(ErrorCode.BAD_TYPE_TAG_FORMAT, _TYPE_FORMAT_MSG, type_name) return None module_name = ".".join(splitted_name[:-1]) class_name = splitted_name[-1] try: module = __import__(module_name, fromlist=class_name) except ModuleNotFoundError: context.error( ErrorCode.TYPE_RESOLVE_ERROR, _("Can't find python module for type {}"), type_name, ) return None if not hasattr(module, class_name): context.error( ErrorCode.TYPE_RESOLVE_ERROR, _("Can't find python type {}"), type_name, ) return None resolved_type = getattr(module, class_name) if not isclass(resolved_type): context.error( ErrorCode.TYPE_RESOLVE_ERROR, _("Python type {} is not a class"), type_name, ) return None return resolved_type()
def _load(self, context: ILoadingContext) -> None: context.error(ErrorCode.VALUE_ERROR, "Test message")