-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
warn for async generator functions #5734
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| Skip async generator test functions, and update the warning message to refer to ``async def`` functions. |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -23,6 +23,7 @@ | |||||
| from _pytest.compat import getimfunc | ||||||
| from _pytest.compat import getlocation | ||||||
| from _pytest.compat import is_generator | ||||||
| from _pytest.compat import iscoroutinefunction | ||||||
| from _pytest.compat import NOTSET | ||||||
| from _pytest.compat import REGEX_TYPE | ||||||
| from _pytest.compat import safe_getattr | ||||||
|
|
@@ -151,15 +152,16 @@ def pytest_configure(config): | |||||
| @hookimpl(trylast=True) | ||||||
| def pytest_pyfunc_call(pyfuncitem): | ||||||
| testfunction = pyfuncitem.obj | ||||||
| iscoroutinefunction = getattr(inspect, "iscoroutinefunction", None) | ||||||
| if iscoroutinefunction is not None and iscoroutinefunction(testfunction): | ||||||
| msg = "Coroutine functions are not natively supported and have been skipped.\n" | ||||||
| if iscoroutinefunction(testfunction) or ( | ||||||
| sys.version_info >= (3, 6) and inspect.isasyncgenfunction(testfunction) | ||||||
bluetech marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
| ): | ||||||
| msg = "async def functions are not natively supported and have been skipped.\n" | ||||||
| msg += "You need to install a suitable plugin for your async framework, for example:\n" | ||||||
| msg += " - pytest-asyncio\n" | ||||||
| msg += " - pytest-trio\n" | ||||||
| msg += " - pytest-tornasync" | ||||||
| warnings.warn(PytestUnhandledCoroutineWarning(msg.format(pyfuncitem.nodeid))) | ||||||
| skip(msg="coroutine function and no async plugin installed (see warnings)") | ||||||
| skip(msg="async def function and no async plugin installed (see warnings)") | ||||||
| funcargs = pyfuncitem.funcargs | ||||||
| testargs = {arg: funcargs[arg] for arg in pyfuncitem._fixtureinfo.argnames} | ||||||
| testfunction(**testargs) | ||||||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @bluetech it might also be easier to just
Suggested change
This would catch generator, async def, async gen and t.i.d.inlineCallbacks all in one go
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't know enough to have an opinion on this. If the test function should absolutely never return anything once it reaches here, maybe a warning is appropriate.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. there are legitimate test functions that return a value as a building block, so this one would be a breaking change
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Sure I was thinking this would be a deprecation warning rather than a skip
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we can make the same call as was made when deprecating direct calls of fixtures and require code to look like: def test_a():
assert something()
return FooBar()
def test_b():
fb = test_a()
assert fb.something()after: def _prepare_for_test():
assert something()
return FooBar()
def test_a():
_prepare_for_test()
def test_b():
fb = _prepare_for_test()
assert fb.something()
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure why you'd need test_a in this case though
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is pretty much just code-reuse - test_a would simply be a "dependency/fixture" for the b test, but ots own a test anyway
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's not code-reuse - it's just redundant, there's no need for
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. so what, it happens in practice, is used in practice and should have a transition period for users to adapt better structural practices |
||||||
|
|
||||||
Uh oh!
There was an error while loading. Please reload this page.