Repository: linkml/linkml-runtime

Issue:
schema_as_dict is over eager and eliminates "name" slots
schema_as_dict will compact the direct yaml representation of a schema such that `name` keys are not repeated in the element when they are used as keys - but this is over-eager and gets rid of name slots

Discussion:

Patch:
diff --git a/linkml_runtime/utils/schema_as_dict.py b/linkml_runtime/utils/schema_as_dict.py
index c590936..edaabca 100644
--- a/linkml_runtime/utils/schema_as_dict.py
+++ b/linkml_runtime/utils/schema_as_dict.py
@@ -29,12 +29,20 @@ def _remove_names(obj: Any, parent: Optional[str]) -> Any:
 
     Also compacts representation of prefixes
 
+    It also takes care of the edge case:
+
+    .. code-block:: yaml
+
+        slots:
+          name:
+            ...
+
     :param obj: dictionary object to recursively transform
     :param parent: key for parent dict
     :return:
     """
     if isinstance(obj, dict):
-        return {k: _remove_names(v, k) for k, v in obj.items() if k != 'name' or parent is None}
+        return {k: _remove_names(v, k) for k, v in obj.items() if k != 'name' or parent is None or parent == 'slots'}
     elif isinstance(obj, list):
         return [_remove_names(x, parent) for x in obj]
     else:


Test patch:
diff --git a/tests/test_utils/input/kitchen_sink_noimports.yaml b/tests/test_utils/input/kitchen_sink_noimports.yaml
index 384bfcc..4464533 100644
--- a/tests/test_utils/input/kitchen_sink_noimports.yaml
+++ b/tests/test_utils/input/kitchen_sink_noimports.yaml
@@ -215,6 +215,8 @@ classes:
     class_uri: prov:Agent
     rank: 1
 
+  EmptyClass:
+
 slots:
   employed at:
     range: Company
@@ -344,3 +346,7 @@ enums:
       PARENT_OF:
       CHILD_OF:
   DiagnosisType:
+  OtherEnum:
+    permissible_values:
+      a:
+      b:
diff --git a/tests/test_utils/test_schema_as_dict.py b/tests/test_utils/test_schema_as_dict.py
index f3b8218..0965df5 100644
--- a/tests/test_utils/test_schema_as_dict.py
+++ b/tests/test_utils/test_schema_as_dict.py
@@ -24,6 +24,8 @@ class SchemaAsDictTestCase(unittest.TestCase):
         tests schema_as_dict, see https://github.com/linkml/linkml/issues/100
         """
         view = SchemaView(SCHEMA_NO_IMPORTS)
+        all_slots = view.all_slots()
+        self.assertIn('name', all_slots)
         logging.debug(view.schema.id)
         ystr = schema_as_yaml_dump(view.schema)
         with open(CLEAN_SCHEMA, 'w') as stream:
@@ -41,6 +43,7 @@ class SchemaAsDictTestCase(unittest.TestCase):
                 for e in elt_dict.values():
                     for pv in e.get('permissible_values', {}).values():
                         assert 'text' not in pv
+        self.assertIn('name', obj['slots'])
 
 if __name__ == '__main__':
     unittest.main()
diff --git a/tests/test_utils/test_schemaview.py b/tests/test_utils/test_schemaview.py
index a08c780..62eae1f 100644
--- a/tests/test_utils/test_schemaview.py
+++ b/tests/test_utils/test_schemaview.py
@@ -218,8 +218,9 @@ class SchemaViewTestCase(unittest.TestCase):
         ordered_c = []
         for c in classes.values():
             ordered_c.append(c.name)
-        assert "HasAliases" == ordered_c[0]
-        assert "agent" == ordered_c[-1]
+        self.assertEqual("HasAliases", ordered_c[0])
+        self.assertEqual("EmptyClass", ordered_c[-1])
+        self.assertEqual("agent", ordered_c[-2])
 
     def test_all_slots_ordered_lexical(self):
         view = SchemaView(SCHEMA_NO_IMPORTS)