diff --git a/src/openai/_compat.py b/src/openai/_compat.py index 020ffeb2ca..286b5be3f7 100644 --- a/src/openai/_compat.py +++ b/src/openai/_compat.py @@ -142,19 +142,21 @@ def model_dump( by_alias: bool | None = None, ) -> dict[str, Any]: if (not PYDANTIC_V1) or hasattr(model, "model_dump"): - return model.model_dump( + kwargs: dict[str, Any] = dict( mode=mode, exclude=exclude, exclude_unset=exclude_unset, exclude_defaults=exclude_defaults, # warnings are not supported in Pydantic v1 warnings=True if PYDANTIC_V1 else warnings, - by_alias=by_alias, ) + if by_alias is not None: + kwargs["by_alias"] = by_alias + return model.model_dump(**kwargs) return cast( "dict[str, Any]", model.dict( # pyright: ignore[reportDeprecated, reportUnnecessaryCast] - exclude=exclude, exclude_unset=exclude_unset, exclude_defaults=exclude_defaults, by_alias=bool(by_alias) + exclude=exclude, exclude_unset=exclude_unset, exclude_defaults=exclude_defaults, by_alias=bool(by_alias) if by_alias is not None else by_alias ), ) diff --git a/tests/test_models.py b/tests/test_models.py index 588869ee35..05db6a85b1 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -157,6 +157,20 @@ def test_unknown_fields() -> None: assert model_dump(m2) == {"foo": "foo", "unknown": {"foo_bar": True}} +def test_model_dump_by_alias_none() -> None: + """Ensure model_dump does not crash when by_alias defaults to None (GH-2921).""" + m = BasicModel.construct(foo="hello") + # by_alias=None is the default — must not raise TypeError + result = model_dump(m) + assert result == {"foo": "hello"} + # Explicit by_alias=None must also work + result = model_dump(m, by_alias=None) + assert result == {"foo": "hello"} + # Explicit by_alias=True/False must still be forwarded + result = model_dump(m, by_alias=False) + assert result == {"foo": "hello"} + + def test_strict_validation_unknown_fields() -> None: class Model(BaseModel): foo: str