aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Lib/pydoc.py
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2024-04-17 13:05:22 +0300
committerGitHub <noreply@github.com>2024-04-17 13:05:22 +0300
commitc917b3e8e113a3e1ffe118e581fac29eaf365191 (patch)
treee9f0379182df42b7b87174a3f55a163f2d7cb299 /Lib/pydoc.py
parent438b7c3071eebaccd1ba215f15a239345b22f813 (diff)
downloadcpython-c917b3e8e113a3e1ffe118e581fac29eaf365191.tar.gz
cpython-c917b3e8e113a3e1ffe118e581fac29eaf365191.zip
gh-65824: Add "Help on ..." to the "less" prompt in pydoc (GH-116183)
Diffstat (limited to 'Lib/pydoc.py')
-rwxr-xr-xLib/pydoc.py37
1 files changed, 22 insertions, 15 deletions
diff --git a/Lib/pydoc.py b/Lib/pydoc.py
index d9cf03fb4ff..02af672a628 100755
--- a/Lib/pydoc.py
+++ b/Lib/pydoc.py
@@ -1637,11 +1637,11 @@ class _PlainTextDoc(TextDoc):
# --------------------------------------------------------- user interfaces
-def pager(text):
+def pager(text, title=''):
"""The first time this is called, determine what kind of pager to use."""
global pager
pager = getpager()
- pager(text)
+ pager(text, title)
def getpager():
"""Decide what method to use for paging through text."""
@@ -1656,24 +1656,24 @@ def getpager():
use_pager = os.environ.get('MANPAGER') or os.environ.get('PAGER')
if use_pager:
if sys.platform == 'win32': # pipes completely broken in Windows
- return lambda text: tempfilepager(plain(text), use_pager)
+ return lambda text, title='': tempfilepager(plain(text), use_pager)
elif os.environ.get('TERM') in ('dumb', 'emacs'):
- return lambda text: pipepager(plain(text), use_pager)
+ return lambda text, title='': pipepager(plain(text), use_pager, title)
else:
- return lambda text: pipepager(text, use_pager)
+ return lambda text, title='': pipepager(text, use_pager, title)
if os.environ.get('TERM') in ('dumb', 'emacs'):
return plainpager
if sys.platform == 'win32':
- return lambda text: tempfilepager(plain(text), 'more <')
+ return lambda text, title='': tempfilepager(plain(text), 'more <')
if hasattr(os, 'system') and os.system('(less) 2>/dev/null') == 0:
- return lambda text: pipepager(text, 'less')
+ return lambda text, title='': pipepager(text, 'less', title)
import tempfile
(fd, filename) = tempfile.mkstemp()
os.close(fd)
try:
if hasattr(os, 'system') and os.system('more "%s"' % filename) == 0:
- return lambda text: pipepager(text, 'more')
+ return lambda text, title='': pipepager(text, 'more', title)
else:
return ttypager
finally:
@@ -1683,12 +1683,18 @@ def plain(text):
"""Remove boldface formatting from text."""
return re.sub('.\b', '', text)
-def pipepager(text, cmd):
+def escape_less(s):
+ return re.sub(r'([?:.%\\])', r'\\\1', s)
+
+def pipepager(text, cmd, title=''):
"""Page through text by feeding it to another program."""
import subprocess
env = os.environ.copy()
+ if title:
+ title += ' '
+ esc_title = escape_less(title)
prompt_string = (
- ' '
+ f' {esc_title}' +
'?ltline %lt?L/%L.'
':byte %bB?s/%s.'
'.'
@@ -1716,7 +1722,7 @@ def pipepager(text, cmd):
# left running and the terminal is in raw mode and unusable.
pass
-def tempfilepager(text, cmd):
+def tempfilepager(text, cmd, title=''):
"""Page through text by invoking a program on a temporary file."""
import tempfile
with tempfile.TemporaryDirectory() as tempdir:
@@ -1733,7 +1739,7 @@ def _escape_stdout(text):
encoding = getattr(sys.stdout, 'encoding', None) or 'utf-8'
return text.encode(encoding, 'backslashreplace').decode(encoding)
-def ttypager(text):
+def ttypager(text, title=''):
"""Page through text on a text terminal."""
lines = plain(_escape_stdout(text)).split('\n')
try:
@@ -1777,7 +1783,7 @@ def ttypager(text):
if tty:
tty.tcsetattr(fd, tty.TCSAFLUSH, old)
-def plainpager(text):
+def plainpager(text, title=''):
"""Simply print unformatted text. This is the ultimate fallback."""
sys.stdout.write(plain(_escape_stdout(text)))
@@ -1879,7 +1885,8 @@ def doc(thing, title='Python Library Documentation: %s', forceload=0,
"""Display text documentation, given an object or a path to an object."""
if output is None:
try:
- pager(render_doc(thing, title, forceload))
+ what = thing if isinstance(thing, str) else type(thing).__name__
+ pager(render_doc(thing, title, forceload), f'Help on {what!s}')
except ImportError as exc:
if is_cli:
raise
@@ -2253,7 +2260,7 @@ module "pydoc_data.topics" could not be found.
text = 'Related help topics: ' + ', '.join(xrefs.split()) + '\n'
wrapped_text = textwrap.wrap(text, 72)
doc += '\n%s\n' % '\n'.join(wrapped_text)
- pager(doc)
+ pager(doc, f'Help on {topic!s}')
def _gettopic(self, topic, more_xrefs=''):
"""Return unbuffered tuple of (topic, xrefs).