@@ -695,6 +695,84 @@ def __format__(self, format_spec):
695695 self .assertRaises (ValueError , format , '' , '#' )
696696 self .assertRaises (ValueError , format , '' , '#20' )
697697
698+ def test_format_map (self ):
699+ self .assertEqual ('' .format_map ({}), '' )
700+ self .assertEqual ('a' .format_map ({}), 'a' )
701+ self .assertEqual ('ab' .format_map ({}), 'ab' )
702+ self .assertEqual ('a{{' .format_map ({}), 'a{' )
703+ self .assertEqual ('a}}' .format_map ({}), 'a}' )
704+ self .assertEqual ('{{b' .format_map ({}), '{b' )
705+ self .assertEqual ('}}b' .format_map ({}), '}b' )
706+ self .assertEqual ('a{{b' .format_map ({}), 'a{b' )
707+
708+ # using mappings
709+ class Mapping (dict ):
710+ def __missing__ (self , key ):
711+ return key
712+ self .assertEqual ('{hello}' .format_map (Mapping ()), 'hello' )
713+ self .assertEqual ('{a} {world}' .format_map (Mapping (a = 'hello' )), 'hello world' )
714+
715+ class InternalMapping :
716+ def __init__ (self ):
717+ self .mapping = {'a' : 'hello' }
718+ def __getitem__ (self , key ):
719+ return self .mapping [key ]
720+ self .assertEqual ('{a}' .format_map (InternalMapping ()), 'hello' )
721+
722+
723+ # classes we'll use for testing
724+ class C :
725+ def __init__ (self , x = 100 ):
726+ self ._x = x
727+ def __format__ (self , spec ):
728+ return spec
729+
730+ class D :
731+ def __init__ (self , x ):
732+ self .x = x
733+ def __format__ (self , spec ):
734+ return str (self .x )
735+
736+ # class with __str__, but no __format__
737+ class E :
738+ def __init__ (self , x ):
739+ self .x = x
740+ def __str__ (self ):
741+ return 'E(' + self .x + ')'
742+
743+ # class with __repr__, but no __format__ or __str__
744+ class F :
745+ def __init__ (self , x ):
746+ self .x = x
747+ def __repr__ (self ):
748+ return 'F(' + self .x + ')'
749+
750+ # class with __format__ that forwards to string, for some format_spec's
751+ class G :
752+ def __init__ (self , x ):
753+ self .x = x
754+ def __str__ (self ):
755+ return "string is " + self .x
756+ def __format__ (self , format_spec ):
757+ if format_spec == 'd' :
758+ return 'G(' + self .x + ')'
759+ return object .__format__ (self , format_spec )
760+
761+ # class that returns a bad type from __format__
762+ class H :
763+ def __format__ (self , format_spec ):
764+ return 1.0
765+
766+ self .assertEqual ('{foo._x}' .format_map ({'foo' : C (20 )}), '20' )
767+
768+ # test various errors
769+ self .assertRaises (TypeError , '{' .format_map )
770+ self .assertRaises (TypeError , '}' .format_map )
771+ self .assertRaises (TypeError , 'a{' .format_map )
772+ self .assertRaises (TypeError , 'a}' .format_map )
773+ self .assertRaises (TypeError , '{a' .format_map )
774+ self .assertRaises (TypeError , '}a' .format_map )
775+
698776 def test_format_auto_numbering (self ):
699777 class C :
700778 def __init__ (self , x = 100 ):
0 commit comments