[python] support legacy model dictionaries
The removed python-legacy generator exposed to_dict() as a
public dictionary API: every declared field, normalized Python names
by default, and wire names with serialize=True. The current Python
generator instead uses to_dict() for its transport projection, so
replacing that behavior directly would also change JSON and request
payloads.
The design discussion accepted a default-off compatibility boundary and
requested the broader option name:
https://github.com/OpenAPITools/openapi-generator/issues/24125
Add compatibleWithPythonLegacy as that default-off switch. Ordinary
fields keep the normalized Python constructor names used by
python-legacy while still accepting wire names. Explicit
nameMappings keep their requested public names. to_dict() uses
public names by default and wire names with serialize=True, while
to_json() and ApiClient retain the current transport projection.
Preserve custom and inherited to_dict() methods, composed-model
wrappers, and model-only generation. Match python-legacy one-level
conversion of list elements and dictionary values rather than
recursively converting nested containers.
Render the compatibility helpers in each model because model-only
generation does not emit a shared support module. Add a dedicated
generated sample for generic, inherited, oneOf, anyOf, nullable,
defaulted, read-only, nested-container, and additional-property
behavior.
Closes #24125.
Summary by cubic
Adds an opt-in compatibleWithPythonLegacy option to restore the python-legacy public to_dict() behavior without changing JSON or request serialization. Updates models (including oneOf/anyOf/generics) and ApiClient to separate legacy dictionaries from transport projections, with docs, tests, and a CI-backed sample.
-
New Features
- Adds
compatibleWithPythonLegacy(default false) to restore legacy public dictionary semantics. - Field aliases use normalized Python constructor names; wire names are accepted; explicit
nameMappingsare respected. to_dict()emits all declared fields (uses None for missing), public names by default and wire names withserialize=True; shallow container conversion; supportsoneOf/anyOf/generics; preserves custom/inheritedto_dict(); helpers rendered per model.to_json()andApiClientdetect generated models and keep the modern transport projection; adds a dedicated sample with runtime tests and CI across Python 3.10–3.14; docs updated.
- Adds
-
Migration
- No behavior change by default.
- To enable, set
additionalProperties.compatibleWithPythonLegacy: "true"in your generator config (seebin/configs/python-legacy-model-dictionaries.yaml).