/ tests / test_utils.py
test_utils.py
 1  import json
 2  from datetime import datetime
 3  
 4  import numpy as np
 5  import pandas as pd
 6  import pytest
 7  
 8  from evidently.legacy.utils.numpy_encoder import NumpyEncoder
 9  
10  
11  @pytest.mark.parametrize(
12      "test_object, expected_json",
13      (
14          (
15              [np.nan, np.inf, -np.inf],
16              "[NaN, Infinity, -Infinity]",
17          ),
18          (
19              [
20                  _type(42)
21                  for _type in (
22                      np.int_,
23                      np.intc,
24                      np.intp,
25                      np.int8,
26                      np.int16,
27                      np.int32,
28                      np.int64,
29                      np.uint8,
30                      np.uint16,
31                      np.uint32,
32                      np.uint64,
33                  )
34              ],
35              "[42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42]",
36          ),
37          (
38              [_type(0.5) for _type in (np.double, np.float16, np.float32, np.float64)],
39              "[0.5, 0.5, 0.5, 0.5]",
40          ),
41          (np.array([np.bool_(1), np.bool_(0)]), "[true, false]"),
42          (
43              np.array([0, 1, 2.1, np.nan, np.inf, pd.NaT]),
44              "[0, 1, 2.1, NaN, Infinity, null]",
45          ),
46          (np.empty((0, 0)), "[]"),
47          (
48              np.array([[0, 1, 2.1], [0, 1, 2.1], [0, 1, 2.1]]),
49              "[[0.0, 1.0, 2.1], [0.0, 1.0, 2.1], [0.0, 1.0, 2.1]]",
50          ),
51          (np.ones((2, 3)), "[[1.0, 1.0, 1.0], [1.0, 1.0, 1.0]]"),
52          (np.void(3), "null"),
53          # pandas date classes
54          ([pd.Timestamp(2022, 2, 3, 12)], '["2022-02-03T12:00:00"]'),
55          (
56              [datetime(year=2022, month=1, day=13, hour=12, minute=45, second=32)],
57              '["2022-01-13T12:45:32"]',
58          ),
59          ([pd.Timedelta(days=1)], '["1 days 00:00:00"]'),
60          # python types
61          (
62              [321123321123, 0.56, True, False, None, "test", {1: 4}],
63              '[321123321123, 0.56, true, false, null, "test", {"1": 4}]',
64          ),
65      ),
66  )
67  def test_numpy_encoder_compatible_types(test_object, expected_json: str) -> None:
68      assert json.dumps(test_object, cls=NumpyEncoder) == expected_json, test_object
69  
70  
71  class _UnsupportedJson:
72      pass
73  
74  
75  @pytest.mark.parametrize(
76      "test_object, type_name_in_error",
77      (
78          (_UnsupportedJson(), "_UnsupportedJson"),
79          ({1, 2, 3}, "set"),
80      ),
81  )
82  def test_numpy_encoder_incompatible_types(test_object, type_name_in_error: str) -> None:
83      with pytest.raises(TypeError) as error:
84          json.dumps(test_object, cls=NumpyEncoder)
85          assert type_name_in_error in str(error)