Skip to content

fix(python): accept only booleans for is_time, as the schema does - #557

Merged
jbonofre merged 1 commit into
apache:mainfrom
ayushtkn:fix/python-is-time-strict-bool
Oct 11, 2026
Merged

jbonofre merged 1 commit into
apache:mainfrom
ayushtkn:fix/python-is-time-strict-bool

Conversation

@ayushtkn

Copy link
Copy Markdown
Member

Summary

ossie-schema.json types $defs.Dimension.properties.is_time as "boolean", but the
field was a plain Optional[bool], so pydantic's lax mode accepted ten values the
schema forbids:

"yes" "true" "True" "no" "off" "1" 1 0 1.0 0.0

The harm is not bad output — it's a lost diagnostic. Coercion stores a real boolean, so
the invalid input is rewritten into valid output and the mistake disappears:

in='yes' -> stored True -> serialized {"is_time": true} -> schema accepts output: True
schema accepts the INPUT 'yes': False

A document written with is_time: "no" is wrong per the spec, and the SDK is the only
place that could say so. It instead turns it into false and a later schema check passes.

StrictBool narrows the field to the two values the schema permits.

is_time is the only "type": "boolean" in the schema and the only bool field in the
SDK, so this is the whole of the change.

Related Issues

Checklist

Specification

  • Spec changes are included in core-spec/ and follow the existing structure
  • Spec changes have been discussed on the mailing list or in a linked issue
  • Breaking changes to the spec are clearly called out in the summary

Ontology

  • Ontology changes in ontology/ are consistent with spec changes
  • New or modified terms are defined and documented

Converters

  • Converter logic in converters/ is updated to reflect spec or ontology changes
  • New converters include tests under the converter's test directory
  • If adding a new converter, .github/labeler.yml is updated with the new path

Validation

  • Validation rules in validation/ are updated if the spec changed
  • New validation cases are covered by tests

Documentation

  • docs/ is updated to reflect any user-facing changes
  • New features or behaviors are documented with examples where appropriate
  • CONTRIBUTING.md is updated if the contribution process changed

Examples

  • examples/ are added or updated for any new spec constructs or converter support

Tests

  • All existing tests pass (pytest / CI green)
  • New functionality is covered by tests

Compliance

  • ASF license headers are present on all new source files
  • No third-party dependencies are added without PMC/IPMC approval
  • If third-party source code is vendored/copied (not just declared as a dependency), NOTICE and/or LICENSE have been updated per ASF policy

The schema types `Dimension.is_time` as `boolean`, but the field was a plain
`Optional[bool]`, so pydantic's lax mode coerced "yes", "true", "True", "no",
"off", "1", 1, 0, 1.0 and 0.0. The package accepted all ten, none of which the
schema allows, and serialized them back as `true` or `false`.

`StrictBool` narrows the field to the two values the schema permits. YAML input
is unaffected, because PyYAML resolves `yes` and `on` to real booleans before
the model sees them, and every `is_time` value in the repository is already a
boolean literal or absent.
Copilot AI balanced review requested due to automatic review settings October 10, 2026 19:20

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Explicit null remains accepted despite being invalid under the schema.

1 open finding
What changed in this PR

Aligns Python validation of is_time with the OSSIE boolean schema.

Changes:

  • Uses StrictBool to prevent coercion.
  • Adds acceptance and rejection tests.
File Description
python/​src/​ossie/​models.py Enforces strict boolean validation.
python/​tests/​test_models.py Tests strict is_time inputs and omission.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

# `bool` would let pydantic's lax mode accept "yes", "1", 1 or 1.0 and store a
# real boolean, so input the schema forbids is silently rewritten into output it
# allows, and the mistake is never reported.
is_time: Optional[StrictBool] = None

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct on the mechanics, and the laundering is the same shape: {"is_time": null} is schema-invalid, the model accepts it, and exclude_none=True drops the key so the output validates.

I'd rather not fix it in this PR, because it isn't specific to is_time. ossie-schema.json permits null for no property anywhere, and all 27 Optional[...] fields in the SDK accept an explicit null and serialize it away — OssieField.model_validate({..., "label": None, "description": None, "datatype": None}) succeeds today and emits a document with those keys simply absent.

The two problems differ in kind. Lax coercion is per-field and per-type, and StrictBool fixes it; this PR applies that to the only "type": "boolean" in the schema. Explicit-null acceptance follows from Optional[X] = None being how pydantic spells "optional", so it is uniform across the models by construction. Patching it on is_time alone would leave the other 26 unchanged and introduce a one-off idiom the next reader would reasonably question.

Doing it properly means deciding whether the SDK distinguishes an absent key from an explicit null across all 10 models — a behaviour change for any caller currently passing label=None. Nothing in this repository does (I checked every Ossie*(...) construction), but that is a decision worth its own PR and review rather than a rider on this one. I'll open it as a follow-up unless a reviewer would rather keep absent and null interchangeable.

@jbonofre jbonofre left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Switching OssieDimension.is_time to Optional[StrictBool] stops pydantic from coercing "yes", 1 and 1.0 into a real boolean 😄
That matches the strictness fixes in #551 and #552.

Two comments:

  • models that currently set is_time to a string or number, such as "true" or 1, will now fail validation. That's the point of the change, but I wanted to mention 😄
  • Optional[StrictBool] still accepts an explicit null, while the test docstring says null is not schema-legal. The field could be updated (nit).

@jbonofre
jbonofre merged commit 0579b9f into apache:main Oct 11, 2026
32 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants