Skip to content

Commit 8f78a9b

Browse files
authored
Fix transitive local reference resolution in external schema files (#2577)
* Add Feedback API schema and models for feedback items * Fix transitive local reference resolution in test input type
1 parent 48ae05b commit 8f78a9b

6 files changed

Lines changed: 104 additions & 1 deletion

File tree

src/datamodel_code_generator/parser/jsonschema.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1914,7 +1914,7 @@ def _parse_file(
19141914
reserved_refs = set(self.reserved_refs.get(key) or [])
19151915
while reserved_refs:
19161916
for reserved_path in sorted(reserved_refs):
1917-
reference = self.model_resolver.get(reserved_path)
1917+
reference = self.model_resolver.references.get(reserved_path)
19181918
if not reference or reference.loaded:
19191919
continue
19201920
object_paths = reserved_path.split("#/", 1)[-1].split("/")
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# generated by datamodel-codegen:
2+
# filename: openapi.yaml
3+
# timestamp: 2019-07-26T00:00:00+00:00
4+
5+
from __future__ import annotations
6+
7+
from pydantic import AwareDatetime, BaseModel
8+
9+
10+
class FeedbackItemBase(BaseModel):
11+
id: int
12+
message: str
13+
14+
15+
class FeedbackItemCreate(FeedbackItemBase):
16+
user_id: int
17+
18+
19+
class FeedbackItem(FeedbackItemBase):
20+
created_at: AwareDatetime
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
openapi: 3.1.0
2+
info:
3+
title: Feedback API
4+
version: 1.0.0
5+
paths:
6+
/feedback:
7+
get:
8+
summary: Get all feedback items
9+
responses:
10+
'200':
11+
description: List of feedback items
12+
content:
13+
application/json:
14+
schema:
15+
type: array
16+
items:
17+
$ref: './schemas/feedback.yaml#/FeedbackItem'
18+
post:
19+
summary: Create a feedback item
20+
requestBody:
21+
required: true
22+
content:
23+
application/json:
24+
schema:
25+
$ref: './schemas/feedback.yaml#/FeedbackItemCreate'
26+
responses:
27+
'201':
28+
description: Created feedback item
29+
content:
30+
application/json:
31+
schema:
32+
$ref: './schemas/feedback.yaml#/FeedbackItem'
33+
components:
34+
schemas:
35+
FeedbackItem:
36+
$ref: './schemas/feedback.yaml#/FeedbackItem'
37+
FeedbackItemCreate:
38+
$ref: './schemas/feedback.yaml#/FeedbackItemCreate'
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
FeedbackItemBase:
2+
type: object
3+
properties:
4+
id:
5+
type: integer
6+
message:
7+
type: string
8+
required:
9+
- id
10+
- message
11+
12+
FeedbackItem:
13+
allOf:
14+
- $ref: '#/FeedbackItemBase'
15+
- type: object
16+
properties:
17+
created_at:
18+
type: string
19+
format: date-time
20+
required:
21+
- created_at
22+
23+
FeedbackItemCreate:
24+
allOf:
25+
- $ref: '#/FeedbackItemBase'
26+
- type: object
27+
properties:
28+
user_id:
29+
type: integer
30+
required:
31+
- user_id

tests/main/openapi/test_main_openapi.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2377,3 +2377,15 @@ def test_main_openapi_webhooks_with_parameters(output_file: Path) -> None:
23772377
assert_func=assert_file_content,
23782378
extra_args=["--openapi-scopes", "schemas", "webhooks", "parameters"],
23792379
)
2380+
2381+
2382+
def test_main_openapi_external_ref_with_transitive_local_ref(output_file: Path) -> None:
2383+
"""Test OpenAPI generation with external ref that has transitive local refs."""
2384+
run_main_and_assert(
2385+
input_path=OPEN_API_DATA_PATH / "external_ref_with_transitive_local_ref" / "openapi.yaml",
2386+
output_path=output_file,
2387+
input_file_type="openapi",
2388+
assert_func=assert_file_content,
2389+
expected_file="external_ref_with_transitive_local_ref/output.py",
2390+
extra_args=["--output-model-type", "pydantic_v2.BaseModel"],
2391+
)

tests/test_infer_input_type.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ def assert_invalid_infer_input_type(file: Path) -> None:
5353
continue
5454
if "reference_same_hierarchy_directory" in file.parts:
5555
continue
56+
if "external_ref_with_transitive_local_ref" in file.parts and file.name != "openapi.yaml":
57+
continue
5658
if file.name.endswith((
5759
"aliases.json",
5860
"extra_data.json",

0 commit comments

Comments
 (0)