@@ -365,6 +365,8 @@ positional and may use other names.
365
365
* ``alias `` is an optional str parameter that provides an alternative
366
366
name for the field. This alternative name is used in the synthesized
367
367
``__init__ `` method.
368
+ * ``converter `` is an optional parameter that specifies a
369
+ callable used to convert values when assigning to the field.
368
370
369
371
It is an error to specify more than one of ``default ``,
370
372
``default_factory `` and ``factory ``.
@@ -526,6 +528,52 @@ This includes, but is not limited to, the following semantics:
526
528
dataclass must be explicitly annotated as e.g. ``x: ClassVar[Final[int]] =
527
529
3 ``.
528
530
531
+ Converters
532
+ ^^^^^^^^^^
533
+
534
+ The ``converter `` parameter can be specified in a field definition to provide a callable
535
+ used to convert values when assigning to the associated attribute. This feature allows for automatic type
536
+ conversion and validation during attribute assignment.
537
+
538
+ Converter behavior:
539
+
540
+ * The converter is used for all attribute assignment, including assignment
541
+ of default values, assignment in synthesized ``__init__ `` methods
542
+ and direct attribute setting (e.g., ``obj.attr = value ``).
543
+ * The converter is not used when reading attributes, as the attributes should already have been converted.
544
+
545
+ Typing rules for converters:
546
+
547
+ * The ``converter `` must be a callable that must accept a single positional argument
548
+ (but may accept other optional arguments, which are ignored for typing purposes).
549
+ * The type of the first positional parameter provides the type of the synthesized ``__init__ `` parameter
550
+ for the field.
551
+ * The return type of the callable must be assignable to the field's declared type.
552
+ * If ``default `` or ``default_factory `` are provided, the type of the default value should be
553
+ assignable to the first positional parameter of the ``converter ``.
554
+
555
+ Example usage:
556
+
557
+ .. code-block :: python
558
+
559
+ def str_or_none (x : Any) -> str | None :
560
+ return str (x) if x is not None else None
561
+
562
+ @custom_dataclass
563
+ class Example :
564
+ int_field: int = custom_field(converter = int )
565
+ str_field: str | None = custom_field(converter = str_or_none)
566
+ path_field: pathlib.Path = custom_field(
567
+ converter = pathlib.Path,
568
+ default = " default/path.txt"
569
+ )
570
+
571
+ # Usage
572
+ example = Example(" 123" , None , " some/path" )
573
+ # example.int_field == 123
574
+ # example.str_field == None
575
+ # example.path_field == pathlib.Path("some/path")
576
+
529
577
530
578
Undefined behavior
531
579
^^^^^^^^^^^^^^^^^^
0 commit comments