fix(python): serialize unrecognized open enum values

2Y
5h ago
+116-6

Why

UnrecognizedStr and UnrecognizedInt hold values of open enums (x-speakeasy-unknown-values: allow) that the SDK does not know. They had no serialization schema, so:

  • dumping a model holding an unknown enum value emitted Pydantic serialization warnings;
  • in an optional nullable open enum field, the unknown value was serialized by the Unset member of the union and then dropped: {"stringOrNull": "future"} was sent as {}.

This affects every Python SDK with open enums and needs no configuration.

What changed

  • Give both types an explicit serializer:
    • Python-mode dumps return the original object, so type(...) is UnrecognizedStr still holds;
    • JSON-mode dumps return a plain str or int;
    • values of another type raise PydanticSerializationUnexpectedValue, so union serialization moves on to the remaining members.
  • Add the open-enum-scalar-unions primary fragment: an open string or integer enum combined with number, boolean or null. The number and boolean cases guard that values of other types still keep their JSON type now that the enum types serialize themselves.
  • Review SDK: only types/basemodel.py changes.

Stack

  1. This PR: unrecognized enum serialization
  2. #149: honour include/exclude filters in model dumps
  3. #146: preserveUnknownFields
  4. #147: modelSerializationMethods

Together these contain the change from #133, split into two fixes and two independent options.

Testing

  • TARGET=primary make test-pythonv2: 679 passed, including the new open-enum cases with warnings raised as errors.
  • With the previous basemodel.py, the unknown-value cases fail: two on warnings, and stringOrNull serializes to {}.
  • TARGET=review make build-pythonv2: integrity validation passes; only types/basemodel.py and gen.lock change.
  • git diff --check passes.

Public-safety check

  • This change contains no credentials, customer documents, private repository URLs, private filesystem paths, or unredacted private logs.
  • Title, body, comments, and commit messages name no customers or customer-derived identifiers, private paths or trackers, or workflow provenance, and are understandable without private context (.claude/skills/public-repo-communication/SKILL.md).
  • Generated fixtures and review SDK changes are public-safe.
  • I reviewed git diff --check.