diff --git a/Doc/library/base64.rst b/Doc/library/base64.rst index 62bf1d49f24..9ff065ab1be 100644 --- a/Doc/library/base64.rst +++ b/Doc/library/base64.rst @@ -116,38 +116,44 @@ The modern interface provides: incorrectly padded or if there are non-alphabet characters present in the string. -The legacy interface: +The legacy interface: .. function:: decode(input, output) - Decode the contents of the *input* file and write the resulting binary data to - the *output* file. *input* and *output* must either be file objects or objects - that mimic the file object interface. *input* will be read until - ``input.read()`` returns an empty string. + Decode the contents of the binary *input* file and write the resulting binary + data to the *output* file. *input* and *output* must either be file objects + or objects that mimic the file object interface working with bytes + objects. *input* will be read until ``input.read()`` returns an empty string. -.. function:: decodestring(s) +.. function:: decodebytes(s) + decodestring(s) - Decode the string *s*, which must contain one or more lines of base64 encoded - data, and return a string containing the resulting binary data. + Decode the bytestring *s*, which must contain one or more lines of base64 + encoded data, and return a bytestring containing the resulting binary data. + ``decodestring`` is a deprecated alias. .. function:: encode(input, output) - Encode the contents of the *input* file and write the resulting base64 encoded - data to the *output* file. *input* and *output* must either be file objects or - objects that mimic the file object interface. *input* will be read until - ``input.read()`` returns an empty string. :func:`encode` returns the encoded - data plus a trailing newline character (``'\n'``). + Encode the contents of the binary *input* file and write the resulting base64 + encoded data to the *output* file. *input* and *output* must either be file + objects or objects that mimic the file object interface working with bytes + objects. *input* will be read until ``input.read()`` returns an empty string. + :func:`encode` returns the encoded data plus a trailing newline character + (``b'\n'``). -.. function:: encodestring(s) +.. 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. + :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. - Encode the string *s*, which can contain arbitrary binary data, and return a - string containing one or more lines of base64-encoded data. - :func:`encodestring` returns a string containing one or more lines of - base64-encoded data always including an extra trailing newline (``'\n'``). An example usage of the module: diff --git a/Lib/base64.py b/Lib/base64.py index 4308fb489db..c1135a88e20 100755 --- a/Lib/base64.py +++ b/Lib/base64.py @@ -13,7 +13,7 @@ import binascii __all__ = [ # Legacy interface exports traditional RFC 1521 Base64 encodings - 'encode', 'decode', 'encodestring', 'decodestring', + 'encode', 'decode', 'encodebytes', 'decodebytes', # Generalized interface for other encodings 'b64encode', 'b64decode', 'b32encode', 'b32decode', 'b16encode', 'b16decode', @@ -329,11 +329,9 @@ def decode(input, output): output.write(s) -def encodestring(s): - """Encode a string into multiple lines of base-64 data. - - Argument and return value are bytes. - """ +def encodebytes(s): + """Encode a bytestring into a bytestring containing multiple lines + of base-64 data.""" if not isinstance(s, bytes_types): raise TypeError("expected bytes, not %s" % s.__class__.__name__) pieces = [] @@ -342,16 +340,26 @@ def encodestring(s): pieces.append(binascii.b2a_base64(chunk)) return b"".join(pieces) +def encodestring(s): + """Legacy alias of encodebytes().""" + import warnings + warnings.warn("encodestring() is a deprecated alias, use encodebytes()", + DeprecationWarning, 2) + return encodebytes(s) -def decodestring(s): - """Decode a string. - Argument and return value are bytes. - """ +def decodebytes(s): + """Decode a bytestring of base-64 data into a bytestring.""" if not isinstance(s, bytes_types): raise TypeError("expected bytes, not %s" % s.__class__.__name__) return binascii.a2b_base64(s) +def decodestring(s): + """Legacy alias of decodebytes().""" + import warnings + warnings.warn("decodestring() is a deprecated alias, use decodebytes()", + DeprecationWarning, 2) + return decodebytes(s) # Usable as a script... diff --git a/Lib/test/test_base64.py b/Lib/test/test_base64.py index e899016f786..149ac8ada12 100644 --- a/Lib/test/test_base64.py +++ b/Lib/test/test_base64.py @@ -6,35 +6,35 @@ import binascii class LegacyBase64TestCase(unittest.TestCase): - def test_encodestring(self): + def test_encodebytes(self): eq = self.assertEqual - eq(base64.encodestring(b"www.python.org"), b"d3d3LnB5dGhvbi5vcmc=\n") - eq(base64.encodestring(b"a"), b"YQ==\n") - eq(base64.encodestring(b"ab"), b"YWI=\n") - eq(base64.encodestring(b"abc"), b"YWJj\n") - eq(base64.encodestring(b""), b"") - eq(base64.encodestring(b"abcdefghijklmnopqrstuvwxyz" + eq(base64.encodebytes(b"www.python.org"), b"d3d3LnB5dGhvbi5vcmc=\n") + eq(base64.encodebytes(b"a"), b"YQ==\n") + eq(base64.encodebytes(b"ab"), b"YWI=\n") + eq(base64.encodebytes(b"abc"), b"YWJj\n") + eq(base64.encodebytes(b""), b"") + eq(base64.encodebytes(b"abcdefghijklmnopqrstuvwxyz" b"ABCDEFGHIJKLMNOPQRSTUVWXYZ" b"0123456789!@#0^&*();:<>,. []{}"), b"YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNE" b"RUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0\nNT" b"Y3ODkhQCMwXiYqKCk7Ojw+LC4gW117fQ==\n") - self.assertRaises(TypeError, base64.encodestring, "") + self.assertRaises(TypeError, base64.encodebytes, "") - def test_decodestring(self): + def test_decodebytes(self): eq = self.assertEqual - eq(base64.decodestring(b"d3d3LnB5dGhvbi5vcmc=\n"), b"www.python.org") - eq(base64.decodestring(b"YQ==\n"), b"a") - eq(base64.decodestring(b"YWI=\n"), b"ab") - eq(base64.decodestring(b"YWJj\n"), b"abc") - eq(base64.decodestring(b"YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNE" + eq(base64.decodebytes(b"d3d3LnB5dGhvbi5vcmc=\n"), b"www.python.org") + eq(base64.decodebytes(b"YQ==\n"), b"a") + eq(base64.decodebytes(b"YWI=\n"), b"ab") + eq(base64.decodebytes(b"YWJj\n"), b"abc") + eq(base64.decodebytes(b"YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNE" b"RUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0\nNT" b"Y3ODkhQCMwXiYqKCk7Ojw+LC4gW117fQ==\n"), b"abcdefghijklmnopqrstuvwxyz" b"ABCDEFGHIJKLMNOPQRSTUVWXYZ" b"0123456789!@#0^&*();:<>,. []{}") - eq(base64.decodestring(b''), b'') - self.assertRaises(TypeError, base64.decodestring, "") + eq(base64.decodebytes(b''), b'') + self.assertRaises(TypeError, base64.decodebytes, "") def test_encode(self): eq = self.assertEqual diff --git a/Lib/test/test_xmlrpc.py b/Lib/test/test_xmlrpc.py index 73d53ee30c9..d4e8122f44f 100644 --- a/Lib/test/test_xmlrpc.py +++ b/Lib/test/test_xmlrpc.py @@ -232,7 +232,7 @@ class BinaryTestCase(unittest.TestCase): def test_decode(self): d = b'\x01\x02\x03abc123\xff\xfe' - de = base64.encodestring(d) + de = base64.encodebytes(d) t1 = xmlrpclib.Binary() t1.decode(de) self.assertEqual(str(t1), str(d, "latin-1")) diff --git a/Lib/xmlrpc/client.py b/Lib/xmlrpc/client.py index 05a1c8ac3a6..c62dbc474e9 100644 --- a/Lib/xmlrpc/client.py +++ b/Lib/xmlrpc/client.py @@ -419,11 +419,11 @@ class Binary: return self.data != other def decode(self, data): - self.data = base64.decodestring(data) + self.data = base64.decodebytes(data) def encode(self, out): out.write("\n") - encoded = base64.encodestring(self.data) + encoded = base64.encodebytes(self.data) out.write(encoded.decode('ascii')) out.write('\n') out.write("\n") @@ -1100,7 +1100,7 @@ class Transport: if auth: import base64 auth = urllib.parse.unquote_to_bytes(auth) - auth = base64.encodestring(auth).decode("utf-8") + auth = base64.encodebytes(auth).decode("utf-8") auth = "".join(auth.split()) # get rid of whitespace extra_headers = [ ("Authorization", "Basic " + auth) diff --git a/Misc/NEWS b/Misc/NEWS index e2aac90b4fa..27e9c84bf56 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -21,6 +21,10 @@ Core and Builtins Library ------- +- Issue #3613: base64.{encode,decode}string are now called + base64.{encode,decode}bytes which reflects what type they accept and return. + The old names are still there as deprecated aliases. + - Issue #5767: Remove sgmlop support from xmlrpc.client. - Issue #6150: Fix test_unicode on wide-unicode builds.