Bug Description
The MMIF spec is explicit that "the annotation-level value takes precedence over the view-level default", and the serialization package honors this when the canonical property name is used — the annotation's value lives in .properties, which Annotation.getitem checks before any distributed contains default.
However, when reading an older MMIF that carries the value under a deprecated property name (which the implementation aliases to the canonical name via _prop_aliases and _props_ephemeral for temporary storage for canonicalization),
|
view._parent_mmif = self |
|
# this dict will be populated with properties |
|
# that are not encoded in individual annotations objects themselves |
|
extrinsic_props = defaultdict(dict) |
|
for at_type, type_lv_props in view.metadata.contains.items(): |
|
for prop_key, prop_value in type_lv_props.items(): |
|
extrinsic_props[at_type][prop_key] = prop_value |
|
for ann in view.get_annotations(): |
|
## for "capital" Annotation properties |
|
# first add all extrinsic properties to the Annotation objects |
|
# as "ephemeral" properties |
|
for prop_key, prop_value in extrinsic_props[ann.at_type].items(): |
|
ann._props_ephemeral[prop_key] = prop_value |
|
# then, do the same to associated Document objects. Note that, |
|
# in a view, it is guaranteed that all Annotation objects are not duplicates |
|
if ann.at_type == AnnotationTypes.Annotation: |
|
doc_id = ann.get_property('document') |
|
try: |
|
for prop_key, prop_value in ann.properties.items(): |
|
doc = cast(Document, self.__getitem__(doc_id)) |
|
if not isinstance(doc, Document): |
|
raise KeyError |
|
doc._props_ephemeral[prop_key] = prop_value |
the common-prop distribution step writes the "view-level default" value into that same temporary dict and hinders the canonicalization step, resulting in loss of the aliased (annotation-level) prop value. Namely the overwrite priority works in reverse.
Reproduction steps
For example,
{
"metadata": { "mmif": "http://mmif.clams.ai/1.2.0" },
"documents": [
{ "@type": "http://mmif.clams.ai/vocabulary/VideoDocument/v1",
"properties": { "id": "m1", "mime": "video/mp4", "location": "file:///v.mp4" } }
],
"views": [
{ "id": "v1",
"metadata": {
"app": "http://example.com/app/1.0",
"contains": {
"http://mmif.clams.ai/vocabulary/TimeFrame/v6": { "document": "m1", "label": "credits" }
}
},
"annotations": [
{ "@type": "http://mmif.clams.ai/vocabulary/TimeFrame/v6",
"properties": { "id": "v1:tf1", "start": 0, "end": 100, "frameType": "bars" } }
]
}
]
}
After reading this MMIF,
m = Mmif(in_str)
print(m.get('v1:tf1').get('label'))
# "credits", not "bars"
### Expected behavior
_No response_
### Log output
```shell
Screenshots
No response
Additional context
this was found while working on #393
Bug Description
The MMIF spec is explicit that "the annotation-level value takes precedence over the view-level default", and the serialization package honors this when the canonical property name is used — the annotation's value lives in .properties, which Annotation.getitem checks before any distributed contains default.
However, when reading an older MMIF that carries the value under a deprecated property name (which the implementation aliases to the canonical name via
_prop_aliasesand_props_ephemeralfor temporary storage for canonicalization),mmif-python/mmif/serialize/mmif.py
Lines 254 to 276 in 12d5c6a
the common-prop distribution step writes the "view-level default" value into that same temporary dict and hinders the canonicalization step, resulting in loss of the aliased (annotation-level) prop value. Namely the overwrite priority works in reverse.
Reproduction steps
For example,
{ "metadata": { "mmif": "http://mmif.clams.ai/1.2.0" }, "documents": [ { "@type": "http://mmif.clams.ai/vocabulary/VideoDocument/v1", "properties": { "id": "m1", "mime": "video/mp4", "location": "file:///v.mp4" } } ], "views": [ { "id": "v1", "metadata": { "app": "http://example.com/app/1.0", "contains": { "http://mmif.clams.ai/vocabulary/TimeFrame/v6": { "document": "m1", "label": "credits" } } }, "annotations": [ { "@type": "http://mmif.clams.ai/vocabulary/TimeFrame/v6", "properties": { "id": "v1:tf1", "start": 0, "end": 100, "frameType": "bars" } } ] } ] }After reading this MMIF,
Screenshots
No response
Additional context
this was found while working on #393