Skip to content

Commit 7c50793

Browse files
Fix util.load_yaml_or_json failures when loading json files
Line number information are not available through the json API, but providing null line number is enough to make it compatible with other parts.
1 parent 00bede6 commit 7c50793

2 files changed

Lines changed: 29 additions & 2 deletions

File tree

glean_parser/util.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from pathlib import Path
1111
import sys
1212
import textwrap
13-
from typing import Any, Callable, Iterable, Sequence, Tuple, Union, Optional
13+
from typing import Any, Callable, Iterable, Sequence, Tuple, Union, Optional, TextIO
1414
import urllib.request
1515

1616
import appdirs # type: ignore
@@ -97,6 +97,18 @@ def _construct_mapping_adding_line(loader, node):
9797
return yaml.load(stream, SafeLineLoader)
9898

9999

100+
def json_load(stream: TextIO):
101+
102+
# The Python json parser doesn't give us access to the line number
103+
def _construct_mapping_adding_empty_line(obj):
104+
mapping = DictWrapper(obj)
105+
mapping.defined_in = {"line": 0}
106+
return mapping
107+
108+
return json.load(stream, object_hook=_construct_mapping_adding_empty_line)
109+
110+
111+
100112
def ordered_yaml_dump(data, **kwargs):
101113
class OrderedDumper(yaml.Dumper):
102114
pass
@@ -126,7 +138,7 @@ def load_yaml_or_json(path: Path):
126138

127139
if path.suffix == ".json":
128140
with path.open("r", encoding="utf-8") as fd:
129-
return json.load(fd)
141+
return json_load(fd)
130142
elif path.suffix in (".yml", ".yaml", ".yamlx"):
131143
with path.open("r", encoding="utf-8") as fd:
132144
return yaml_load(fd)

tests/test_parser.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@
77
import json
88
import re
99
import textwrap
10+
import tempfile
1011

1112
import pytest
1213

1314
from glean_parser import metrics
1415
from glean_parser import parser
16+
from glean_parser.util import load_yaml_or_json
1517

1618
import util
1719

@@ -1181,6 +1183,19 @@ def test_no_internal_fields_exposed():
11811183
assert expected_json == out_json
11821184

11831185

1186+
def test_json_loader():
1187+
yaml_input = ROOT / "data" / "all_metrics.yaml"
1188+
yaml_obj = load_yaml_or_json(yaml_input)
1189+
1190+
with tempfile.NamedTemporaryFile(delete_on_close=False) as fd:
1191+
json.dump(yaml_obj, fd)
1192+
json_input = fd.name
1193+
1194+
json_obj = load_yaml_or_json(json_input)
1195+
1196+
assert yaml_obj == json_obj
1197+
1198+
11841199
def test_object():
11851200
structure = {"type": "array", "items": {"type": "number"}}
11861201
contents = [{"category": {"metric": {"type": "object", "structure": structure}}}]

0 commit comments

Comments
 (0)