@@ -652,6 +652,69 @@ def test_add_missing_columns_dtype():
652652 pd .testing .assert_frame_equal (ref_df , test_df )
653653
654654
655+ @pytest .mark .parametrize (
656+ "default, nullable" ,
657+ [
658+ (None , True ),
659+ (np .nan , True ),
660+ (pd .NA , True ),
661+ (pd .NaT , True ),
662+ (7 , False ),
663+ ("missing" , False ),
664+ (False , False ),
665+ ],
666+ )
667+ @pytest .mark .parametrize ("size" , [0 , 2 ])
668+ @pytest .mark .parametrize ("coerce" , [False , True ])
669+ @pytest .mark .parametrize ("lazy" , [False , True ])
670+ def test_add_missing_columns_without_dtype (
671+ default : Any , nullable : bool , size : int , coerce : bool , lazy : bool
672+ ) -> None :
673+ """Missing untyped columns retain pandas' inferred default dtype."""
674+ index = pd .Index ([4 ] * size , name = "row" )
675+ frame = pd .DataFrame ({"present" : range (size )}, index = index )
676+ schema = DataFrameSchema (
677+ {
678+ "untyped" : Column (default = default , nullable = nullable ),
679+ "present" : Column (int ),
680+ "typed" : Column ("Int8" , default = pd .NA , nullable = True ),
681+ "null" : Column (nullable = True ),
682+ "optional" : Column (required = False , default = 1 ),
683+ },
684+ add_missing_columns = True ,
685+ coerce = coerce ,
686+ )
687+ expected = pd .DataFrame (
688+ {
689+ "untyped" : default ,
690+ "present" : range (size ),
691+ "typed" : pd .NA ,
692+ "null" : None ,
693+ },
694+ index = index ,
695+ ).astype ({"typed" : "Int8" })
696+
697+ validated = schema .validate (frame , lazy = lazy )
698+
699+ pd .testing .assert_frame_equal (validated , expected )
700+ assert frame .columns .tolist () == ["present" ]
701+
702+
703+ @pytest .mark .parametrize ("lazy" , [False , True ])
704+ def test_add_missing_untyped_column_with_schema_dtype (lazy : bool ) -> None :
705+ """Schema-level coercion still applies to an added untyped column."""
706+ schema = DataFrameSchema (
707+ {"missing" : Column (default = "7" )},
708+ dtype = "int64" ,
709+ coerce = True ,
710+ add_missing_columns = True ,
711+ )
712+
713+ validated = schema .validate (pd .DataFrame (index = [0 ]), lazy = lazy )
714+
715+ pd .testing .assert_frame_equal (validated , pd .DataFrame ({"missing" : [7 ]}))
716+
717+
655718def test_add_missing_columns_reports_all_in_lazy_validation ():
656719 """Lazy validation should report every missing non-nullable column without
657720 a default value, not only the first one.
0 commit comments