mirror of
https://github.com/python/cpython.git
synced 2025-08-04 08:59:19 +00:00
gh-41872: Fix quick extraction of module docstrings from a file in pydoc (GH-127520)
It now supports docstrings with single quotes, escape sequences, raw string literals, and other Python syntax. Co-authored-by: Éric <merwok@netwok.org> Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
This commit is contained in:
parent
cdfb8bc93a
commit
474e419792
3 changed files with 104 additions and 15 deletions
|
@ -4,6 +4,7 @@ import sys
|
|||
import contextlib
|
||||
import importlib.util
|
||||
import inspect
|
||||
import io
|
||||
import pydoc
|
||||
import py_compile
|
||||
import keyword
|
||||
|
@ -899,6 +900,82 @@ class PydocDocTest(unittest.TestCase):
|
|||
synopsis = pydoc.synopsis(TESTFN, {})
|
||||
self.assertEqual(synopsis, 'line 1: h\xe9')
|
||||
|
||||
def test_source_synopsis(self):
|
||||
def check(source, expected, encoding=None):
|
||||
if isinstance(source, str):
|
||||
source_file = StringIO(source)
|
||||
else:
|
||||
source_file = io.TextIOWrapper(io.BytesIO(source), encoding=encoding)
|
||||
with source_file:
|
||||
result = pydoc.source_synopsis(source_file)
|
||||
self.assertEqual(result, expected)
|
||||
|
||||
check('"""Single line docstring."""',
|
||||
'Single line docstring.')
|
||||
check('"""First line of docstring.\nSecond line.\nThird line."""',
|
||||
'First line of docstring.')
|
||||
check('"""First line of docstring.\\nSecond line.\\nThird line."""',
|
||||
'First line of docstring.')
|
||||
check('""" Whitespace around docstring. """',
|
||||
'Whitespace around docstring.')
|
||||
check('import sys\n"""No docstring"""',
|
||||
None)
|
||||
check(' \n"""Docstring after empty line."""',
|
||||
'Docstring after empty line.')
|
||||
check('# Comment\n"""Docstring after comment."""',
|
||||
'Docstring after comment.')
|
||||
check(' # Indented comment\n"""Docstring after comment."""',
|
||||
'Docstring after comment.')
|
||||
check('""""""', # Empty docstring
|
||||
'')
|
||||
check('', # Empty file
|
||||
None)
|
||||
check('"""Embedded\0null byte"""',
|
||||
None)
|
||||
check('"""Embedded null byte"""\0',
|
||||
None)
|
||||
check('"""Café and résumé."""',
|
||||
'Café and résumé.')
|
||||
check("'''Triple single quotes'''",
|
||||
'Triple single quotes')
|
||||
check('"Single double quotes"',
|
||||
'Single double quotes')
|
||||
check("'Single single quotes'",
|
||||
'Single single quotes')
|
||||
check('"""split\\\nline"""',
|
||||
'splitline')
|
||||
check('"""Unrecognized escape \\sequence"""',
|
||||
'Unrecognized escape \\sequence')
|
||||
check('"""Invalid escape seq\\uence"""',
|
||||
None)
|
||||
check('r"""Raw \\stri\\ng"""',
|
||||
'Raw \\stri\\ng')
|
||||
check('b"""Bytes literal"""',
|
||||
None)
|
||||
check('f"""f-string"""',
|
||||
None)
|
||||
check('"""Concatenated""" \\\n"string" \'literals\'',
|
||||
'Concatenatedstringliterals')
|
||||
check('"""String""" + """expression"""',
|
||||
None)
|
||||
check('("""In parentheses""")',
|
||||
'In parentheses')
|
||||
check('("""Multiple lines """\n"""in parentheses""")',
|
||||
'Multiple lines in parentheses')
|
||||
check('()', # tuple
|
||||
None)
|
||||
check(b'# coding: iso-8859-15\n"""\xa4uro sign"""',
|
||||
'€uro sign', encoding='iso-8859-15')
|
||||
check(b'"""\xa4"""', # Decoding error
|
||||
None, encoding='utf-8')
|
||||
|
||||
with tempfile.NamedTemporaryFile(mode='w+', encoding='utf-8') as temp_file:
|
||||
temp_file.write('"""Real file test."""\n')
|
||||
temp_file.flush()
|
||||
temp_file.seek(0)
|
||||
result = pydoc.source_synopsis(temp_file)
|
||||
self.assertEqual(result, "Real file test.")
|
||||
|
||||
@requires_docstrings
|
||||
def test_synopsis_sourceless(self):
|
||||
os = import_helper.import_fresh_module('os')
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue