Skip to content

Commit fc68422

Browse files
authored
Handle all schema generation errors in InstanceOf (pydantic#12705)
1 parent b5eadd1 commit fc68422

3 files changed

Lines changed: 36 additions & 6 deletions

File tree

pydantic/_internal/_generate_schema.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,13 @@
5858
from ..aliases import AliasChoices, AliasPath
5959
from ..annotated_handlers import GetCoreSchemaHandler, GetJsonSchemaHandler
6060
from ..config import ConfigDict, JsonDict, JsonEncoder, JsonSchemaExtraCallable
61-
from ..errors import PydanticSchemaGenerationError, PydanticUndefinedAnnotation, PydanticUserError
61+
from ..errors import (
62+
PydanticForbiddenQualifier,
63+
PydanticInvalidForJsonSchema,
64+
PydanticSchemaGenerationError,
65+
PydanticUndefinedAnnotation,
66+
PydanticUserError,
67+
)
6268
from ..functional_validators import AfterValidator, BeforeValidator, FieldValidatorModes, PlainValidator, WrapValidator
6369
from ..json_schema import JsonSchemaValue
6470
from ..version import version_short
@@ -328,6 +334,15 @@ def _add_custom_serialization_from_json_encoders(
328334
return schema
329335

330336

337+
GENERATE_SCHEMA_ERRORS = (
338+
PydanticForbiddenQualifier,
339+
PydanticInvalidForJsonSchema,
340+
PydanticSchemaGenerationError,
341+
PydanticUndefinedAnnotation,
342+
)
343+
"""Errors raised during core schema generation. This does *not* include `InvalidSchemaError`, which is raised during schema cleaning."""
344+
345+
331346
class InvalidSchemaError(Exception):
332347
"""The core schema is invalid."""
333348

pydantic/functional_validators.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -782,15 +782,15 @@ def __class_getitem__(cls, item: AnyType) -> AnyType:
782782

783783
@classmethod
784784
def __get_pydantic_core_schema__(cls, source: Any, handler: GetCoreSchemaHandler) -> core_schema.CoreSchema:
785-
from pydantic import PydanticSchemaGenerationError
785+
from pydantic._internal._generate_schema import GENERATE_SCHEMA_ERRORS
786786

787787
# use the generic _origin_ as the second argument to isinstance when appropriate
788788
instance_of_schema = core_schema.is_instance_schema(_generics.get_origin(source) or source)
789789

790790
try:
791791
# Try to generate the "standard" schema, which will be used when loading from JSON
792792
original_schema = handler(source)
793-
except PydanticSchemaGenerationError:
793+
except GENERATE_SCHEMA_ERRORS:
794794
# If that fails, just produce a schema that can validate from python
795795
return instance_of_schema
796796
else:

tests/test_types.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6268,14 +6268,22 @@ def test_instanceof_invalid_core_schema():
62686268
class MyClass:
62696269
pass
62706270

6271+
@dataclass
6272+
class ClassWithInvalidAnnotations:
6273+
a: 'Unknown' = 1 # noqa: F821
6274+
b: NotRequired[int] = 1
6275+
62716276
class MyModel(BaseModel):
62726277
a: InstanceOf[MyClass]
62736278
b: Optional[InstanceOf[MyClass]]
6279+
c: InstanceOf[ClassWithInvalidAnnotations]
6280+
6281+
MyModel(a=MyClass(), b=None, c=ClassWithInvalidAnnotations())
6282+
MyModel(a=MyClass(), b=MyClass(), c=ClassWithInvalidAnnotations())
62746283

6275-
MyModel(a=MyClass(), b=None)
6276-
MyModel(a=MyClass(), b=MyClass())
62776284
with pytest.raises(ValidationError) as exc_info:
6278-
MyModel(a=1, b=1)
6285+
MyModel(a=1, b=1, c=1)
6286+
62796287
assert exc_info.value.errors(include_url=False) == [
62806288
{
62816289
'ctx': {'class': 'test_instanceof_invalid_core_schema.<locals>.MyClass'},
@@ -6291,6 +6299,13 @@ class MyModel(BaseModel):
62916299
'msg': 'Input should be an instance of test_instanceof_invalid_core_schema.<locals>.MyClass',
62926300
'type': 'is_instance_of',
62936301
},
6302+
{
6303+
'ctx': {'class': 'test_instanceof_invalid_core_schema.<locals>.ClassWithInvalidAnnotations'},
6304+
'input': 1,
6305+
'loc': ('c',),
6306+
'msg': 'Input should be an instance of test_instanceof_invalid_core_schema.<locals>.ClassWithInvalidAnnotations',
6307+
'type': 'is_instance_of',
6308+
},
62946309
]
62956310
with pytest.raises(
62966311
PydanticInvalidForJsonSchema, match='Cannot generate a JsonSchema for core_schema.IsInstanceSchema'

0 commit comments

Comments
 (0)