gh-69113: Fix doctest to report line numbers for __test__ strings (#141624)

Enhanced the _find_lineno method in doctest to correctly identify and
report line numbers for doctests defined in __test__ dictionaries when
formatted as triple-quoted strings.

Finds a non-blank line in the test string and matches it in the source
file, verifying subsequent lines also match to handle duplicate lines.

Previously, doctest would report "line None" for __test__ dictionary
strings, making it difficult to debug failing tests.

Co-authored-by: Jurjen N.E. Bos <jneb@users.sourceforge.net>
Co-authored-by: R. David Murray <rdmurray@bitdance.com>
This commit is contained in:
Sanyam Khurana 2025-12-06 15:47:08 -05:00 committed by GitHub
parent c91c373ef6
commit 100e316e53
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 145 additions and 4 deletions

View file

@ -1167,6 +1167,32 @@ def _find_lineno(self, obj, source_lines):
if pat.match(source_lines[lineno]):
return lineno
# Handle __test__ string doctests formatted as triple-quoted
# strings. Find a non-blank line in the test string and match it
# in the source, verifying subsequent lines also match to handle
# duplicate lines.
if isinstance(obj, str) and source_lines is not None:
obj_lines = obj.splitlines(keepends=True)
# Skip the first line (may be on same line as opening quotes)
# and any blank lines to find a meaningful line to match.
start_index = 1
while (start_index < len(obj_lines)
and not obj_lines[start_index].strip()):
start_index += 1
if start_index < len(obj_lines):
target_line = obj_lines[start_index]
for lineno, source_line in enumerate(source_lines):
if source_line == target_line:
# Verify subsequent lines also match
for i in range(start_index + 1, len(obj_lines) - 1):
source_idx = lineno + i - start_index
if source_idx >= len(source_lines):
break
if obj_lines[i] != source_lines[source_idx]:
break
else:
return lineno - start_index
# We couldn't find the line number.
return None