torchcell.datamodels.schema.ProvenanceGapMixin
- class ProvenanceGapMixin(*, provenance_gaps: list[~torchcell.verification.sourced.ProvenanceGap] = <factory>)[source]
Bases:
ModelStrictMixin giving a model a
provenance_gapslist of typed field-absences.Shared by
Phenotype,Environment, andCompoundso a field the source does not carry – a phenotypen_samplesa secondary curation layer dropped, an environmenttemperatureYeastPhenome never recorded, a compoundinchikeyno resolver could map – is a documented, typed ABSENCE (with a reason +looked_in) rather than a guess or a silent None. Two invariants keep it honest and machine-checkable: (1) eachgap.fieldnames a real field on the concrete model (checked againstmodel_fields, so inherited fields resolve too); (2) a gapped field must beNone– you cannot both store a value and declare it missing.provenance_gapsitself cannot be gapped.#753 adds the PER-KEY form of invariant (2). A dict-valued field that is sourced for some keys and unsourced for others (Rapp 2026’s
target_metabolite_ids: 1,077 features with a sourced identity, 244 merged isobaric features with 2 to 11 candidates each and no sourced pick) cannot beNone, so the whole-field rule refused the gap and the 244 keys had to live outside the record. A gap that nameskeysis admitted beside a populated mapping, on the strictly stronger condition that the mapping does NOT carry any of those keys: storing a value and declaring it missing is still refused, now key by key.- validate_provenance_gaps() ProvenanceGapMixin[source]
Each ProvenanceGap must name a real field on this model, and that field must be None (you cannot both store a value and declare it missing).
- model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'frozen': True}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].