Skip to content

[python] fix: additionalProperties:true schema inherits object instead of BaseModel (#20153)#23862

Open
Shaun-3adesign wants to merge 3 commits into
OpenAPITools:masterfrom
Shaun-3adesign:fix/python-fastapi-additionalproperties-true-parent
Open

[python] fix: additionalProperties:true schema inherits object instead of BaseModel (#20153)#23862
Shaun-3adesign wants to merge 3 commits into
OpenAPITools:masterfrom
Shaun-3adesign:fix/python-fastapi-additionalproperties-true-parent

Conversation

@Shaun-3adesign
Copy link
Copy Markdown

@Shaun-3adesign Shaun-3adesign commented May 23, 2026

Fixes #20153

Schemas that declare additionalProperties: true alongside named properties were generating broken Python FastAPI (and Connexion) output — an invalid import and the wrong base class:

# Before (broken)
from openapi_server.models.object import object   # invalid — module does not exist

class HttpRequest(object):                        # wrong — should be BaseModel
    ...
# After (fixed)
from pydantic import BaseModel

class HttpRequest(BaseModel):                     # correct base class
    additional_properties: Dict[str, Any] = {}    # correct additional-props field
    ...

Root cause: ModelUtils.isMapSchema() returns true for any schema whose additionalProperties is the boolean true, even when the schema also has named properties. This caused DefaultCodegen.updateModelForObject() to call addAdditionPropertiesToCodeGenModel()addParentContainer()addParentFromContainer(), setting model.parent = toInstantiationType(schema). For additionalProperties: true, getSchemaType(new Schema()) returns "object", so model.parent becomes Python's built-in type name. AbstractPythonCodegen.postProcessAllModels() then adds it to imports, producing the invalid from openapi_server.models.object import object.

PythonClientCodegen already had a correct override that avoided this, but PythonFastAPIServerCodegen and AbstractPythonConnexionServerCodegen did not.

Fix: Move the correct addAdditionPropertiesToCodeGenModel() override from PythonClientCodegen up to AbstractPythonCodegen. All Python generators now share the same implementation: only additionalPropertiesType is set (used for typing in templates), and model.parent is left null so the template correctly falls back to BaseModel. The now-redundant override in PythonClientCodegen is removed along with the two unused imports it left behind.

PR checklist

  • Read the contribution guidelines.
  • Pull Request title clearly describes the work in the pull request and Pull Request description provides details about how to validate the work. Missing information here may result in delayed response from the community.
  • Run the following to build the project and update samples:
    ./mvnw clean package || exit
    ./bin/generate-samples.sh ./bin/configs/*.yaml || exit
    ./bin/utils/export_docs_generators.sh || exit
    
    Commit all changed files.
    This is important, as CI jobs will verify all generator outputs of your HEAD commit as it would merge with master.
    These must match the expectations made by your contribution.
    You may regenerate an individual generator by passing the relevant config(s) as an argument to the script, for example ./bin/generate-samples.sh bin/configs/java*.
    IMPORTANT: Do NOT purge/delete any folders/files (e.g. tests) when regenerating the samples as manually written tests may be removed.
  • File the PR against the correct branch: master (upcoming 7.x.0 minor release - breaking changes with fallbacks), 8.0.x (breaking changes without fallbacks)
  • If your PR solves a reported issue, reference it using GitHub's linking syntax (e.g., having "fixes #123" present in the PR description)
  • If your PR is targeting a particular programming language, @mention the technical committee members, so they are more likely to review the pull request.

Summary by cubic

Fixes #20153. Python FastAPI and Connexion now generate correct models for schemas with additionalProperties: true: classes inherit BaseModel and no invalid object import is emitted.

  • Bug Fixes
    • Moved addAdditionPropertiesToCodeGenModel to AbstractPythonCodegen; only set additionalPropertiesType and leave model.parent unset to fall back to BaseModel.
    • Removed the duplicate override from PythonClientCodegen.
    • Added a regression test (issue_20153.yaml) verifying class HttpRequest(BaseModel), presence of additional_properties, and absence of from openapi_server.models.object import object.
    • Re-generated Python client petstore samples with a fresh build to restore UploadFileWithAdditionalPropertiesRequestObject exports and correct type hints across six Python client samples.

Written for commit a66eea0. Summary will update on new commits. Review in cubic

…del not object (fixes OpenAPITools#20153)

Root cause:

ModelUtils.isMapSchema() returns true for any schema whose additionalProperties is the boolean
true, including schemas that also have named properties (e.g. the BBC TAMS http-request.json
schema). This caused DefaultCodegen.updateModelForObject() to call
addAdditionPropertiesToCodeGenModel() → addParentContainer() → addParentFromContainer(), setting
model.parent = toInstantiationType(schema).

For additionalProperties:true (a Boolean), ModelUtils.getAdditionalProperties() returns a new
empty Schema, and getSchemaType(new Schema()) returns "object" — Python's built-in type name.

In AbstractPythonCodegen.postProcessAllModels():
  if (!StringUtils.isEmpty(model.parent)) {
      modelImports.add(model.parent);  // adds "object" → invalid import
  }

The mustache template then generates:
  from openapi_server.models.object import object   ← invalid (module does not exist)
  class HTTPRequest(object):                        ← wrong (should be BaseModel)

PythonClientCodegen already had a correct override that avoided this, but
PythonFastAPIServerCodegen and AbstractPythonConnexionServerCodegen did not — they fell
through to the broken DefaultCodegen implementation.

Fix:

Move the correct addAdditionPropertiesToCodeGenModel() override up from PythonClientCodegen to
AbstractPythonCodegen. All Python generators (python-fastapi, python-flask, python-client) now
share the same implementation: only additionalPropertiesType is set (used for typing in
templates), and model.parent is left null so the template correctly falls back to BaseModel.

Remove the now-redundant override from PythonClientCodegen and clean up the two unused imports
(Schema, ModelUtils) it left behind.

Test:

Add a regression test testAdditionalPropertiesTrueUsesBaseModel in
PythonFastAPIServerCodegenTest backed by a new fixture
src/test/resources/bugs/issue_20153.yaml. The fixture models the BBC TAMS http-request.json
schema (a typed object with named properties and additionalProperties:true) and asserts:
  - class HttpRequest(BaseModel): is present (correct base class)
  - additional_properties: Dict[str, Any] = {} is present (correct additional-props field)
  - from openapi_server.models.object import object is absent (no invalid import)
Removes stale UploadFileWithAdditionalPropertiesRequestObject from all
six Python client petstore samples (python, python-aiohttp, python-httpx,
python-lazyImports, python-pydantic-v1, python-pydantic-v1-aiohttp).

The model no longer exists in the petstore spec — the uploadFileWithAdditionalProperties
endpoint's inline object schema is structurally identical to the one used by
testObjectForMultipartRequests, so the generator resolves both to
TestObjectForMultipartRequestsRequestMarker. The samples were out of date
due to a prior spec edit that was not followed by a full regeneration.

Not caused by the additionalProperties:true BaseModel fix — python-fastapi
samples are unchanged.
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 41 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

…AdditionalPropertiesRequestObject

The previous regeneration commit (24025ec) was produced with a stale
JAR (built at 12:20 before the AbstractPythonCodegen fix landed at 21:29).
That stale generator incorrectly deduped the inline `object` schema in the
`uploadFileWithAdditionalProperties` endpoint with the structurally
identical `marker` schema from `testObjectForMultipartRequests`, resolving
both to TestObjectForMultipartRequestsRequestMarker.  This caused a P1
regression:

- UploadFileWithAdditionalPropertiesRequestObject was removed from the
  top-level petstore_api/__init__.py exports in all six Python samples,
  breaking the runtime import used by tests/test_rest.py:44 which calls
  petstore_api.UploadFileWithAdditionalPropertiesRequestObject().
- fake_api.py incorrectly typed the `object` parameter of
  upload_file_with_additional_properties as TestObjectForMultipartRequestsRequestMarker
  instead of the correct UploadFileWithAdditionalPropertiesRequestObject.
- FILES manifests and README model listings were missing the model.

Fix: rebuild the generator JAR from the current branch code using
  docker run maven:3-eclipse-temurin-17 mvn clean package -DskipTests=true
then re-run bin/generate-samples.sh for the six affected configs:
  python, python-aiohttp, python-httpx, python-lazyImports,
  python-pydantic-v1, python-pydantic-v1-aiohttp

The fresh generation correctly emits UploadFileWithAdditionalPropertiesRequestObject
as a distinct model for the upload endpoint's inline object schema, restoring
the exports, correct type annotations, docs, and FILES entries across all six
samples.

Affected files per sample (×6):
  .openapi-generator/FILES  — model file entry restored
  README.md                 — model added back to model listing
  docs/FakeApi.md           — upload endpoint docs show correct type
  petstore_api/__init__.py  — export restored (2 lines: __all__ + import)
  petstore_api/api/fake_api.py — correct UploadFileWithAdditionalPropertiesRequestObject type
  petstore_api/models/__init__.py — model import restored
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.

[BUG][Python] python-fastapi 7.9.0 generates wrong imports

1 participant