#3613: add base64.encodebytes and decodebytes as the new spelling of encodestring and decodestring; deprecate the latter.

This commit is contained in:
Georg Brandl 2009-06-04 09:11:51 +00:00
parent cef803f82c
commit b54d801280
6 changed files with 66 additions and 48 deletions

View File

@ -116,38 +116,44 @@ The modern interface provides:
incorrectly padded or if there are non-alphabet characters present in the incorrectly padded or if there are non-alphabet characters present in the
string. string.
The legacy interface:
The legacy interface:
.. function:: decode(input, output) .. function:: decode(input, output)
Decode the contents of the *input* file and write the resulting binary data to Decode the contents of the binary *input* file and write the resulting binary
the *output* file. *input* and *output* must either be file objects or objects data to the *output* file. *input* and *output* must either be file objects
that mimic the file object interface. *input* will be read until or objects that mimic the file object interface working with bytes
``input.read()`` returns an empty string. 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 Decode the bytestring *s*, which must contain one or more lines of base64
data, and return a string containing the resulting binary data. encoded data, and return a bytestring containing the resulting binary data.
``decodestring`` is a deprecated alias.
.. function:: encode(input, output) .. function:: encode(input, output)
Encode the contents of the *input* file and write the resulting base64 encoded Encode the contents of the binary *input* file and write the resulting base64
data to the *output* file. *input* and *output* must either be file objects or encoded data to the *output* file. *input* and *output* must either be file
objects that mimic the file object interface. *input* will be read until objects or objects that mimic the file object interface working with bytes
``input.read()`` returns an empty string. :func:`encode` returns the encoded objects. *input* will be read until ``input.read()`` returns an empty string.
data plus a trailing newline character (``'\n'``). :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: An example usage of the module:

View File

@ -13,7 +13,7 @@ import binascii
__all__ = [ __all__ = [
# Legacy interface exports traditional RFC 1521 Base64 encodings # Legacy interface exports traditional RFC 1521 Base64 encodings
'encode', 'decode', 'encodestring', 'decodestring', 'encode', 'decode', 'encodebytes', 'decodebytes',
# Generalized interface for other encodings # Generalized interface for other encodings
'b64encode', 'b64decode', 'b32encode', 'b32decode', 'b64encode', 'b64decode', 'b32encode', 'b32decode',
'b16encode', 'b16decode', 'b16encode', 'b16decode',
@ -329,11 +329,9 @@ def decode(input, output):
output.write(s) output.write(s)
def encodestring(s): def encodebytes(s):
"""Encode a string into multiple lines of base-64 data. """Encode a bytestring into a bytestring containing multiple lines
of base-64 data."""
Argument and return value are bytes.
"""
if not isinstance(s, bytes_types): if not isinstance(s, bytes_types):
raise TypeError("expected bytes, not %s" % s.__class__.__name__) raise TypeError("expected bytes, not %s" % s.__class__.__name__)
pieces = [] pieces = []
@ -342,16 +340,26 @@ def encodestring(s):
pieces.append(binascii.b2a_base64(chunk)) pieces.append(binascii.b2a_base64(chunk))
return b"".join(pieces) 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): if not isinstance(s, bytes_types):
raise TypeError("expected bytes, not %s" % s.__class__.__name__) raise TypeError("expected bytes, not %s" % s.__class__.__name__)
return binascii.a2b_base64(s) 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... # Usable as a script...

View File

@ -6,35 +6,35 @@ import binascii
class LegacyBase64TestCase(unittest.TestCase): class LegacyBase64TestCase(unittest.TestCase):
def test_encodestring(self): def test_encodebytes(self):
eq = self.assertEqual eq = self.assertEqual
eq(base64.encodestring(b"www.python.org"), b"d3d3LnB5dGhvbi5vcmc=\n") eq(base64.encodebytes(b"www.python.org"), b"d3d3LnB5dGhvbi5vcmc=\n")
eq(base64.encodestring(b"a"), b"YQ==\n") eq(base64.encodebytes(b"a"), b"YQ==\n")
eq(base64.encodestring(b"ab"), b"YWI=\n") eq(base64.encodebytes(b"ab"), b"YWI=\n")
eq(base64.encodestring(b"abc"), b"YWJj\n") eq(base64.encodebytes(b"abc"), b"YWJj\n")
eq(base64.encodestring(b""), b"") eq(base64.encodebytes(b""), b"")
eq(base64.encodestring(b"abcdefghijklmnopqrstuvwxyz" eq(base64.encodebytes(b"abcdefghijklmnopqrstuvwxyz"
b"ABCDEFGHIJKLMNOPQRSTUVWXYZ" b"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
b"0123456789!@#0^&*();:<>,. []{}"), b"0123456789!@#0^&*();:<>,. []{}"),
b"YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNE" b"YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNE"
b"RUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0\nNT" b"RUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0\nNT"
b"Y3ODkhQCMwXiYqKCk7Ojw+LC4gW117fQ==\n") 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 = self.assertEqual
eq(base64.decodestring(b"d3d3LnB5dGhvbi5vcmc=\n"), b"www.python.org") eq(base64.decodebytes(b"d3d3LnB5dGhvbi5vcmc=\n"), b"www.python.org")
eq(base64.decodestring(b"YQ==\n"), b"a") eq(base64.decodebytes(b"YQ==\n"), b"a")
eq(base64.decodestring(b"YWI=\n"), b"ab") eq(base64.decodebytes(b"YWI=\n"), b"ab")
eq(base64.decodestring(b"YWJj\n"), b"abc") eq(base64.decodebytes(b"YWJj\n"), b"abc")
eq(base64.decodestring(b"YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNE" eq(base64.decodebytes(b"YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNE"
b"RUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0\nNT" b"RUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0\nNT"
b"Y3ODkhQCMwXiYqKCk7Ojw+LC4gW117fQ==\n"), b"Y3ODkhQCMwXiYqKCk7Ojw+LC4gW117fQ==\n"),
b"abcdefghijklmnopqrstuvwxyz" b"abcdefghijklmnopqrstuvwxyz"
b"ABCDEFGHIJKLMNOPQRSTUVWXYZ" b"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
b"0123456789!@#0^&*();:<>,. []{}") b"0123456789!@#0^&*();:<>,. []{}")
eq(base64.decodestring(b''), b'') eq(base64.decodebytes(b''), b'')
self.assertRaises(TypeError, base64.decodestring, "") self.assertRaises(TypeError, base64.decodebytes, "")
def test_encode(self): def test_encode(self):
eq = self.assertEqual eq = self.assertEqual

View File

@ -232,7 +232,7 @@ class BinaryTestCase(unittest.TestCase):
def test_decode(self): def test_decode(self):
d = b'\x01\x02\x03abc123\xff\xfe' d = b'\x01\x02\x03abc123\xff\xfe'
de = base64.encodestring(d) de = base64.encodebytes(d)
t1 = xmlrpclib.Binary() t1 = xmlrpclib.Binary()
t1.decode(de) t1.decode(de)
self.assertEqual(str(t1), str(d, "latin-1")) self.assertEqual(str(t1), str(d, "latin-1"))

View File

@ -419,11 +419,11 @@ class Binary:
return self.data != other return self.data != other
def decode(self, data): def decode(self, data):
self.data = base64.decodestring(data) self.data = base64.decodebytes(data)
def encode(self, out): def encode(self, out):
out.write("<value><base64>\n") out.write("<value><base64>\n")
encoded = base64.encodestring(self.data) encoded = base64.encodebytes(self.data)
out.write(encoded.decode('ascii')) out.write(encoded.decode('ascii'))
out.write('\n') out.write('\n')
out.write("</base64></value>\n") out.write("</base64></value>\n")
@ -1100,7 +1100,7 @@ class Transport:
if auth: if auth:
import base64 import base64
auth = urllib.parse.unquote_to_bytes(auth) 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 auth = "".join(auth.split()) # get rid of whitespace
extra_headers = [ extra_headers = [
("Authorization", "Basic " + auth) ("Authorization", "Basic " + auth)

View File

@ -21,6 +21,10 @@ Core and Builtins
Library 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 #5767: Remove sgmlop support from xmlrpc.client.
- Issue #6150: Fix test_unicode on wide-unicode builds. - Issue #6150: Fix test_unicode on wide-unicode builds.