22import binascii
33import os
44from array import array
5- from functools import update_wrapper
65from test .support import os_helper
76from test .support import script_helper
87from test .support .import_helper import import_fresh_module
98
10- base64 = import_fresh_module ("base64" , blocked = ["_base64" ])
9+ py_base64 = import_fresh_module ("base64" , blocked = ["_base64" ])
1110c_base64 = import_fresh_module ("base64" , fresh = ["_base64" ])
1211
1312
14- def with_c_implementation (test_func ):
15- if c_base64 is None :
16- return test_func
17-
18- def _test_func (self ):
19- global base64
20-
21- # Test Python implementation
22- test_func (self )
23-
24- # Test C implementation
25- base64_ = base64
26- try :
27- base64 = c_base64
28- test_func (self )
29- finally :
30- base64 = base64_
31-
32- update_wrapper (_test_func , test_func )
33-
34- return _test_func
35-
36-
37- class LegacyBase64TestCase (unittest .TestCase ):
13+ class LegacyBase64TestCase :
3814
3915 # Legacy API is not as permissive as the modern API
4016 def check_type_errors (self , f ):
@@ -46,6 +22,7 @@ def check_type_errors(self, f):
4622 self .assertRaises (TypeError , f , int_data )
4723
4824 def test_encodebytes (self ):
25+ base64 = self .module
4926 eq = self .assertEqual
5027 eq (base64 .encodebytes (b"www.python.org" ), b"d3d3LnB5dGhvbi5vcmc=\n " )
5128 eq (base64 .encodebytes (b"a" ), b"YQ==\n " )
@@ -67,6 +44,7 @@ def test_encodebytes(self):
6744 self .check_type_errors (base64 .encodebytes )
6845
6946 def test_decodebytes (self ):
47+ base64 = self .module
7048 eq = self .assertEqual
7149 eq (base64 .decodebytes (b"d3d3LnB5dGhvbi5vcmc=\n " ), b"www.python.org" )
7250 eq (base64 .decodebytes (b"YQ==\n " ), b"a" )
@@ -88,6 +66,7 @@ def test_decodebytes(self):
8866 self .check_type_errors (base64 .decodebytes )
8967
9068 def test_encode (self ):
69+ base64 = self .module
9170 eq = self .assertEqual
9271 from io import BytesIO , StringIO
9372 infp = BytesIO (b'abcdefghijklmnopqrstuvwxyz'
@@ -105,6 +84,7 @@ def test_encode(self):
10584 self .assertRaises (TypeError , base64 .encode , StringIO ('abc' ), StringIO ())
10685
10786 def test_decode (self ):
87+ base64 = self .module
10888 from io import BytesIO , StringIO
10989 infp = BytesIO (b'd3d3LnB5dGhvbi5vcmc=' )
11090 outfp = BytesIO ()
@@ -116,7 +96,16 @@ def test_decode(self):
11696 self .assertRaises (TypeError , base64 .encode , StringIO ('YWJj\n ' ), StringIO ())
11797
11898
119- class BaseXYTestCase (unittest .TestCase ):
99+ class LegacyBase64TestCasePython (LegacyBase64TestCase , unittest .TestCase ):
100+ module = py_base64
101+
102+
103+ @unittest .skipUnless (c_base64 , "requires _base64" )
104+ class LegacyBase64TestCaseC (LegacyBase64TestCase , unittest .TestCase ):
105+ module = c_base64
106+
107+
108+ class BaseXYTestCase :
120109
121110 # Modern API completely ignores exported dimension and format data and
122111 # treats any buffer as a stream of bytes
@@ -128,6 +117,7 @@ def check_decode_type_errors(self, f):
128117 self .assertRaises (TypeError , f , [])
129118
130119 def check_other_types (self , f , bytes_data , expected ):
120+ base64 = self .module
131121 eq = self .assertEqual
132122 b = bytearray (bytes_data )
133123 eq (f (b ), expected )
@@ -154,6 +144,7 @@ def check_nonbyte_element_format(self, f, data):
154144
155145
156146 def test_b64encode (self ):
147+ base64 = self .module
157148 eq = self .assertEqual
158149 # Test default alphabet
159150 eq (base64 .b64encode (b"www.python.org" ), b"d3d3LnB5dGhvbi5vcmc=" )
@@ -204,6 +195,7 @@ def test_b64encode(self):
204195 self .check_encode_type_errors (base64 .urlsafe_b64encode )
205196
206197 def test_b64decode (self ):
198+ base64 = self .module
207199 eq = self .assertEqual
208200
209201 tests = {b"d3d3LnB5dGhvbi5vcmc=" : b"www.python.org" ,
@@ -260,10 +252,12 @@ def test_b64decode(self):
260252 self .check_decode_type_errors (base64 .urlsafe_b64decode )
261253
262254 def test_b64decode_padding_error (self ):
255+ base64 = self .module
263256 self .assertRaises (binascii .Error , base64 .b64decode , b'abc' )
264257 self .assertRaises (binascii .Error , base64 .b64decode , 'abc' )
265258
266259 def test_b64decode_invalid_chars (self ):
260+ base64 = self .module
267261 # issue 1466065: Test some invalid characters.
268262 tests = ((b'%3d==' , b'\xdd ' ),
269263 (b'$3d==' , b'\xdd ' ),
@@ -296,6 +290,7 @@ def test_b64decode_invalid_chars(self):
296290 self .assertEqual (base64 .urlsafe_b64decode (b'++--//__' ), res )
297291
298292 def test_b32encode (self ):
293+ base64 = self .module
299294 eq = self .assertEqual
300295 eq (base64 .b32encode (b'' ), b'' )
301296 eq (base64 .b32encode (b'\x00 ' ), b'AA======' )
@@ -309,6 +304,7 @@ def test_b32encode(self):
309304 self .check_encode_type_errors (base64 .b32encode )
310305
311306 def test_b32decode (self ):
307+ base64 = self .module
312308 eq = self .assertEqual
313309 tests = {b'' : b'' ,
314310 b'AA======' : b'\x00 ' ,
@@ -326,6 +322,7 @@ def test_b32decode(self):
326322 self .check_decode_type_errors (base64 .b32decode )
327323
328324 def test_b32decode_casefold (self ):
325+ base64 = self .module
329326 eq = self .assertEqual
330327 tests = {b'' : b'' ,
331328 b'ME======' : b'a' ,
@@ -367,6 +364,7 @@ def test_b32decode_casefold(self):
367364 self .assertRaises (binascii .Error , base64 .b32decode , data_str )
368365
369366 def test_b32decode_error (self ):
367+ base64 = self .module
370368 tests = [b'abc' , b'ABCDEF==' , b'==ABCDEF' ]
371369 prefixes = [b'M' , b'ME' , b'MFRA' , b'MFRGG' , b'MFRGGZA' , b'MFRGGZDF' ]
372370 for i in range (0 , 17 ):
@@ -383,6 +381,7 @@ def test_b32decode_error(self):
383381 base64 .b32decode (data .decode ('ascii' ))
384382
385383 def test_b32hexencode (self ):
384+ base64 = self .module
386385 test_cases = [
387386 # to_encode, expected
388387 (b'' , b'' ),
@@ -398,10 +397,12 @@ def test_b32hexencode(self):
398397 self .assertEqual (base64 .b32hexencode (to_encode ), expected )
399398
400399 def test_b32hexencode_other_types (self ):
400+ base64 = self .module
401401 self .check_other_types (base64 .b32hexencode , b'abcd' , b'C5H66P0=' )
402402 self .check_encode_type_errors (base64 .b32hexencode )
403403
404404 def test_b32hexdecode (self ):
405+ base64 = self .module
405406 test_cases = [
406407 # to_decode, expected, casefold
407408 (b'' , b'' , False ),
@@ -432,10 +433,12 @@ def test_b32hexdecode(self):
432433 casefold ), expected )
433434
434435 def test_b32hexdecode_other_types (self ):
436+ base64 = self .module
435437 self .check_other_types (base64 .b32hexdecode , b'C5H66===' , b'abc' )
436438 self .check_decode_type_errors (base64 .b32hexdecode )
437439
438440 def test_b32hexdecode_error (self ):
441+ base64 = self .module
439442 tests = [b'abc' , b'ABCDEF==' , b'==ABCDEF' , b'c4======' ]
440443 prefixes = [b'M' , b'ME' , b'MFRA' , b'MFRGG' , b'MFRGGZA' , b'MFRGGZDF' ]
441444 for i in range (0 , 17 ):
@@ -453,6 +456,7 @@ def test_b32hexdecode_error(self):
453456
454457
455458 def test_b16encode (self ):
459+ base64 = self .module
456460 eq = self .assertEqual
457461 eq (base64 .b16encode (b'\x01 \x02 \xab \xcd \xef ' ), b'0102ABCDEF' )
458462 eq (base64 .b16encode (b'\x00 ' ), b'00' )
@@ -462,6 +466,7 @@ def test_b16encode(self):
462466 self .check_encode_type_errors (base64 .b16encode )
463467
464468 def test_b16decode (self ):
469+ base64 = self .module
465470 eq = self .assertEqual
466471 eq (base64 .b16decode (b'0102ABCDEF' ), b'\x01 \x02 \xab \xcd \xef ' )
467472 eq (base64 .b16decode ('0102ABCDEF' ), b'\x01 \x02 \xab \xcd \xef ' )
@@ -488,8 +493,8 @@ def test_b16decode(self):
488493 # Incorrect "padding"
489494 self .assertRaises (binascii .Error , base64 .b16decode , '010' )
490495
491- @with_c_implementation
492496 def test_a85encode (self ):
497+ base64 = self .module
493498 eq = self .assertEqual
494499
495500 tests = {
@@ -539,8 +544,8 @@ def test_a85encode(self):
539544 eq (base64 .a85encode (b' ' * 6 , foldspaces = True , adobe = False ), b'y+<U' )
540545 eq (base64 .a85encode (b' ' * 5 , foldspaces = True , adobe = False ), b'y+9' )
541546
542- @with_c_implementation
543547 def test_b85encode (self ):
548+ base64 = self .module
544549 eq = self .assertEqual
545550
546551 tests = {
@@ -574,8 +579,8 @@ def test_b85encode(self):
574579 self .check_other_types (base64 .b85encode , b"www.python.org" ,
575580 b'cXxL#aCvlSZ*DGca%T' )
576581
577- @with_c_implementation
578582 def test_z85encode (self ):
583+ base64 = self .module
579584 eq = self .assertEqual
580585
581586 tests = {
@@ -609,8 +614,8 @@ def test_z85encode(self):
609614 self .check_other_types (base64 .z85encode , b"www.python.org" ,
610615 b'CxXl-AcVLsz/dgCA+t' )
611616
612- @with_c_implementation
613617 def test_a85decode (self ):
618+ base64 = self .module
614619 eq = self .assertEqual
615620
616621 tests = {
@@ -656,8 +661,8 @@ def test_a85decode(self):
656661 self .check_other_types (base64 .a85decode , b'GB\\ 6`E-ZP=Df.1GEb>' ,
657662 b"www.python.org" )
658663
659- @with_c_implementation
660664 def test_b85decode (self ):
665+ base64 = self .module
661666 eq = self .assertEqual
662667
663668 tests = {
@@ -692,8 +697,8 @@ def test_b85decode(self):
692697 self .check_other_types (base64 .b85decode , b'cXxL#aCvlSZ*DGca%T' ,
693698 b"www.python.org" )
694699
695- @with_c_implementation
696700 def test_z85decode (self ):
701+ base64 = self .module
697702 eq = self .assertEqual
698703
699704 tests = {
@@ -728,8 +733,8 @@ def test_z85decode(self):
728733 self .check_other_types (base64 .z85decode , b'CxXl-AcVLsz/dgCA+t' ,
729734 b'www.python.org' )
730735
731- @with_c_implementation
732736 def test_a85_padding (self ):
737+ base64 = self .module
733738 eq = self .assertEqual
734739
735740 eq (base64 .a85encode (b"x" , pad = True ), b'GQ7^D' )
@@ -744,8 +749,8 @@ def test_a85_padding(self):
744749 eq (base64 .a85decode (b'G^+IX' ), b"xxxx" )
745750 eq (base64 .a85decode (b'G^+IXGQ7^D' ), b"xxxxx\x00 \x00 \x00 " )
746751
747- @with_c_implementation
748752 def test_b85_padding (self ):
753+ base64 = self .module
749754 eq = self .assertEqual
750755
751756 eq (base64 .b85encode (b"x" , pad = True ), b'cmMzZ' )
@@ -760,8 +765,8 @@ def test_b85_padding(self):
760765 eq (base64 .b85decode (b'czAet' ), b"xxxx" )
761766 eq (base64 .b85decode (b'czAetcmMzZ' ), b"xxxxx\x00 \x00 \x00 " )
762767
763- @with_c_implementation
764768 def test_a85decode_errors (self ):
769+ base64 = self .module
765770 illegal = (set (range (32 )) | set (range (118 , 256 ))) - set (b' \t \n \r \v ' )
766771 for c in illegal :
767772 with self .assertRaises (ValueError , msg = bytes ([c ])):
@@ -798,8 +803,8 @@ def test_a85decode_errors(self):
798803 self .assertRaises (ValueError , base64 .a85decode , b'aaaay' ,
799804 foldspaces = True )
800805
801- @with_c_implementation
802806 def test_b85decode_errors (self ):
807+ base64 = self .module
803808 illegal = list (range (33 )) + \
804809 list (b'"\' ,./:[\\ ]' ) + \
805810 list (range (128 , 256 ))
@@ -813,8 +818,8 @@ def test_b85decode_errors(self):
813818 self .assertRaises (ValueError , base64 .b85decode , b'|NsC' )
814819 self .assertRaises (ValueError , base64 .b85decode , b'|NsC1' )
815820
816- @with_c_implementation
817821 def test_z85decode_errors (self ):
822+ base64 = self .module
818823 illegal = list (range (33 )) + \
819824 list (b'"\' ,;_`|\\ ~' ) + \
820825 list (range (128 , 256 ))
@@ -830,6 +835,7 @@ def test_z85decode_errors(self):
830835 self .assertRaises (ValueError , base64 .z85decode , b'%nSc1' )
831836
832837 def test_decode_nonascii_str (self ):
838+ base64 = self .module
833839 decode_funcs = (base64 .b64decode ,
834840 base64 .standard_b64decode ,
835841 base64 .urlsafe_b64decode ,
@@ -845,6 +851,7 @@ def test_ErrorHeritage(self):
845851 self .assertTrue (issubclass (binascii .Error , ValueError ))
846852
847853 def test_RFC4648_test_cases (self ):
854+ base64 = self .module
848855 # test cases from RFC 4648 section 10
849856 b64encode = base64 .b64encode
850857 b32hexencode = base64 .b32hexencode
@@ -884,6 +891,15 @@ def test_RFC4648_test_cases(self):
884891 self .assertEqual (b16encode (b"foobar" ), b"666F6F626172" )
885892
886893
894+ class BaseXYTestCasePython (BaseXYTestCase , unittest .TestCase ):
895+ module = py_base64
896+
897+
898+ @unittest .skipUnless (c_base64 , "requires _base64" )
899+ class BaseXYTestCaseC (BaseXYTestCase , unittest .TestCase ):
900+ module = c_base64
901+
902+
887903class TestMain (unittest .TestCase ):
888904 def tearDown (self ):
889905 if os .path .exists (os_helper .TESTFN ):
0 commit comments