Skip to content

DID-python: _get_superclass_str should handle bare dict superclasses #52

Description

@stevevanhooser

Summary

_get_superclass_str() in DID-python's doc2sql.py does not handle document_class.superclasses when it is a bare dict instead of a list. This causes meta.superclass to be stored as empty string in the doc_data table, which makes isa() queries miss documents.

Root cause

MATLAB's jsonencode unwraps single-element cell arrays to scalars. Documents with only one superclass (e.g. just base) arrive from the cloud with superclasses as a bare dict:

"superclasses": {"definition": "$NDIDOCUMENTPATH/base.json"}

instead of the expected list form:

"superclasses": [{"definition": "$NDIDOCUMENTPATH/base.json"}]

In _get_superclass_str(), the document_class.superclasses path (line 72-84) only handles lists:

superclasses = get_field(doc_props, ["document_class.superclasses"])
if isinstance(superclasses, list):   # <-- bare dict falls through here
    ...
return ""  # <-- returns empty string

Documents with multiple superclasses are unaffected because MATLAB keeps multi-element arrays as arrays.

Impact

In a test dataset with 7221 documents, 98 had only base as a superclass. All 98 were stored with empty meta.superclass, causing isa('base') to miss them entirely.

Suggested fix

In _get_superclass_str(), handle a bare dict the same way as a single-element list, for both the top-level superclasses check and the document_class.superclasses check:

# After getting superclasses from document_class
if isinstance(superclasses, dict):
    superclasses = [superclasses]
if isinstance(superclasses, list):
    # ... existing list handling code

Workaround

NDI-python PR #50 adds normalization in ndi_document._normalize_depends_on() to wrap bare dict superclasses into a list before it reaches DID-python. This fixes the issue at the NDI layer, but DID-python should also be robust to this input independently.

Reproduction

from did.implementations.doc2sql import _get_superclass_str

# Works (list)
props = {'document_class': {'superclasses': [{'definition': '$NDIDOCUMENTPATH/base.json'}]}}
assert _get_superclass_str(props) == 'base'

# Fails (bare dict from MATLAB)
props = {'document_class': {'superclasses': {'definition': '$NDIDOCUMENTPATH/base.json'}}}
assert _get_superclass_str(props) == 'base'  # Returns '' instead

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions