Index: Doc/library/base64.rst =================================================================== --- Doc/library/base64.rst (révision 81532) +++ Doc/library/base64.rst (copie de travail) @@ -26,7 +26,8 @@ Encode a string use Base64. - *s* is the string to encode. Optional *altchars* must be a string of at least + *s* is the byte or unicode string to encode (unicode is first encoded to + utf-8). Optional *altchars* must be a byte string of at least length 2 (additional characters are ignored) which specifies an alternative alphabet for the ``+`` and ``/`` characters. This allows an application to e.g. generate URL or filesystem safe Base64 strings. The default is ``None``, for @@ -73,8 +74,8 @@ .. function:: b32encode(s) - Encode a string using Base32. *s* is the string to encode. The encoded string - is returned. + Encode a string using Base32. *s* is the byte or unicode string to encode + (unicode is first encoded to utf-8). The encoded byte string is returned. .. function:: b32decode(s, casefold=False, map01=None) @@ -101,7 +102,8 @@ Encode a string using Base16. - *s* is the string to encode. The encoded string is returned. + *s* is the byte or unicode string to encode (unicode is first encoded to + utf-8). The encoded byte string is returned. .. function:: b16decode(s, casefold=False) @@ -148,8 +150,9 @@ .. function:: encodebytes(s) encodestring(s) - Encode the bytestring *s*, which can contain arbitrary binary data, and - return a bytestring containing one or more lines of base64-encoded data. + Encode the byte or unicode string *s*, which can contain arbitrary binary data, and + return a byte string containing one or more lines of base64-encoded data. + Unicode is first encoded to utf-8. :func:`encodebytes` returns a string containing one or more lines of base64-encoded data always including an extra trailing newline (``b'\n'``). ``encodestring`` is a deprecated alias. Index: Lib/base64.py =================================================================== --- Lib/base64.py (révision 81533) +++ Lib/base64.py (copie de travail) @@ -28,6 +28,7 @@ bytes_types = (bytes, bytearray) # Types acceptable as binary data +text_types = (bytes, bytearray, str) # Types acceptable as text data def _translate(s, altchars): @@ -43,16 +44,19 @@ # Base64 encoding/decoding uses binascii def b64encode(s, altchars=None): - """Encode a byte string using Base64. + """Encode a string using Base64. - s is the byte string to encode. Optional altchars must be a byte - string of length 2 which specifies an alternative alphabet for the - '+' and '/' characters. This allows an application to - e.g. generate url or filesystem safe Base64 strings. + s is the byte or unicode string to encode (unicode is first encoded to + utf-8). Optional altchars must be a byte string of length 2 which + specifies an alternative alphabet for the '+' and '/' characters. This + allows an application to e.g. generate url or filesystem safe Base64 + strings. The encoded byte string is returned. """ - if not isinstance(s, bytes_types): + if isinstance(s, str): + s = s.encode("utf-8") + elif not isinstance(s, bytes_types): raise TypeError("expected bytes, not %s" % s.__class__.__name__) # Strip off the trailing newline encoded = binascii.b2a_base64(s)[:-1] @@ -145,11 +149,14 @@ def b32encode(s): - """Encode a byte string using Base32. + """Encode a string using Base32. - s is the byte string to encode. The encoded byte string is returned. + s is the byte or unicode string to encode (unicode is first encoded to + utf-8). The encoded byte string is returned. """ - if not isinstance(s, bytes_types): + if isinstance(s, str): + s = s.encode("utf-8") + elif not isinstance(s, bytes_types): raise TypeError("expected bytes, not %s" % s.__class__.__name__) quanta, leftover = divmod(len(s), 5) # Pad the last quantum with zero bits if necessary @@ -267,11 +274,14 @@ # lowercase. The RFC also recommends against accepting input case # insensitively. def b16encode(s): - """Encode a byte string using Base16. + """Encode a string using Base16. - s is the byte string to encode. The encoded byte string is returned. + s is the byte or unicode string to encode (unicode is first encoded to + utf-8). The encoded byte string is returned. """ - if not isinstance(s, bytes_types): + if isinstance(s, str): + s = s.encode("utf-8") + elif not isinstance(s, bytes_types): raise TypeError("expected bytes, not %s" % s.__class__.__name__) return binascii.hexlify(s).upper() @@ -330,9 +340,11 @@ def encodebytes(s): - """Encode a bytestring into a bytestring containing multiple lines - of base-64 data.""" - if not isinstance(s, bytes_types): + """Encode a byte or an unicode string into a byte string containing multiple lines + of base-64 data. Unicode is first encoded to utf-8.""" + if isinstance(s, str): + s = s.encode("utf-8") + elif not isinstance(s, bytes_types): raise TypeError("expected bytes, not %s" % s.__class__.__name__) pieces = [] for i in range(0, len(s), MAXBINSIZE): Index: Lib/test/test_base64.py =================================================================== --- Lib/test/test_base64.py (révision 81533) +++ Lib/test/test_base64.py (copie de travail) @@ -21,7 +21,9 @@ b"YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNE" b"RUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0\nNT" b"Y3ODkhQCMwXiYqKCk7Ojw+LC4gW117fQ==\n") - self.assertRaises(TypeError, base64.encodebytes, "") + # Test str type + eq(base64.encodebytes("abc"), b"YWJj\n") + eq(base64.encodebytes("\xe9\u20ac"), b'w6nigqw=\n') def test_decodebytes(self): eq = self.assertEqual @@ -77,9 +79,9 @@ b"Y3ODkhQCMwXiYqKCk7Ojw+LC4gW117fQ==") # Test with arbitrary alternative characters eq(base64.b64encode(b'\xd3V\xbeo\xf7\x1d', altchars=b'*$'), b'01a*b$cd') - # Check if passing a str object raises an error - self.assertRaises(TypeError, base64.b64encode, "") - self.assertRaises(TypeError, base64.b64encode, b"", altchars="") + # Test str type + eq(base64.b64encode("abc"), b"YWJj") + eq(base64.b64encode("\xe9\u20ac"), b'w6nigqw=') # Test standard alphabet eq(base64.standard_b64encode(b"www.python.org"), b"d3d3LnB5dGhvbi5vcmc=") eq(base64.standard_b64encode(b"a"), b"YQ==") @@ -92,13 +94,14 @@ b"YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNE" b"RUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0NT" b"Y3ODkhQCMwXiYqKCk7Ojw+LC4gW117fQ==") + # Test str type + eq(base64.standard_b64encode("abc"), b"YWJj") + eq(base64.standard_b64encode("\xe9\u20ac"), b'w6nigqw=') # Check if passing a str object raises an error - self.assertRaises(TypeError, base64.standard_b64encode, "") self.assertRaises(TypeError, base64.standard_b64encode, b"", altchars="") # Test with 'URL safe' alternative characters eq(base64.urlsafe_b64encode(b'\xd3V\xbeo\xf7\x1d'), b'01a-b_cd') - # Check if passing a str object raises an error - self.assertRaises(TypeError, base64.urlsafe_b64encode, "") + eq(base64.urlsafe_b64encode('\u083e\u083f'), b'4KC-4KC_') def test_b64decode(self): eq = self.assertEqual @@ -150,7 +153,9 @@ eq(base64.b32encode(b'abc'), b'MFRGG===') eq(base64.b32encode(b'abcd'), b'MFRGGZA=') eq(base64.b32encode(b'abcde'), b'MFRGGZDF') - self.assertRaises(TypeError, base64.b32encode, "") + # Test str type + eq(base64.b32encode('abc'), b'MFRGG===') + eq(base64.b32encode("\xe9\u20ac"), b'YOU6FAVM') def test_b32decode(self): eq = self.assertEqual @@ -193,7 +198,9 @@ eq = self.assertEqual eq(base64.b16encode(b'\x01\x02\xab\xcd\xef'), b'0102ABCDEF') eq(base64.b16encode(b'\x00'), b'00') - self.assertRaises(TypeError, base64.b16encode, "") + # Test str type + eq(base64.b16encode("abc"), b'616263') + eq(base64.b16encode("\xe9\u20ac"), b'C3A9E282AC') def test_b16decode(self): eq = self.assertEqual