Skip to content

Commit 54a40cb

Browse files
committed
Force test_xmlrpc to pass. I'm not happy with how I did this, but I don't
see a better way; the 'Binary' class is poorly specified so it's unclear what behavior is relied upon.
1 parent 98b349f commit 54a40cb

3 files changed

Lines changed: 35 additions & 15 deletions

File tree

Lib/base64.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ def b16decode(s, casefold=False):
298298
MAXBINSIZE = (MAXLINESIZE//4)*3
299299

300300
def encode(input, output):
301-
"""Encode a file."""
301+
"""Encode a file; input and output are binary files."""
302302
while True:
303303
s = input.read(MAXBINSIZE)
304304
if not s:
@@ -313,7 +313,7 @@ def encode(input, output):
313313

314314

315315
def decode(input, output):
316-
"""Decode a file."""
316+
"""Decode a file; input and output are binary files."""
317317
while True:
318318
line = input.readline()
319319
if not line:
@@ -323,7 +323,10 @@ def decode(input, output):
323323

324324

325325
def encodestring(s):
326-
"""Encode a string into multiple lines of base-64 data."""
326+
"""Encode a string into multiple lines of base-64 data.
327+
328+
Argument and return value are bytes.
329+
"""
327330
if not isinstance(s, bytes):
328331
raise TypeError("expected bytes, not %s" % s.__class__.__name__)
329332
pieces = []
@@ -334,7 +337,10 @@ def encodestring(s):
334337

335338

336339
def decodestring(s):
337-
"""Decode a string."""
340+
"""Decode a string.
341+
342+
Argument and return value are bytes.
343+
"""
338344
if not isinstance(s, bytes):
339345
raise TypeError("expected bytes, not %s" % s.__class__.__name__)
340346
return binascii.a2b_base64(s)

Lib/test/test_xmlrpc.py

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
'anint': 2**20,
1515
'ashortlong': 2,
1616
'anotherlist': ['.zyx.41'],
17-
'abase64': xmlrpclib.Binary("my dog has fleas"),
17+
'abase64': xmlrpclib.Binary(b"my dog has fleas"),
1818
'boolean': False,
1919
'unicode': '\u4000\u6000\u8000',
2020
'ukey\u4000': 'regular value',
@@ -32,8 +32,9 @@
3232
class XMLRPCTestCase(unittest.TestCase):
3333

3434
def test_dump_load(self):
35-
self.assertEquals(alist,
36-
xmlrpclib.loads(xmlrpclib.dumps((alist,)))[0][0])
35+
dump = xmlrpclib.dumps((alist,))
36+
load = xmlrpclib.loads(dump)
37+
self.assertEquals(alist, load[0][0])
3738

3839
def test_dump_bare_datetime(self):
3940
# This checks that an unwrapped datetime.date object can be handled
@@ -222,24 +223,30 @@ def test_decode(self):
222223
self.assertEqual(t1, tref)
223224

224225
class BinaryTestCase(unittest.TestCase):
226+
227+
# XXX What should str(Binary(b"\xff")) return? I'm chosing "\xff"
228+
# for now (i.e. interpreting the binary data as Latin-1-encoded
229+
# text). But this feels very unsatisfactory. Perhaps we should
230+
# only define repr(), and return r"Binary(b'\xff')" instead?
231+
225232
def test_default(self):
226233
t = xmlrpclib.Binary()
227234
self.assertEqual(str(t), '')
228235

229236
def test_string(self):
230-
d = '\x01\x02\x03abc123\xff\xfe'
237+
d = b'\x01\x02\x03abc123\xff\xfe'
231238
t = xmlrpclib.Binary(d)
232-
self.assertEqual(str(t), d)
239+
self.assertEqual(str(t), str(d, "latin-1"))
233240

234241
def test_decode(self):
235-
d = '\x01\x02\x03abc123\xff\xfe'
242+
d = b'\x01\x02\x03abc123\xff\xfe'
236243
de = base64.encodestring(d)
237244
t1 = xmlrpclib.Binary()
238245
t1.decode(de)
239-
self.assertEqual(str(t1), d)
246+
self.assertEqual(str(t1), str(d, "latin-1"))
240247

241248
t2 = xmlrpclib._binary(de)
242-
self.assertEqual(str(t2), d)
249+
self.assertEqual(str(t2), str(d, "latin-1"))
243250

244251

245252
PORT = None

Lib/xmlrpclib.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,13 @@ class Binary:
364364
"""Wrapper for binary data."""
365365

366366
def __init__(self, data=None):
367+
if data is None:
368+
data = b""
369+
else:
370+
if not isinstance(data, bytes):
371+
raise TypeError("expected bytes, not %s" %
372+
data.__class__.__name__)
373+
data = bytes(data) # Make a copy of the bytes!
367374
self.data = data
368375

369376
##
@@ -372,7 +379,7 @@ def __init__(self, data=None):
372379
# @return Buffer contents, as an 8-bit string.
373380

374381
def __str__(self):
375-
return self.data or ""
382+
return str(self.data, "latin-1") # XXX encoding?!
376383

377384
def __eq__(self, other):
378385
if isinstance(other, Binary):
@@ -385,7 +392,7 @@ def __ne__(self, other):
385392
return self.data != other
386393

387394
def decode(self, data):
388-
self.data = str8(base64.decodestring(data))
395+
self.data = base64.decodestring(data)
389396

390397
def encode(self, out):
391398
out.write("<value><base64>\n")
@@ -827,7 +834,7 @@ def end_struct(self, data):
827834

828835
def end_base64(self, data):
829836
value = Binary()
830-
value.decode(data)
837+
value.decode(data.encode("ascii"))
831838
self.append(value)
832839
self._value = 0
833840
dispatch["base64"] = end_base64

0 commit comments

Comments
 (0)