I think your best bet (if you are set on this pattern) is to wrap your wrapper, providing the type hint again:
from typing import Annotated, Any
from pydantic import (
BaseModel, ValidationError, ValidationInfo,
ValidatorFunctionWrapHandler, WrapValidator
)
def wrap_with_type(type_):
def wrapper(value: Any,
handler: ValidatorFunctionWrapHandler,
info: ValidationInfo) -> Any:
try:
return handler(value)
except ValidationError as e:
# Custom error handling where I want to know the expected type.
# I'm looking for something like this:
if type_ == str:
# Do something
elif type_ == int | bool:
# Do something else
else:
raise
return WrapValidator(wrapper)
class MyModel(BaseModel):
foo: Annotated[str, wrap_with_type(str)]
class AnotherModel(BaseModel):
bar: Annotated[int | bool, wrap_with_type(int | bool)]
That will allow you to do what you want, but it comes with costs: your code is less readable, and there's now redundant information in your class definition. It might be worth rethinking your design to separate your validator into one for each of the expected types. Without a RME, it is hard to offer another solution. I'd be happy to help work something out though.
If it's any consolation, I am surprised this isn't something you could grab during validation. Consider delving into the project's source code to see if there's a contribution to be made!