mirror of https://github.com/tiangolo/fastapi.git
🐛 Avoid accessing non-existing "$ref" key for Pydantic v2 compat remapping (#14361)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
parent
74b4c3c9a1
commit
8f99a2b734
|
|
@ -304,7 +304,7 @@ def _remap_definitions_and_field_mappings(
|
||||||
old_name_to_new_name_map = {}
|
old_name_to_new_name_map = {}
|
||||||
for field_key, schema in field_mapping.items():
|
for field_key, schema in field_mapping.items():
|
||||||
model = field_key[0].type_
|
model = field_key[0].type_
|
||||||
if model not in model_name_map:
|
if model not in model_name_map or "$ref" not in schema:
|
||||||
continue
|
continue
|
||||||
new_name = model_name_map[model]
|
new_name = model_name_map[model]
|
||||||
old_name = schema["$ref"].split("/")[-1]
|
old_name = schema["$ref"].split("/")[-1]
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,92 @@
|
||||||
|
import pytest
|
||||||
|
from fastapi import FastAPI
|
||||||
|
from fastapi.testclient import TestClient
|
||||||
|
from inline_snapshot import snapshot
|
||||||
|
from pydantic import BaseModel
|
||||||
|
|
||||||
|
from tests.utils import needs_py310, needs_pydanticv2
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(name="client")
|
||||||
|
def get_client():
|
||||||
|
from enum import Enum
|
||||||
|
|
||||||
|
app = FastAPI()
|
||||||
|
|
||||||
|
class PlatformRole(str, Enum):
|
||||||
|
admin = "admin"
|
||||||
|
user = "user"
|
||||||
|
|
||||||
|
class OtherRole(str, Enum): ...
|
||||||
|
|
||||||
|
class User(BaseModel):
|
||||||
|
username: str
|
||||||
|
role: PlatformRole | OtherRole
|
||||||
|
|
||||||
|
@app.get("/users")
|
||||||
|
async def get_user() -> User:
|
||||||
|
return {"username": "alice", "role": "admin"}
|
||||||
|
|
||||||
|
client = TestClient(app)
|
||||||
|
return client
|
||||||
|
|
||||||
|
|
||||||
|
@needs_py310
|
||||||
|
@needs_pydanticv2
|
||||||
|
def test_get(client: TestClient):
|
||||||
|
response = client.get("/users")
|
||||||
|
assert response.json() == {"username": "alice", "role": "admin"}
|
||||||
|
|
||||||
|
|
||||||
|
@needs_py310
|
||||||
|
@needs_pydanticv2
|
||||||
|
def test_openapi_schema(client: TestClient):
|
||||||
|
response = client.get("openapi.json")
|
||||||
|
assert response.json() == snapshot(
|
||||||
|
{
|
||||||
|
"openapi": "3.1.0",
|
||||||
|
"info": {"title": "FastAPI", "version": "0.1.0"},
|
||||||
|
"paths": {
|
||||||
|
"/users": {
|
||||||
|
"get": {
|
||||||
|
"summary": "Get User",
|
||||||
|
"operationId": "get_user_users_get",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Successful Response",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {"$ref": "#/components/schemas/User"}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"schemas": {
|
||||||
|
"PlatformRole": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["admin", "user"],
|
||||||
|
"title": "PlatformRole",
|
||||||
|
},
|
||||||
|
"User": {
|
||||||
|
"properties": {
|
||||||
|
"username": {"type": "string", "title": "Username"},
|
||||||
|
"role": {
|
||||||
|
"anyOf": [
|
||||||
|
{"$ref": "#/components/schemas/PlatformRole"},
|
||||||
|
{"enum": [], "title": "OtherRole"},
|
||||||
|
],
|
||||||
|
"title": "Role",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"type": "object",
|
||||||
|
"required": ["username", "role"],
|
||||||
|
"title": "User",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
Loading…
Reference in New Issue