Skip to content

Commit 10c0155

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 10c0155

File tree

2 files changed

+32
-2
lines changed

2 files changed

+32
-2
lines changed

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: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,16 @@
55

66
from pathlib import Path
77
import json
8+
import os
89
import re
910
import textwrap
11+
import tempfile
1012

1113
import pytest
1214

1315
from glean_parser import metrics
1416
from glean_parser import parser
17+
from glean_parser.util import load_yaml_or_json
1518

1619
import util
1720

@@ -1181,6 +1184,21 @@ def test_no_internal_fields_exposed():
11811184
assert expected_json == out_json
11821185

11831186

1187+
def test_json_loader():
1188+
yaml_input = ROOT / "data" / "all_metrics.yaml"
1189+
yaml_obj = load_yaml_or_json(yaml_input)
1190+
1191+
with tempfile.NamedTemporaryFile(mode="w+", delete=False) as fd:
1192+
json.dump(yaml_obj, fd)
1193+
json_input = fd.name
1194+
1195+
json_obj = load_yaml_or_json(json_input)
1196+
1197+
os.remove(json_input)
1198+
1199+
assert yaml_obj == json_obj
1200+
1201+
11841202
def test_object():
11851203
structure = {"type": "array", "items": {"type": "number"}}
11861204
contents = [{"category": {"metric": {"type": "object", "structure": structure}}}]

0 commit comments

Comments
 (0)