Repository: linkml/linkml

Issue:
pythongen ifabsent generates incorrect values for class_curie and slot_curie
the metamodel has a slot class_uri, with an `ifabsent` defined as follows:

```yaml
classes:
  ClassDefinition:
     slots:
       - ...
       - class_uri
       - ...
slots:       
  class_uri:
    range: uriorcurie
    description: URI of the class that provides a semantic interpretation of the element in a linked data context. The URI may come from any namespace and may be shared between schemas
    ifabsent: class_curie
```

The documentation for `ifabsent` says:

```
        * class_curie -- CURIE for the containing class
        * class_uri -- URI for the containing class
```

this means that if I would expect

```python
>>> cls = ClassDefinition("Foo")
>>> print(cls.class_curie)
myschema:Foo
```

however, with the `ifabsent_function` changes in

- #1171.   

meta.py now says:

```python
class ClassDefinition(...):
    ...
    class_curie: ... = class_class_curie
```

so the actual behavior we get is:

```python
>>> cls = ClassDefinition("Foo")
>>> print(cls.class_curie)
linkml:ClassDefinition
```

I think we revert to having the generated default being `None` for all x_uri slots.


Discussion:
codecov-commenter: ## [Codecov](https://codecov.io/gh/linkml/linkml/pull/1343?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=linkml) Report
> Merging [#1343](https://codecov.io/gh/linkml/linkml/pull/1343?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=linkml) (5bcf620) into [main](https://codecov.io/gh/linkml/linkml/commit/a3bc3761821576ca02a383c8aeb518aff3d132ce?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=linkml) (a3bc376) will **decrease** coverage by `0.12%`.
> The diff coverage is `100.00%`.

:mega: This organization is not using Codecov’s [GitHub App Integration](https://github.com/apps/codecov). We recommend you install it so Codecov can continue to function properly for your repositories. [Learn more](https://about.codecov.io/blog/codecov-is-updating-its-github-integration/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=linkml)

```diff
@@            Coverage Diff             @@
##             main    #1343      +/-   ##
==========================================
- Coverage   80.39%   80.27%   -0.12%     
==========================================
  Files          77       77              
  Lines        9084     9029      -55     
  Branches     2241     2193      -48     
==========================================
- Hits         7303     7248      -55     
  Misses       1354     1354              
  Partials      427      427              
```


| [Impacted Files](https://codecov.io/gh/linkml/linkml/pull/1343?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=linkml) | Coverage Δ | |
|---|---|---|
| [linkml/utils/ifabsent\_functions.py](https://codecov.io/gh/linkml/linkml/pull/1343?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=linkml#diff-bGlua21sL3V0aWxzL2lmYWJzZW50X2Z1bmN0aW9ucy5weQ==) | `82.60% <100.00%> (+0.79%)` | :arrow_up: |

... and [15 files with indirect coverage changes](https://codecov.io/gh/linkml/linkml/pull/1343/indirect-changes?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=linkml)

Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=linkml). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=linkml)


Patch:
diff --git a/linkml/utils/ifabsent_functions.py b/linkml/utils/ifabsent_functions.py
index fa4aa7e5..5d88b9e8 100644
--- a/linkml/utils/ifabsent_functions.py
+++ b/linkml/utils/ifabsent_functions.py
@@ -54,6 +54,17 @@ def uri_for(s: str, loader: SchemaLoader) -> str:
     return loader.namespaces.curie_for(uri, True, True) or strval(uri)
 
 
+def default_ns_for(loader: SchemaLoader, cls: ClassDefinition) -> str:
+    """Return code to produce the default namespace for the supplied class"""
+    # TODO: figure out how to mark a slot as a namespace
+    return "sfx(str(self.id))" if "id" in cls.slots else "None"
+    # cls_id = None
+    # for slotname in cls.slots:
+    #     slot = loader.schema.slots[slotname]
+    #     if slot.identifier:
+    #         cls_id = slotname
+    # return f"sfx(str(self.{cls_id}))" if cls_id else "None"
+
 # Library of named default values -- this is here to prevent code injection
 # Contents: Match text (as re),
 #           flag that indicates whether we're generating a default value expression or postinig code
@@ -91,7 +102,8 @@ default_library: List[
     ("bnode", False, lambda _, __, ___, ____: "bnode()"),
     (r"string\((.*)\)", False, lambda m, __, ___, ____: strval(m[1])),
     (r"uri\((.*)\)", False, lambda m, loader, _, __: uri_for(m[1], loader)),
-    ("default_ns", False, lambda _, loader, __, ____: f"{strval(loader.schema.default_prefix)}"),
+    ("default_ns", True, lambda _, loader, cls, ____: default_ns_for(loader, cls)),
+    # ("default_ns", False, lambda _, loader, __, ____: f"{strval(loader.schema.default_prefix)}"),
 ]
 
 


Test patch:
diff --git a/tests/test_issues/test_issue_675.py b/tests/test_issues/test_issue_675.py
index e88ab330..cf9685d1 100644
--- a/tests/test_issues/test_issue_675.py
+++ b/tests/test_issues/test_issue_675.py
@@ -95,7 +95,8 @@ class IfAbsentTestCase(unittest.TestCase):
         self.assertIsNone(sample.class_uri_slot)
         print(m.HighClass.class_class_uri)
         print("default_ns fails")
-        self.assertEqual(sample.default_ns_slot, 'ex')
+        # self.assertEqual(sample.default_ns_slot, 'ex')
+        self.assertEqual(sample.default_ns_slot, None)
         print("default_range fails")
         # self.assertEqual(sample.default_range_slot, 'string')
         self.assertIsNone(sample.default_range_slot)