Exemplo n.º 1
0
def test_get_default_value_for_field_without_default_value():
    @dataclass
    class X:
        i: int

    with pytest.raises(DefaultValueNotFoundError):
        get_default_value_for_field(field=fields(X)[0])
Exemplo n.º 2
0
def from_dict(data_class: Type[T],
              data: Data,
              config: Optional[Config] = None) -> T:
    """Create a data class instance from a dictionary.

    :param data_class: a data class type
    :param data: a dictionary of a input data
    :param config: a configuration of the creation process
    :return: an instance of a data class
    """
    init_values: Data = {}
    post_init_values: Data = {}
    config = config or Config()
    try:
        data_class_hints = get_type_hints(data_class,
                                          globalns=config.forward_references)
    except NameError as error:
        raise ForwardReferenceError(str(error))
    data_class_fields = get_fields(data_class)
    if config.strict:
        extra_fields = set(data.keys()) - {f.name for f in data_class_fields}
        if extra_fields:
            raise UnexpectedDataError(keys=extra_fields)
    for field in data_class_fields:
        field = copy.copy(field)
        field.type = data_class_hints[field.name]
        try:
            try:
                field_data = data[field.name]
                transformed_value = transform_value(
                    type_hooks=config.type_hooks,
                    cast=config.cast,
                    target_type=field.type,
                    value=field_data)
                value = _build_value(type_=field.type,
                                     data=transformed_value,
                                     config=config)
            except DaciteFieldError as error:
                error.update_path(field.name)
                raise
            if config.check_types and not is_instance(value, field.type):
                raise WrongTypeError(field_path=field.name,
                                     field_type=field.type,
                                     value=value)
        except KeyError:
            try:
                value = get_default_value_for_field(field)
            except DefaultValueNotFoundError:
                if not field.init:
                    continue
                raise MissingValueError(field.name)
        if field.init:
            init_values[field.name] = value
        else:
            post_init_values[field.name] = value

    return create_instance(data_class=data_class,
                           init_values=init_values,
                           post_init_values=post_init_values)
Exemplo n.º 3
0
def test_get_default_value_for_field_with_default_value():
    @dataclass
    class X:
        i: int = 1

    value = get_default_value_for_field(field=fields(X)[0])

    assert value == 1
Exemplo n.º 4
0
def test_get_default_value_for_optional_field():
    @dataclass
    class X:
        i: Optional[int]

    value = get_default_value_for_field(field=fields(X)[0])

    assert value is None
Exemplo n.º 5
0
def test_get_default_value_for_field_with_default_factory():
    @dataclass
    class X:
        i: int = field(default_factory=lambda: 1)

    value = get_default_value_for_field(field=fields(X)[0])

    assert value == 1
Exemplo n.º 6
0
def from_dict(data_class: Type[T],
              data: Data,
              config: Optional[Config] = None) -> T:
    """Create a data class instance from a dictionary.

    :param data_class: a data class type
    :param data: a dictionary of a input data
    :param config: a configuration of the creation process
    :return: an instance of a data class
    """
    init_values: Data = {}
    post_init_values: Data = {}
    config = config or Config()
    config.validate(data_class, data)
    try:
        data_class_hints = get_type_hints(data_class,
                                          globalns=config.forward_references)
    except NameError as error:
        raise ForwardReferenceError(str(error))
    for field in fields(data_class):
        field = copy.copy(field)
        field.type = data_class_hints[field.name]
        try:
            try:
                value = _build_value(type_=field.type,
                                     data=config.get_value(field, data),
                                     config=config.make_inner(field))
            except DaciteFieldError as error:
                error.update_path(field.name)
                raise
            if config.check_types and not is_instance(value, field.type):
                raise WrongTypeError(field_path=field.name,
                                     field_type=field.type,
                                     value=value)
        except ValueNotFoundError:
            try:
                value = get_default_value_for_field(field)
            except DefaultValueNotFoundError:
                if not field.init:
                    continue
                raise MissingValueError(field.name)
        if field.init:
            init_values[field.name] = value
        else:
            post_init_values[field.name] = value

    return create_instance(data_class=data_class,
                           init_values=init_values,
                           post_init_values=post_init_values)