@@ -1637,11 +1637,11 @@ def bold(self, text):
16371637
16381638# --------------------------------------------------------- user interfaces
16391639
1640- def pager (text ):
1640+ def pager (text , title = '' ):
16411641 """The first time this is called, determine what kind of pager to use."""
16421642 global pager
16431643 pager = getpager ()
1644- pager (text )
1644+ pager (text , title )
16451645
16461646def getpager ():
16471647 """Decide what method to use for paging through text."""
@@ -1656,24 +1656,24 @@ def getpager():
16561656 use_pager = os .environ .get ('MANPAGER' ) or os .environ .get ('PAGER' )
16571657 if use_pager :
16581658 if sys .platform == 'win32' : # pipes completely broken in Windows
1659- return lambda text : tempfilepager (plain (text ), use_pager )
1659+ return lambda text , title = '' : tempfilepager (plain (text ), use_pager )
16601660 elif os .environ .get ('TERM' ) in ('dumb' , 'emacs' ):
1661- return lambda text : pipepager (plain (text ), use_pager )
1661+ return lambda text , title = '' : pipepager (plain (text ), use_pager , title )
16621662 else :
1663- return lambda text : pipepager (text , use_pager )
1663+ return lambda text , title = '' : pipepager (text , use_pager , title )
16641664 if os .environ .get ('TERM' ) in ('dumb' , 'emacs' ):
16651665 return plainpager
16661666 if sys .platform == 'win32' :
1667- return lambda text : tempfilepager (plain (text ), 'more <' )
1667+ return lambda text , title = '' : tempfilepager (plain (text ), 'more <' )
16681668 if hasattr (os , 'system' ) and os .system ('(less) 2>/dev/null' ) == 0 :
1669- return lambda text : pipepager (text , 'less' )
1669+ return lambda text , title = '' : pipepager (text , 'less' , title )
16701670
16711671 import tempfile
16721672 (fd , filename ) = tempfile .mkstemp ()
16731673 os .close (fd )
16741674 try :
16751675 if hasattr (os , 'system' ) and os .system ('more "%s"' % filename ) == 0 :
1676- return lambda text : pipepager (text , 'more' )
1676+ return lambda text , title = '' : pipepager (text , 'more' , title )
16771677 else :
16781678 return ttypager
16791679 finally :
@@ -1683,12 +1683,18 @@ def plain(text):
16831683 """Remove boldface formatting from text."""
16841684 return re .sub ('.\b ' , '' , text )
16851685
1686- def pipepager (text , cmd ):
1686+ def escape_less (s ):
1687+ return re .sub (r'([?:.%\\])' , r'\\\1' , s )
1688+
1689+ def pipepager (text , cmd , title = '' ):
16871690 """Page through text by feeding it to another program."""
16881691 import subprocess
16891692 env = os .environ .copy ()
1693+ if title :
1694+ title += ' '
1695+ esc_title = escape_less (title )
16901696 prompt_string = (
1691- ' '
1697+ f' { esc_title } ' +
16921698 '?ltline %lt?L/%L.'
16931699 ':byte %bB?s/%s.'
16941700 '.'
@@ -1716,7 +1722,7 @@ def pipepager(text, cmd):
17161722 # left running and the terminal is in raw mode and unusable.
17171723 pass
17181724
1719- def tempfilepager (text , cmd ):
1725+ def tempfilepager (text , cmd , title = '' ):
17201726 """Page through text by invoking a program on a temporary file."""
17211727 import tempfile
17221728 with tempfile .TemporaryDirectory () as tempdir :
@@ -1733,7 +1739,7 @@ def _escape_stdout(text):
17331739 encoding = getattr (sys .stdout , 'encoding' , None ) or 'utf-8'
17341740 return text .encode (encoding , 'backslashreplace' ).decode (encoding )
17351741
1736- def ttypager (text ):
1742+ def ttypager (text , title = '' ):
17371743 """Page through text on a text terminal."""
17381744 lines = plain (_escape_stdout (text )).split ('\n ' )
17391745 try :
@@ -1777,7 +1783,7 @@ def ttypager(text):
17771783 if tty :
17781784 tty .tcsetattr (fd , tty .TCSAFLUSH , old )
17791785
1780- def plainpager (text ):
1786+ def plainpager (text , title = '' ):
17811787 """Simply print unformatted text. This is the ultimate fallback."""
17821788 sys .stdout .write (plain (_escape_stdout (text )))
17831789
@@ -1879,7 +1885,8 @@ def doc(thing, title='Python Library Documentation: %s', forceload=0,
18791885 """Display text documentation, given an object or a path to an object."""
18801886 if output is None :
18811887 try :
1882- pager (render_doc (thing , title , forceload ))
1888+ what = thing if isinstance (thing , str ) else type (thing ).__name__
1889+ pager (render_doc (thing , title , forceload ), f'Help on { what !s} ' )
18831890 except ImportError as exc :
18841891 if is_cli :
18851892 raise
@@ -2253,7 +2260,7 @@ def showtopic(self, topic, more_xrefs=''):
22532260 text = 'Related help topics: ' + ', ' .join (xrefs .split ()) + '\n '
22542261 wrapped_text = textwrap .wrap (text , 72 )
22552262 doc += '\n %s\n ' % '\n ' .join (wrapped_text )
2256- pager (doc )
2263+ pager (doc , f'Help on { topic !s } ' )
22572264
22582265 def _gettopic (self , topic , more_xrefs = '' ):
22592266 """Return unbuffered tuple of (topic, xrefs).
0 commit comments