55import binascii
66import array
77
8+ # Note: "*_hex" functions are aliases for "(un)hexlify"
9+ b2a_functions = ['b2a_base64' , 'b2a_hex' , 'b2a_hqx' , 'b2a_qp' , 'b2a_uu' ,
10+ 'hexlify' , 'rlecode_hqx' ]
11+ a2b_functions = ['a2b_base64' , 'a2b_hex' , 'a2b_hqx' , 'a2b_qp' , 'a2b_uu' ,
12+ 'unhexlify' , 'rledecode_hqx' ]
13+ all_functions = a2b_functions + b2a_functions + ['crc32' , 'crc_hqx' ]
14+
15+
816class BinASCIITest (unittest .TestCase ):
917
1018 type2test = bytes
@@ -24,30 +32,45 @@ def test_exceptions(self):
2432
2533 def test_functions (self ):
2634 # Check presence of all functions
27- funcs = []
28- for suffix in "base64" , "hqx" , "uu" , "hex" :
29- prefixes = ["a2b_" , "b2a_" ]
30- if suffix == "hqx" :
31- prefixes .extend (["crc_" , "rlecode_" , "rledecode_" ])
32- for prefix in prefixes :
33- name = prefix + suffix
34- self .assertTrue (hasattr (getattr (binascii , name ), '__call__' ))
35- self .assertRaises (TypeError , getattr (binascii , name ))
36- for name in ("hexlify" , "unhexlify" ):
35+ for name in all_functions :
3736 self .assertTrue (hasattr (getattr (binascii , name ), '__call__' ))
3837 self .assertRaises (TypeError , getattr (binascii , name ))
3938
39+ def test_returned_value (self ):
40+ # Limit to the minimum of all limits (b2a_uu)
41+ MAX_ALL = 45
42+ raw = self .rawdata [:MAX_ALL ]
43+ for fa , fb in zip (a2b_functions , b2a_functions ):
44+ a2b = getattr (binascii , fa )
45+ b2a = getattr (binascii , fb )
46+ try :
47+ a = b2a (self .type2test (raw ))
48+ res = a2b (self .type2test (a ))
49+ except Exception as err :
50+ self .fail ("{}/{} conversion raises {!r}" .format (fb , fa , err ))
51+ if fb == 'b2a_hqx' :
52+ # b2a_hqx returns a tuple
53+ res , _ = res
54+ self .assertEqual (res , raw , "{}/{} conversion: "
55+ "{!r} != {!r}" .format (fb , fa , res , raw ))
56+ self .assertIsInstance (res , bytes )
57+ self .assertIsInstance (a , bytes )
58+ self .assertLess (max (c for c in a ), 128 )
59+ self .assertIsInstance (binascii .crc_hqx (raw , 0 ), int )
60+ self .assertIsInstance (binascii .crc32 (raw ), int )
61+
4062 def test_base64valid (self ):
4163 # Test base64 with valid data
4264 MAX_BASE64 = 57
4365 lines = []
44- for i in range (0 , len (self .data ), MAX_BASE64 ):
45- b = self .data [i :i + MAX_BASE64 ]
66+ for i in range (0 , len (self .rawdata ), MAX_BASE64 ):
67+ b = self .type2test ( self . rawdata [i :i + MAX_BASE64 ])
4668 a = binascii .b2a_base64 (b )
4769 lines .append (a )
4870 res = bytes ()
4971 for line in lines :
50- b = binascii .a2b_base64 (line )
72+ a = self .type2test (line )
73+ b = binascii .a2b_base64 (a )
5174 res += b
5275 self .assertEqual (res , self .rawdata )
5376
@@ -57,7 +80,7 @@ def test_base64invalid(self):
5780 MAX_BASE64 = 57
5881 lines = []
5982 for i in range (0 , len (self .data ), MAX_BASE64 ):
60- b = self .data [i :i + MAX_BASE64 ]
83+ b = self .type2test ( self . rawdata [i :i + MAX_BASE64 ])
6184 a = binascii .b2a_base64 (b )
6285 lines .append (a )
6386
@@ -79,24 +102,26 @@ def addnoise(line):
79102 return res + noise + line
80103 res = bytearray ()
81104 for line in map (addnoise , lines ):
82- b = binascii .a2b_base64 (line )
105+ a = self .type2test (line )
106+ b = binascii .a2b_base64 (a )
83107 res += b
84108 self .assertEqual (res , self .rawdata )
85109
86110 # Test base64 with just invalid characters, which should return
87111 # empty strings. TBD: shouldn't it raise an exception instead ?
88- self .assertEqual (binascii .a2b_base64 (fillers ), b'' )
112+ self .assertEqual (binascii .a2b_base64 (self . type2test ( fillers ) ), b'' )
89113
90114 def test_uu (self ):
91115 MAX_UU = 45
92116 lines = []
93117 for i in range (0 , len (self .data ), MAX_UU ):
94- b = self .data [i :i + MAX_UU ]
118+ b = self .type2test ( self . rawdata [i :i + MAX_UU ])
95119 a = binascii .b2a_uu (b )
96120 lines .append (a )
97121 res = bytes ()
98122 for line in lines :
99- b = binascii .a2b_uu (line )
123+ a = self .type2test (line )
124+ b = binascii .a2b_uu (a )
100125 res += b
101126 self .assertEqual (res , self .rawdata )
102127
@@ -112,19 +137,27 @@ def test_uu(self):
112137 self .assertEqual (binascii .b2a_uu (b'x' ), b'!> \n ' )
113138
114139 def test_crc32 (self ):
115- crc = binascii .crc32 (b"Test the CRC-32 of" )
116- crc = binascii .crc32 (b" this string." , crc )
140+ crc = binascii .crc32 (self . type2test ( b"Test the CRC-32 of" ) )
141+ crc = binascii .crc32 (self . type2test ( b" this string." ) , crc )
117142 self .assertEqual (crc , 1571220330 )
118143
119144 self .assertRaises (TypeError , binascii .crc32 )
120145
121- # The hqx test is in test_binhex.py
146+ def test_hqx (self ):
147+ # Perform binhex4 style RLE-compression
148+ # Then calculate the hexbin4 binary-to-ASCII translation
149+ rle = binascii .rlecode_hqx (self .data )
150+ a = binascii .b2a_hqx (self .type2test (rle ))
151+ b , _ = binascii .a2b_hqx (self .type2test (a ))
152+ res = binascii .rledecode_hqx (b )
153+
154+ self .assertEqual (res , self .rawdata )
122155
123156 def test_hex (self ):
124157 # test hexlification
125158 s = b'{s\005 \000 \000 \000 worldi\002 \000 \000 \000 s\005 \000 \000 \000 helloi\001 \000 \000 \000 0'
126- t = binascii .b2a_hex (s )
127- u = binascii .a2b_hex (t )
159+ t = binascii .b2a_hex (self . type2test ( s ) )
160+ u = binascii .a2b_hex (self . type2test ( t ) )
128161 self .assertEqual (s , u )
129162 self .assertRaises (binascii .Error , binascii .a2b_hex , t [:- 1 ])
130163 self .assertRaises (binascii .Error , binascii .a2b_hex , t [:- 1 ] + b'q' )
@@ -165,16 +198,17 @@ def test_qp(self):
165198
166199 def test_empty_string (self ):
167200 # A test for SF bug #1022953. Make sure SystemError is not raised.
168- for n in ['b2a_qp' , 'a2b_hex' , 'b2a_base64' , 'a2b_uu' , 'a2b_qp' ,
169- 'b2a_hex' , 'unhexlify' , 'hexlify' , 'crc32' , 'b2a_hqx' ,
170- 'a2b_hqx' , 'a2b_base64' , 'rlecode_hqx' , 'b2a_uu' ,
171- 'rledecode_hqx' ]:
172- f = getattr (binascii , n )
201+ empty = self .type2test (b'' )
202+ for func in all_functions :
203+ if func == 'crc_hqx' :
204+ # crc_hqx needs 2 arguments
205+ binascii .crc_hqx (empty , 0 )
206+ continue
207+ f = getattr (binascii , func )
173208 try :
174- f (b'' )
175- except SystemError as err :
176- self .fail ("%s(b'') raises SystemError: %s" % (n , err ))
177- binascii .crc_hqx (b'' , 0 )
209+ f (empty )
210+ except Exception as err :
211+ self .fail ("{}({!r}) raises {!r}" .format (func , empty , err ))
178212
179213 def test_no_binary_strings (self ):
180214 # b2a_ must not accept strings
@@ -190,13 +224,18 @@ def type2test(self, s):
190224 return array .array ('B' , list (s ))
191225
192226
227+ class BytearrayBinASCIITest (BinASCIITest ):
228+ type2test = bytearray
229+
230+
193231class MemoryviewBinASCIITest (BinASCIITest ):
194232 type2test = memoryview
195233
196234
197235def test_main ():
198236 support .run_unittest (BinASCIITest ,
199237 ArrayBinASCIITest ,
238+ BytearrayBinASCIITest ,
200239 MemoryviewBinASCIITest )
201240
202241if __name__ == "__main__" :
0 commit comments