summaryrefslogtreecommitdiffstats
path: root/Lib/test
diff options
context:
space:
mode:
authorSrinivas Reddy Thatiparthy (తాటిపర్తి శ్రీనివాస్ రెడ్డి) <thatiparthysreenivas@gmail.com>2025-01-08 10:32:07 (GMT)
committerGitHub <noreply@github.com>2025-01-08 10:32:07 (GMT)
commit474e419792484d1c16e7d9c99b7bf144136b9307 (patch)
tree3ec41062488693a5296ccc867ce786a04152d802 /Lib/test
parentcdfb8bc93a4d8c06d2404ba2d243937ba209438c (diff)
downloadcpython-474e419792484d1c16e7d9c99b7bf144136b9307.zip
cpython-474e419792484d1c16e7d9c99b7bf144136b9307.tar.gz
cpython-474e419792484d1c16e7d9c99b7bf144136b9307.tar.bz2
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>
Diffstat (limited to 'Lib/test')
-rw-r--r--Lib/test/test_pydoc/test_pydoc.py77
1 files changed, 77 insertions, 0 deletions
diff --git a/Lib/test/test_pydoc/test_pydoc.py b/Lib/test/test_pydoc/test_pydoc.py
index c798b11..cec18aa 100644
--- a/Lib/test/test_pydoc/test_pydoc.py
+++ b/Lib/test/test_pydoc/test_pydoc.py
@@ -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')