diff --git a/Lib/pydoc.py b/Lib/pydoc.py
index 69c83e08511..4973b8fb179 100644
--- a/Lib/pydoc.py
+++ b/Lib/pydoc.py
@@ -75,6 +75,7 @@ class or function within a module or module in a package. If the
import warnings
from annotationlib import Format
from collections import deque
+from html import escape as html_escape
from reprlib import Repr
from traceback import format_exception_only
@@ -552,7 +553,7 @@ def repr1(self, x, level):
methodname = 'repr_' + '_'.join(type(x).__name__.split())
if hasattr(self, methodname):
return getattr(self, methodname)(x, level)
- return self.escape(cram(stripid(repr(x)), self.maxother))
+ return html_escape(cram(stripid(repr(x)), self.maxother))
def repr_string(self, x, level):
test = cram(x, self.maxstring)
@@ -560,18 +561,18 @@ def repr_string(self, x, level):
if '\\' in test and '\\' not in replace(testrepr, r'\\', ''):
# Backslashes are only literal in the string and are never
# needed to make any special characters, so show a raw string.
- return 'r' + testrepr[0] + self.escape(test) + testrepr[0]
+ return 'r' + testrepr[0] + html_escape(test) + testrepr[0]
return re.sub(r'((\\[\\abfnrtv\'"]|\\[0-9]..|\\x..|\\u....)+)',
r'\1',
- self.escape(testrepr))
+ html_escape(testrepr, quote=False))
repr_str = repr_string
def repr_instance(self, x, level):
try:
- return self.escape(cram(stripid(repr(x)), self.maxstring))
+ return html_escape(cram(stripid(repr(x)), self.maxstring))
except:
- return self.escape('<%s instance>' % x.__class__.__name__)
+ return html_escape('<%s instance>' % x.__class__.__name__)
repr_unicode = repr_string
@@ -633,7 +634,7 @@ def bigsection(self, title, *args):
def preformat(self, text):
"""Format literal preformatted text."""
- text = self.escape(text.expandtabs())
+ text = html_escape(text.expandtabs(), quote=False)
return replace(text, '\n\n', '\n \n', '\n\n', '\n \n',
' ', ' ', '\n', '
\n')
@@ -711,7 +712,7 @@ def filelink(self, url, path):
def markup(self, text, escape=None, funcs={}, classes={}, methods={}):
"""Mark up some plain text, given a context of symbols to look for.
Each context dictionary maps object names to anchor names."""
- escape = escape or self.escape
+ escape = escape or html_escape
results = []
here = 0
pattern = re.compile(r'\b((http|https|ftp)://\S+[\w/]|'
@@ -794,9 +795,9 @@ def docmodule(self, object, name=None, mod=None, *ignored):
if version := self._get_version(object):
if version[:11] == '$' + 'Revision: ' and version[-1:] == '$':
version = version[11:-1].strip()
- info.append('version %s' % self.escape(version))
+ info.append('version %s' % html_escape(version))
if hasattr(object, '__date__'):
- info.append(self.escape(str(object.__date__)))
+ info.append(html_escape(str(object.__date__)))
if info:
head = head + ' (%s)' % ', '.join(info)
docloc = self.getdocloc(object)
@@ -2156,6 +2157,11 @@ def showsymbol(self, symbol):
topic, _, xrefs = target.partition(' ')
self.showtopic(topic, xrefs)
+ def _getsymbol(self, symbol):
+ target = self.symbols[symbol]
+ topic, _, xrefs = target.partition(' ')
+ return self._gettopic(topic, xrefs)
+
def listmodules(self, key=''):
if key:
self.output.write('''
@@ -2321,6 +2327,7 @@ def _start_server(urlhandler, hostname, port):
import email.message
import select
import threading
+ from urllib.parse import unquote
class DocHandler(http.server.BaseHTTPRequestHandler):
@@ -2440,11 +2447,14 @@ def page(self, title, contents):
%s