[python] Deserialize Optional[...] response types

Merged
HD
2mo ago
+107-0

Fixes #24712

Problem

ApiClient.__deserialize parses only List[...], Dict[...] and native type names. The generator fills _response_types_map from the response annotation, so a nullable response emits "Dict[str, Optional[object]]", which falls through to getattr(models, "Optional[object]") and makes every successful response raise AttributeError.

Change

Unwrap Optional[...] before the existing rules. data is None has already returned above, so the inner type determines the result.

Verification

  • Issue repro spec: AttributeError before, {'a': 1} after.
  • 4 tests added to the python sample; 3 fail on master.
  • pytest tests/: 155 passed. The 12 failures need the live petstore server, same on master.
  • mvn test -Dtest='Python*Test': 102 passed.

/cc @cbornet @tomplus @krjakbrjak @fa0311


Summary by cubic

Deserializes Python Optional[...] response types by unwrapping to the inner type, so nullable responses no longer raise AttributeError. Old: ApiClient.__deserialize treated Optional[...] as a model and failed. New: it detects and unwraps Optional[...] before existing List[...]/Dict[...] rules; None still returns None. Fixes #24712.

Review notes

  • Changes are in modules/openapi-generator/src/main/resources/python/api_client.mustache; regenerated sample clients mirror the update.
  • Adds tests for Optional[Pet], Optional[List[str]], and Dict[str, Optional[object]]; local suites pass, petstore live-server failures match master.
  • No migration actions; generated Python clients now correctly deserialize nullable responses.