Skip to content
This repository was archived by the owner on Nov 1, 2023. It is now read-only.

Commit f4fc087

Browse files
authored
Merge pull request #34 from owid/fix-load-json
Fix load json
2 parents 323d302 + 5edee4c commit f4fc087

File tree

7 files changed

+42
-25
lines changed

7 files changed

+42
-25
lines changed

.bumpversion.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[bumpversion]
2-
current_version = 0.4.7
2+
current_version = 0.4.8
33
commit = True
44
tag = True
55

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# owid-datautils
2-
![version](https://img.shields.io/badge/version-0.4.7-blue)
2+
![version](https://img.shields.io/badge/version-0.4.8-blue)
33
![version](https://img.shields.io/badge/python-3.8|3.9|3.10-blue.svg?&logo=python&logoColor=yellow) [![codecov](https://codecov.io/gh/owid/owid-datautils-py/branch/main/graph/badge.svg?token=2emTQEJedw)](https://codecov.io/gh/owid/owid-datautils-py)
44
[![Documentation Status](https://readthedocs.org/projects/owid-datautils/badge/?version=latest)](https://docs.owid.io/projects/owid-datautils/en/latest/?badge=latest)
55

docs/conf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
author = "Our World In Data"
2323

2424
# The full version, including alpha/beta/rc tags
25-
release = "0.4.7"
25+
release = "0.4.8"
2626

2727

2828
# -- General configuration ---------------------------------------------------

owid/datautils/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
"""Library to support the work of the Data Team at Our World in Data."""
22

3-
__version__ = "0.4.7"
3+
__version__ = "0.4.8"

owid/datautils/io/local.py

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,35 @@
22

33
import json
44
from pathlib import Path
5-
from typing import Any, cast, Dict, Hashable, List, Tuple, Union
5+
from typing import Any, Hashable, List, Tuple, Union
66

77
from owid.datautils.common import warn_on_list_of_entities
88

99

1010
def _load_json_data_and_duplicated_keys(
1111
ordered_pairs: List[Tuple[Hashable, Any]]
12-
) -> Tuple[Dict[Any, Any], List[Any]]:
12+
) -> Any:
1313
clean_dict = {}
1414
duplicated_keys = []
1515
for key, value in ordered_pairs:
1616
if key in clean_dict:
1717
duplicated_keys.append(key)
1818
clean_dict[key] = value
19+
if len(duplicated_keys) > 0:
20+
warn_on_list_of_entities(
21+
list_of_entities=duplicated_keys,
22+
warning_message="Duplicated entities found.",
23+
show_list=True,
24+
)
1925

20-
return clean_dict, duplicated_keys
26+
return clean_dict
2127

2228

23-
def load_json(
24-
json_file: Union[str, Path], warn_on_duplicated_keys: bool = True
25-
) -> Dict[Any, Any]:
29+
def load_json(json_file: Union[str, Path], warn_on_duplicated_keys: bool = True) -> Any:
2630
"""Load data from json file, and optionally warn if there are duplicated keys.
2731
28-
If json file contains duplicated keys, a warning is optionally raised, and only the latest value of the key is kept.
32+
If json file contains duplicated keys, a warning is optionally raised, and only the value of the latest duplicated
33+
key is kept.
2934
3035
Parameters
3136
----------
@@ -41,20 +46,15 @@ def load_json(
4146
4247
"""
4348
with open(json_file, "r") as _json_file:
49+
json_content = _json_file.read()
4450
if warn_on_duplicated_keys:
45-
data, duplicated_keys = json.loads(
46-
_json_file.read(), object_pairs_hook=_load_json_data_and_duplicated_keys
51+
data = json.loads(
52+
json_content, object_pairs_hook=_load_json_data_and_duplicated_keys
4753
)
48-
if len(duplicated_keys) > 0:
49-
warn_on_list_of_entities(
50-
duplicated_keys,
51-
f"Duplicated entities found in {json_file}",
52-
show_list=True,
53-
)
5454
else:
55-
data = json.loads(_json_file.read())
55+
data = json.loads(json_content)
5656

57-
return cast(Dict[Any, Any], data)
57+
return data
5858

5959

6060
def save_json(data: Any, json_file: Union[str, Path], **kwargs: Any) -> None:

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "owid-datautils"
3-
version = "0.4.7"
3+
version = "0.4.8"
44
description = "Data utils library by the Data Team at Our World in Data"
55
authors = ["Our World In Data <tech@ourworldindata.org>"]
66
license = "MIT"

tests/io/test_local.py

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,39 @@ class TestLoadJson:
1313
def test_load_json_without_duplicated_keys(self, _):
1414
assert load_json(_) == {"1": "10", "2": "20"}
1515

16+
@patch(
17+
"builtins.open",
18+
new_callable=mock_open,
19+
read_data='{"1": {"1_1": "1", "1_2": "2"}, "2": "20"}',
20+
)
21+
def test_load_json_without_duplicated_keys_with_more_levels(self, _):
22+
assert load_json(_) == {"1": {"1_1": "1", "1_2": "2"}, "2": "20"}
23+
24+
@patch(
25+
"builtins.open",
26+
new_callable=mock_open,
27+
read_data='[{"1": {"1_1": "1", "1_2": "2"}, "2": "20"}, {"1": "10"}]',
28+
)
29+
def test_load_json_without_duplicated_keys_with_more_levels_in_a_list(self, _):
30+
# Here the key "1" is repeated, however, it is in a different dictionary, so it is not a duplicated key.
31+
assert load_json(_) == [{"1": {"1_1": "1", "1_2": "2"}, "2": "20"}, {"1": "10"}]
32+
1633
@patch(
1734
"builtins.open",
1835
new_callable=mock_open,
1936
read_data='{"1": "10", "2": "20", "1": "100"}',
2037
)
21-
def test_load_json_with_duplicated_keys(self, _):
38+
def test_load_json_with_duplicated_keys_and_no_warning(self, _):
2239
assert load_json(_, warn_on_duplicated_keys=False) == {"1": "100", "2": "20"}
2340

2441
@patch(
2542
"builtins.open",
2643
new_callable=mock_open,
2744
read_data='{"1": "10", "2": "20", "1": "100"}',
2845
)
29-
def test_warn_on_load_json_with_duplicated_keys(self, _):
46+
def test_warn_on_load_json_with_duplicated_keys_and_warning(self, _):
3047
with warns(UserWarning, match="Duplicated"):
31-
load_json(_, warn_on_duplicated_keys=True)
48+
assert load_json(_, warn_on_duplicated_keys=True) == {"1": "100", "2": "20"}
3249

3350
@patch("builtins.open", new_callable=mock_open, read_data="{}")
3451
def test_load_empty_json(self, _):

0 commit comments

Comments
 (0)