mirror of
https://github.com/python/cpython.git
synced 2025-09-14 12:46:49 +00:00
bpo-35753: Fix crash in doctest with unwrap-able functions (GH-22981) (#25926)
Ignore objects that inspect.unwrap throws due to
too many wrappers. This is a very rare case, however
it can easily be surfaced when a module under doctest
imports unitest.mock.call into its namespace.
We simply skip any object that throws this exception.
This should handle the majority of cases.
(cherry picked from commit 565a31804c
)
Co-authored-by: Alfred Perlstein <alfred@fb.com>
This commit is contained in:
parent
ce4fee210b
commit
10d6f6bfd7
3 changed files with 29 additions and 3 deletions
|
@ -973,6 +973,17 @@ class DocTestFinder:
|
|||
else:
|
||||
raise ValueError("object must be a class or function")
|
||||
|
||||
def _is_routine(self, obj):
|
||||
"""
|
||||
Safely unwrap objects and determine if they are functions.
|
||||
"""
|
||||
maybe_routine = obj
|
||||
try:
|
||||
maybe_routine = inspect.unwrap(maybe_routine)
|
||||
except ValueError:
|
||||
pass
|
||||
return inspect.isroutine(maybe_routine)
|
||||
|
||||
def _find(self, tests, obj, name, module, source_lines, globs, seen):
|
||||
"""
|
||||
Find tests for the given object and any contained objects, and
|
||||
|
@ -995,9 +1006,9 @@ class DocTestFinder:
|
|||
if inspect.ismodule(obj) and self._recurse:
|
||||
for valname, val in obj.__dict__.items():
|
||||
valname = '%s.%s' % (name, valname)
|
||||
|
||||
# Recurse to functions & classes.
|
||||
if ((inspect.isroutine(inspect.unwrap(val))
|
||||
or inspect.isclass(val)) and
|
||||
if ((self._is_routine(val) or inspect.isclass(val)) and
|
||||
self._from_module(module, val)):
|
||||
self._find(tests, val, valname, module, source_lines,
|
||||
globs, seen)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue