Skip to content

Commit 05901ff

Browse files
ilovelinuxkoxudaxi
andauthored
Fix --base-class-map and --enum-field-as-literal-map long inline json support (#3075)
* Create test * Fix base-class-map and enum-field-as-literal-map long inline json support * Improve explanatory comment * Create test * Fix formatting --------- Co-authored-by: Antonio Spadaro <9268789+ilovelinux@users.noreply.github.com> Co-authored-by: Koudai Aono <koxudaxi@gmail.com>
1 parent 5ba49a7 commit 05901ff

2 files changed

Lines changed: 45 additions & 1 deletion

File tree

src/datamodel_code_generator/arguments.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,14 +88,26 @@ def _external_ref_mapping(value: str) -> str:
8888
def _json_value_or_file(value: str) -> dict[str, object]:
8989
"""Parse a JSON value or load it from a JSON file path."""
9090
path = Path(value).expanduser()
91-
if path.is_file():
91+
92+
# In Python<=3.13, long json values would cause `path.is_file()` to raise an OSError exception
93+
# because the string is too long to be interpreted as a filename.
94+
# This changed in Python>=3.14 since now `path.is_file()` catches OSError and returns `false` instead.
95+
# Therefore we are going to catch OSError exception raised in Python<=3.13 to replicate Python>=3.14 behavior.
96+
is_file: bool
97+
try:
98+
is_file = path.is_file()
99+
except OSError:
100+
is_file = False
101+
102+
if is_file:
92103
try:
93104
json_input = path.read_text(encoding=DEFAULT_ENCODING)
94105
except (OSError, UnicodeDecodeError) as e:
95106
msg = f"Unable to read JSON file {value!r}: {e}"
96107
raise ArgumentTypeError(msg) from e
97108
else:
98109
json_input = value
110+
99111
try:
100112
result = json.loads(json_input)
101113
except json.JSONDecodeError as e:

tests/main/jsonschema/test_main_jsonschema.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
from __future__ import annotations
44

5+
import itertools
56
import json
67
import os
78
import tempfile
@@ -3143,6 +3144,21 @@ def test_main_jsonschema_base_class_map_empty_list(output_file: Path) -> None:
31433144
)
31443145

31453146

3147+
def test_main_jsonschema_base_class_map_long_json(output_file: Path) -> None:
3148+
"""Test base_class_map with very long json string."""
3149+
run_main_and_assert(
3150+
input_path=JSON_SCHEMA_DATA_PATH / "base_class_map_empty_list.json",
3151+
output_path=output_file,
3152+
input_file_type="jsonschema",
3153+
assert_func=assert_file_content,
3154+
expected_file="base_class_map_empty_list.py",
3155+
extra_args=[
3156+
"--base-class-map",
3157+
'{"User": [' + ",".join(itertools.repeat('""', 100)) + "]}",
3158+
],
3159+
)
3160+
3161+
31463162
def test_long_description(output_file: Path) -> None:
31473163
"""Test long description handling."""
31483164
run_main_and_assert(
@@ -4659,6 +4675,22 @@ def test_main_enum_field_as_literal_map_from_file(output_file: Path, tmp_path: P
46594675
)
46604676

46614677

4678+
def test_main_enum_field_as_literal_map_long_json(output_file: Path) -> None:
4679+
"""Test enum_field_as_literal_map with very long json string."""
4680+
long_inline_mapping = '{"status": "literal",' + ",".join(f'"unused_field_{i}": "enum"' for i in range(100)) + "}"
4681+
run_main_and_assert(
4682+
input_path=JSON_SCHEMA_DATA_PATH / "enum_field_as_literal_map.json",
4683+
output_path=output_file,
4684+
input_file_type=None,
4685+
assert_func=assert_file_content,
4686+
expected_file="enum_field_as_literal_map.py",
4687+
extra_args=[
4688+
"--enum-field-as-literal-map",
4689+
long_inline_mapping,
4690+
],
4691+
)
4692+
4693+
46624694
def test_main_enum_field_as_literal_map_override_global(output_file: Path) -> None:
46634695
"""Test --enum-field-as-literal-map overrides global --enum-field-as-literal."""
46644696
run_main_and_assert(

0 commit comments

Comments
 (0)