Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/datamodel_code_generator/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ def is_pydantic_v2() -> bool:

_YAML_1_2_BOOL_PATTERN = re.compile(r"^(?:true|false|True|False|TRUE|FALSE)$")
_YAML_DEPRECATED_BOOL_VALUES = {"True", "False", "TRUE", "FALSE"}
# Pattern for scientific notation without decimal point (e.g., 1e-5, 1E+10)
# Standard YAML only matches floats with decimal points, missing patterns like "1e-5"
_YAML_SCIENTIFIC_NOTATION_PATTERN = re.compile(r"^[-+]?[0-9][0-9_]*[eE][-+]?[0-9]+$")


def _construct_yaml_bool_with_warning(loader: Any, node: Any) -> bool:
Expand Down Expand Up @@ -104,6 +107,13 @@ class CustomSafeLoader(_SafeLoader): # type: ignore[valid-type,misc]
))
CustomSafeLoader.yaml_constructors["tag:yaml.org,2002:bool"] = _construct_yaml_bool_with_warning

# Add scientific notation without decimal point (e.g., 1e-5) as float
for key in ["-", "+", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]:
CustomSafeLoader.yaml_implicit_resolvers.setdefault(key, []).append((
"tag:yaml.org,2002:float",
_YAML_SCIENTIFIC_NOTATION_PATTERN,
))

return CustomSafeLoader


Expand Down
14 changes: 14 additions & 0 deletions tests/data/expected/main/yaml/scientific_notation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# generated by datamodel-codegen:
# filename: scientific_notation.yaml
# timestamp: 2019-07-26T00:00:00+00:00

from __future__ import annotations

from pydantic import BaseModel


class Model(BaseModel):
exponential_default: float | None = 1e-05
positive_exp: float | None = 20000000000.0
negative_prefix: float | None = -30000.0
with_decimal: float | None = 1.5e-05
15 changes: 15 additions & 0 deletions tests/data/yaml/scientific_notation.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
$schema: http://json-schema.org/draft-07/schema#
type: object
properties:
exponential_default:
type: number
default: 1e-5
positive_exp:
type: number
default: 2E+10
negative_prefix:
type: number
default: -3e4
with_decimal:
type: number
default: 1.5e-5
16 changes: 16 additions & 0 deletions tests/main/test_main_yaml.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,19 @@ def test_main_yaml_deprecated_bool(output_file: Path) -> None:
output_path=output_file,
input_file_type="openapi",
)


def test_main_yaml_scientific_notation(output_file: Path) -> None:
"""Test YAML file with scientific notation default values (issue #1955).

Scientific notation without decimal point (e.g., 1e-5) should be parsed as float,
not as string.
"""
run_main_and_assert(
input_path=YAML_DATA_PATH / "scientific_notation.yaml",
output_path=output_file,
input_file_type="jsonschema",
extra_args=["--output-model-type", "pydantic_v2.BaseModel"],
assert_func=assert_file_content,
expected_file="yaml/scientific_notation.py",
)
Loading