1- from dataclasses import dataclass
1+ from dataclasses import dataclass , make_dataclass
22from enum import Enum
33from typing import Annotated , Literal
44
55import pytest
66from annotated_types import Ge , Gt , Le , MinLen , Predicate
77
88from python_introspect import (
9+ AnnotatedDataclassValidationMixin ,
910 overlay_non_none_dataclass ,
1011 validate_annotated_dataclass ,
1112)
@@ -21,13 +22,10 @@ class Mode(Enum):
2122
2223
2324@dataclass (frozen = True )
24- class BaseConfig :
25+ class BaseConfig ( AnnotatedDataclassValidationMixin ) :
2526 port : Port = 7000
2627 mode : Mode = Mode .FIRST
2728
28- def __post_init__ (self ) -> None :
29- validate_annotated_dataclass (self )
30-
3129
3230@dataclass (frozen = True )
3331class ChildConfig (BaseConfig ):
@@ -53,6 +51,19 @@ def test_validation_rejects_wrong_nominal_types_without_coercion() -> None:
5351 ChildConfig (mode = "first" )
5452
5553
54+ def test_inherited_validation_survives_dataclass_recreation () -> None :
55+ RecreatedConfig = make_dataclass (
56+ "RecreatedConfig" ,
57+ (("port" , Port , 7000 ),),
58+ bases = (AnnotatedDataclassValidationMixin ,),
59+ frozen = True ,
60+ )
61+
62+ assert RecreatedConfig (port = 8000 ).port == 8000
63+ with pytest .raises (ValueError , match = "port must be at least" ):
64+ RecreatedConfig (port = 0 )
65+
66+
5667@dataclass (frozen = True )
5768class OptionalConfig :
5869 port : Port | None = None
0 commit comments