@@ -378,6 +378,10 @@ def test_lone_surrogates(self):
378378 before + after )
379379 self .assertEqual (test_sequence .decode (self .encoding , "replace" ),
380380 before + self .ill_formed_sequence_replace + after )
381+ backslashreplace = '' .join ('\\ x%02x' % b
382+ for b in self .ill_formed_sequence )
383+ self .assertEqual (test_sequence .decode (self .encoding , "backslashreplace" ),
384+ before + backslashreplace + after )
381385
382386class UTF32Test (ReadTest , unittest .TestCase ):
383387 encoding = "utf-32"
@@ -1300,14 +1304,19 @@ def test_bug1251300(self):
13001304 "unicode_internal" )
13011305 if sys .byteorder == "little" :
13021306 invalid = b"\x00 \x00 \x11 \x00 "
1307+ invalid_backslashreplace = r"\x00\x00\x11\x00"
13031308 else :
13041309 invalid = b"\x00 \x11 \x00 \x00 "
1310+ invalid_backslashreplace = r"\x00\x11\x00\x00"
13051311 with support .check_warnings ():
13061312 self .assertRaises (UnicodeDecodeError ,
13071313 invalid .decode , "unicode_internal" )
13081314 with support .check_warnings ():
13091315 self .assertEqual (invalid .decode ("unicode_internal" , "replace" ),
13101316 '\ufffd ' )
1317+ with support .check_warnings ():
1318+ self .assertEqual (invalid .decode ("unicode_internal" , "backslashreplace" ),
1319+ invalid_backslashreplace )
13111320
13121321 @unittest .skipUnless (SIZEOF_WCHAR_T == 4 , 'specific to 32-bit wchar_t' )
13131322 def test_decode_error_attributes (self ):
@@ -2042,6 +2051,16 @@ def test_decode_with_string_map(self):
20422051 ("ab\ufffd " , 3 )
20432052 )
20442053
2054+ self .assertEqual (
2055+ codecs .charmap_decode (b"\x00 \x01 \x02 " , "backslashreplace" , "ab" ),
2056+ ("ab\\ x02" , 3 )
2057+ )
2058+
2059+ self .assertEqual (
2060+ codecs .charmap_decode (b"\x00 \x01 \x02 " , "backslashreplace" , "ab\ufffe " ),
2061+ ("ab\\ x02" , 3 )
2062+ )
2063+
20452064 self .assertEqual (
20462065 codecs .charmap_decode (b"\x00 \x01 \x02 " , "ignore" , "ab" ),
20472066 ("ab" , 3 )
@@ -2118,6 +2137,25 @@ def test_decode_with_int2str_map(self):
21182137 ("ab\ufffd " , 3 )
21192138 )
21202139
2140+ self .assertEqual (
2141+ codecs .charmap_decode (b"\x00 \x01 \x02 " , "backslashreplace" ,
2142+ {0 : 'a' , 1 : 'b' }),
2143+ ("ab\\ x02" , 3 )
2144+ )
2145+
2146+ self .assertEqual (
2147+ codecs .charmap_decode (b"\x00 \x01 \x02 " , "backslashreplace" ,
2148+ {0 : 'a' , 1 : 'b' , 2 : None }),
2149+ ("ab\\ x02" , 3 )
2150+ )
2151+
2152+ # Issue #14850
2153+ self .assertEqual (
2154+ codecs .charmap_decode (b"\x00 \x01 \x02 " , "backslashreplace" ,
2155+ {0 : 'a' , 1 : 'b' , 2 : '\ufffe ' }),
2156+ ("ab\\ x02" , 3 )
2157+ )
2158+
21212159 self .assertEqual (
21222160 codecs .charmap_decode (b"\x00 \x01 \x02 " , "ignore" ,
21232161 {0 : 'a' , 1 : 'b' }),
@@ -2194,6 +2232,18 @@ def test_decode_with_int2int_map(self):
21942232 ("ab\ufffd " , 3 )
21952233 )
21962234
2235+ self .assertEqual (
2236+ codecs .charmap_decode (b"\x00 \x01 \x02 " , "backslashreplace" ,
2237+ {0 : a , 1 : b }),
2238+ ("ab\\ x02" , 3 )
2239+ )
2240+
2241+ self .assertEqual (
2242+ codecs .charmap_decode (b"\x00 \x01 \x02 " , "backslashreplace" ,
2243+ {0 : a , 1 : b , 2 : 0xFFFE }),
2244+ ("ab\\ x02" , 3 )
2245+ )
2246+
21972247 self .assertEqual (
21982248 codecs .charmap_decode (b"\x00 \x01 \x02 " , "ignore" ,
21992249 {0 : a , 1 : b }),
@@ -2253,9 +2303,13 @@ def test_unicode_escape(self):
22532303
22542304 self .assertRaises (UnicodeDecodeError , codecs .unicode_escape_decode , br"\U00110000" )
22552305 self .assertEqual (codecs .unicode_escape_decode (r"\U00110000" , "replace" ), ("\ufffd " , 10 ))
2306+ self .assertEqual (codecs .unicode_escape_decode (r"\U00110000" , "backslashreplace" ),
2307+ (r"\x5c\x55\x30\x30\x31\x31\x30\x30\x30\x30" , 10 ))
22562308
22572309 self .assertRaises (UnicodeDecodeError , codecs .raw_unicode_escape_decode , br"\U00110000" )
22582310 self .assertEqual (codecs .raw_unicode_escape_decode (r"\U00110000" , "replace" ), ("\ufffd " , 10 ))
2311+ self .assertEqual (codecs .raw_unicode_escape_decode (r"\U00110000" , "backslashreplace" ),
2312+ (r"\x5c\x55\x30\x30\x31\x31\x30\x30\x30\x30" , 10 ))
22592313
22602314
22612315class UnicodeEscapeTest (unittest .TestCase ):
@@ -2894,11 +2948,13 @@ def test_cp932(self):
28942948 (b'[\xff ]' , 'strict' , None ),
28952949 (b'[\xff ]' , 'ignore' , '[]' ),
28962950 (b'[\xff ]' , 'replace' , '[\ufffd ]' ),
2951+ (b'[\xff ]' , 'backslashreplace' , '[\\ xff]' ),
28972952 (b'[\xff ]' , 'surrogateescape' , '[\udcff ]' ),
28982953 (b'[\xff ]' , 'surrogatepass' , None ),
28992954 (b'\x81 \x00 abc' , 'strict' , None ),
29002955 (b'\x81 \x00 abc' , 'ignore' , '\x00 abc' ),
29012956 (b'\x81 \x00 abc' , 'replace' , '\ufffd \x00 abc' ),
2957+ (b'\x81 \x00 abc' , 'backslashreplace' , '\\ xff\x00 abc' ),
29022958 ))
29032959
29042960 def test_cp1252 (self ):
0 commit comments