Skip to content

⬆️ Update Pydantic v2 code to address deprecations#15101

Merged
tiangolo merged 34 commits intofastapi:masterfrom
svlandeg:feat/depr
Apr 23, 2026
Merged

⬆️ Update Pydantic v2 code to address deprecations#15101
tiangolo merged 34 commits intofastapi:masterfrom
svlandeg:feat/depr

Conversation

@svlandeg
Copy link
Copy Markdown
Member

@svlandeg svlandeg commented Mar 12, 2026

When running ty on the code base (cf #15091), we got two valid deprecation warnings:

eval_type_lenient

color

  • pydantic.color.Color has been deprecated since pydantic#6003, which was released as part of v2.0b3.
  • This PR updates ENCODERS_BY_TYPE to also cover the new pydantic_extra_types.color.Color. The added unit test fails on master.

Open question

As Pydantic updates & makes older functionality deprecated, we could (also in the future) be tempted to update the methods (especially when ty tells us to), without realizing we might be breaking older versions that we still support according to our pyproject.toml. For this reason, I'd want to add a specific test CLI run with Pydantic 2.7.0 to ensure it keeps working as expected. Aye? Nay?

UPDATE: cf #15139!

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented Mar 12, 2026

Merging this PR will not alter performance

✅ 20 untouched benchmarks


Comparing svlandeg:feat/depr (e0e2568) with master (aeb9f4b)1

Open in CodSpeed

Footnotes

  1. No successful run was found on master (cbd64b0) during the generation of this report, so aeb9f4b was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

@svlandeg svlandeg self-assigned this Mar 12, 2026
Comment thread fastapi/_compat/v2.py Outdated
@svlandeg svlandeg marked this pull request as ready for review March 13, 2026 11:00
@svlandeg svlandeg removed their assignment Mar 13, 2026
@svlandeg svlandeg requested a review from YuriiMotov March 13, 2026 11:06
AhsanSheraz

This comment was marked as outdated.

@github-actions github-actions Bot added the conflicts Automatically generated when a PR has a merge conflict label Mar 15, 2026
@github-actions

This comment was marked as resolved.

@svlandeg

This comment was marked as outdated.

@AhsanSheraz

This comment was marked as outdated.

@svlandeg svlandeg self-assigned this Mar 16, 2026
@svlandeg

This comment was marked as outdated.

@svlandeg svlandeg changed the title ⬆️ Update Pydantic v2 code to address deprecation warnings ⬆️ Update Pydantic v2 code to address deprecations Mar 17, 2026
@svlandeg svlandeg marked this pull request as draft March 17, 2026 14:33
"module_path",
[
pytest.param("pydantic.color"),
pytest.param("pydantic_extra_types.color"),
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For pydantic_extra_types.color, this will fail on master with

ValueError: [TypeError("'Color' object is not iterable"), TypeError('vars() argument must have dict attribute')]

Copy link
Copy Markdown
Member

@YuriiMotov YuriiMotov Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For pydantic_extra_types.color, this will fail on master with

ValueError: [TypeError("'Color' object is not iterable"), TypeError('vars() argument must have dict attribute')]

I took me some time to understand this comment 😅

Just to clarify if somebody also gets confused: it fails on master because pydantic_extra_types.color.Color is not currently supported by jsonable_encoder. This PR adds such support

@svlandeg svlandeg marked this pull request as ready for review March 18, 2026 11:13
@svlandeg svlandeg removed their assignment Mar 18, 2026
@svlandeg svlandeg requested a review from YuriiMotov March 18, 2026 11:13
@svlandeg
Copy link
Copy Markdown
Member Author

Thanks for the detailed review Yurii, I addressed everything, let me know what you think!

Copy link
Copy Markdown
Member

@YuriiMotov YuriiMotov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Comment thread fastapi/_compat/v2.py
globalns: dict[str, Any] | None = None,
localns: dict[str, Any] | None = None,
) -> Any:
# eval_type_lenient has been deprecated since Pydantic v2.10.0b1 (PR #10530)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As an alternative, we can use try...except:

    try:    
        return _pydantic_typing_extra.try_eval_type(value, globalns, localns)[0]
    except AttrbuteError:
        return _pydantic_typing_extra.eval_type_lenient(  # ty: ignore[deprecated]
            value, globalns, localns
        )  # pragma: no cover

Or move this to module level, and only use it inside evaluate_forwardref (so that evaluate_forwardref would make it typed).

It might also be a bit faster (but it's only used at app stratup, so maybe not as important)

Copy link
Copy Markdown
Member Author

@svlandeg svlandeg Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea I think it's a style preference, I'm personally more fan of checking explicitely first rather than relying on a try-except, but both are valid options. I'll leave it up to Sebastián to decide if he's got a preference 🙂

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found it a bit unfortunate that this PR still relies on an internal function.. The only reason I kept eval_type_lenient() in Pydantic was because FastAPI was using it, and now the same issue exists with try_eval_type().

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Viicos: right, good point. What would be the better way to address this? I can make a new PR.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it might be worth solving this cleanly, that is by first having the ability to do such evaluations using the stdlib. I proposed https://discuss.python.org/t/100698 a while ago, I'll try to continue working on it. Then we could see how can this be used in FastAPI/Pydantic!

"module_path",
[
pytest.param("pydantic.color"),
pytest.param("pydantic_extra_types.color"),
Copy link
Copy Markdown
Member

@YuriiMotov YuriiMotov Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For pydantic_extra_types.color, this will fail on master with

ValueError: [TypeError("'Color' object is not iterable"), TypeError('vars() argument must have dict attribute')]

I took me some time to understand this comment 😅

Just to clarify if somebody also gets confused: it fails on master because pydantic_extra_types.color.Color is not currently supported by jsonable_encoder. This PR adds such support

@svlandeg svlandeg self-assigned this Mar 23, 2026
@svlandeg svlandeg removed their assignment Mar 23, 2026
Copy link
Copy Markdown
Member

@tiangolo tiangolo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, thank you! 🙌

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants