Skip to content

Commit 2ec6e2c

Browse files
authored
Fix namespace subnamespace reference resolution in OpenAPI generation (#2580)
1 parent 81ef088 commit 2ec6e2c

6 files changed

Lines changed: 76 additions & 1 deletion

File tree

src/datamodel_code_generator/parser/base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -815,7 +815,7 @@ def __change_from_import(
815815
if from_ and import_ and alias != name:
816816
data_type.alias = alias if data_type.reference.short_name == import_ else f"{alias}.{name}"
817817

818-
if init:
818+
if init and not data_type.full_name.startswith(model.module_name + "."):
819819
from_ = "." + from_
820820
imports.append(
821821
Import(
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# generated by datamodel-codegen:
2+
# filename: namespace_subns_ref.json
3+
# timestamp: 1985-10-26T08:21:00+00:00
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# generated by datamodel-codegen:
2+
# filename: namespace_subns_ref.json
3+
# timestamp: 1985-10-26T08:21:00+00:00
4+
5+
from __future__ import annotations
6+
7+
from typing import Optional
8+
9+
from pydantic import BaseModel
10+
11+
from . import subns
12+
13+
14+
class Wrapper(BaseModel):
15+
item: Optional[subns.Item] = None
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# generated by datamodel-codegen:
2+
# filename: namespace_subns_ref.json
3+
# timestamp: 1985-10-26T08:21:00+00:00
4+
5+
from __future__ import annotations
6+
7+
from typing import Optional
8+
9+
from pydantic import BaseModel
10+
11+
12+
class Item(BaseModel):
13+
name: Optional[str] = None
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"openapi": "3.0.1",
3+
"info": {
4+
"title": "Test API",
5+
"version": "1.0.0"
6+
},
7+
"paths": {},
8+
"components": {
9+
"schemas": {
10+
"ns.wrapper": {
11+
"type": "object",
12+
"properties": {
13+
"item": {
14+
"$ref": "#/components/schemas/ns.subns.item"
15+
}
16+
}
17+
},
18+
"ns.subns.item": {
19+
"type": "object",
20+
"properties": {
21+
"name": {
22+
"type": "string"
23+
}
24+
}
25+
}
26+
}
27+
}
28+
}

tests/main/openapi/test_main_openapi.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2401,3 +2401,19 @@ def test_main_openapi_external_ref_with_transitive_local_ref(output_file: Path)
24012401
expected_file="external_ref_with_transitive_local_ref/output.py",
24022402
extra_args=["--output-model-type", "pydantic_v2.BaseModel"],
24032403
)
2404+
2405+
2406+
def test_main_openapi_namespace_subns_ref(output_dir: Path) -> None:
2407+
"""Test OpenAPI generation with namespaced schema referencing subnamespace.
2408+
2409+
Regression test for issue #2366: When a schema with a dot-delimited name
2410+
(e.g., ns.wrapper) references another schema in a subnamespace
2411+
(e.g., ns.subns.item), the generated import should be "from . import subns"
2412+
(same package) instead of "from .. import subns" (parent package).
2413+
"""
2414+
with freeze_time(TIMESTAMP):
2415+
run_main_and_assert(
2416+
input_path=OPEN_API_DATA_PATH / "namespace_subns_ref.json",
2417+
output_path=output_dir,
2418+
expected_directory=EXPECTED_OPENAPI_PATH / "namespace_subns_ref",
2419+
)

0 commit comments

Comments
 (0)