Repository: biolink/biolinkml

Issue:
enums are not imported in generated python code
E.g

```yaml
id: https://microbiomedata/schema

prefixes:
  biolinkml: https://w3id.org/biolink/biolinkml/

imports:
  - biolinkml:types
  - issues_368_imports

classes:

  c:
    is_a: parent_class
    slots:
      - s

slots:
  s:
    range: e
```

where the imported file is:

```yaml
id: https://microbiomedata/schema/mixs

classes:
  parent_class: {}

enums:
  e:
    permissible_values:
      a: A
      b: B
```

```bash
$ gen-python --no-mergeimports tests/test_issues/input/issue_368.yaml
```

makes:

```python
...
from . issues_368_imports import ParentClass
...
```

but the python should also import `E`

Discussion:

Patch:
diff --git a/biolinkml/generators/pythongen.py b/biolinkml/generators/pythongen.py
index 63f4a7ca..48c9d2e1 100644
--- a/biolinkml/generators/pythongen.py
+++ b/biolinkml/generators/pythongen.py
@@ -197,12 +197,15 @@ dataclasses._init_fn = dataclasses_init_fn_with_kwargs
                 add_type_ref(self.schema.types[typ.typeof])
             rval.add_element(typ)
 
+        def add_enum_ref(e: EnumDefinition) -> None:
+            rval.add_element(e)
+
         def add_slot_range(slot: SlotDefinition) -> None:
             if slot.range:
                 if slot.range in self.schema.types:
                     add_type_ref(self.schema.types[slot.range])
                 elif slot.range in self.schema.enums:
-                    pass
+                    add_enum_ref(self.schema.enums[slot.range])
                 else:
                     cls = self.schema.classes[slot.range]
                     if cls.imported_from:


Test patch:
diff --git a/tests/test_issues/input/issue_368.yaml b/tests/test_issues/input/issue_368.yaml
new file mode 100644
index 00000000..0bc27c5b
--- /dev/null
+++ b/tests/test_issues/input/issue_368.yaml
@@ -0,0 +1,19 @@
+id: https://microbiomedata/schema
+
+prefixes:
+  biolinkml: https://w3id.org/biolink/biolinkml/
+
+imports:
+  - biolinkml:types
+  - issues_368_imports
+
+classes:
+
+  c:
+    is_a: parent_class
+    slots:
+      - s
+
+slots:
+  s:
+    range: e
diff --git a/tests/test_issues/input/issues_368_imports.yaml b/tests/test_issues/input/issues_368_imports.yaml
new file mode 100644
index 00000000..7e576cb0
--- /dev/null
+++ b/tests/test_issues/input/issues_368_imports.yaml
@@ -0,0 +1,10 @@
+id: https://microbiomedata/schema/mixs
+
+classes:
+  parent_class: {}
+
+enums:
+  e:
+    permissible_values:
+      a: A
+      b: B
diff --git a/tests/test_issues/test_issue_368.py b/tests/test_issues/test_issue_368.py
new file mode 100644
index 00000000..fa90edd4
--- /dev/null
+++ b/tests/test_issues/test_issue_368.py
@@ -0,0 +1,57 @@
+import os
+import unittest
+
+from jsonasobj import as_json
+
+from biolinkml.generators.pythongen import PythonGenerator
+from tests.test_issues.environment import env
+from tests.utils.python_comparator import compare_python, compile_python
+from tests.utils.test_environment import TestEnvironmentTestCase
+
+
+class Issue368TestCase(TestEnvironmentTestCase):
+    env = env
+
+    def header(self, txt: str) -> str:
+        return '\n' + ("=" * 20) + f" {txt} " + ("=" * 20)
+
+    def test_issue_368(self):
+        """ Make sure that types are generated as part of the output """
+        env.generate_single_file('issues_368_imports.py',
+                                lambda: PythonGenerator(env.input_path('issues_368_imports.yaml'),
+                                                     mergeimports=False).serialize(),
+                                comparator=lambda exp, act: compare_python(exp, act, self.env.expected_path('issues_368_imports.py')),
+                                value_is_returned=True)
+        env.generate_single_file('issue_368.py',
+                                 lambda: PythonGenerator(env.input_path('issue_368.yaml'),
+                                                         mergeimports=False).serialize(),
+                                 comparator=lambda exp, act: compare_python(exp, act, self.env.expected_path('issue_368.py')),
+                                 value_is_returned=True)
+        with open(env.expected_path('issue_368.py')) as f:
+            python= f.read()
+
+        has_imports = False
+        for line in python.split("\n"):
+            if line.startswith("from . issues_368_imports"):
+                imps = line.replace("from . issues_368_imports import ","").split(", ")
+                assert 'E' in imps
+                assert 'ParentClass' in imps
+                has_imports = True
+        assert has_imports
+        module = compile_python(env.expected_path('issue_368.py'))
+
+        enum_inst = module.E("a") # EnumInstanceImpl
+        example = module.C(s="a")
+        assert hasattr(example, "s")
+        assert example.s.code.text == enum_inst.code.text
+        assert str(example.s) == "a: A"
+        def output_generator(dirname) -> None:
+            with open(os.path.join(dirname, 'issue_368_1.json'), 'w') as f:
+                f.write(as_json(example))
+
+        # TODO: fix this
+        # env.generate_directory('issue_368', lambda dirname: output_generator(dirname))
+
+
+if __name__ == '__main__':
+    unittest.main()