Ich habe eine benutzerdefinierte Klasse erstellt, die int unterordnet und eine __get_pydantic_core_schema__-Methode implementiert.
Wenn ich diese benutzerdefinierte Klasse in einem Pydantic-Modell verwende, möchte ich, dass der Typprüfer (Basedpyright) versteht, dass das Attribut des instanziierten Modells nur von dem ist Typ meiner benutzerdefinierten Klasse (
Code: Select all
MyCustomInt
Allerdings Ich möchte nicht für jedes Modell, das meine benutzerdefinierte Klasse verwendet, Überladungen definieren oder die Methode __init__ überschreiben, da dies den Zweck verfehlt und den Code sehr ausführlich macht, insbesondere wenn ich alle Attribute in jedem __init__ neu definieren muss Überladung/Überschreibung.
Hier ist ein minimal reproduzierbares Beispiel:
Code: Select all
from typing import Any, reveal_type
from pydantic_core import CoreSchema, core_schema
from pydantic import GetCoreSchemaHandler, BaseModel
class MyCustomInt(int):
@classmethod
def __get_pydantic_core_schema__(
cls,
_source_type: Any,
_handler: GetCoreSchemaHandler,
) -> CoreSchema:
def validate_from_int(value: int) -> "MyCustomInt":
if value < 0:
raise ValueError("Cannot be negative")
return cls(value)
from_int_schema = core_schema.chain_schema(
[
core_schema.int_schema(),
core_schema.no_info_plain_validator_function(validate_from_int),
]
)
return core_schema.json_or_python_schema(
json_schema=from_int_schema,
python_schema=core_schema.union_schema(
[
core_schema.is_instance_schema(cls),
from_int_schema,
]
),
serialization=core_schema.plain_serializer_function_ser_schema(
str,
return_schema=core_schema.str_schema(),
when_used='json'
),
)
class MyModel(BaseModel):
value: MyCustomInt
model = MyModel(value="123") # Error: Argument of type "str" cannot be assigned to parameter "value" of type "MyCustomInt" in function "__init__"
reveal_type(model.value) # Revealed type is 'MyCustomInt' - Good!
model = MyModel(value=123) # Error: Argument of type "int" cannot be assigned to parameter "value" of type "MyCustomInt" in function "__init__"
reveal_type(model.value) # Revealed type is 'MyCustomInt' - Good!
Gibt es eine Möglichkeit, das zu informieren Typprüfer über die akzeptablen Validierungstypen für MyCustomInt, ohne __init__ in jedem Modell überladen oder überschreiben zu müssen?