Skip to content

Ossie->Honeydew converter ignores a field's explicit datatype #411

Description

@christianeu-db

Summary

As of @ fc6c9df, _ossie_field_to_honeydew_datatype derives the Honeydew type only from the shape of dimension; it never reads the spec datatype. So a Date becomes number and a Boolean becomes string, even though Honeydew has date and bool. The declared type has zero effect on the output.

Root cause

def _ossie_field_to_honeydew_datatype(field: dict[str, Any]) -> str:
    hd_ext = _get_honeydew_extension(field)
    if hd_ext.get("datatype"):            # honeydew round-trip extension only
        return hd_ext["datatype"]
    dimension = field.get("dimension")
    if isinstance(dimension, dict) and dimension.get("is_time"):
        return "timestamp"
    if dimension is not None:
        return "string"
    return "number"                       # field["datatype"] is never read

The function gets the whole field but consults only the Honeydew extension and dimension. The spec enum is ignored.

Why it survived (and why it's a bug, not a design choice)

The heuristic and the README line "Ossie fields have no explicit datatype" were written in the converter's first commit (2026-05-27), when the spec had no datatype field. The datatype enum was added later, in #113 (2026-07-23).

Repro (against the real converter at HEAD)

import sys, types
sys.modules.setdefault("yaml", types.ModuleType("yaml"))   # module imports yaml at load; env is offline
from ossie_honeydew.converter import _ossie_field_to_honeydew_datatype as to_hd

for dt, want in [("Boolean", "bool"), ("Integer", "number"), ("Date", "date")]:
    got = to_hd({"name": "f", "datatype": dt})
    print(f"{dt:8} -> {got:8} (want {want}) [{'OK' if got == want else 'BUG'}]")
# Boolean  -> number   (want bool)   [BUG]
# Integer  -> number   (want number) [BUG]   <- 'right' only by coincidence
# Date     -> number   (want date)   [BUG]

# Proof datatype is never read: hold the dimension fixed, vary datatype -> identical output
print({dt: to_hd({"datatype": dt, "dimension": {"is_time": False}})
       for dt in ("Date", "Boolean", "Integer", "Float", "String")})
# {'Date': 'string', 'Boolean': 'string', 'Integer': 'string', 'Float': 'string', 'String': 'string'}

Suggested fix

Map the spec datatype before the heuristic; keep the heuristic only when datatype is absent or Opaque. Target vocabulary matches what the reverse path already accepts:

OSSIE_TO_HONEYDEW = {
    "String": "string", "Integer": "number", "Decimal": "number", "Float": "number",
    "Boolean": "bool", "Date": "date", "Time": "time",
    "DateTime": "timestamp", "DateTimeTz": "timestamp",
}
# after the hd_ext short-circuit:
dt = field.get("datatype")
if dt in OSSIE_TO_HONEYDEW:
    return OSSIE_TO_HONEYDEW[dt]
# else fall through to the existing dimension heuristic

Also fix the now-false README limitation (which says Ossie doesn't have data types) and add tests for Boolean/Integer/Float/Date/DateTime:

assert _ossie_field_to_honeydew_datatype({"datatype": "Date"}) == "date"   # currently 'number'

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions