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 __main__.PickleTestMemIO = PickleTestMemIO 380 submemio = PickleTestMemIO(buf, 80) 381 submemio.seek(2) 382 383 # We only support pickle protocol 2 and onward since we use extended 384 # __reduce__ API of PEP 307 to provide pickling support. 385 for proto in range(2, pickle.HIGHEST_PROTOCOL): 386 for obj in (memio, submemio): 387 obj2 = pickle.loads(pickle.dumps(obj, protocol=proto)) 388 self.assertEqual(obj.getvalue(), obj2.getvalue()) 389 self.assertEqual(obj.__class__, obj2.__class__) 390 self.assertEqual(obj.foo, obj2.foo) 391 self.assertEqual(obj.tell(), obj2.tell()) 392 obj.close() 393 self.assertRaises(ValueError, pickle.dumps, obj, proto) 394 del __main__.PickleTestMemIO 395 396 397class PyBytesIOTest(MemoryTestMixin, MemorySeekTestMixin, unittest.TestCase): 398 399 UnsupportedOperation = pyio.UnsupportedOperation 400 401 @staticmethod 402 def buftype(s): 403 return s.encode("ascii") 404 ioclass = pyio.BytesIO 405 EOF = b"" 406 407 def test_read1(self): 408 buf = self.buftype("1234567890") 409 memio = self.ioclass(buf) 410 411 self.assertRaises(TypeError, memio.read1) 412 self.assertEqual(memio.read(), buf) 413 414 def test_readinto(self): 415 buf = self.buftype("1234567890") 416 memio = self.ioclass(buf) 417 418 b = bytearray(b"hello") 419 self.assertEqual(memio.readinto(b), 5) 420 self.assertEqual(b, b"12345") 421 self.assertEqual(memio.readinto(b), 5) 422 self.assertEqual(b, b"67890") 423 self.assertEqual(memio.readinto(b), 0) 424 self.assertEqual(b, b"67890") 425 b = bytearray(b"hello world") 426 memio.seek(0) 427 self.assertEqual(memio.readinto(b), 10) 428 self.assertEqual(b, b"1234567890d") 429 b = bytearray(b"") 430 memio.seek(0) 431 self.assertEqual(memio.readinto(b), 0) 432 self.assertEqual(b, b"") 433 self.assertRaises(TypeError, memio.readinto, '') 434 import array 435 a = array.array(b'b', b"hello world") 436 memio = self.ioclass(buf) 437 memio.readinto(a) 438 self.assertEqual(a.tostring(), b"1234567890d") 439 memio.close() 440 self.assertRaises(ValueError, memio.readinto, b) 441 memio = self.ioclass(b"123") 442 b = bytearray() 443 memio.seek(42) 444 memio.readinto(b) 445 self.assertEqual(b, b"") 446 447 def test_relative_seek(self): 448 buf = self.buftype("1234567890") 449 memio = self.ioclass(buf) 450 451 self.assertEqual(memio.seek(-1, 1), 0) 452 self.assertEqual(memio.seek(3, 1), 3) 453 self.assertEqual(memio.seek(-4, 1), 0) 454 self.assertEqual(memio.seek(-1, 2), 9) 455 self.assertEqual(memio.seek(1, 1), 10) 456 self.assertEqual(memio.seek(1, 2), 11) 457 memio.seek(-3, 2) 458 self.assertEqual(memio.read(), buf[-3:]) 459 memio.seek(0) 460 memio.seek(1, 1) 461 self.assertEqual(memio.read(), buf[1:]) 462 463 def test_unicode(self): 464 memio = self.ioclass() 465 466 self.assertRaises(TypeError, self.ioclass, "1234567890") 467 self.assertRaises(TypeError, memio.write, "1234567890") 468 self.assertRaises(TypeError, memio.writelines, ["1234567890"]) 469 470 def test_bytes_array(self): 471 buf = b"1234567890" 472 import array 473 a = array.array(b'b', buf) 474 memio = self.ioclass(a) 475 self.assertEqual(memio.getvalue(), buf) 476 self.assertEqual(memio.write(a), 10) 477 self.assertEqual(memio.getvalue(), buf) 478 479 def test_issue5449(self): 480 buf = self.buftype("1234567890") 481 self.ioclass(initial_bytes=buf) 482 self.assertRaises(TypeError, self.ioclass, buf, foo=None) 483 484 485class TextIOTestMixin: 486 487 def test_newlines_property(self): 488 memio = self.ioclass(newline=None) 489 # The C StringIO decodes newlines in write() calls, but the Python 490 # implementation only does when reading. This function forces them to 491 # be decoded for testing. 492 def force_decode(): 493 memio.seek(0) 494 memio.read() 495 self.assertEqual(memio.newlines, None) 496 memio.write("a\n") 497 force_decode() 498 self.assertEqual(memio.newlines, "\n") 499 memio.write("b\r\n") 500 force_decode() 501 self.assertEqual(memio.newlines, ("\n", "\r\n")) 502 memio.write("c\rd") 503 force_decode() 504 self.assertEqual(memio.newlines, ("\r", "\n", "\r\n")) 505 506 def test_relative_seek(self): 507 memio = self.ioclass() 508 509 self.assertRaises(IOError, memio.seek, -1, 1) 510 self.assertRaises(IOError, memio.seek, 3, 1) 511 self.assertRaises(IOError, memio.seek, -3, 1) 512 self.assertRaises(IOError, memio.seek, -1, 2) 513 self.assertRaises(IOError, memio.seek, 1, 1) 514 self.assertRaises(IOError, memio.seek, 1, 2) 515 516 def test_textio_properties(self): 517 memio = self.ioclass() 518 519 # These are just dummy values but we nevertheless check them for fear 520 # of unexpected breakage. 521 self.assertIsNone(memio.encoding) 522 self.assertIsNone(memio.errors) 523 self.assertFalse(memio.line_buffering) 524 525 def test_newline_none(self): 526 # newline=None 527 memio = self.ioclass("a\nb\r\nc\rd", newline=None) 528 self.assertEqual(list(memio), ["a\n", "b\n", "c\n", "d"]) 529 memio.seek(0) 530 self.assertEqual(memio.read(1), "a") 531 self.assertEqual(memio.read(2), "\nb") 532 self.assertEqual(memio.read(2), "\nc") 533 self.assertEqual(memio.read(1), "\n") 534 memio = self.ioclass(newline=None) 535 self.assertEqual(2, memio.write("a\n")) 536 self.assertEqual(3, memio.write("b\r\n")) 537 self.assertEqual(3, memio.write("c\rd")) 538 memio.seek(0) 539 self.assertEqual(memio.read(), "a\nb\nc\nd") 540 memio = self.ioclass("a\r\nb", newline=None) 541 self.assertEqual(memio.read(3), "a\nb") 542 543 def test_newline_empty(self): 544 # newline="" 545 memio = self.ioclass("a\nb\r\nc\rd", newline="") 546 self.assertEqual(list(memio), ["a\n", "b\r\n", "c\r", "d"]) 547 memio.seek(0) 548 self.assertEqual(memio.read(4), "a\nb\r") 549 self.assertEqual(memio.read(2), "\nc") 550 self.assertEqual(memio.read(1), "\r") 551 memio = self.ioclass(newline="") 552 self.assertEqual(2, memio.write("a\n")) 553 self.assertEqual(2, memio.write("b\r")) 554 self.assertEqual(2, memio.write("\nc")) 555 self.assertEqual(2, memio.write("\rd")) 556 memio.seek(0) 557 self.assertEqual(list(memio), ["a\n", "b\r\n", "c\r", "d"]) 558 559 def test_newline_lf(self): 560 # newline="\n" 561 memio = self.ioclass("a\nb\r\nc\rd") 562 self.assertEqual(list(memio), ["a\n", "b\r\n", "c\rd"]) 563 564 def test_newline_cr(self): 565 # newline="\r" 566 memio = self.ioclass("a\nb\r\nc\rd", newline="\r") 567 self.assertEqual(memio.read(), "a\rb\r\rc\rd") 568 memio.seek(0) 569 self.assertEqual(list(memio), ["a\r", "b\r", "\r", "c\r", "d"]) 570 571 def test_newline_crlf(self): 572 # newline="\r\n" 573 memio = self.ioclass("a\nb\r\nc\rd", newline="\r\n") 574 self.assertEqual(memio.read(), "a\r\nb\r\r\nc\rd") 575 memio.seek(0) 576 self.assertEqual(list(memio), ["a\r\n", "b\r\r\n", "c\rd"]) 577 578 def test_issue5265(self): 579 # StringIO can duplicate newlines in universal newlines mode 580 memio = self.ioclass("a\r\nb\r\n", newline=None) 581 self.assertEqual(memio.read(5), "a\nb\n") 582 583 584class PyStringIOTest(MemoryTestMixin, MemorySeekTestMixin, 585 TextIOTestMixin, unittest.TestCase): 586 buftype = unicode 587 ioclass = pyio.StringIO 588 UnsupportedOperation = pyio.UnsupportedOperation 589 EOF = "" 590 591 592class PyStringIOPickleTest(TextIOTestMixin, unittest.TestCase): 593 """Test if pickle restores properly the internal state of StringIO. 594 """ 595 buftype = unicode 596 UnsupportedOperation = pyio.UnsupportedOperation 597 EOF = "" 598 599 class ioclass(pyio.StringIO): 600 def __new__(cls, *args, **kwargs): 601 return pickle.loads(pickle.dumps(pyio.StringIO(*args, **kwargs))) 602 def __init__(self, *args, **kwargs): 603 pass 604 605 606class CBytesIOTest(PyBytesIOTest): 607 ioclass = io.BytesIO 608 UnsupportedOperation = io.UnsupportedOperation 609 610 test_bytes_array = unittest.skip( 611 "array.array() does not have the new buffer API" 612 )(PyBytesIOTest.test_bytes_array) 613 614 615 def test_getstate(self): 616 memio = self.ioclass() 617 state = memio.__getstate__() 618 self.assertEqual(len(state), 3) 619 bytearray(state[0]) # Check if state[0] supports the buffer interface. 620 self.assertIsInstance(state[1], int) 621 self.assertTrue(isinstance(state[2], dict) or state[2] is None) 622 memio.close() 623 self.assertRaises(ValueError, memio.__getstate__) 624 625 def test_setstate(self): 626 # This checks whether __setstate__ does proper input validation. 627 memio = self.ioclass() 628 memio.__setstate__((b"no error", 0, None)) 629 memio.__setstate__((bytearray(b"no error"), 0, None)) 630 memio.__setstate__((b"no error", 0, {'spam': 3})) 631 self.assertRaises(ValueError, memio.__setstate__, (b"", -1, None)) 632 self.assertRaises(TypeError, memio.__setstate__, ("unicode", 0, None)) 633 self.assertRaises(TypeError, memio.__setstate__, (b"", 0.0, None)) 634 self.assertRaises(TypeError, memio.__setstate__, (b"", 0, 0)) 635 self.assertRaises(TypeError, memio.__setstate__, (b"len-test", 0)) 636 self.assertRaises(TypeError, memio.__setstate__) 637 self.assertRaises(TypeError, memio.__setstate__, 0) 638 memio.close() 639 self.assertRaises(ValueError, memio.__setstate__, (b"closed", 0, None)) 640 641 check_sizeof = support.check_sizeof 642 643 @support.cpython_only 644 def test_sizeof(self): 645 basesize = support.calcobjsize(b'P2PP2P') 646 check = self.check_sizeof 647 self.assertEqual(object.__sizeof__(io.BytesIO()), basesize) 648 check(io.BytesIO(), basesize ) 649 check(io.BytesIO(b'a'), basesize + 1 + 1 ) 650 check(io.BytesIO(b'a' * 1000), basesize + 1000 + 1 ) 651 652class CStringIOTest(PyStringIOTest): 653 ioclass = io.StringIO 654 UnsupportedOperation = io.UnsupportedOperation 655 656 # XXX: For the Python version of io.StringIO, this is highly 657 # dependent on the encoding used for the underlying buffer. 658 def test_widechar(self): 659 buf = self.buftype("\U0002030a\U00020347") 660 memio = self.ioclass(buf) 661 662 self.assertEqual(memio.getvalue(), buf) 663 self.assertEqual(memio.write(buf), len(buf)) 664 self.assertEqual(memio.tell(), len(buf)) 665 self.assertEqual(memio.getvalue(), buf) 666 self.assertEqual(memio.write(buf), len(buf)) 667 self.assertEqual(memio.tell(), len(buf) * 2) 668 self.assertEqual(memio.getvalue(), buf + buf) 669 670 def test_getstate(self): 671 memio = self.ioclass() 672 state = memio.__getstate__() 673 self.assertEqual(len(state), 4) 674 self.assertIsInstance(state[0], unicode) 675 self.assertIsInstance(state[1], str) 676 self.assertIsInstance(state[2], int) 677 self.assertTrue(isinstance(state[3], dict) or state[3] is None) 678 memio.close() 679 self.assertRaises(ValueError, memio.__getstate__) 680 681 def test_setstate(self): 682 # This checks whether __setstate__ does proper input validation. 683 memio = self.ioclass() 684 memio.__setstate__(("no error", "\n", 0, None)) 685 memio.__setstate__(("no error", "", 0, {'spam': 3})) 686 self.assertRaises(ValueError, memio.__setstate__, ("", "f", 0, None)) 687 self.assertRaises(ValueError, memio.__setstate__, ("", "", -1, None)) 688 self.assertRaises(TypeError, memio.__setstate__, (b"", "", 0, None)) 689 # trunk is more tolerant than py3k on the type of the newline param 690 #self.assertRaises(TypeError, memio.__setstate__, ("", b"", 0, None)) 691 self.assertRaises(TypeError, memio.__setstate__, ("", "", 0.0, None)) 692 self.assertRaises(TypeError, memio.__setstate__, ("", "", 0, 0)) 693 self.assertRaises(TypeError, memio.__setstate__, ("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__, ("closed", "", 0, None)) 698 699 700class CStringIOPickleTest(PyStringIOPickleTest): 701 UnsupportedOperation = io.UnsupportedOperation 702 703 class ioclass(io.StringIO): 704 def __new__(cls, *args, **kwargs): 705 return pickle.loads(pickle.dumps(io.StringIO(*args, **kwargs), 706 protocol=2)) 707 def __init__(self, *args, **kwargs): 708 pass 709 710 711def test_main(): 712 tests = [PyBytesIOTest, PyStringIOTest, CBytesIOTest, CStringIOTest, 713 PyStringIOPickleTest, CStringIOPickleTest] 714 support.run_unittest(*tests) 715 716if __name__ == '__main__': 717 test_main() 718