Skip to content

Commit

Permalink
Fix dlite.Instance.from_dict() to correctly parse ref-type properti…
Browse files Browse the repository at this point in the history
…es (#983)

Make it possible to correctly parse YAML files with ref-type properties.
* Parse ref-type in yaml files
* Update bindings/python/tests/test_ref_type.py
* Only test ref-type for yaml if yaml is installed

---------

Co-authored-by: Francesca L. Bleken <[email protected]>
  • Loading branch information
jesper-friis and francescalb authored Oct 28, 2024
1 parent 0764dca commit f716ad0
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 6 deletions.
11 changes: 11 additions & 0 deletions bindings/python/tests/input/test_ref_type_middle.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
http://onto-ns.com/meta/0.2/Middle:
description: Middle-level nested data structure.
dimensions: []
properties:
- name: name
type: string
description: Value of this structure.
- name: leaf
type: ref
$ref: http://onto-ns.com/meta/0.1/Leaf
description: Reference to low-level structure.
21 changes: 16 additions & 5 deletions bindings/python/tests/test_ref_type.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,24 @@
from pathlib import Path

import dlite
from dlite.testutils import importcheck

yaml = importcheck("yaml")


thisdir = Path(__file__).resolve().parent
indir = thisdir / "input"

dlite.storage_path.append(indir / "test_ref_type.json")
dlite.storage_path.append(indir)
dlite.storage_path.append(indir / "test_ref_type_middle.yaml")

# If yaml is available, we read Middle v0.2, which is defined in
# `test_ref_type_middle.yaml`. Otherwise, we read Middle v0.1, which
# is defined together with the other datamodels in `test_ref_type.json`.
version = "0.2" if yaml else "0.1"

Top = dlite.get_instance("http://onto-ns.com/meta/0.1/Top")
Middle = dlite.get_instance("http://onto-ns.com/meta/0.1/Middle")
Middle = dlite.get_instance(f"http://onto-ns.com/meta/{version}/Middle")
Leaf = dlite.get_instance("http://onto-ns.com/meta/0.1/Leaf")
Linked = dlite.get_instance("http://onto-ns.com/meta/0.1/Linked")
Tree = dlite.get_instance("http://onto-ns.com/meta/0.1/Tree")
Expand Down Expand Up @@ -78,6 +87,8 @@
assert cyclic.subtree[0].subtree[0] == cyclic
assert cyclic.subtree[0].subtree[0].subtree[0] == cyclic

# Instantiate nested from dict
# For issue #515
# middle = Middle(properties={"name": "nested", "leaf": {"a": 1, "b": True}})
# For isue #982: ref-type in yaml
assert Middle.getprop("leaf").ref == "http://onto-ns.com/meta/0.1/Leaf"

# For issue #515: Instantiate nested from dict
#middle = Middle(properties={"name": "nested", "leaf": {"a": 1, "b": True}})
12 changes: 11 additions & 1 deletion bindings/python/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,16 @@ def instance_from_dict(d, id=None, single=None, check_storages=True):
if meta.is_metameta:
if "uri" in d:
uri = d["uri"]
else:
elif "identity" in d:
uri = d["identity"]
elif "name" in d and "version" in d and "namespace" in d:
uri = dlite.join_meta_uri(d["name"], d["version"], d["namespace"])
elif id and dlite.urlparse(id).scheme:
uri = id
else:
raise TypeError(
"`id` required for metadata when the URI is not in the dict"
)

if check_storages:
try:
Expand Down Expand Up @@ -169,6 +177,7 @@ def instance_from_dict(d, id=None, single=None, check_storages=True):
dlite.Property(
name=p["name"],
type=p["type"],
ref=p.get("$ref", p.get("ref")),
shape=p.get("shape", p.get("dims")),
unit=p.get("unit"),
description=p.get("description"),
Expand All @@ -180,6 +189,7 @@ def instance_from_dict(d, id=None, single=None, check_storages=True):
dlite.Property(
name=k,
type=v["type"],
ref=v.get("$ref", v.get("ref")),
shape=v.get("shape", v.get("dims")),
unit=v.get("unit"),
description=v.get("description"),
Expand Down

0 comments on commit f716ad0

Please sign in to comment.