1717import types
1818import typing
1919import unittest
20+ import unittest .mock
2021import urllib .parse
2122import xml .etree
2223import xml .etree .ElementTree
@@ -658,16 +659,13 @@ def test_fail_help_output_redirect(self):
658659
659660 @unittest .skipIf (hasattr (sys , 'gettrace' ) and sys .gettrace (),
660661 'trace function introduces __locals__ unexpectedly' )
662+ @unittest .mock .patch ('pydoc.pager' )
661663 @requires_docstrings
662- def test_help_output_redirect (self ):
664+ def test_help_output_redirect (self , pager_mock ):
663665 # issue 940286, if output is set in Helper, then all output from
664666 # Helper.help should be redirected
665- getpager_old = pydoc .getpager
666- getpager_new = lambda : (lambda x : x )
667667 self .maxDiff = None
668668
669- buf = StringIO ()
670- helper = pydoc .Helper (output = buf )
671669 unused , doc_loc = get_pydoc_text (pydoc_mod )
672670 module = "test.test_pydoc.pydoc_mod"
673671 help_header = """
@@ -677,21 +675,112 @@ def test_help_output_redirect(self):
677675 help_header = textwrap .dedent (help_header )
678676 expected_help_pattern = help_header + expected_text_pattern
679677
680- pydoc .getpager = getpager_new
681- try :
678+ with captured_output ('stdout' ) as output , \
679+ captured_output ('stderr' ) as err , \
680+ StringIO () as buf :
681+ helper = pydoc .Helper (output = buf )
682+ helper .help (module )
683+ result = buf .getvalue ().strip ()
684+ expected_text = expected_help_pattern % (
685+ (doc_loc ,) +
686+ expected_text_data_docstrings +
687+ (inspect .getabsfile (pydoc_mod ),))
688+ self .assertEqual ('' , output .getvalue ())
689+ self .assertEqual ('' , err .getvalue ())
690+ self .assertEqual (expected_text , result )
691+
692+ pager_mock .assert_not_called ()
693+
694+ @unittest .skipIf (hasattr (sys , 'gettrace' ) and sys .gettrace (),
695+ 'trace function introduces __locals__ unexpectedly' )
696+ @requires_docstrings
697+ @unittest .mock .patch ('pydoc.pager' )
698+ def test_help_output_redirect_various_requests (self , pager_mock ):
699+ # issue 940286, if output is set in Helper, then all output from
700+ # Helper.help should be redirected
701+
702+ def run_pydoc_for_request (request , expected_text_part ):
703+ """Helper function to run pydoc with its output redirected"""
682704 with captured_output ('stdout' ) as output , \
683- captured_output ('stderr' ) as err :
684- helper .help (module )
705+ captured_output ('stderr' ) as err , \
706+ StringIO () as buf :
707+ helper = pydoc .Helper (output = buf )
708+ helper .help (request )
685709 result = buf .getvalue ().strip ()
686- expected_text = expected_help_pattern % (
687- (doc_loc ,) +
688- expected_text_data_docstrings +
689- (inspect .getabsfile (pydoc_mod ),))
690- self .assertEqual ('' , output .getvalue ())
691- self .assertEqual ('' , err .getvalue ())
692- self .assertEqual (expected_text , result )
693- finally :
694- pydoc .getpager = getpager_old
710+ self .assertEqual ('' , output .getvalue (), msg = f'failed on request "{ request } "' )
711+ self .assertEqual ('' , err .getvalue (), msg = f'failed on request "{ request } "' )
712+ self .assertIn (expected_text_part , result , msg = f'failed on request "{ request } "' )
713+ pager_mock .assert_not_called ()
714+
715+ self .maxDiff = None
716+
717+ # test for "keywords"
718+ run_pydoc_for_request ('keywords' , 'Here is a list of the Python keywords.' )
719+ # test for "symbols"
720+ run_pydoc_for_request ('symbols' , 'Here is a list of the punctuation symbols' )
721+ # test for "topics"
722+ run_pydoc_for_request ('topics' , 'Here is a list of available topics.' )
723+ # test for "modules" skipped, see test_modules()
724+ # test for symbol "%"
725+ run_pydoc_for_request ('%' , 'The power operator' )
726+ # test for special True, False, None keywords
727+ run_pydoc_for_request ('True' , 'class bool(int)' )
728+ run_pydoc_for_request ('False' , 'class bool(int)' )
729+ run_pydoc_for_request ('None' , 'class NoneType(object)' )
730+ # test for keyword "assert"
731+ run_pydoc_for_request ('assert' , 'The "assert" statement' )
732+ # test for topic "TYPES"
733+ run_pydoc_for_request ('TYPES' , 'The standard type hierarchy' )
734+ # test for "pydoc.Helper.help"
735+ run_pydoc_for_request ('pydoc.Helper.help' , 'Help on function help in pydoc.Helper:' )
736+ # test for pydoc.Helper.help
737+ run_pydoc_for_request (pydoc .Helper .help , 'Help on function help in module pydoc:' )
738+ # test for pydoc.Helper() instance skipped because it is always meant to be interactive
739+
740+ def test_showtopic (self ):
741+ with captured_stdout () as showtopic_io :
742+ helper = pydoc .Helper ()
743+ helper .showtopic ('with' )
744+ helptext = showtopic_io .getvalue ()
745+ self .assertIn ('The "with" statement' , helptext )
746+
747+ def test_fail_showtopic (self ):
748+ with captured_stdout () as showtopic_io :
749+ helper = pydoc .Helper ()
750+ helper .showtopic ('abd' )
751+ expected = "no documentation found for 'abd'"
752+ self .assertEqual (expected , showtopic_io .getvalue ().strip ())
753+
754+ @unittest .mock .patch ('pydoc.pager' )
755+ def test_fail_showtopic_output_redirect (self , pager_mock ):
756+ with StringIO () as buf :
757+ helper = pydoc .Helper (output = buf )
758+ helper .showtopic ("abd" )
759+ expected = "no documentation found for 'abd'"
760+ self .assertEqual (expected , buf .getvalue ().strip ())
761+
762+ pager_mock .assert_not_called ()
763+
764+ @unittest .skipIf (hasattr (sys , 'gettrace' ) and sys .gettrace (),
765+ 'trace function introduces __locals__ unexpectedly' )
766+ @requires_docstrings
767+ @unittest .mock .patch ('pydoc.pager' )
768+ def test_showtopic_output_redirect (self , pager_mock ):
769+ # issue 940286, if output is set in Helper, then all output from
770+ # Helper.showtopic should be redirected
771+ self .maxDiff = None
772+
773+ with captured_output ('stdout' ) as output , \
774+ captured_output ('stderr' ) as err , \
775+ StringIO () as buf :
776+ helper = pydoc .Helper (output = buf )
777+ helper .showtopic ('with' )
778+ result = buf .getvalue ().strip ()
779+ self .assertEqual ('' , output .getvalue ())
780+ self .assertEqual ('' , err .getvalue ())
781+ self .assertIn ('The "with" statement' , result )
782+
783+ pager_mock .assert_not_called ()
695784
696785 def test_lambda_with_return_annotation (self ):
697786 func = lambda a , b , c : 1
0 commit comments