1"""Unit tests for memory-based file-like objects. 2StringIO -- for unicode strings 3BytesIO -- for bytes 4""" 5 6from __future__ import unicode_literals 7from __future__ import print_function 8 9import unittest 10from test import test_support as support 11 12import io 13import _pyio as pyio 14import pickle 15 16class MemorySeekTestMixin: 17 18 def testInit(self): 19 buf = self.buftype("1234567890") 20 bytesIo = self.ioclass(buf) 21 22 def testRead(self): 23 buf = self.buftype("1234567890") 24 bytesIo = self.ioclass(buf) 25 26 self.assertEqual(buf[:1], bytesIo.read(1)) 27 self.assertEqual(buf[1:5], bytesIo.read(4)) 28 self.assertEqual(buf[5:], bytesIo.read(900)) 29 self.assertEqual(self.EOF, bytesIo.read()) 30 31 def testReadNoArgs(self): 32 buf = self.buftype("1234567890") 33 bytesIo = self.ioclass(buf) 34 35 self.assertEqual(buf, bytesIo.read()) 36 self.assertEqual(self.EOF, bytesIo.read()) 37 38 def testSeek(self): 39 buf = self.buftype("1234567890") 40 bytesIo = self.ioclass(buf) 41 42 bytesIo.read(5) 43 bytesIo.seek(0) 44 self.assertEqual(buf, bytesIo.read()) 45 46 bytesIo.seek(3) 47 self.assertEqual(buf[3:], bytesIo.read()) 48 self.assertRaises(TypeError, bytesIo.seek, 0.0) 49 50 def testTell(self): 51 buf = self.buftype("1234567890") 52 bytesIo = self.ioclass(buf) 53 54 self.assertEqual(0, bytesIo.tell()) 55 bytesIo.seek(5) 56 self.assertEqual(5, bytesIo.tell()) 57 bytesIo.seek(10000) 58 self.assertEqual(10000, bytesIo.tell()) 59 60 61class MemoryTestMixin: 62 63 def test_detach(self): 64 buf = self.ioclass() 65 self.assertRaises(self.UnsupportedOperation, buf.detach) 66 67 def write_ops(self, f, t): 68 self.assertEqual(f.write(t("blah.")), 5) 69 self.assertEqual(f.seek(0), 0) 70 self.assertEqual(f.write(t("Hello.")), 6) 71 self.assertEqual(f.tell(), 6) 72 self.assertEqual(f.seek(5), 5) 73 self.assertEqual(f.tell(), 5) 74 self.assertEqual(f.write(t(" world\n\n\n")), 9) 75 self.assertEqual(f.seek(0), 0) 76 self.assertEqual(f.write(t("h")), 1) 77 self.assertEqual(f.truncate(12), 12) 78 self.assertEqual(f.tell(), 1) 79 80 def test_write(self): 81 buf = self.buftype("hello world\n") 82 memio = self.ioclass(buf) 83 84 self.write_ops(memio, self.buftype) 85 self.assertEqual(memio.getvalue(), buf) 86 memio = self.ioclass() 87 self.write_ops(memio, self.buftype) 88 self.assertEqual(memio.getvalue(), buf) 89 self.assertRaises(TypeError, memio.write, None) 90 memio.close() 91 self.assertRaises(ValueError, memio.write, self.buftype("")) 92 93 def test_writelines(self): 94 buf = self.buftype("1234567890") 95 memio = self.ioclass() 96 97 self.assertEqual(memio.writelines([buf] * 100), None) 98 self.assertEqual(memio.getvalue(), buf * 100) 99 memio.writelines([]) 100 self.assertEqual(memio.getvalue(), buf * 100) 101 memio = self.ioclass() 102 self.assertRaises(TypeError, memio.writelines, [buf] + [1]) 103 self.assertEqual(memio.getvalue(), buf) 104 self.assertRaises(TypeError, memio.writelines, None) 105 memio.close() 106 self.assertRaises(ValueError, memio.writelines, []) 107 108 def test_writelines_error(self): 109 memio = self.ioclass() 110 def error_gen(): 111 yield self.buftype('spam') 112 raise KeyboardInterrupt 113 114 self.assertRaises(KeyboardInterrupt, memio.writelines, error_gen()) 115 116 def test_truncate(self): 117 buf = self.buftype("1234567890") 118 memio = self.ioclass(buf) 119 120 self.assertRaises(ValueError, memio.truncate, -1) 121 memio.seek(6) 122 self.assertEqual(memio.truncate(), 6) 123 self.assertEqual(memio.getvalue(), buf[:6]) 124 self.assertEqual(memio.truncate(4), 4) 125 self.assertEqual(memio.getvalue(), buf[:4]) 126 # truncate() accepts long objects 127 self.assertEqual(memio.truncate(4L), 4) 128 self.assertEqual(memio.getvalue(), buf[:4]) 129 self.assertEqual(memio.tell(), 6) 130 memio.seek(0, 2) 131 memio.write(buf) 132 self.assertEqual(memio.getvalue(), buf[:4] + buf) 133 pos = memio.tell() 134 self.assertEqual(memio.truncate(None), pos) 135 self.assertEqual(memio.tell(), pos) 136 self.assertRaises(TypeError, memio.truncate, '0') 137 memio.close() 138 self.assertRaises(ValueError, memio.truncate, 0) 139 140 def test_init(self): 141 buf = self.buftype("1234567890") 142 memio = self.ioclass(buf) 143 self.assertEqual(memio.getvalue(), buf) 144 memio = self.ioclass(None) 145 self.assertEqual(memio.getvalue(), self.EOF) 146 memio.__init__(buf * 2) 147 self.assertEqual(memio.getvalue(), buf * 2) 148 memio.__init__(buf) 149 self.assertEqual(memio.getvalue(), buf) 150 151 def test_read(self): 152 buf = self.buftype("1234567890") 153 memio = self.ioclass(buf) 154 155 self.assertEqual(memio.read(0), self.EOF) 156 self.assertEqual(memio.read(1), buf[:1]) 157 # read() accepts long objects 158 self.assertEqual(memio.read(4L), buf[1:5]) 159 self.assertEqual(memio.read(900), buf[5:]) 160 self.assertEqual(memio.read(), self.EOF) 161 memio.seek(0) 162 self.assertEqual(memio.read(), buf) 163 self.assertEqual(memio.read(), self.EOF) 164 self.assertEqual(memio.tell(), 10) 165 memio.seek(0) 166 self.assertEqual(memio.read(-1), buf) 167 memio.seek(0) 168 self.assertEqual(type(memio.read()), type(buf)) 169 memio.seek(100) 170 self.assertEqual(type(memio.read()), type(buf)) 171 memio.seek(0) 172 self.assertEqual(memio.read(None), buf) 173 self.assertRaises(TypeError, memio.read, '') 174 memio.close() 175 self.assertRaises(ValueError, memio.read) 176 177 def test_readline(self): 178 buf = self.buftype("1234567890\n") 179 memio = self.ioclass(buf * 2) 180 181 self.assertEqual(memio.readline(0), self.EOF) 182 self.assertEqual(memio.readline(), buf) 183 self.assertEqual(memio.readline(), buf) 184 self.assertEqual(memio.readline(), self.EOF) 185 memio.seek(0) 186 self.assertEqual(memio.readline(5), buf[:5]) 187 # readline() accepts long objects 188 self.assertEqual(memio.readline(5L), buf[5:10]) 189 self.assertEqual(memio.readline(5), buf[10:15]) 190 memio.seek(0) 191 self.assertEqual(memio.readline(-1), buf) 192 memio.seek(0) 193 self.assertEqual(memio.readline(0), self.EOF) 194 195 buf = self.buftype("1234567890\n") 196 memio = self.ioclass((buf * 3)[:-1]) 197 self.assertEqual(memio.readline(), buf) 198 self.assertEqual(memio.readline(), buf) 199 self.assertEqual(memio.readline(), buf[:-1]) 200 self.assertEqual(memio.readline(), self.EOF) 201 memio.seek(0) 202 self.assertEqual(type(memio.readline()), type(buf)) 203 self.assertEqual(memio.readline(), buf) 204 self.assertRaises(TypeError, memio.readline, '') 205 memio.close() 206 self.assertRaises(ValueError, memio.readline) 207 208 def test_readlines(self): 209 buf = self.buftype("1234567890\n") 210 memio = self.ioclass(buf * 10) 211 212 self.assertEqual(memio.readlines(), [buf] * 10) 213 memio.seek(5) 214 self.assertEqual(memio.readlines(), [buf[5:]] + [buf] * 9) 215 memio.seek(0) 216 # readlines() accepts long objects 217 self.assertEqual(memio.readlines(15L), [buf] * 2) 218 memio.seek(0) 219 self.assertEqual(memio.readlines(-1), [buf] * 10) 220 memio.seek(0) 221 self.assertEqual(memio.readlines(0), [buf] * 10) 222 memio.seek(0) 223 self.assertEqual(type(memio.readlines()[0]), type(buf)) 224 memio.seek(0) 225 self.assertEqual(memio.readlines(None), [buf] * 10) 226 self.assertRaises(TypeError, memio.readlines, '') 227 memio.close() 228 self.assertRaises(ValueError, memio.readlines) 229 230 def test_iterator(self): 231 buf = self.buftype("1234567890\n") 232 memio = self.ioclass(buf * 10) 233 234 self.assertEqual(iter(memio), memio) 235 self.assertTrue(hasattr(memio, '__iter__')) 236 self.assertTrue(hasattr(memio, 'next')) 237 i = 0 238 for line in memio: 239 self.assertEqual(line, buf) 240 i += 1 241 self.assertEqual(i, 10) 242 memio.seek(0) 243 i = 0 244 for line in memio: 245 self.assertEqual(line, buf) 246 i += 1 247 self.assertEqual(i, 10) 248 memio = self.ioclass(buf * 2) 249 memio.close() 250 self.assertRaises(ValueError, next, memio) 251 252 def test_getvalue(self): 253 buf = self.buftype("1234567890") 254 memio = self.ioclass(buf) 255 256 self.assertEqual(memio.getvalue(), buf) 257 memio.read() 258 self.assertEqual(memio.getvalue(), buf) 259 self.assertEqual(type(memio.getvalue()), type(buf)) 260 memio = self.ioclass(buf * 1000) 261 self.assertEqual(memio.getvalue()[-3:], self.buftype("890")) 262 memio = self.ioclass(buf) 263 memio.close() 264 self.assertRaises(ValueError, memio.getvalue) 265 266 def test_seek(self): 267 buf = self.buftype("1234567890") 268 memio = self.ioclass(buf) 269 270 memio.read(5) 271 self.assertRaises(ValueError, memio.seek, -1) 272 self.assertRaises(ValueError, memio.seek, 1, -1) 273 self.assertRaises(ValueError, memio.seek, 1, 3) 274 self.assertEqual(memio.seek(0), 0) 275 self.assertEqual(memio.seek(0, 0), 0) 276 self.assertEqual(memio.read(), buf) 277 self.assertEqual(memio.seek(3), 3) 278 # seek() accepts long objects 279 self.assertEqual(memio.seek(3L), 3) 280 self.assertEqual(memio.seek(0, 1), 3) 281 self.assertEqual(memio.read(), buf[3:]) 282 self.assertEqual(memio.seek(len(buf)), len(buf)) 283 self.assertEqual(memio.read(), self.EOF) 284 memio.seek(len(buf) + 1) 285 self.assertEqual(memio.read(), self.EOF) 286 self.assertEqual(memio.seek(0, 2), len(buf)) 287 self.assertEqual(memio.read(), self.EOF) 288 memio.close() 289 self.assertRaises(ValueError, memio.seek, 0) 290 291 def test_overseek(self): 292 buf = self.buftype("1234567890") 293 memio = self.ioclass(buf) 294 295 self.assertEqual(memio.seek(len(buf) + 1), 11) 296 self.assertEqual(memio.read(), self.EOF) 297 self.assertEqual(memio.tell(), 11) 298 self.assertEqual(memio.getvalue(), buf) 299 memio.write(self.EOF) 300 self.assertEqual(memio.getvalue(), buf) 301 memio.write(buf) 302 self.assertEqual(memio.getvalue(), buf + self.buftype('\0') + buf) 303 304 def test_tell(self): 305 buf = self.buftype("1234567890") 306 memio = self.ioclass(buf) 307 308 self.assertEqual(memio.tell(), 0) 309 memio.seek(5) 310 self.assertEqual(memio.tell(), 5) 311 memio.seek(10000) 312 self.assertEqual(memio.tell(), 10000) 313 memio.close() 314 self.assertRaises(ValueError, memio.tell) 315 316 def test_flush(self): 317 buf = self.buftype("1234567890") 318 memio = self.ioclass(buf) 319 320 self.assertEqual(memio.flush(), None) 321 322 def test_flags(self): 323 memio = self.ioclass() 324 325 self.assertEqual(memio.writable(), True) 326 self.assertEqual(memio.readable(), True) 327 self.assertEqual(memio.seekable(), True) 328 self.assertEqual(memio.isatty(), False) 329 self.assertEqual(memio.closed, False) 330 memio.close() 331 self.assertRaises(ValueError, memio.writable) 332 self.assertRaises(ValueError, memio.readable) 333 self.assertRaises(ValueError, memio.seekable) 334 self.assertRaises(ValueError, memio.isatty) 335 self.assertEqual(memio.closed, True) 336 337 def test_subclassing(self): 338 buf = self.buftype("1234567890") 339 def test1(): 340 class MemIO(self.ioclass): 341 pass 342 m = MemIO(buf) 343 return m.getvalue() 344 def test2(): 345 class MemIO(self.ioclass): 346 def __init__(me, a, b): 347 self.ioclass.__init__(me, a) 348 m = MemIO(buf, None) 349 return m.getvalue() 350 self.assertEqual(test1(), buf) 351 self.assertEqual(test2(), buf) 352 353 def test_instance_dict_leak(self): 354 # Test case for issue #6242. 355 # This will be caught by regrtest.py -R if this leak. 356 for _ in range(100): 357 memio = self.ioclass() 358 memio.foo = 1 359 360 def test_pickling(self): 361 buf = self.buftype("1234567890") 362 memio = self.ioclass(buf) 363 memio.foo = 42 364 memio.seek(2) 365 366 class PickleTestMemIO(self.ioclass): 367 def __init__(me, initvalue, foo): 368 self.ioclass.__init__(me, initvalue) 369 me.foo = foo 370 # __getnewargs__ is undefined on purpose. This checks that PEP 307 371 # is used to provide pickling support. 372 373 # Pickle expects the class to be on the module level. Here we use a 374 # little hack to allow the PickleTestMemIO class to derive from 375 # self.ioclass without having to define all combinations explicitly on 376 # the module-level. 377 import __main__ 378 PickleTestMemIO.__module__ = '__main__' 379 PickleTestMemIO.__qualname__ = PickleTestMemIO.__name__ 380 __main__.PickleTestMemIO = PickleTestMemIO 381 submemio = PickleTestMemIO(buf, 80) 382 submemio.seek(2) 383 384 # We only support pickle protocol 2 and onward since we use extended 385 # __reduce__ API of PEP 307 to provide pickling support. 386 for proto in range(2, pickle.HIGHEST_PROTOCOL + 1): 387 for obj in (memio, submemio): 388 obj2 = pickle.loads(pickle.dumps(obj, protocol=proto)) 389 self.assertEqual(obj.getvalue(), obj2.getvalue()) 390 self.assertEqual(obj.__class__, obj2.__class__) 391 self.assertEqual(obj.foo, obj2.foo) 392 self.assertEqual(obj.tell(), obj2.tell()) 393 obj.close() 394 self.assertRaises(ValueError, pickle.dumps, obj, proto) 395 del __main__.PickleTestMemIO 396 397 398class PyBytesIOTest(MemoryTestMixin, MemorySeekTestMixin, unittest.TestCase): 399 # Test _pyio.BytesIO; class also inherited for testing C implementation 400 401 UnsupportedOperation = pyio.UnsupportedOperation 402 403 @staticmethod 404 def buftype(s): 405 return s.encode("ascii") 406 ioclass = pyio.BytesIO 407 EOF = b"" 408 409 def test_read1(self): 410 buf = self.buftype("1234567890") 411 memio = self.ioclass(buf) 412 413 self.assertRaises(TypeError, memio.read1) 414 self.assertEqual(memio.read(), buf) 415 416 def test_readinto(self): 417 buf = self.buftype("1234567890") 418 memio = self.ioclass(buf) 419 420 b = bytearray(b"hello") 421 self.assertEqual(memio.readinto(b), 5) 422 self.assertEqual(b, b"12345") 423 self.assertEqual(memio.readinto(b), 5) 424 self.assertEqual(b, b"67890") 425 self.assertEqual(memio.readinto(b), 0) 426 self.assertEqual(b, b"67890") 427 b = bytearray(b"hello world") 428 memio.seek(0) 429 self.assertEqual(memio.readinto(b), 10) 430 self.assertEqual(b, b"1234567890d") 431 b = bytearray(b"") 432 memio.seek(0) 433 self.assertEqual(memio.readinto(b), 0) 434 self.assertEqual(b, b"") 435 self.assertRaises(TypeError, memio.readinto, '') 436 import array 437 a = array.array(b'b', b"hello world") 438 memio = self.ioclass(buf) 439 memio.readinto(a) 440 self.assertEqual(a.tostring(), b"1234567890d") 441 memio.close() 442 self.assertRaises(ValueError, memio.readinto, b) 443 memio = self.ioclass(b"123") 444 b = bytearray() 445 memio.seek(42) 446 memio.readinto(b) 447 self.assertEqual(b, b"") 448 449 def test_relative_seek(self): 450 buf = self.buftype("1234567890") 451 memio = self.ioclass(buf) 452 453 self.assertEqual(memio.seek(-1, 1), 0) 454 self.assertEqual(memio.seek(3, 1), 3) 455 self.assertEqual(memio.seek(-4, 1), 0) 456 self.assertEqual(memio.seek(-1, 2), 9) 457 self.assertEqual(memio.seek(1, 1), 10) 458 self.assertEqual(memio.seek(1, 2), 11) 459 memio.seek(-3, 2) 460 self.assertEqual(memio.read(), buf[-3:]) 461 memio.seek(0) 462 memio.seek(1, 1) 463 self.assertEqual(memio.read(), buf[1:]) 464 465 def test_unicode(self): 466 memio = self.ioclass() 467 468 self.assertRaises(TypeError, self.ioclass, "1234567890") 469 self.assertRaises(TypeError, memio.write, "1234567890") 470 self.assertRaises(TypeError, memio.writelines, ["1234567890"]) 471 472 def test_bytes_array(self): 473 buf = b"1234567890" 474 import array 475 a = array.array(b'b', buf) 476 memio = self.ioclass(a) 477 self.assertEqual(memio.getvalue(), buf) 478 self.assertEqual(memio.write(a), 10) 479 self.assertEqual(memio.getvalue(), buf) 480 481 def test_issue5449(self): 482 buf = self.buftype("1234567890") 483 self.ioclass(initial_bytes=buf) 484 self.assertRaises(TypeError, self.ioclass, buf, foo=None) 485 486 487class TextIOTestMixin: 488 489 def test_newlines_property(self): 490 memio = self.ioclass(newline=None) 491 # The C StringIO decodes newlines in write() calls, but the Python 492 # implementation only does when reading. This function forces them to 493 # be decoded for testing. 494 def force_decode(): 495 memio.seek(0) 496 memio.read() 497 self.assertEqual(memio.newlines, None) 498 memio.write("a\n") 499 force_decode() 500 self.assertEqual(memio.newlines, "\n") 501 memio.write("b\r\n") 502 force_decode() 503 self.assertEqual(memio.newlines, ("\n", "\r\n")) 504 memio.write("c\rd") 505 force_decode() 506 self.assertEqual(memio.newlines, ("\r", "\n", "\r\n")) 507 508 def test_relative_seek(self): 509 memio = self.ioclass() 510 511 self.assertRaises(IOError, memio.seek, -1, 1) 512 self.assertRaises(IOError, memio.seek, 3, 1) 513 self.assertRaises(IOError, memio.seek, -3, 1) 514 self.assertRaises(IOError, memio.seek, -1, 2) 515 self.assertRaises(IOError, memio.seek, 1, 1) 516 self.assertRaises(IOError, memio.seek, 1, 2) 517 518 def test_textio_properties(self): 519 memio = self.ioclass() 520 521 # These are just dummy values but we nevertheless check them for fear 522 # of unexpected breakage. 523 self.assertIsNone(memio.encoding) 524 self.assertIsNone(memio.errors) 525 self.assertFalse(memio.line_buffering) 526 527 def test_newline_default(self): 528 memio = self.ioclass("a\nb\r\nc\rd") 529 self.assertEqual(list(memio), ["a\n", "b\r\n", "c\rd"]) 530 self.assertEqual(memio.getvalue(), "a\nb\r\nc\rd") 531 532 memio = self.ioclass() 533 self.assertEqual(memio.write("a\nb\r\nc\rd"), 8) 534 memio.seek(0) 535 self.assertEqual(list(memio), ["a\n", "b\r\n", "c\rd"]) 536 self.assertEqual(memio.getvalue(), "a\nb\r\nc\rd") 537 538 def test_newline_none(self): 539 # newline=None 540 memio = self.ioclass("a\nb\r\nc\rd", newline=None) 541 self.assertEqual(list(memio), ["a\n", "b\n", "c\n", "d"]) 542 memio.seek(0) 543 self.assertEqual(memio.read(1), "a") 544 self.assertEqual(memio.read(2), "\nb") 545 self.assertEqual(memio.read(2), "\nc") 546 self.assertEqual(memio.read(1), "\n") 547 self.assertEqual(memio.getvalue(), "a\nb\nc\nd") 548 549 memio = self.ioclass(newline=None) 550 self.assertEqual(2, memio.write("a\n")) 551 self.assertEqual(3, memio.write("b\r\n")) 552 self.assertEqual(3, memio.write("c\rd")) 553 memio.seek(0) 554 self.assertEqual(memio.read(), "a\nb\nc\nd") 555 self.assertEqual(memio.getvalue(), "a\nb\nc\nd") 556 557 memio = self.ioclass("a\r\nb", newline=None) 558 self.assertEqual(memio.read(3), "a\nb") 559 560 def test_newline_empty(self): 561 # newline="" 562 memio = self.ioclass("a\nb\r\nc\rd", newline="") 563 self.assertEqual(list(memio), ["a\n", "b\r\n", "c\r", "d"]) 564 memio.seek(0) 565 self.assertEqual(memio.read(4), "a\nb\r") 566 self.assertEqual(memio.read(2), "\nc") 567 self.assertEqual(memio.read(1), "\r") 568 self.assertEqual(memio.getvalue(), "a\nb\r\nc\rd") 569 570 memio = self.ioclass(newline="") 571 self.assertEqual(2, memio.write("a\n")) 572 self.assertEqual(2, memio.write("b\r")) 573 self.assertEqual(2, memio.write("\nc")) 574 self.assertEqual(2, memio.write("\rd")) 575 memio.seek(0) 576 self.assertEqual(list(memio), ["a\n", "b\r\n", "c\r", "d"]) 577 self.assertEqual(memio.getvalue(), "a\nb\r\nc\rd") 578 579 def test_newline_lf(self): 580 # newline="\n" 581 memio = self.ioclass("a\nb\r\nc\rd", newline="\n") 582 self.assertEqual(list(memio), ["a\n", "b\r\n", "c\rd"]) 583 self.assertEqual(memio.getvalue(), "a\nb\r\nc\rd") 584 585 memio = self.ioclass(newline="\n") 586 self.assertEqual(memio.write("a\nb\r\nc\rd"), 8) 587 memio.seek(0) 588 self.assertEqual(list(memio), ["a\n", "b\r\n", "c\rd"]) 589 self.assertEqual(memio.getvalue(), "a\nb\r\nc\rd") 590 591 def test_newline_cr(self): 592 # newline="\r" 593 memio = self.ioclass("a\nb\r\nc\rd", newline="\r") 594 self.assertEqual(memio.read(), "a\rb\r\rc\rd") 595 memio.seek(0) 596 self.assertEqual(list(memio), ["a\r", "b\r", "\r", "c\r", "d"]) 597 self.assertEqual(memio.getvalue(), "a\rb\r\rc\rd") 598 599 memio = self.ioclass(newline="\r") 600 self.assertEqual(memio.write("a\nb\r\nc\rd"), 8) 601 memio.seek(0) 602 self.assertEqual(list(memio), ["a\r", "b\r", "\r", "c\r", "d"]) 603 memio.seek(0) 604 self.assertEqual(memio.readlines(), ["a\r", "b\r", "\r", "c\r", "d"]) 605 self.assertEqual(memio.getvalue(), "a\rb\r\rc\rd") 606 607 def test_newline_crlf(self): 608 # newline="\r\n" 609 memio = self.ioclass("a\nb\r\nc\rd", newline="\r\n") 610 self.assertEqual(memio.read(), "a\r\nb\r\r\nc\rd") 611 memio.seek(0) 612 self.assertEqual(list(memio), ["a\r\n", "b\r\r\n", "c\rd"]) 613 memio.seek(0) 614 self.assertEqual(memio.readlines(), ["a\r\n", "b\r\r\n", "c\rd"]) 615 self.assertEqual(memio.getvalue(), "a\r\nb\r\r\nc\rd") 616 617 memio = self.ioclass(newline="\r\n") 618 self.assertEqual(memio.write("a\nb\r\nc\rd"), 8) 619 memio.seek(0) 620 self.assertEqual(list(memio), ["a\r\n", "b\r\r\n", "c\rd"]) 621 self.assertEqual(memio.getvalue(), "a\r\nb\r\r\nc\rd") 622 623 def test_issue5265(self): 624 # StringIO can duplicate newlines in universal newlines mode 625 memio = self.ioclass("a\r\nb\r\n", newline=None) 626 self.assertEqual(memio.read(5), "a\nb\n") 627 self.assertEqual(memio.getvalue(), "a\nb\n") 628 629 630class PyStringIOTest(MemoryTestMixin, MemorySeekTestMixin, 631 TextIOTestMixin, unittest.TestCase): 632 buftype = unicode 633 ioclass = pyio.StringIO 634 UnsupportedOperation = pyio.UnsupportedOperation 635 EOF = "" 636 637 def test_lone_surrogates(self): 638 # Issue #20424 639 surrogate = unichr(0xd800) 640 memio = self.ioclass(surrogate) 641 self.assertEqual(memio.read(), surrogate) 642 643 memio = self.ioclass() 644 memio.write(surrogate) 645 self.assertEqual(memio.getvalue(), surrogate) 646 647 648class PyStringIOPickleTest(TextIOTestMixin, unittest.TestCase): 649 """Test if pickle restores properly the internal state of StringIO. 650 """ 651 buftype = unicode 652 UnsupportedOperation = pyio.UnsupportedOperation 653 EOF = "" 654 655 class ioclass(pyio.StringIO): 656 def __new__(cls, *args, **kwargs): 657 return pickle.loads(pickle.dumps(pyio.StringIO(*args, **kwargs))) 658 def __init__(self, *args, **kwargs): 659 pass 660 661 662class CBytesIOTest(PyBytesIOTest): 663 ioclass = io.BytesIO 664 UnsupportedOperation = io.UnsupportedOperation 665 666 test_bytes_array = unittest.skip( 667 "array.array() does not have the new buffer API" 668 )(PyBytesIOTest.test_bytes_array) 669 670 671 def test_getstate(self): 672 memio = self.ioclass() 673 state = memio.__getstate__() 674 self.assertEqual(len(state), 3) 675 bytearray(state[0]) # Check if state[0] supports the buffer interface. 676 self.assertIsInstance(state[1], int) 677 if state[2] is not None: 678 self.assertIsInstance(state[2], dict) 679 memio.close() 680 self.assertRaises(ValueError, memio.__getstate__) 681 682 def test_setstate(self): 683 # This checks whether __setstate__ does proper input validation. 684 memio = self.ioclass() 685 memio.__setstate__((b"no error", 0, None)) 686 memio.__setstate__((bytearray(b"no error"), 0, None)) 687 memio.__setstate__((b"no error", 0, {'spam': 3})) 688 self.assertRaises(ValueError, memio.__setstate__, (b"", -1, None)) 689 self.assertRaises(TypeError, memio.__setstate__, ("unicode", 0, None)) 690 self.assertRaises(TypeError, memio.__setstate__, (b"", 0.0, None)) 691 self.assertRaises(TypeError, memio.__setstate__, (b"", 0, 0)) 692 self.assertRaises(TypeError, memio.__setstate__, (b"len-test", 0)) 693 self.assertRaises(TypeError, memio.__setstate__) 694 self.assertRaises(TypeError, memio.__setstate__, 0) 695 memio.close() 696 self.assertRaises(ValueError, memio.__setstate__, (b"closed", 0, None)) 697 698 check_sizeof = support.check_sizeof 699 700 @support.cpython_only 701 def test_sizeof(self): 702 basesize = support.calcobjsize(b'P2PP2P') 703 check = self.check_sizeof 704 self.assertEqual(object.__sizeof__(io.BytesIO()), basesize) 705 check(io.BytesIO(), basesize ) 706 check(io.BytesIO(b'a'), basesize + 1 + 1 ) 707 check(io.BytesIO(b'a' * 1000), basesize + 1000 + 1 ) 708 709class CStringIOTest(PyStringIOTest): 710 ioclass = io.StringIO 711 UnsupportedOperation = io.UnsupportedOperation 712 713 # XXX: For the Python version of io.StringIO, this is highly 714 # dependent on the encoding used for the underlying buffer. 715 def test_widechar(self): 716 buf = self.buftype("\U0002030a\U00020347") 717 memio = self.ioclass(buf) 718 719 self.assertEqual(memio.getvalue(), buf) 720 self.assertEqual(memio.write(buf), len(buf)) 721 self.assertEqual(memio.tell(), len(buf)) 722 self.assertEqual(memio.getvalue(), buf) 723 self.assertEqual(memio.write(buf), len(buf)) 724 self.assertEqual(memio.tell(), len(buf) * 2) 725 self.assertEqual(memio.getvalue(), buf + buf) 726 727 def test_getstate(self): 728 memio = self.ioclass() 729 state = memio.__getstate__() 730 self.assertEqual(len(state), 4) 731 self.assertIsInstance(state[0], unicode) 732 self.assertIsInstance(state[1], str) 733 self.assertIsInstance(state[2], int) 734 if state[3] is not None: 735 self.assertIsInstance(state[3], dict) 736 memio.close() 737 self.assertRaises(ValueError, memio.__getstate__) 738 739 def test_setstate(self): 740 # This checks whether __setstate__ does proper input validation. 741 memio = self.ioclass() 742 memio.__setstate__(("no error", "\n", 0, None)) 743 memio.__setstate__(("no error", "", 0, {'spam': 3})) 744 self.assertRaises(ValueError, memio.__setstate__, ("", "f", 0, None)) 745 self.assertRaises(ValueError, memio.__setstate__, ("", "", -1, None)) 746 self.assertRaises(TypeError, memio.__setstate__, (b"", "", 0, None)) 747 # trunk is more tolerant than py3k on the type of the newline param 748 #self.assertRaises(TypeError, memio.__setstate__, ("", b"", 0, None)) 749 self.assertRaises(TypeError, memio.__setstate__, ("", "", 0.0, None)) 750 self.assertRaises(TypeError, memio.__setstate__, ("", "", 0, 0)) 751 self.assertRaises(TypeError, memio.__setstate__, ("len-test", 0)) 752 self.assertRaises(TypeError, memio.__setstate__) 753 self.assertRaises(TypeError, memio.__setstate__, 0) 754 memio.close() 755 self.assertRaises(ValueError, memio.__setstate__, ("closed", "", 0, None)) 756 757 758class CStringIOPickleTest(PyStringIOPickleTest): 759 UnsupportedOperation = io.UnsupportedOperation 760 761 class ioclass(io.StringIO): 762 def __new__(cls, *args, **kwargs): 763 return pickle.loads(pickle.dumps(io.StringIO(*args, **kwargs), 764 protocol=2)) 765 def __init__(self, *args, **kwargs): 766 pass 767 768 769def test_main(): 770 tests = [PyBytesIOTest, PyStringIOTest, CBytesIOTest, CStringIOTest, 771 PyStringIOPickleTest, CStringIOPickleTest] 772 support.run_unittest(*tests) 773 774if __name__ == '__main__': 775 test_main() 776