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