@@ -473,5 +473,165 @@ def test_collection_of_two_buildables_history(self):
473473 self .assertRegex (output , expected )
474474
475475
476+ class AsFlattenedDictTests (absltest .TestCase ):
477+
478+ def test_simple_flattened_dict (self ):
479+ cfg = fdl .Config (fn_x_y , 1 , 'abc' )
480+ output = printing .as_dict_flattened (cfg )
481+
482+ expected = {'x' : 1 , 'y' : 'abc' }
483+ self .assertEqual (output , expected )
484+
485+ def test_skip_unset_argument (self ):
486+ cfg = fdl .Config (fn_x_y , 3.14 )
487+ output = printing .as_dict_flattened (cfg )
488+
489+ expected = {'x' : 3.14 }
490+ self .assertEqual (output , expected )
491+
492+ def test_nested (self ):
493+ cfg = fdl .Config (fn_x_y , 'x' , fdl .Config (fn_x_y , 'nest_x' , 123 ))
494+ output = printing .as_dict_flattened (cfg )
495+
496+ expected = {'x' : 'x' , 'y.x' : 'nest_x' , 'y.y' : 123 }
497+ self .assertEqual (output , expected )
498+
499+ def test_class (self ):
500+ cfg = fdl .Config (SampleClass , 'a_param' , b = 123 )
501+ output = printing .as_dict_flattened (cfg )
502+
503+ expected = {'a' : 'a_param' , 'b' : 123 }
504+ self .assertEqual (output , expected )
505+
506+ def test_kwargs (self ):
507+ cfg = fdl .Config (fn_with_kwargs , 1 , abc = 'extra kwarg value' )
508+ output = printing .as_dict_flattened (cfg )
509+
510+ expected = {'x' : 1 , 'abc' : 'extra kwarg value' }
511+ self .assertEqual (output , expected )
512+
513+ def test_nested_kwargs (self ):
514+ cfg = fdl .Config (
515+ fn_with_kwargs , extra = fdl .Config (fn_with_kwargs , 1 , nested_extra = 'whee' )
516+ )
517+ output = printing .as_dict_flattened (cfg )
518+
519+ expected = {'extra.x' : 1 , 'extra.nested_extra' : 'whee' }
520+ self .assertEqual (output , expected )
521+
522+ def test_nested_collections (self ):
523+ cfg = fdl .Config (
524+ fn_x_y , [fdl .Config (fn_x_y , 1 , '1' ), fdl .Config (SampleClass , 2 )]
525+ )
526+ output = printing .as_dict_flattened (cfg )
527+
528+ expected = {'x[0].x' : 1 , 'x[0].y' : '1' , 'x[1].a' : 2 }
529+ self .assertEqual (output , expected )
530+
531+ def test_multiple_nested_collections (self ):
532+ cfg = fdl .Config (
533+ fn_x_y ,
534+ {'a' : fdl .Config (fn_with_kwargs , abc = [1 , 2 , 3 ]), 'b' : [3 , 2 , 1 ]},
535+ [fdl .Config (fn_x_y , [fdl .Config (fn_x_y , 1 , 2 )])],
536+ )
537+ output = printing .as_dict_flattened (cfg )
538+
539+ expected = {
540+ "x['a'].abc" : [1 , 2 , 3 ],
541+ "x['b']" : [3 , 2 , 1 ],
542+ 'y[0].x[0].x' : 1 ,
543+ 'y[0].x[0].y' : 2 ,
544+ }
545+ self .assertEqual (output , expected )
546+
547+ def test_skip_default_values (self ):
548+ def test_fn (w , x , y = 3 , z = 'abc' ): # pylint: disable=unused-argument
549+ pass
550+
551+ cfg = fdl .Config (test_fn , 1 )
552+ output = printing .as_dict_flattened (cfg )
553+
554+ expected = {'w' : 1 }
555+ self .assertEqual (output , expected )
556+
557+ def test_tagged_values (self ):
558+ cfg = fdl .Config (fn_x_y , x = SampleTag .new (), y = SampleTag .new (default = 'abc' ))
559+ output = printing .as_dict_flattened (cfg )
560+
561+ expected = "'abc' #__main__.SampleTag"
562+ self .assertEqual (repr (output ['y' ]), expected )
563+
564+ fdl .set_tagged (cfg , tag = SampleTag , value = 'cba' )
565+ output = printing .as_dict_flattened (cfg )
566+
567+ expected = "'cba' #__main__.SampleTag"
568+ self .assertEqual (repr (output ['x' ]), expected )
569+ self .assertEqual (repr (output ['y' ]), expected )
570+
571+ def test_partial (self ):
572+ partial = fdl .Partial (fn_x_y )
573+ partial .x = 'abc'
574+ output = printing .as_dict_flattened (partial )
575+
576+ expected = {'x' : 'abc' }
577+ self .assertEqual (output , expected )
578+
579+ def test_builtin_types_annotations (self ):
580+ cfg = fdl .Config (fn_with_type_annotations , 1 )
581+ cfg .y = 'abc'
582+ output = printing .as_dict_flattened (cfg )
583+
584+ expected = {'x' : 1 , 'y' : 'abc' }
585+ self .assertEqual (output , expected )
586+
587+ def test_annotated_kwargs (self ):
588+ cfg = fdl .Config (annotated_kwargs_helper , x = 1 , y = 'oops' )
589+ output = printing .as_dict_flattened (cfg )
590+
591+ expected = {'x' : 1 , 'y' : 'oops' }
592+ self .assertEqual (output , expected )
593+
594+ def test_disabling_type_annotations (self ):
595+ cfg = fdl .Config (fn_with_type_annotations , 1 )
596+ cfg .y = 'abc'
597+ output = printing .as_dict_flattened (cfg )
598+
599+ expected = {'x' : 1 , 'y' : 'abc' }
600+ self .assertEqual (output , expected )
601+
602+ def test_union_type (self ):
603+ def to_integer (x : Union [int , str ]):
604+ return int (x )
605+
606+ cfg = fdl .Config (to_integer , 1 )
607+ output = printing .as_dict_flattened (cfg )
608+
609+ expected = {'x' : 1 }
610+ self .assertEqual (output , expected )
611+
612+ def test_parameterized_generic (self ):
613+ if not (sys .version_info .major == 3 and sys .version_info .minor >= 9 ):
614+ self .skipTest ('types.GenericAlias is 3.9+ only.' )
615+
616+ def takes_list (x : list [int ]):
617+ return x
618+
619+ cfg = fdl .Config (takes_list , [1 , 2 , 3 ])
620+ output = printing .as_dict_flattened (cfg )
621+
622+ expected = {'x' : [1 , 2 , 3 ]}
623+ self .assertEqual (output , expected )
624+
625+ def test_materialized_default_values (self ):
626+ def test_fn (w , x , y = 3 , z = 'abc' ):
627+ del w , x , y , z # Unused.
628+
629+ cfg = fdl .Config (test_fn , 1 )
630+ fdl .materialize_defaults (cfg )
631+ output = printing .as_dict_flattened (cfg )
632+ expected = {'w' : 1 , 'y' : 3 , 'z' : 'abc' }
633+ self .assertEqual (output , expected )
634+
635+
476636if __name__ == '__main__' :
477637 absltest .main ()
0 commit comments