Fix usage of pytester with doctests (#6802)

Use `request.node.name` instead of `request.function.__name__`:
`request.function` is `None` with `DoctestItem`s.
This commit is contained in:
Daniel Hahler 2020-03-04 05:33:50 +01:00 committed by GitHub
parent 197b7c3bce
commit acec0b688f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 32 additions and 4 deletions

View File

@ -0,0 +1 @@
The :fixture:`testdir fixture <testdir>` works within doctests now.

View File

@ -543,7 +543,11 @@ class Testdir:
self._mod_collections = ( self._mod_collections = (
WeakKeyDictionary() WeakKeyDictionary()
) # type: WeakKeyDictionary[Module, List[Union[Item, Collector]]] ) # type: WeakKeyDictionary[Module, List[Union[Item, Collector]]]
name = request.function.__name__ if request.function:
name = request.function.__name__ # type: str
else:
name = request.node.name
self._name = name
self.tmpdir = tmpdir_factory.mktemp(name, numbered=True) self.tmpdir = tmpdir_factory.mktemp(name, numbered=True)
self.test_tmproot = tmpdir_factory.mktemp("tmp-" + name, numbered=True) self.test_tmproot = tmpdir_factory.mktemp("tmp-" + name, numbered=True)
self.plugins = [] # type: List[Union[str, _PluggyPlugin]] self.plugins = [] # type: List[Union[str, _PluggyPlugin]]
@ -617,7 +621,7 @@ class Testdir:
if lines: if lines:
source = "\n".join(to_text(x) for x in lines) source = "\n".join(to_text(x) for x in lines)
basename = self.request.function.__name__ basename = self._name
items.insert(0, (basename, source)) items.insert(0, (basename, source))
ret = None ret = None
@ -720,7 +724,7 @@ class Testdir:
example_dir = example_dir.join(*extra_element.args) example_dir = example_dir.join(*extra_element.args)
if name is None: if name is None:
func_name = self.request.function.__name__ func_name = self._name
maybe_dir = example_dir / func_name maybe_dir = example_dir / func_name
maybe_file = example_dir / (func_name + ".py") maybe_file = example_dir / (func_name + ".py")
@ -1059,7 +1063,7 @@ class Testdir:
path = self.tmpdir.join(str(source)) path = self.tmpdir.join(str(source))
assert not withinit, "not supported for paths" assert not withinit, "not supported for paths"
else: else:
kw = {self.request.function.__name__: Source(source).strip()} kw = {self._name: Source(source).strip()}
path = self.makepyfile(**kw) path = self.makepyfile(**kw)
if withinit: if withinit:
self.makepyfile(__init__="#") self.makepyfile(__init__="#")

View File

@ -89,6 +89,29 @@ def test_testdir_runs_with_plugin(testdir) -> None:
result.assert_outcomes(passed=1) result.assert_outcomes(passed=1)
def test_testdir_with_doctest(testdir):
"""Check that testdir can be used within doctests.
It used to use `request.function`, which is `None` with doctests."""
testdir.makepyfile(
**{
"sub/t-doctest.py": """
'''
>>> import os
>>> testdir = getfixture("testdir")
>>> str(testdir.makepyfile("content")).replace(os.sep, '/')
'.../basetemp/sub.t-doctest0/sub.py'
'''
""",
"sub/__init__.py": "",
}
)
result = testdir.runpytest(
"-p", "pytester", "--doctest-modules", "sub/t-doctest.py"
)
assert result.ret == 0
def test_runresult_assertion_on_xfail(testdir) -> None: def test_runresult_assertion_on_xfail(testdir) -> None:
testdir.makepyfile( testdir.makepyfile(
""" """