From bd424674c1d166b46dd8f4f08558ff5e3d9993b1 Mon Sep 17 00:00:00 2001 From: Dj Padzensky Date: Wed, 29 May 2024 13:22:15 -0700 Subject: [PATCH] Adding a special case for floats that are passed the strings "nan" or "inf" --- dacite/core.py | 2 ++ dacite/types.py | 2 ++ tests/core/test_base.py | 16 ++++++++++++++++ 3 files changed, 20 insertions(+) diff --git a/dacite/core.py b/dacite/core.py index 9e45129..a263cbc 100644 --- a/dacite/core.py +++ b/dacite/core.py @@ -97,6 +97,8 @@ def _build_value(type_: Type, data: Any, config: Config) -> Any: data = _build_value_for_collection(collection=type_, data=data, config=config) elif cache(is_dataclass)(type_) and isinstance(data, Mapping): data = from_dict(data_class=type_, data=data, config=config) + elif type_ == float and isinstance(data, str) and data.lower() in ["nan", "inf"]: + return type_(data) for cast_type in config.cast: if is_subclass(type_, cast_type): if is_generic_collection(type_): diff --git a/dacite/types.py b/dacite/types.py index af7b495..1c1e171 100644 --- a/dacite/types.py +++ b/dacite/types.py @@ -99,6 +99,8 @@ def is_instance(value: Any, type_: Type) -> bool: # As described in PEP 484 - section: "The numeric tower" if (type_ in [float, complex] and isinstance(value, (int, float))) or isinstance(value, type_): return True + if type_ == float and isinstance(value, str) and value.lower() in ["nan", "inf"]: + return True except TypeError: pass if type_ == Any: diff --git a/tests/core/test_base.py b/tests/core/test_base.py index a866d57..7451868 100644 --- a/tests/core/test_base.py +++ b/tests/core/test_base.py @@ -1,3 +1,4 @@ +import math from dataclasses import dataclass, field from typing import Any, NewType, Optional, List @@ -204,3 +205,18 @@ class A: a2 = from_dict(A, {"name": "a2"}) assert a1.items is not a2.items + + +def test_translate_nan_to_float(): + @dataclass + class X: + i: float + n: float + + result_1 = from_dict(X, {"i": "inf", "n": "nan"}) + result_2 = from_dict(X, {"i": "INF", "n": "NaN"}) + + assert math.isnan(result_1.n) + assert math.isnan(result_2.n) + assert math.isinf(result_1.i) + assert math.isinf(result_2.i)