예제 #1
0
 def wrapper(cls, data):
     try:
         result = coercer(cls, data)
     except AssertionError:
         raise
     except Exception:
         raise bad_type(data, cls)
     if not isinstance(result, cls):
         raise bad_type(data, cls)
     return result
예제 #2
0
 def method(data: Any) -> Any:
     if isinstance(data, cls):
         return data
     elif cls == float and isinstance(data, int):
         return float(data)
     else:
         raise bad_type(data, cls)
예제 #3
0
 def method(data: Any) -> Any:
     if not isinstance(data, cls):
         if cls == float and isinstance(data, int):
             data = float(data)
         else:
             raise bad_type(data, cls)
     if data is not None:
         errors = constraint_errors(data)
         if errors:
             raise ValidationError(errors)
     return data
예제 #4
0
def coerce(cls: Type[T], data: Any) -> T:
    try:
        if isinstance(data, cls):
            return data
        if data is None and cls is not NoneType:
            raise ValueError
        if cls is bool and isinstance(data, str):
            return STR_TO_BOOL[data.lower()]  # type: ignore
        if cls is NoneType and data in STR_NONE_VALUES:
            return None  # type: ignore
        if cls is list and isinstance(data, str):
            raise ValueError
        return cls(data)  # type: ignore
    except (ValueError, TypeError, KeyError):
        raise bad_type(data, cls)
예제 #5
0
 def method(data: Any) -> Any:
     if not isinstance(data, list):
         raise bad_type(data, list)
     elts: List[Any] = []
     elt_errors: Dict[ErrorKey, ValidationError] = {}
     for i, (deserialize_elt,
             elt) in enumerate(zip(elt_deserializers, data)):
         try:
             elts.append(deserialize_elt(elt))
         except ValidationError as err:
             elt_errors[i] = err
     errors = constraint_errors(data) if constraint_errors else ()
     if elt_errors or errors:
         raise ValidationError(errors, elt_errors)
     return tuple(elts)
예제 #6
0
 def method(data: Any) -> Any:
     if not isinstance(data, dict):
         raise bad_type(data, dict)
     items = {}
     item_errors: Dict[ErrorKey, ValidationError] = {}
     for key, value in data.items():
         assert isinstance(key, str)
         try:
             items[deserialize_key(key)] = deserialize_value(value)
         except ValidationError as err:
             item_errors[key] = err
     errors = constraint_errors(data) if constraint_errors else ()
     if item_errors or errors:
         raise ValidationError(errors, item_errors)
     return items if cls is DICT_TYPE else MAPPING_TYPES[cls](items)
예제 #7
0
 def method(data: Any) -> Any:
     if not isinstance(data, list):
         raise bad_type(data, list)
     elts = []
     elt_errors: Dict[ErrorKey, ValidationError] = {}
     for i, elt in enumerate(data):
         try:
             elts.append(deserialize_value(elt))
         except ValidationError as err:
             elt_errors[i] = err
     errors = constraint_errors(data) if constraint_errors else ()
     if elt_errors or errors:
         raise ValidationError(errors, elt_errors)
     return elts if cls is LIST_TYPE else COLLECTION_TYPES[cls](
         elts)
예제 #8
0
 def method(data: Any) -> Any:
     # Optional optimization
     if data is none_check:
         return None
     error: Optional[ValidationError] = None
     for deserialize_alt in alt_deserializers:
         try:
             return deserialize_alt(data)
         except ValidationError as err:
             error = merge_errors(error, err)
     if none_check is None:
         error = merge_errors(error, bad_type(data, NoneType))
     if error is None:  # empty union
         return data
     else:
         raise error
예제 #9
0
            def method(data: Any) -> Any:
                if not isinstance(data, dict):
                    raise bad_type(data, dict)
                values: Dict[str, Any] = {}
                aliases: List[str] = []
                errors = list(
                    constraint_errors(data)) if constraint_errors else []
                field_errors: Dict[ErrorKey, ValidationError] = OrderedDict()
                for (
                        name,
                        alias,
                        field_method,
                        required,
                        fall_back_on_default,
                ) in normal_fields:
                    if alias in data:
                        aliases.append(alias)
                        try:
                            values[name] = field_method(data[alias])
                        except ValidationError as err:
                            if not fall_back_on_default:
                                field_errors[alias] = err
                    elif not required:
                        pass
                    elif required is True:
                        field_errors[alias] = MISSING_PROPERTY
                    else:
                        assert isinstance(required, AbstractSet)
                        requiring = required & data.keys()
                        if requiring:
                            msg = f"missing property (required by {sorted(requiring)})"
                            field_errors[alias] = ValidationError([msg])
                if has_aggregate_field:
                    for (
                            name,
                            flattened_alias,
                            field_method,
                            fall_back_on_default,
                    ) in flattened_fields:

                        flattened = {
                            alias: data[alias]
                            for alias in flattened_alias if alias in data
                        }
                        aliases.extend(flattened)
                        try:
                            values[name] = field_method(flattened)
                        except ValidationError as err:
                            if not fall_back_on_default:
                                errors.extend(err.messages)
                                field_errors.update(err.children)
                    if len(data) != len(aliases):
                        remain = data.keys() - set(aliases)
                    else:
                        remain = set()
                    for (
                            name,
                            pattern,
                            field_method,
                            fall_back_on_default,
                    ) in pattern_fields:
                        matched = {
                            key: data[key]
                            for key in remain if pattern.match(key)
                        }
                        remain -= matched.keys()
                        try:
                            values[name] = field_method(matched)
                        except ValidationError as err:
                            if not fall_back_on_default:
                                errors.extend(err.messages)
                                field_errors.update(err.children)
                    if additional_field is not None:
                        name, field_method, fall_back_on_default = additional_field
                        additional = {key: data[key] for key in remain}
                        try:
                            values[name] = field_method(additional)
                        except ValidationError as err:
                            if not fall_back_on_default:
                                errors.extend(err.messages)
                                field_errors.update(err.children)
                    elif remain and not additional_properties:
                        for key in remain:
                            field_errors[key] = UNEXPECTED_PROPERTY
                elif len(data) != len(aliases) and not additional_properties:
                    for key in data.keys() - set(aliases):
                        field_errors[key] = UNEXPECTED_PROPERTY

                validators2: Sequence[Validator]
                if validators:
                    init: Dict[str, Any] = {}
                    for name, default_factory in init_defaults:
                        if name in values:
                            init[name] = values[name]
                        elif name not in field_errors:
                            assert default_factory is not None
                            init[name] = default_factory()
                    # Don't keep validators when all dependencies are default
                    validators2 = [
                        v for v in validators
                        if v.dependencies & values.keys()
                    ]
                    if field_errors or errors:
                        error = ValidationError(errors, field_errors)
                        invalid_fields = field_errors.keys(
                        ) | post_init_modified
                        validators2 = [
                            v for v in validators2
                            if not v.dependencies & invalid_fields
                        ]
                        try:
                            validate(
                                ValidatorMock(cls, values),
                                validators2,
                                init,
                                aliaser=aliaser,
                            )
                        except ValidationError as err:
                            error = merge_errors(error, err)
                        raise error
                elif field_errors or errors:
                    raise ValidationError(errors, field_errors)
                else:
                    validators2, init = (
                    ), ...  # type: ignore # only for linter
                try:
                    res = cls(**values)
                except (AssertionError, ValidationError):
                    raise
                except TypeError as err:
                    if str(err).startswith("__init__() got"):
                        raise Unsupported(cls)
                    else:
                        raise ValidationError([str(err)])
                except Exception as err:
                    raise ValidationError([str(err)])
                if validators2:
                    validate(res, validators2, init, aliaser=aliaser)
                return res