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