Skip to content

Commit f9a07f2

Browse files
author
Tim Peters
committed
Issue #19138: doctest's IGNORE_EXCEPTION_DETAIL now allows no detail at all.
1 parent 88c2987 commit f9a07f2

File tree

3 files changed

+60
-4
lines changed

3 files changed

+60
-4
lines changed

Lib/doctest.py

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,32 @@ def _comment_line(line):
318318
else:
319319
return '#'
320320

321+
def _strip_exception_details(msg):
322+
# Support for IGNORE_EXCEPTION_DETAIL.
323+
# Get rid of everything except the exception name; in particular, drop
324+
# the possibly dotted module path (if any) and the exception message (if
325+
# any). We assume that a colon is never part of a dotted name, or of an
326+
# exception name.
327+
# E.g., given
328+
# "foo.bar.MyError: la di da"
329+
# return "MyError"
330+
# Or for "abc.def" or "abc.def:\n" return "def".
331+
332+
start, end = 0, len(msg)
333+
# The exception name must appear on the first line.
334+
i = msg.find("\n")
335+
if i >= 0:
336+
end = i
337+
# retain up to the first colon (if any)
338+
i = msg.find(':', 0, end)
339+
if i >= 0:
340+
end = i
341+
# retain just the exception name
342+
i = msg.rfind('.', 0, end)
343+
if i >= 0:
344+
start = i+1
345+
return msg[start: end]
346+
321347
class _OutputRedirectingPdb(pdb.Pdb):
322348
"""
323349
A specialized version of the python debugger that redirects stdout
@@ -1325,10 +1351,9 @@ def __run(self, test, compileflags, out):
13251351

13261352
# Another chance if they didn't care about the detail.
13271353
elif self.optionflags & IGNORE_EXCEPTION_DETAIL:
1328-
m1 = re.match(r'(?:[^:]*\.)?([^:]*:)', example.exc_msg)
1329-
m2 = re.match(r'(?:[^:]*\.)?([^:]*:)', exc_msg)
1330-
if m1 and m2 and check(m1.group(1), m2.group(1),
1331-
self.optionflags):
1354+
if check(_strip_exception_details(example.exc_msg),
1355+
_strip_exception_details(exc_msg),
1356+
self.optionflags):
13321357
outcome = SUCCESS
13331358

13341359
# Report the outcome.

Lib/test/test_doctest.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1054,6 +1054,33 @@ def exceptions(): r"""
10541054
ValueError: message
10551055
TestResults(failed=1, attempted=1)
10561056
1057+
If the exception does not have a message, you can still use
1058+
IGNORE_EXCEPTION_DETAIL to normalize the modules between Python 2 and 3:
1059+
1060+
>>> def f(x):
1061+
... r'''
1062+
... >>> from http.client import HTTPException
1063+
... >>> raise HTTPException() #doctest: +IGNORE_EXCEPTION_DETAIL
1064+
... Traceback (most recent call last):
1065+
... foo.bar.HTTPException
1066+
... '''
1067+
>>> test = doctest.DocTestFinder().find(f)[0]
1068+
>>> doctest.DocTestRunner(verbose=False).run(test)
1069+
TestResults(failed=0, attempted=2)
1070+
1071+
Note that a trailing colon doesn't matter either:
1072+
1073+
>>> def f(x):
1074+
... r'''
1075+
... >>> from http.client import HTTPException
1076+
... >>> raise HTTPException() #doctest: +IGNORE_EXCEPTION_DETAIL
1077+
... Traceback (most recent call last):
1078+
... foo.bar.HTTPException:
1079+
... '''
1080+
>>> test = doctest.DocTestFinder().find(f)[0]
1081+
>>> doctest.DocTestRunner(verbose=False).run(test)
1082+
TestResults(failed=0, attempted=2)
1083+
10571084
If an exception is raised but not expected, then it is reported as an
10581085
unexpected exception:
10591086

Misc/NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ Core and Builtins
1818
Library
1919
-------
2020

21+
- Issue #19138: doctest's IGNORE_EXCEPTION_DETAIL now allows a match when
22+
no exception detail exists (no colon following the exception's name, or
23+
a colon does follow but no text follows the colon).
24+
2125
- Issue #19827: On UNIX, setblocking() and settimeout() methods of
2226
socket.socket can now avoid a second syscall if the ioctl() function can be
2327
used, or if the non-blocking flag of the socket is unchanged.

0 commit comments

Comments
 (0)