Skip to content

Commit 28371b0

Browse files
committed
clean up template if group/field was linked to field/group
1 parent 769bfd8 commit 28371b0

File tree

2 files changed

+41
-16
lines changed

2 files changed

+41
-16
lines changed

src/pynxtools/dataconverter/validation.py

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -694,6 +694,7 @@ def handle_attributes(
694694
"""
695695
for attr_name in attrs:
696696
full_path = f"{entry_name}/{path}/@{attr_name}"
697+
697698
if attr_name in ("NX_class", "units", "target"):
698699
# Ignore special attrs
699700
continue
@@ -1108,21 +1109,36 @@ def handle_group(node: NexusGroup, keys: Mapping[str, Any], prev_path: str):
11081109
# Don't process if this is actually a sub-variant of this group
11091110
continue
11101111
nx_class, _ = split_class_and_name_of(variant)
1112+
if variant.endswith("target"):
1113+
# We need to do this for cases where the target was added automatically,
1114+
# but the group was incorrectly linked to a field.
1115+
continue
11111116
if not isinstance(keys[variant], Mapping):
11121117
# Groups should have subelements
1118+
11131119
if nx_class is not None:
11141120
collector.collect_and_log(
11151121
variant_path,
11161122
ValidationProblem.ExpectedGroup,
11171123
None,
11181124
)
1119-
# TODO: decide if we want to remove such keys
1120-
# collector.collect_and_log(
1121-
# variant_path,
1122-
# ValidationProblem.KeyToBeRemoved,
1123-
# node.nx_type,
1124-
# )
1125-
# keys_to_remove.append(not_visited_key)
1125+
collector.collect_and_log(
1126+
variant_path,
1127+
ValidationProblem.KeyToBeRemoved,
1128+
node.nx_type,
1129+
)
1130+
keys_to_remove.append(variant_path)
1131+
for subkey in keys.keys():
1132+
if subkey.startswith(variant) and subkey != variant:
1133+
name = subkey.split(variant)[-1]
1134+
subkey_path = f"{variant_path}/{name}"
1135+
collector.collect_and_log(
1136+
subkey_path,
1137+
ValidationProblem.KeyToBeRemoved,
1138+
"attribute" if name.startswith("@") else "field",
1139+
)
1140+
keys_to_remove.append(subkey_path)
1141+
11261142
continue
11271143
if node.nx_class == "NXdata":
11281144
handle_nxdata(node, keys[variant], prev_path=variant_path)
@@ -1201,6 +1217,7 @@ def _follow_link(
12011217
if f"{key_path}/@target" not in mapping:
12021218
# Target attribute added automatically
12031219
mapping[f"{key_path}/@target"] = value["link"]
1220+
resolved_keys[f"{key}@target"] = value["link"]
12041221
else:
12051222
attr_target = mapping[f"{key_path}/@target"]
12061223
remove_from_not_visited(f"{key_path}/@target")
@@ -1243,14 +1260,18 @@ def handle_field(node: NexusNode, keys: Mapping[str, Any], prev_path: str):
12431260
ValidationProblem.ExpectedField,
12441261
None,
12451262
)
1246-
# TODO: decide if we want to remove such keys
1247-
# collector.collect_and_log(
1248-
# variant_path,
1249-
# ValidationProblem.KeyToBeRemoved,
1250-
# node.nx_type,
1251-
# )
1252-
# keys_to_remove.append(variant_path)
1263+
collector.collect_and_log(
1264+
variant_path,
1265+
ValidationProblem.KeyToBeRemoved,
1266+
node.nx_type,
1267+
)
1268+
keys_to_remove.append(variant_path)
1269+
for subkey in keys.keys():
1270+
if subkey.startswith(variant) and subkey != variant:
1271+
subkey_path = f"{prev_path}/{subkey.replace('@', '/@')}"
1272+
keys_to_remove.append(subkey_path)
12531273
continue
1274+
12541275
if node.optionality == "required" and isinstance(keys[variant], Mapping):
12551276
# Check if all fields in the dict are actual attributes (startswith @)
12561277
all_attrs = True

tests/dataconverter/test_validation.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -984,6 +984,7 @@ def format_error_message(msg: str) -> str:
984984
),
985985
[
986986
"Expected a field at /ENTRY[my_entry]/identified_calibration/identifier_1, but found a group.",
987+
"The field /ENTRY[my_entry]/identified_calibration/identifier_1 will not be written.",
987988
"The type ('group') of the given concept 'identifier_1' conflicts with another "
988989
"existing concept /ENTRY/identified_calibration/identifier_1 of the same name, which is of type 'field'.",
989990
"The field /ENTRY[my_entry]/identified_calibration/identifier_1/some_field will not be written.",
@@ -1128,8 +1129,10 @@ def format_error_message(msg: str) -> str:
11281129
),
11291130
[
11301131
"Expected a field at /ENTRY[my_entry]/OPTIONAL_group[some_group]/required_field, but found a group.",
1132+
"The field /ENTRY[my_entry]/OPTIONAL_group[some_group]/required_field will not be written.",
11311133
"Expected a group at /ENTRY[my_entry]/USER[my_user], but found a field or attribute.",
1132-
"Field /ENTRY[my_entry]/USER[my_user] has no documentation.",
1134+
"The group /ENTRY[my_entry]/USER[my_user] will not be written.",
1135+
"The attribute /ENTRY[my_entry]/USER[my_user]/@target will not be written.",
11331136
],
11341137
id="appdef-links-with-wrong-nexus-types",
11351138
),
@@ -1176,7 +1179,8 @@ def format_error_message(msg: str) -> str:
11761179
),
11771180
[
11781181
"Expected a group at /ENTRY[my_entry]/DATA[my_data], but found a field or attribute.",
1179-
"Field /ENTRY[my_entry]/DATA[my_data] has no documentation.",
1182+
"The group /ENTRY[my_entry]/DATA[my_data] will not be written.",
1183+
"The attribute /ENTRY[my_entry]/DATA[my_data]/@target will not be written.",
11801184
"Expected a field at /ENTRY[my_entry]/SAMPLE[my_sample]/name, but found a group.",
11811185
],
11821186
id="baseclass-links-with-wrong-nexus-types",

0 commit comments

Comments
 (0)