Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions hed/schema/hed_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -581,8 +581,7 @@ def _update_all_entries(self):
""" Call finalize_entry on every schema entry(tag, unit, etc). """
for key_class, section in self._sections.items():
self._initialize_attributes(key_class)
for entry in section.values():
entry.finalize_entry(self)
section._finalize_section(self)

def _initialize_attributes(self, key_class):
""" Set the valid attributes for a section.
Expand Down
59 changes: 39 additions & 20 deletions hed/schema/hed_schema_section.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,17 +61,15 @@ def _check_if_duplicate(self, name_key, new_entry):

return return_entry

def _add_to_dict(self, name, new_entry, parent_index=None):
def _add_to_dict(self, name, new_entry):
""" Add a name to the dictionary for this section. """
name_key = name
if not self.case_sensitive:
name_key = name.lower()

return_entry = self._check_if_duplicate(name_key, new_entry)

if parent_index is None:
parent_index = len(self.all_entries)
self.all_entries.insert(parent_index, new_entry)
self.all_entries.append(new_entry)
return return_entry

def get_entries_with_attribute(self, attribute_name, return_name_only=False, schema_namespace=""):
Expand Down Expand Up @@ -146,6 +144,10 @@ def __eq__(self, other):
def __bool__(self):
return bool(self.all_names)

def _finalize_section(self, hed_schema):
for entry in self.values():
entry.finalize_entry(hed_schema)


class HedSchemaUnitClassSection(HedSchemaSection):
def _check_if_duplicate(self, name_key, new_entry):
Expand Down Expand Up @@ -211,22 +213,6 @@ def _check_if_duplicate(self, name, new_entry):

return new_entry

def _add_to_dict(self, name, new_entry, parent_index=None):
if new_entry.has_attribute(HedKey.InLibrary):
parent_name = new_entry.parent_name
if parent_name.lower() in self:
# Make sure we insert the new entry after all previous relevant ones, as order isn't assured
# for rooted tags
parent_entry = self.get(parent_name.lower())
parent_index = self.all_entries.index(parent_entry)
for i in range(parent_index, len(self.all_entries)):
if self.all_entries[i].name.startswith(parent_entry.name):
parent_index = i + 1
continue
break

return super()._add_to_dict(name, new_entry, parent_index)

def get(self, key):
if not self.case_sensitive:
key = key.lower()
Expand All @@ -241,3 +227,36 @@ def __contains__(self, key):
if not self.case_sensitive:
key = key.lower()
return key in self.long_form_tags

@staticmethod
def _divide_tags_into_dict(divide_list):
result = {}
for item in divide_list:
key, _, value = item.long_tag_name.partition('/')
if key not in result:
result[key] = []
result[key].append(item)

return list(result.values())

def _finalize_section(self, hed_schema):
split_list = self._divide_tags_into_dict(self.all_entries)

# Sort the extension allowed lists
extension_allowed_node = 0
for values in split_list:
node = values[0]
if node.has_attribute(HedKey.ExtensionAllowed):
# Make sure we sort / characters to the front.
values.sort(key=lambda x: x.long_tag_name.replace("/", "\0"))
extension_allowed_node += 1

# sort the top level nodes so extension allowed is at the bottom
split_list.sort(key=lambda x: x[0].has_attribute(HedKey.ExtensionAllowed))

# sort the extension allowed top level nodes
if extension_allowed_node:
split_list[extension_allowed_node:] = sorted(split_list[extension_allowed_node:], key=lambda x: x[0].long_tag_name)
self.all_entries = [subitem for tag_list in split_list for subitem in tag_list]
super()._finalize_section(hed_schema)

1 change: 1 addition & 0 deletions hed/schema/schema_io/wiki2schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,7 @@ def _read_schema(self, lines):
for line_number, line in lines:
if line.startswith(wiki_constants.ROOT_TAG):
parent_tags = []
level_adj = 0
else:
level = self._get_tag_level(line) + level_adj
if level < len(parent_tags):
Expand Down
6 changes: 5 additions & 1 deletion hed/schema/schema_io/xml2schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,11 @@ def _populate_tag_dictionaries(self):
for tag_element in tag_elements:
tag = self._get_tag_path_from_tag_element(tag_element)
if loading_from_chain:
tag = tag.replace(loading_from_chain_short, loading_from_chain)
if loading_from_chain_short == tag or not tag.startswith(loading_from_chain_short):
loading_from_chain_short = ""
loading_from_chain = ""
else:
tag = tag.replace(loading_from_chain_short, loading_from_chain)
tag_entry = self._parse_node(tag_element, HedSectionKey.AllTags, tag)

rooted_entry = schema_validation_util.find_rooted_entry(tag_entry, self._schema, self._loading_merged)
Expand Down
18 changes: 18 additions & 0 deletions tests/data/schema_tests/merge_tests/bad_sort_test.mediawiki
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
HED library="testlib" version="1.0.2"

'''Prologue'''
This is to make sure it's properly handling tags that are a previous tag name extended with a dash.

!# start schema

'''BaseTag'''{extensionAllowed}
* Node
** Subnode1
* Node-extended
** Subnode3

!# end schema

'''Epilogue'''

!# end hed
49 changes: 49 additions & 0 deletions tests/data/schema_tests/merge_tests/sorted_root.mediawiki
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
HED library="testlib" version="1.0.2" withStandard="8.2.0" unmerged="true"

'''Prologue'''
This schema is the first official release that includes an xsd and requires unit class, unit modifier, value class, schema attribute and property sections.

!# start schema

'''Violin-sound''' {rooted=Instrument-sound} [These should be sorted. Violin should be last]
* Violin-subsound3
* Violin-subsound1
* Violin-subsound2

'''Oboe-sound''' {rooted=Instrument-sound} [These should be sorted. Oboe should be second]
* Oboe-subsound2
* Oboe-subsound1

'''B-nonextension''' [These should not be sorted. B should be first]
* SubnodeB1
* SubnodeB2

'''A-nonextension''' [These should not be sorted. A should be second]
* SubnodeA3
* SubnodeA1
* SubnodeA2

'''Flute-sound''' {rooted=Instrument-sound} [These should be sorted. Flute should be first]
* Flute-subsound2
* Flute-subsound1

'''C-nonextension''' [These should not be sorted. C should be last]
* SubnodeC3
* SubnodeC1
* SubnodeC2

'''B-extensionallowed'''{extensionAllowed} [These should be sorted. This section should be second.]
* SubnodeE3
* SubnodeE1
* SubnodeE2

'''A-extensionallowed'''{extensionAllowed} [These should be sorted. This section should be first.]
* SubnodeD3
* SubnodeD1
* SubnodeD2

!# end schema

'''Epilogue'''

!# end hed
Loading