Merge pull request #11317 from tjsmart/fix-issue-11237

Fix doctest collection of `functools.cached_property` objects.
This commit is contained in:
Ronny Pfannschmidt 2023-09-07 14:39:02 +02:00 committed by GitHub
commit e787d2ed48
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 38 additions and 0 deletions

View File

@ -382,6 +382,7 @@ Tor Colvin
Trevor Bekolay Trevor Bekolay
Tushar Sadhwani Tushar Sadhwani
Tyler Goodlet Tyler Goodlet
Tyler Smart
Tzu-ping Chung Tzu-ping Chung
Vasily Kuznetsov Vasily Kuznetsov
Victor Maryama Victor Maryama

View File

@ -0,0 +1 @@
Fix doctest collection of `functools.cached_property` objects.

View File

@ -1,5 +1,6 @@
"""Discover and run doctests in modules and test files.""" """Discover and run doctests in modules and test files."""
import bdb import bdb
import functools
import inspect import inspect
import os import os
import platform import platform
@ -536,6 +537,23 @@ class DoctestModule(Module):
tests, obj, name, module, source_lines, globs, seen tests, obj, name, module, source_lines, globs, seen
) )
if sys.version_info < (3, 13):
def _from_module(self, module, object):
"""`cached_property` objects are never considered a part
of the 'current module'. As such they are skipped by doctest.
Here we override `_from_module` to check the underlying
function instead. https://github.com/python/cpython/issues/107995
"""
if isinstance(object, functools.cached_property):
object = object.func
# Type ignored because this is a private function.
return super()._from_module(module, object) # type: ignore[misc]
else: # pragma: no cover
pass
if self.path.name == "conftest.py": if self.path.name == "conftest.py":
module = self.config.pluginmanager._importconftest( module = self.config.pluginmanager._importconftest(
self.path, self.path,

View File

@ -482,6 +482,24 @@ class TestDoctests:
reprec = pytester.inline_run(p, "--doctest-modules") reprec = pytester.inline_run(p, "--doctest-modules")
reprec.assertoutcome(failed=1) reprec.assertoutcome(failed=1)
def test_doctest_cached_property(self, pytester: Pytester):
p = pytester.makepyfile(
"""
import functools
class Foo:
@functools.cached_property
def foo(self):
'''
>>> assert False, "Tacos!"
'''
...
"""
)
result = pytester.runpytest(p, "--doctest-modules")
result.assert_outcomes(failed=1)
assert "Tacos!" in result.stdout.str()
def test_doctestmodule_external_and_issue116(self, pytester: Pytester): def test_doctestmodule_external_and_issue116(self, pytester: Pytester):
p = pytester.mkpydir("hello") p = pytester.mkpydir("hello")
p.joinpath("__init__.py").write_text( p.joinpath("__init__.py").write_text(