@@ -81,6 +81,10 @@ def _default_chunk_size():
8181)
8282
8383
84+ class BadIndex :
85+ def __index__ (self ):
86+ 1 / 0
87+
8488class MockRawIOWithoutRead :
8589 """A RawIO implementation without read(), so as to exercise the default
8690 RawIO.read() which calls readinto()."""
@@ -2613,8 +2617,31 @@ def test_constructor(self):
26132617 self .assertEqual (t .encoding , "utf-8" )
26142618 self .assertEqual (t .line_buffering , True )
26152619 self .assertEqual ("\xe9 \n " , t .readline ())
2616- self .assertRaises (TypeError , t .__init__ , b , encoding = "utf-8" , newline = 42 )
2617- self .assertRaises (ValueError , t .__init__ , b , encoding = "utf-8" , newline = 'xyzzy' )
2620+ invalid_type = TypeError if self .is_C else ValueError
2621+ with self .assertRaises (invalid_type ):
2622+ t .__init__ (b , encoding = 42 )
2623+ with self .assertRaises (UnicodeEncodeError ):
2624+ t .__init__ (b , encoding = '\udcfe ' )
2625+ with self .assertRaises (ValueError ):
2626+ t .__init__ (b , encoding = 'utf-8\0 ' )
2627+ with self .assertRaises (invalid_type ):
2628+ t .__init__ (b , encoding = "utf-8" , errors = 42 )
2629+ if support .Py_DEBUG or sys .flags .dev_mode or self .is_C :
2630+ with self .assertRaises (UnicodeEncodeError ):
2631+ t .__init__ (b , encoding = "utf-8" , errors = '\udcfe ' )
2632+ if support .Py_DEBUG or sys .flags .dev_mode :
2633+ # TODO: If encoded to UTF-8, should also be checked for
2634+ # embedded null characters.
2635+ with self .assertRaises (ValueError ):
2636+ t .__init__ (b , encoding = "utf-8" , errors = 'replace\0 ' )
2637+ with self .assertRaises (TypeError ):
2638+ t .__init__ (b , encoding = "utf-8" , newline = 42 )
2639+ with self .assertRaises (ValueError ):
2640+ t .__init__ (b , encoding = "utf-8" , newline = '\udcfe ' )
2641+ with self .assertRaises (ValueError ):
2642+ t .__init__ (b , encoding = "utf-8" , newline = '\n \0 ' )
2643+ with self .assertRaises (ValueError ):
2644+ t .__init__ (b , encoding = "utf-8" , newline = 'xyzzy' )
26182645
26192646 def test_uninitialized (self ):
26202647 t = self .TextIOWrapper .__new__ (self .TextIOWrapper )
@@ -3663,6 +3690,59 @@ def test_reconfigure_defaults(self):
36633690
36643691 self .assertEqual (txt .detach ().getvalue (), b'LF\n CRLF\r \n ' )
36653692
3693+ def test_reconfigure_errors (self ):
3694+ txt = self .TextIOWrapper (self .BytesIO (), 'ascii' , 'replace' , '\r ' )
3695+ with self .assertRaises (TypeError ): # there was a crash
3696+ txt .reconfigure (encoding = 42 )
3697+ if self .is_C :
3698+ with self .assertRaises (UnicodeEncodeError ):
3699+ txt .reconfigure (encoding = '\udcfe ' )
3700+ with self .assertRaises (LookupError ):
3701+ txt .reconfigure (encoding = 'locale\0 ' )
3702+ # TODO: txt.reconfigure(encoding='utf-8\0')
3703+ # TODO: txt.reconfigure(encoding='nonexisting')
3704+ with self .assertRaises (TypeError ):
3705+ txt .reconfigure (errors = 42 )
3706+ if self .is_C :
3707+ with self .assertRaises (UnicodeEncodeError ):
3708+ txt .reconfigure (errors = '\udcfe ' )
3709+ # TODO: txt.reconfigure(errors='ignore\0')
3710+ # TODO: txt.reconfigure(errors='nonexisting')
3711+ with self .assertRaises (TypeError ):
3712+ txt .reconfigure (newline = 42 )
3713+ with self .assertRaises (ValueError ):
3714+ txt .reconfigure (newline = '\udcfe ' )
3715+ with self .assertRaises (ValueError ):
3716+ txt .reconfigure (newline = 'xyz' )
3717+ if not self .is_C :
3718+ # TODO: Should fail in C too.
3719+ with self .assertRaises (ValueError ):
3720+ txt .reconfigure (newline = '\n \0 ' )
3721+ if self .is_C :
3722+ # TODO: Use __bool__(), not __index__().
3723+ with self .assertRaises (ZeroDivisionError ):
3724+ txt .reconfigure (line_buffering = BadIndex ())
3725+ with self .assertRaises (OverflowError ):
3726+ txt .reconfigure (line_buffering = 2 ** 1000 )
3727+ with self .assertRaises (ZeroDivisionError ):
3728+ txt .reconfigure (write_through = BadIndex ())
3729+ with self .assertRaises (OverflowError ):
3730+ txt .reconfigure (write_through = 2 ** 1000 )
3731+ with self .assertRaises (ZeroDivisionError ): # there was a crash
3732+ txt .reconfigure (line_buffering = BadIndex (),
3733+ write_through = BadIndex ())
3734+ self .assertEqual (txt .encoding , 'ascii' )
3735+ self .assertEqual (txt .errors , 'replace' )
3736+ self .assertIs (txt .line_buffering , False )
3737+ self .assertIs (txt .write_through , False )
3738+
3739+ txt .reconfigure (encoding = 'latin1' , errors = 'ignore' , newline = '\r \n ' ,
3740+ line_buffering = True , write_through = True )
3741+ self .assertEqual (txt .encoding , 'latin1' )
3742+ self .assertEqual (txt .errors , 'ignore' )
3743+ self .assertIs (txt .line_buffering , True )
3744+ self .assertIs (txt .write_through , True )
3745+
36663746 def test_reconfigure_newline (self ):
36673747 raw = self .BytesIO (b'CR\r EOF' )
36683748 txt = self .TextIOWrapper (raw , 'ascii' , newline = '\n ' )
@@ -4693,9 +4773,11 @@ def load_tests(loader, tests, pattern):
46934773 if test .__name__ .startswith ("C" ):
46944774 for name , obj in c_io_ns .items ():
46954775 setattr (test , name , obj )
4776+ test .is_C = True
46964777 elif test .__name__ .startswith ("Py" ):
46974778 for name , obj in py_io_ns .items ():
46984779 setattr (test , name , obj )
4780+ test .is_C = False
46994781
47004782 suite = loader .suiteClass ()
47014783 for test in tests :
0 commit comments