iker-python-common 1.0.10__tar.gz → 1.0.11__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/PKG-INFO +1 -1
  2. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/src/iker/common/utils/jsonutils.py +75 -19
  3. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/src/iker_python_common.egg-info/PKG-INFO +1 -1
  4. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/test/iker_tests/common/utils/jsonutils_test.py +302 -1
  5. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/.editorconfig +0 -0
  6. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/.github/workflows/pr.yml +0 -0
  7. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/.github/workflows/push.yml +0 -0
  8. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/.gitignore +0 -0
  9. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/MANIFEST.in +0 -0
  10. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/README.md +0 -0
  11. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/VERSION +0 -0
  12. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/pyproject.toml +0 -0
  13. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/resources/unittest/shutils/dir.baz/file.bar.baz +0 -0
  14. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/resources/unittest/shutils/dir.baz/file.foo.bar +0 -0
  15. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/resources/unittest/shutils/dir.baz/file.foo.baz +0 -0
  16. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/resources/unittest/shutils/dir.foo/dir.foo.bar/dir.foo.bar.baz/file.foo.bar.baz +0 -0
  17. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/resources/unittest/shutils/dir.foo/dir.foo.bar/file.bar.baz +0 -0
  18. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/resources/unittest/shutils/dir.foo/dir.foo.bar/file.foo.bar +0 -0
  19. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/resources/unittest/shutils/dir.foo/dir.foo.bar/file.foo.baz +0 -0
  20. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/resources/unittest/shutils/dir.foo/file.bar +0 -0
  21. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/resources/unittest/shutils/dir.foo/file.baz +0 -0
  22. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/resources/unittest/shutils/dir.foo/file.foo +0 -0
  23. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/setup.cfg +0 -0
  24. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/setup.py +0 -0
  25. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/src/iker/common/__init__.py +0 -0
  26. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/src/iker/common/utils/__init__.py +0 -0
  27. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/src/iker/common/utils/argutils.py +0 -0
  28. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/src/iker/common/utils/config.py +0 -0
  29. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/src/iker/common/utils/dbutils.py +0 -0
  30. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/src/iker/common/utils/dockerutils.py +0 -0
  31. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/src/iker/common/utils/dtutils.py +0 -0
  32. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/src/iker/common/utils/funcutils.py +0 -0
  33. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/src/iker/common/utils/logger.py +0 -0
  34. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/src/iker/common/utils/numutils.py +0 -0
  35. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/src/iker/common/utils/randutils.py +0 -0
  36. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/src/iker/common/utils/retry.py +0 -0
  37. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/src/iker/common/utils/s3utils.py +0 -0
  38. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/src/iker/common/utils/sequtils.py +0 -0
  39. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/src/iker/common/utils/shutils.py +0 -0
  40. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/src/iker/common/utils/span.py +0 -0
  41. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/src/iker/common/utils/strutils.py +0 -0
  42. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/src/iker/common/utils/testutils.py +0 -0
  43. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/src/iker_python_common.egg-info/SOURCES.txt +0 -0
  44. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/src/iker_python_common.egg-info/dependency_links.txt +0 -0
  45. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/src/iker_python_common.egg-info/not-zip-safe +0 -0
  46. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/src/iker_python_common.egg-info/requires.txt +0 -0
  47. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/src/iker_python_common.egg-info/top_level.txt +0 -0
  48. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/test/iker_tests/__init__.py +0 -0
  49. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/test/iker_tests/common/utils/argutils_test.py +0 -0
  50. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/test/iker_tests/common/utils/config_test.py +0 -0
  51. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/test/iker_tests/common/utils/dbutils_test.py +0 -0
  52. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/test/iker_tests/common/utils/dockerutils_test.py +0 -0
  53. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/test/iker_tests/common/utils/dtutils_test.py +0 -0
  54. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/test/iker_tests/common/utils/funcutils_test.py +0 -0
  55. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/test/iker_tests/common/utils/logger_test.py +0 -0
  56. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/test/iker_tests/common/utils/numutils_test.py +0 -0
  57. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/test/iker_tests/common/utils/randutils_test.py +0 -0
  58. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/test/iker_tests/common/utils/retry_test.py +0 -0
  59. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/test/iker_tests/common/utils/s3utils_test.py +0 -0
  60. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/test/iker_tests/common/utils/sequtils_test.py +0 -0
  61. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/test/iker_tests/common/utils/shutils_test.py +0 -0
  62. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/test/iker_tests/common/utils/span_test.py +0 -0
  63. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/test/iker_tests/common/utils/strutils_test.py +0 -0
  64. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/test/iker_tests/common/utils/testutils_test.py +0 -0
  65. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/test/iker_tests/docker_fixtures.py +0 -0
  66. {iker_python_common-1.0.10 → iker_python_common-1.0.11}/test/iker_tests/iker_test.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: iker-python-common
3
- Version: 1.0.10
3
+ Version: 1.0.11
4
4
  Classifier: Programming Language :: Python :: 3
5
5
  Classifier: Programming Language :: Python :: 3.11
6
6
  Classifier: Programming Language :: Python :: 3.12
@@ -15,6 +15,8 @@ __all__ = [
15
15
  "JsonArrayCompatible",
16
16
  "JsonObjectCompatible",
17
17
  "JsonTypeCompatible",
18
+ "NodePath",
19
+ "json_traverse",
18
20
  "json_reformat",
19
21
  "json_sanitize",
20
22
  "json_compare",
@@ -32,6 +34,65 @@ JsonObjectCompatible = Mapping[JsonKeyCompatible, "JsonTypeCompatible"]
32
34
  JsonArrayCompatible = Sequence["JsonTypeCompatible"]
33
35
  JsonTypeCompatible = JsonValueCompatible | JsonObjectCompatible | JsonArrayCompatible
34
36
 
37
+ NodePath = list[str | int]
38
+
39
+
40
+ def default_key_visitor(node_path: NodePath, key: JsonKeyCompatible) -> JsonKey:
41
+ return str(key)
42
+
43
+
44
+ def default_value_visitor(node_path: NodePath, value: JsonValueCompatible) -> JsonValue:
45
+ if value is None or isinstance(value, JsonValue):
46
+ return value
47
+ if isinstance(value, SupportsFloat):
48
+ return float(value)
49
+ if isinstance(value, SupportsInt):
50
+ return int(value)
51
+ raise ValueError(f"unsupported type '{type(value)}' encountered")
52
+
53
+
54
+ def default_object_visitor(node_path: NodePath, old_object: JsonObjectCompatible, new_object: JsonObject) -> JsonType:
55
+ return new_object
56
+
57
+
58
+ def default_array_visitor(node_path: NodePath, old_array: JsonArrayCompatible, new_array: JsonArray) -> JsonType:
59
+ return new_array
60
+
61
+
62
+ def json_traverse(
63
+ obj: Any,
64
+ key_visitor: Callable[[NodePath, JsonKeyCompatible], JsonKey] = default_key_visitor,
65
+ value_visitor: Callable[[NodePath, JsonValueCompatible], JsonType] = default_value_visitor,
66
+ object_visitor: Callable[[NodePath, JsonObjectCompatible, JsonObject], JsonType] = default_object_visitor,
67
+ array_visitor: Callable[[NodePath, JsonArrayCompatible, JsonArray], JsonType] = default_array_visitor,
68
+ stop_func: Callable[[NodePath], bool] = lambda x: False,
69
+ *,
70
+ raise_if_unregistered: bool = True,
71
+ unregistered_visitor: Callable[[NodePath, Any], JsonType] | None = None,
72
+ ) -> JsonType:
73
+ def func(obj: Any, node_path: NodePath):
74
+ if stop_func(node_path):
75
+ return None
76
+ if obj is None or isinstance(obj, (JsonValue | JsonValueCompatible)):
77
+ return value_visitor(node_path, obj)
78
+ if isinstance(obj, Mapping):
79
+ return object_visitor(
80
+ node_path,
81
+ obj,
82
+ {key_visitor(node_path, key): func(value, node_path + [key]) for key, value in obj.items()},
83
+ )
84
+ if isinstance(obj, Sequence):
85
+ return array_visitor(
86
+ node_path,
87
+ obj,
88
+ [func(item, node_path + [index]) for index, item in enumerate(obj)],
89
+ )
90
+ if raise_if_unregistered or unregistered_visitor is None:
91
+ raise ValueError(f"unregistered type '{type(obj)}' encountered")
92
+ return unregistered_visitor(node_path, obj)
93
+
94
+ return func(obj, [])
95
+
35
96
 
36
97
  def default_key_formatter(key: JsonKeyCompatible) -> JsonKey:
37
98
  return str(key)
@@ -55,25 +116,20 @@ def json_reformat(
55
116
  raise_if_unregistered: bool = True,
56
117
  unregistered_formatter: Callable[[Any], JsonType] | None = None,
57
118
  ) -> JsonType:
58
- if obj is None or isinstance(obj, (JsonValue | JsonValueCompatible)):
59
- return value_formatter(obj)
60
- if isinstance(obj, Mapping):
61
- return {key_formatter(key): json_reformat(value,
62
- key_formatter,
63
- value_formatter,
64
- raise_if_unregistered=raise_if_unregistered,
65
- unregistered_formatter=unregistered_formatter)
66
- for key, value in obj.items()}
67
- if isinstance(obj, Sequence):
68
- return [json_reformat(item,
69
- key_formatter,
70
- value_formatter,
71
- raise_if_unregistered=raise_if_unregistered,
72
- unregistered_formatter=unregistered_formatter)
73
- for item in obj]
74
- if raise_if_unregistered or unregistered_formatter is None:
75
- raise ValueError(f"unregistered type '{type(obj)}' encountered")
76
- return unregistered_formatter(obj)
119
+ def key_visitor(node_path: NodePath, key: JsonKeyCompatible) -> JsonKey:
120
+ return key_formatter(key)
121
+
122
+ def value_visitor(node_path: NodePath, value: JsonValueCompatible) -> JsonType:
123
+ return value_formatter(value)
124
+
125
+ def unregistered_visitor(node_path: NodePath, obj: Any) -> JsonType:
126
+ return unregistered_formatter(obj) if unregistered_formatter is not None else None
127
+
128
+ return json_traverse(obj,
129
+ key_visitor=key_visitor,
130
+ value_visitor=value_visitor,
131
+ raise_if_unregistered=raise_if_unregistered,
132
+ unregistered_visitor=unregistered_visitor)
77
133
 
78
134
 
79
135
  def json_sanitize(obj: Any, *, str_inf_nan: bool = True, str_unregistered: bool = True) -> JsonType:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: iker-python-common
3
- Version: 1.0.10
3
+ Version: 1.0.11
4
4
  Classifier: Programming Language :: Python :: 3
5
5
  Classifier: Programming Language :: Python :: 3.11
6
6
  Classifier: Programming Language :: Python :: 3.12
@@ -8,7 +8,7 @@ from typing import SupportsFloat, SupportsInt
8
8
  import ddt
9
9
  import pytest
10
10
 
11
- from iker.common.utils.jsonutils import json_compare, json_reformat, json_sanitize
11
+ from iker.common.utils.jsonutils import json_compare, json_reformat, json_sanitize, json_traverse
12
12
 
13
13
 
14
14
  @dataclass(eq=True, frozen=True)
@@ -271,6 +271,307 @@ class JsonUtilsTest(unittest.TestCase):
271
271
  ),
272
272
  )
273
273
  @ddt.unpack
274
+ def test_json_traverse(self, data, expect):
275
+ self.assertTrue(json_compare(json_traverse(data), expect))
276
+
277
+ def test_json_traverse__object_array_visitor(self):
278
+ data = {
279
+ "none": None,
280
+ "bool": {
281
+ "bool_true": True,
282
+ "bool_false": False,
283
+ },
284
+ "int": {
285
+ "int_one": 1,
286
+ "int_minus_one": -1,
287
+ "int_zero": 0,
288
+ "int_wrapped": MultipliedInt(1, -1000),
289
+ },
290
+ "float": {
291
+ "float_one": 1.0,
292
+ "float_minus_one": -1.0,
293
+ "float_zero": 0.0,
294
+ "float_one_e_nine": 1.0e9,
295
+ "float_minus_one_e_minus_nine": -1.0e-9,
296
+ "float_nan": math.nan,
297
+ "float_inf": math.inf,
298
+ "float_minus_inf": -math.inf,
299
+ "float_wrapped": MultipliedFloat(1.0, -1000.0),
300
+ },
301
+ "str": {
302
+ "str_empty": "",
303
+ "str": "dummy",
304
+ },
305
+ "list":
306
+ [None, True, False, 1, -1, 0, 1., -1., 0., 1e9, -1e-9, math.nan, math.inf, -math.inf, "", "dummy"],
307
+ "tuple":
308
+ (None, True, False, 1, -1, 0, 1., -1., 0., 1e9, -1e-9, math.nan, math.inf, -math.inf, "", "dummy"),
309
+ }
310
+
311
+ expect = {
312
+ "none": None,
313
+ "bool": {
314
+ "bool_true": True,
315
+ "bool_false": False,
316
+ },
317
+ "int": {
318
+ "int_one": 1,
319
+ "int_minus_one": -1,
320
+ "int_zero": 0,
321
+ "int_wrapped": None,
322
+ },
323
+ "float": {
324
+ "float_one": 1.0,
325
+ "float_minus_one": -1.0,
326
+ "float_zero": 0.0,
327
+ "float_one_e_nine": 1.0e9,
328
+ "float_minus_one_e_minus_nine": -1.0e-9,
329
+ "float_nan": math.nan,
330
+ "float_inf": math.inf,
331
+ "float_minus_inf": -math.inf,
332
+ "float_wrapped": None,
333
+ },
334
+ "str": [
335
+ ["str_empty", ""],
336
+ ["str", "dummy"],
337
+ ],
338
+ "list":
339
+ [None, True, False, 1, -1, 0, 1., -1., 0., 1e9, -1e-9, math.nan, math.inf, -math.inf, "", "dummy"]
340
+ + [None, True, False, 1, -1, 0, 1., -1., 0., 1e9, -1e-9, None, math.inf, -math.inf, "", "dummy"],
341
+ "tuple":
342
+ [None, True, False, 1, -1, 0, 1., -1., 0., 1e9, -1e-9, math.nan, math.inf, -math.inf, "", "dummy"]
343
+ + [None, True, False, 1, -1, 0, 1., -1., 0., 1e9, -1e-9, None, math.inf, -math.inf, "", "dummy"],
344
+ }
345
+
346
+ def object_visitor(node_path, old_object, new_object):
347
+ if node_path == ["str"]:
348
+ return [[key, value] for key, value in new_object.items()]
349
+ return new_object
350
+
351
+ def array_visitor(node_path, old_array, new_array):
352
+ return list(old_array) + list(new_array)
353
+
354
+ def stop_func(node_path) -> bool:
355
+ return node_path in (
356
+ ["int", "int_wrapped"],
357
+ ["float", "float_wrapped"],
358
+ ["list", 11],
359
+ ["tuple", 11],
360
+ [0],
361
+ ["dummy"],
362
+ )
363
+
364
+ self.assertTrue(json_compare(json_traverse(data,
365
+ object_visitor=object_visitor,
366
+ array_visitor=array_visitor,
367
+ stop_func=stop_func),
368
+ expect))
369
+
370
+ @ddt.data(
371
+ (None, None),
372
+ (True, True),
373
+ (False, False),
374
+ (1, 1),
375
+ (-1, -1),
376
+ (0, 0),
377
+ (1.0, 1.0),
378
+ (-1.0, -1.0),
379
+ (0.0, 0.0),
380
+ (1.0e9, 1.0e9),
381
+ (-1.0e-9, -1.0e-9),
382
+ (math.nan, math.nan),
383
+ (math.inf, math.inf),
384
+ (-math.inf, -math.inf),
385
+ (MultipliedInt(-1, 100), -100),
386
+ (MultipliedInt(1, 100), 100),
387
+ (MultipliedFloat(1.0, 100.0), 100.0),
388
+ (MultipliedFloat(-1.0, 100.0), -100.0),
389
+ ("", ""),
390
+ ("dummy", "dummy"),
391
+ (
392
+ [None, True, False, 1, -1, 0, 1.0, -1.0, 0.0, 1.0e9, -1.0e-9, math.nan, math.inf, -math.inf, "", "dummy"],
393
+ [None, True, False, 1, -1, 0, 1.0, -1.0, 0.0, 1.0e9, -1.0e-9, math.nan, math.inf, -math.inf, "", "dummy"],
394
+ ),
395
+ (
396
+ (None, True, False, 1, -1, 0, 1.0, -1.0, 0.0, 1.0e9, -1.0e-9, math.nan, math.inf, -math.inf, "", "dummy"),
397
+ [None, True, False, 1, -1, 0, 1.0, -1.0, 0.0, 1.0e9, -1.0e-9, math.nan, math.inf, -math.inf, "", "dummy"],
398
+ ),
399
+ (
400
+ {
401
+ "none": None,
402
+ "bool_true": True,
403
+ "bool_false": False,
404
+ "int_one": 1,
405
+ "int_minus_one": -1,
406
+ "int_zero": 0,
407
+ "int_wrapped": MultipliedInt(1, -1000),
408
+ "float_one": 1.0,
409
+ "float_minus_one": -1.0,
410
+ "float_zero": 0.0,
411
+ "float_one_e_nine": 1.0e9,
412
+ "float_minus_one_e_minus_nine": -1.0e-9,
413
+ "float_nan": math.nan,
414
+ "float_inf": math.inf,
415
+ "float_minus_inf": -math.inf,
416
+ "float_wrapped": MultipliedFloat(1.0, -1000.0),
417
+ "str_empty": "",
418
+ "str": "dummy",
419
+ },
420
+ {
421
+ "none": None,
422
+ "bool_true": True,
423
+ "bool_false": False,
424
+ "int_one": 1,
425
+ "int_minus_one": -1,
426
+ "int_zero": 0,
427
+ "int_wrapped": -1000,
428
+ "float_one": 1.0,
429
+ "float_minus_one": -1.0,
430
+ "float_zero": 0.0,
431
+ "float_one_e_nine": 1.0e9,
432
+ "float_minus_one_e_minus_nine": -1.0e-9,
433
+ "float_nan": math.nan,
434
+ "float_inf": math.inf,
435
+ "float_minus_inf": -math.inf,
436
+ "float_wrapped": -1000.0,
437
+ "str_empty": "",
438
+ "str": "dummy",
439
+ },
440
+ ),
441
+ (
442
+ {
443
+ "none": None,
444
+ "bool": {
445
+ "bool_true": True,
446
+ "bool_false": False,
447
+ },
448
+ "int": {
449
+ "int_one": 1,
450
+ "int_minus_one": -1,
451
+ "int_zero": 0,
452
+ "int_wrapped": MultipliedInt(1, -1000),
453
+ },
454
+ "float": {
455
+ "float_one": 1.0,
456
+ "float_minus_one": -1.0,
457
+ "float_zero": 0.0,
458
+ "float_one_e_nine": 1.0e9,
459
+ "float_minus_one_e_minus_nine": -1.0e-9,
460
+ "float_nan": math.nan,
461
+ "float_inf": math.inf,
462
+ "float_minus_inf": -math.inf,
463
+ "float_wrapped": MultipliedFloat(1.0, -1000.0),
464
+ },
465
+ "str": {
466
+ "str_empty": "",
467
+ "str": "dummy",
468
+ },
469
+ "list":
470
+ [None, True, False, 1, -1, 0, 1., -1., 0., 1e9, -1e-9, math.nan, math.inf, -math.inf, "", "dummy"],
471
+ "tuple":
472
+ (None, True, False, 1, -1, 0, 1., -1., 0., 1e9, -1e-9, math.nan, math.inf, -math.inf, "", "dummy"),
473
+ },
474
+ {
475
+ "none": None,
476
+ "bool": {
477
+ "bool_true": True,
478
+ "bool_false": False,
479
+ },
480
+ "int": {
481
+ "int_one": 1,
482
+ "int_minus_one": -1,
483
+ "int_zero": 0,
484
+ "int_wrapped": -1000,
485
+ },
486
+ "float": {
487
+ "float_one": 1.0,
488
+ "float_minus_one": -1.0,
489
+ "float_zero": 0.0,
490
+ "float_one_e_nine": 1.0e9,
491
+ "float_minus_one_e_minus_nine": -1.0e-9,
492
+ "float_nan": math.nan,
493
+ "float_inf": math.inf,
494
+ "float_minus_inf": -math.inf,
495
+ "float_wrapped": -1000.0,
496
+ },
497
+ "str": {
498
+ "str_empty": "",
499
+ "str": "dummy",
500
+ },
501
+ "list":
502
+ [None, True, False, 1, -1, 0, 1., -1., 0., 1e9, -1e-9, math.nan, math.inf, -math.inf, "", "dummy"],
503
+ "tuple":
504
+ [None, True, False, 1, -1, 0, 1., -1., 0., 1e9, -1e-9, math.nan, math.inf, -math.inf, "", "dummy"],
505
+ },
506
+ ),
507
+ (
508
+ WrappedDict({
509
+ PrefixedStr("key", "none"): None,
510
+ PrefixedStr("key", "bool"): WrappedDict({
511
+ PrefixedStr("key", "bool_true"): True,
512
+ PrefixedStr("key", "bool_false"): False,
513
+ }),
514
+ PrefixedStr("key", "int"): WrappedDict({
515
+ PrefixedStr("key", "int_one"): 1,
516
+ PrefixedStr("key", "int_minus_one"): -1,
517
+ PrefixedStr("key", "int_zero"): 0,
518
+ PrefixedStr("key", "int_wrapped"): MultipliedInt(1, -1000),
519
+ }),
520
+ PrefixedStr("key", "float"): WrappedDict({
521
+ PrefixedStr("key", "float_one"): 1.0,
522
+ PrefixedStr("key", "float_minus_one"): -1.0,
523
+ PrefixedStr("key", "float_zero"): 0.0,
524
+ PrefixedStr("key", "float_one_e_nine"): 1.0e9,
525
+ PrefixedStr("key", "float_minus_one_e_minus_nine"): -1.0e-9,
526
+ PrefixedStr("key", "float_nan"): math.nan,
527
+ PrefixedStr("key", "float_inf"): math.inf,
528
+ PrefixedStr("key", "float_minus_inf"): -math.inf,
529
+ PrefixedStr("key", "float_wrapped"): MultipliedFloat(1.0, -1000.0),
530
+ }),
531
+ PrefixedStr("key", "str"): WrappedDict({
532
+ PrefixedStr("key", "str_empty"): "",
533
+ PrefixedStr("key", "str"): "dummy",
534
+ }),
535
+ PrefixedStr("key", "list"): WrappedList(
536
+ [None, True, False, 1, -1, 0, 1., -1., 0., 1e9, -1e-9, math.nan, math.inf, -math.inf, "", "dummy"]),
537
+ PrefixedStr("key", "tuple"):
538
+ (None, True, False, 1, -1, 0, 1., -1., 0., 1e9, -1e-9, math.nan, math.inf, -math.inf, "", "dummy"),
539
+ }),
540
+ {
541
+ "key::none": None,
542
+ "key::bool": {
543
+ "key::bool_true": True,
544
+ "key::bool_false": False,
545
+ },
546
+ "key::int": {
547
+ "key::int_one": 1,
548
+ "key::int_minus_one": -1,
549
+ "key::int_zero": 0,
550
+ "key::int_wrapped": -1000,
551
+ },
552
+ "key::float": {
553
+ "key::float_one": 1.0,
554
+ "key::float_minus_one": -1.0,
555
+ "key::float_zero": 0.0,
556
+ "key::float_one_e_nine": 1.0e9,
557
+ "key::float_minus_one_e_minus_nine": -1.0e-9,
558
+ "key::float_nan": math.nan,
559
+ "key::float_inf": math.inf,
560
+ "key::float_minus_inf": -math.inf,
561
+ "key::float_wrapped": -1000.0,
562
+ },
563
+ "key::str": {
564
+ "key::str_empty": "",
565
+ "key::str": "dummy",
566
+ },
567
+ "key::list":
568
+ [None, True, False, 1, -1, 0, 1., -1., 0., 1e9, -1e-9, math.nan, math.inf, -math.inf, "", "dummy"],
569
+ "key::tuple":
570
+ [None, True, False, 1, -1, 0, 1., -1., 0., 1e9, -1e-9, math.nan, math.inf, -math.inf, "", "dummy"],
571
+ },
572
+ ),
573
+ )
574
+ @ddt.unpack
274
575
  def test_json_reformat(self, data, expect):
275
576
  self.assertTrue(json_compare(json_reformat(data), expect))
276
577