mirror of
https://github.com/python/cpython.git
synced 2024-11-24 18:34:43 +08:00
Issue #23374: Fixed pydoc failure with non-ASCII files when stdout encoding
differs from file system encoding (e.g. on Mac OS).
This commit is contained in:
commit
7065f376e0
20
Lib/pydoc.py
20
Lib/pydoc.py
@ -1405,9 +1405,6 @@ class _PlainTextDoc(TextDoc):
|
||||
def pager(text):
|
||||
"""The first time this is called, determine what kind of pager to use."""
|
||||
global pager
|
||||
# Escape non-encodable characters to avoid encoding errors later
|
||||
encoding = sys.getfilesystemencoding()
|
||||
text = text.encode(encoding, 'backslashreplace').decode(encoding)
|
||||
pager = getpager()
|
||||
pager(text)
|
||||
|
||||
@ -1450,10 +1447,12 @@ def plain(text):
|
||||
|
||||
def pipepager(text, cmd):
|
||||
"""Page through text by feeding it to another program."""
|
||||
pipe = os.popen(cmd, 'w')
|
||||
import subprocess
|
||||
proc = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE)
|
||||
try:
|
||||
with proc:
|
||||
with io.TextIOWrapper(proc.stdin, errors='backslashreplace') as pipe:
|
||||
pipe.write(text)
|
||||
pipe.close()
|
||||
except OSError:
|
||||
pass # Ignore broken pipes caused by quitting the pager program.
|
||||
|
||||
@ -1461,16 +1460,21 @@ def tempfilepager(text, cmd):
|
||||
"""Page through text by invoking a program on a temporary file."""
|
||||
import tempfile
|
||||
filename = tempfile.mktemp()
|
||||
with open(filename, 'w') as file:
|
||||
with open(filename, 'w', errors='backslashreplace') as file:
|
||||
file.write(text)
|
||||
try:
|
||||
os.system(cmd + ' "' + filename + '"')
|
||||
finally:
|
||||
os.unlink(filename)
|
||||
|
||||
def _escape_stdout(text):
|
||||
# Escape non-encodable characters to avoid encoding errors later
|
||||
encoding = getattr(sys.stdout, 'encoding', None) or 'utf-8'
|
||||
return text.encode(encoding, 'backslashreplace').decode(encoding)
|
||||
|
||||
def ttypager(text):
|
||||
"""Page through text on a text terminal."""
|
||||
lines = plain(text).split('\n')
|
||||
lines = plain(_escape_stdout(text)).split('\n')
|
||||
try:
|
||||
import tty
|
||||
fd = sys.stdin.fileno()
|
||||
@ -1514,7 +1518,7 @@ def ttypager(text):
|
||||
|
||||
def plainpager(text):
|
||||
"""Simply print unformatted text. This is the ultimate fallback."""
|
||||
sys.stdout.write(plain(text))
|
||||
sys.stdout.write(plain(_escape_stdout(text)))
|
||||
|
||||
def describe(thing):
|
||||
"""Produce a short description of the given thing."""
|
||||
|
@ -34,6 +34,10 @@ try:
|
||||
except ImportError:
|
||||
threading = None
|
||||
|
||||
class nonascii:
|
||||
'Це не латиниця'
|
||||
pass
|
||||
|
||||
if test.support.HAVE_DOCSTRINGS:
|
||||
expected_data_docstrings = (
|
||||
'dictionary for instance variables (if defined)',
|
||||
@ -460,6 +464,11 @@ class PydocDocTest(unittest.TestCase):
|
||||
self.assertEqual(expected, result,
|
||||
"documentation for missing module found")
|
||||
|
||||
def test_not_ascii(self):
|
||||
result = run_pydoc('test.test_pydoc.nonascii', PYTHONIOENCODING='ascii')
|
||||
encoded = nonascii.__doc__.encode('ascii', 'backslashreplace')
|
||||
self.assertIn(encoded, result)
|
||||
|
||||
def test_input_strip(self):
|
||||
missing_module = " test.i_am_not_here "
|
||||
result = str(run_pydoc(missing_module), 'ascii')
|
||||
|
@ -13,6 +13,9 @@ Core and Builtins
|
||||
Library
|
||||
-------
|
||||
|
||||
- Issue #23374: Fixed pydoc failure with non-ASCII files when stdout encoding
|
||||
differs from file system encoding (e.g. on Mac OS).
|
||||
|
||||
- Issue #23481: Remove RC4 from the SSL module's default cipher list.
|
||||
|
||||
- Issue #21548: Fix pydoc.synopsis() and pydoc.apropos() on modules with empty
|
||||
|
Loading…
Reference in New Issue
Block a user