Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@tamird
Copy link
Contributor

@tamird tamird commented May 6, 2024

Change the signature of ValidationException.errors to return
Sequence[pydantic_core.ErrorDetails] in Pydantic V2.

Update the documentation to explain that RequestValidationError isn't
literally a subclass since Pydantic V2.

Closes (UPD YuriiMotov: actually not) #10424.
Closes #11176.

@tamird tamird force-pushed the errors-better-types branch 3 times, most recently from 45a560a to 338a33e Compare May 7, 2024 16:48
@tamird
Copy link
Contributor Author

tamird commented May 7, 2024

@tiangolo this is green now. I believe it is technically a breaking change.

@tamird tamird force-pushed the errors-better-types branch 9 times, most recently from 025ef5f to b91428d Compare May 10, 2024 08:57
@bertomaniac

This comment was marked as resolved.

@tamird
Copy link
Contributor Author

tamird commented Aug 8, 2024

3 months and no review :(

@bertomaniac
Copy link

Dang, I just checked out your PR and tried it for my test. It doesn't fix it because I think this code block still needs to strip out ctx and input from pydantic v2s ValidationError.errors() call:

            except ValidationError as exc:
                errors: List[ErrorDetails] = [
                    {**err, "loc": loc + err.get("loc", ())}  # type: ignore [typeddict-unknown-key]
                    for err in exc.errors(include_url=False)
                ]
                return None, errors

perhaps

for err in exc.errors(include_url=False, include_input=False, include_context=False)

See here in pydantic docs: https://docs.pydantic.dev/latest/api/pydantic_core/#pydantic_core.ValidationError.errors

@estebanx64 estebanx64 changed the title ValidationException.errors() are ErrorDetails 🦺 Update docs for RequestValidationError in pydantic v2 Aug 31, 2024
@estebanx64 estebanx64 changed the title 🦺 Update docs for RequestValidationError in pydantic v2 🦺 Update implementarion and docs for RequestValidationError in pydantic v2 Aug 31, 2024
@estebanx64
Copy link
Contributor

Hi @tamird 👋

We'll be reviewing this PR soon. 🤓

Thank you for your interest and time in helping us with your contribution 🙇

@tamird

This comment was marked as off-topic.

@tiangolo
Copy link
Member

@tamird thanks for the interest. There's no need to ping or contact individual maintainers, we already have this PR in the project and we'll review it eventually.

If you would like to help accelerate things, there are many ways to contribute, for example helping others with questions: https://fastapi.tiangolo.com/help-fastapi/#help-others-with-questions-in-github

@tamird tamird force-pushed the errors-better-types branch from 39429c1 to 9b65f64 Compare November 21, 2024 22:47
Copy link
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.

This PR modifies ValidationException and derived classes (RequestValidationError and ResponseValidationError) so that their .errors() method would return Sequence["ErrorDetails"] instead of Sequence[Any].

Where ErrorDetails is a TypedDict imported from Pydantic (pydantic.error_wrappers.ErrorDict for V1 and pydantic_core.ErrorDetails for V2).

class ErrorDetails(_TypedDict):
    type: str
    loc: tuple[int | str, ...]
    msg: str
    input: _Any
    ctx: _NotRequired[dict[str, _Any]]
    url: _NotRequired[str]

So, I guess the intention is to provide type hints in case user write something like:

from fastapi import Request
from fastapi.exceptions import RequestValidationError
from fastapi.responses import JSONResponse

async def request_validation_exception_handler(
    request: Request, exc: RequestValidationError
) -> JSONResponse:
    errors = exc.errors()  # Here I expect to ge list of `ErrorDetails`
    ...

But in VSCode I can still see that elements of errors are of type Any:
image

@tamird, could you please take a look?

@tamird
Copy link
Contributor Author

tamird commented Jul 22, 2025

But in VSCode I can still see that elements of errors are of type Any: image

@tamird, could you please take a look?

I do not see the token "Any" in your screenshot.

@github-actions github-actions bot removed the waiting label Jul 22, 2025
@YuriiMotov
Copy link
Member

I do not see the token "Any" in your screenshot.

You can see that errors is just Sequence instead of Sequence[ErrorDetails]. If I access the element as errors[0] it will be of type Any:
image

@tamird
Copy link
Contributor Author

tamird commented Jul 22, 2025

I do not see the token "Any" in your screenshot.

You can see that errors is just Sequence instead of Sequence[ErrorDetails]. If I access the element as errors[0] it will be of type Any: image

I see. Rather than post a screenshot, perhaps you could add a type annotation in the relevant place? I'm not sure how your local environment is set up, and I'm not sure exactly what code you're looking at. A test change would be a robust way to ensure that the type annotations are working as intended.

@github-actions github-actions bot removed the waiting label Jul 22, 2025
@YuriiMotov
Copy link
Member

I'm not sure how your local environment is set up, and I'm not sure exactly what code you're looking at.

I looked at the code from this comment.

And I use fresh virtual environment with the latest versions of packages installed using pip install -r requirements.txt.

I don't think this is a problem of my environment set up. If I create my own function with the same return type annotation, it works well
image

And if I try the same with:

from fastapi.exceptions import ValidationException

exc = ValidationException([])

b = exc.errors()[0]

It gives my Any

Full code example that you or anybody else can try:

from collections.abc import Sequence

from fastapi.exceptions import ValidationException
from pydantic_core import ErrorDetails


# =============================================
def my_errors() -> Sequence["ErrorDetails"]:
    pass

a = my_errors()[0]  # ErrorDetails


# =============================================
exc = ValidationException([])

b = exc.errors()[0]  # Any

Rather than post a screenshot, perhaps you could add a type annotation in the relevant place?

A test change would be a robust way to ensure that the type annotations are working as intended.

Sorry, I didn't get the above messages. Could you please clarify what you mean?

These tests are all marked `@needs_pydanticv2` so they don't run on
Pydantic V1.
@tamird tamird force-pushed the errors-better-types branch from b8cba06 to d317859 Compare July 23, 2025 14:10
@tamird
Copy link
Contributor Author

tamird commented Jul 23, 2025

@YuriiMotov I have added type annotations in the relevant tests and confirmed locally that changing the annotations to Sequence[str] does cause mypy to complain (see updated commit message).

@github-actions github-actions bot removed the waiting label Jul 23, 2025
tamird added 2 commits July 23, 2025 10:11
This will allow mypy to check the return type of
`ValidationException.errors()` in a later commit.
@tamird tamird force-pushed the errors-better-types branch 2 times, most recently from 49b0e39 to 7ad235e Compare July 23, 2025 14:17
Change the signature of `ValidationException.errors` to return
`Sequence[pydantic_core.ErrorDetails]` in Pydantic V2.

Add type annotations in tests and locally run mypy to ensure it fails if
the annotations changes to e.g. `Sequence[str]`. Unfortunately running
mypy over tests isn't currently part of CI.
@tamird tamird force-pushed the errors-better-types branch from 7ad235e to ee3c9ea Compare July 23, 2025 14:21
@tamird tamird requested a review from YuriiMotov July 23, 2025 14:47
@YuriiMotov
Copy link
Member

YuriiMotov commented Jul 24, 2025

This still doesn't show me type hints in VSCode for the following code example with Pydantic V2:

from fastapi.exceptions import ValidationException

exc = ValidationException([])

b = exc.errors()[0]  # VSCode shows `(variable) b: Any`

At the same time it does show type correctly with Pydantic V1.

I think we should either make it working with Pydantic V2 or explain what is the purpose of this PR (what it gives us)

@tamird
Copy link
Contributor Author

tamird commented Jul 24, 2025

This still doesn't show me type hints in VSCode for the following code example with Pydantic V2:

from fastapi.exceptions import ValidationException

exc = ValidationException([])

b = exc.errors()[0]  # VSCode shows `(variable) b: Any`

At the same time it does show type correctly with Pydantic V1.

I think we should either make it working with Pydantic V2 or explain what is the purpose of this PR (what it gives us)

I'd prefer not to try to debug your VSCode setup. If you run mypy over the tests which have the type annotation showing that the type is Sequence[ErrorDetails] (e.g. tests/test_filter_pydantic_sub_model_pv2.py), does it pass?

@YuriiMotov
Copy link
Member

I'd prefer not to try to debug your VSCode setup. If you run mypy over the tests which have the type annotation showing that the type is Sequence[ErrorDetails] (e.g. tests/test_filter_pydantic_sub_model_pv2.py), does it pass?

I think it's not a problem of my VSCode setup. It works perfectly fine in other cases.
Does it work in your IDE?
Could anybody else check it?

@tamird
Copy link
Contributor Author

tamird commented Jul 24, 2025

It looks like the if TYPE_CHECKING guards are interfering with the type checker, at least in the IDE.

Let me play with it some more.

@YuriiMotov YuriiMotov marked this pull request as draft September 8, 2025 20:55
@github-actions github-actions bot added the conflicts Automatically generated when a PR has a merge conflict label Sep 29, 2025
@github-actions
Copy link
Contributor

This pull request has a merge conflict that needs to be resolved.

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

Labels

conflicts Automatically generated when a PR has a merge conflict p4 refactor

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants