@@ -410,10 +410,43 @@ def py_type(self) -> str:
410410 def unwrapped_py_type (self ) -> str :
411411 return self ._py_type (wrap = False )
412412
413+ @property
414+ def annotations (self ) -> list [str ]:
415+ """List of the Pydantic annotation to add to the field."""
416+ assert self .output_file .settings .pydantic_dataclasses
417+
418+ annotations = []
419+
420+ if self .proto_obj .type in (FieldType .TYPE_INT32 , FieldType .TYPE_SFIXED32 , FieldType .TYPE_SINT32 ):
421+ annotations .append ("pydantic.Field(ge=-2**31, le=2**31 - 1)" )
422+
423+ elif self .proto_obj .type in (FieldType .TYPE_UINT32 , FieldType .TYPE_FIXED32 ):
424+ annotations .append ("pydantic.Field(ge=0, le=2**32 - 1)" )
425+
426+ elif self .proto_obj .type in (FieldType .TYPE_INT64 , FieldType .TYPE_SFIXED64 , FieldType .TYPE_SINT64 ):
427+ annotations .append ("pydantic.Field(ge=-2**63, le=2**63 - 1)" )
428+
429+ elif self .proto_obj .type in (FieldType .TYPE_UINT64 , FieldType .TYPE_FIXED64 ):
430+ annotations .append ("pydantic.Field(ge=0, le=2**64 - 1)" )
431+
432+ elif self .proto_obj .type == FieldType .TYPE_FLOAT :
433+ annotations .append ("pydantic.AfterValidator(betterproto2.validators.validate_float32)" )
434+
435+ elif self .proto_obj .type == FieldType .TYPE_STRING :
436+ annotations .append ("pydantic.AfterValidator(betterproto2.validators.validate_string)" )
437+
438+ return annotations
439+
413440 @property
414441 def annotation (self ) -> str :
415442 py_type = self .py_type
416443
444+ # Add the pydantic annotation if needed
445+ if self .output_file .settings .pydantic_dataclasses :
446+ annotations = self .annotations
447+ if annotations :
448+ py_type = f"typing.Annotated[{ py_type } , { ', ' .join (annotations )} ]"
449+
417450 if self .use_builtins :
418451 py_type = f"builtins.{ py_type } "
419452 if self .repeated :
0 commit comments