@@ -794,6 +794,42 @@ def test_stderr_none(self):
794794 self .assertNotIn (b'Warning!' , stderr )
795795 self .assertNotIn (b'Error' , stderr )
796796
797+ def test_issue31285 (self ):
798+ # warn_explicit() should neither raise a SystemError nor cause an
799+ # assertion failure, in case the return value of get_source() has a
800+ # bad splitlines() method.
801+ def get_bad_loader (splitlines_ret_val ):
802+ class BadLoader :
803+ def get_source (self , fullname ):
804+ class BadSource (str ):
805+ def splitlines (self ):
806+ return splitlines_ret_val
807+ return BadSource ('spam' )
808+ return BadLoader ()
809+
810+ wmod = self .module
811+ with original_warnings .catch_warnings (module = wmod ):
812+ wmod .filterwarnings ('default' , category = UserWarning )
813+
814+ with support .captured_stderr () as stderr :
815+ wmod .warn_explicit (
816+ 'foo' , UserWarning , 'bar' , 1 ,
817+ module_globals = {'__loader__' : get_bad_loader (42 ),
818+ '__name__' : 'foobar' })
819+ self .assertIn ('UserWarning: foo' , stderr .getvalue ())
820+
821+ show = wmod ._showwarnmsg
822+ try :
823+ del wmod ._showwarnmsg
824+ with support .captured_stderr () as stderr :
825+ wmod .warn_explicit (
826+ 'eggs' , UserWarning , 'bar' , 1 ,
827+ module_globals = {'__loader__' : get_bad_loader ([42 ]),
828+ '__name__' : 'foobar' })
829+ self .assertIn ('UserWarning: eggs' , stderr .getvalue ())
830+ finally :
831+ wmod ._showwarnmsg = show
832+
797833 @support .cpython_only
798834 def test_issue31411 (self ):
799835 # warn_explicit() shouldn't raise a SystemError in case
0 commit comments