Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

detection of forward references may sometimes be incorrect in pythongen #1168

Open
cmungall opened this issue Dec 15, 2022 · 1 comment
Open
Assignees
Labels
bug Something that should work but isn't, with an example and a test case. generator-python

Comments

@cmungall
Copy link
Member

cmungall commented Dec 15, 2022

This replaces:

It looks like there are some situations where foward ref detection falsely assumes no forward reference when it should use one

This is because _sort_classes is applied prior to writing classes, but the following code operates over the asserted sort order

def forward_reference(self, slot_range: str, owning_class: str) -> bool:
"""Determine whether slot_range is a forward reference"""
if (
slot_range in self.schema.classes
and self.schema.classes[slot_range].imported_from
) or (
slot_range in self.schema.enums
and self.schema.enums[slot_range].imported_from
):
return False
if slot_range in self.schema.enums:
return True
for cname in self.schema.classes:
if cname == owning_class:
return True # Occurs on or after
elif cname == slot_range:
return False # Occurs before
return True

this replicates the issue:

id: http://example.org/issue-1168
name: issue_1168
description: Tests forward reference edge case
see_also:
  - https://github.com/linkml/linkml/issues/1168

classes:
  C:
    is_a: D
    attributes:
      d:
        range: D
  D:
    attributes:
      c:
        range: C

the order becomes D, C:

@dataclass
class D(YAMLRoot):
    _inherited_slots: ClassVar[List[str]] = []

    class_class_uri: ClassVar[URIRef] = URIRef("http://example.org/issue-1168/D")
    class_class_curie: ClassVar[str] = None
    class_name: ClassVar[str] = "D"
    class_model_uri: ClassVar[URIRef] = URIRef("http://example.org/issue-1168/D")

    c: Optional[Union[dict, C]] = None
    ...


@dataclass
class C(D):

which yields

NameError: name 'C' is not defined

The workaround is to order elements with your schema accordingly, but this should not be necessary

@cmungall
Copy link
Member Author

Note: an alternative approach here is simply to record when a class definition is written, and always forward ref if it has not been written

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something that should work but isn't, with an example and a test case. generator-python
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants