-
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add asyncio/anyio taskgroup support to ASYNC101. Fix func_has_decorat…
…or to recognize decorators that are calls but not attributes. Clarify difference between ASYNC101 and ASYNC119
- Loading branch information
Showing
8 changed files
with
231 additions
and
36 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,74 +1,129 @@ | ||
# ASYNCIO_NO_ERROR - nursery/cancelscope in asyncio is called taskgroup/timeout | ||
# Note: this one *shouldn't* be giving the same errors for anyio (but it currently does) | ||
# since it has TaskGroups instead of nurseries. #TODO #215 | ||
# type: ignore | ||
# ASYNCIO_NO_ERROR | ||
|
||
# This file contains errors shared between trio and anyio, since they have some | ||
# overlap in naming. | ||
# See async101_xxx which has errors specific to trio/asyncio/anyio. | ||
|
||
|
||
import contextlib | ||
import contextlib as bla | ||
from contextlib import asynccontextmanager, contextmanager, contextmanager as blahabla | ||
import pytest | ||
import pytest as blo | ||
from pytest import fixture | ||
|
||
import trio | ||
|
||
|
||
def foo0(): | ||
with trio.open_nursery() as _: | ||
# cancel scope aliases | ||
async def foo_fail_after(): | ||
with trio.fail_after(10): | ||
yield 1 # error: 8 | ||
|
||
|
||
async def foo1(): | ||
async with trio.open_nursery() as _: | ||
async def foo_fail_at(): | ||
with trio.fail_at(10): | ||
yield 1 # error: 8 | ||
|
||
|
||
@contextmanager | ||
def foo2(): | ||
with trio.open_nursery() as _: | ||
yield 1 # safe | ||
async def foo_move_on_aft(): | ||
with trio.move_on_after(10): | ||
yield 1 # error: 8 | ||
|
||
|
||
async def foo3(): | ||
async with trio.CancelScope() as _: | ||
# `as` makes no difference | ||
async def foo_move_on_at(): | ||
with trio.move_on_at(10) as _: | ||
yield 1 # error: 8 | ||
|
||
|
||
@asynccontextmanager | ||
async def foo4(): | ||
async with trio.open_nursery() as _: | ||
yield 1 # safe | ||
async def foo_CancelScope(): | ||
with trio.CancelScope() as _: | ||
yield 1 # error: 8 | ||
|
||
|
||
# the visitor does not care if the `with` is async | ||
async def foo_async_with(): | ||
async with trio.CancelScope() as _: # type: ignore[attr-defined] | ||
yield 1 # error: 8 | ||
|
||
|
||
# raises error at each yield | ||
async def foo_multiple_yield(): | ||
with trio.CancelScope() as _: | ||
yield 1 # error: 8 | ||
yield 1 # error: 8 | ||
|
||
|
||
# nested method is safe | ||
async def foo5(): | ||
async with trio.open_nursery(): | ||
with trio.CancelScope(): | ||
yield 1 # error: 8 | ||
|
||
def foo6(): | ||
yield 1 # safe | ||
|
||
|
||
# @[async]contextmanager suppresses the error | ||
@contextmanager | ||
def foo_contextmanager(): | ||
with trio.CancelScope() as _: | ||
yield 1 # safe | ||
|
||
|
||
@asynccontextmanager | ||
async def foo4(): | ||
with trio.CancelScope() as _: | ||
yield 1 # safe | ||
|
||
|
||
@contextlib.asynccontextmanager | ||
async def foo7(): | ||
async with trio.open_nursery() as _: | ||
with trio.CancelScope() as _: | ||
yield 1 # safe | ||
|
||
|
||
# pytest.fixture also silences async101, as they're morally context managers | ||
@fixture | ||
def foo_fixture(): | ||
with trio.CancelScope() as _: | ||
yield 1 # safe | ||
|
||
|
||
@pytest.fixture | ||
def foo_pytest_fixture(): | ||
with trio.CancelScope() as _: | ||
yield 1 # safe | ||
|
||
|
||
# it does not care about what library that [async]contextmanager or fixture is in | ||
@bla.contextmanager | ||
def foo8(): | ||
with trio.open_nursery() as _: | ||
def foo_bla_contextmanager(): | ||
with trio.CancelScope() as _: | ||
yield 1 # safe | ||
|
||
|
||
@blo.fixture | ||
def foo_blo_fixture(): | ||
with trio.CancelScope() as _: | ||
yield 1 # safe | ||
|
||
|
||
# but any other decorator does nothing | ||
@blahabla | ||
def foo9(): | ||
with trio.open_nursery() as _: | ||
def foo_blahabla(): | ||
with trio.CancelScope() as _: | ||
yield 1 # error: 8 | ||
|
||
|
||
@pytest.fixture() | ||
def foo_false_alarm(): | ||
with trio.open_nursery() as _: | ||
# parentheses and parameters are also fine | ||
@fixture() | ||
def foo_pytest_fixture_paren(): | ||
with trio.CancelScope() as _: | ||
yield 1 | ||
|
||
|
||
@pytest.fixture | ||
def foo_false_alarm_2(): | ||
with trio.open_nursery() as _: | ||
@pytest.fixture(autouse=True) | ||
def foo_pytest_fixture_params(): | ||
with trio.CancelScope() as _: | ||
yield 1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
# BASE_LIBRARY anyio | ||
# TRIO_NO_ERROR | ||
# ASYNCIO_NO_ERROR | ||
|
||
import anyio | ||
|
||
|
||
async def foo(): | ||
async with anyio.create_task_group(): | ||
yield 1 # error: 8 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
# BASE_LIBRARY asyncio | ||
# TRIO_NO_ERROR | ||
# ANYIO_NO_ERROR | ||
# TaskGroup and timeout[_at] was added in 3.11, we run type checking with 3.9 | ||
# mypy: disable-error-code=attr-defined | ||
import contextlib | ||
import contextlib as bla | ||
from contextlib import asynccontextmanager, contextmanager, contextmanager as blahabla | ||
|
||
import asyncio | ||
import pytest | ||
|
||
|
||
async def test_async_with(): | ||
async with asyncio.TaskGroup() as _: | ||
yield 1 # error: 8 | ||
|
||
|
||
async def test_timeout(): | ||
async with asyncio.timeout() as _: | ||
yield 1 # error: 8 | ||
|
||
|
||
async def test_timeout_at(): | ||
async with asyncio.timeout_at() as _: | ||
yield 1 # error: 8 | ||
|
||
|
||
async def test_nested_method(): | ||
async with asyncio.TaskGroup(): | ||
yield 1 # error: 8 | ||
|
||
def foo6(): | ||
yield 1 # safe | ||
|
||
|
||
# TaskGroup is an async cm, but the visitor does not care about that | ||
def test_with(): | ||
with asyncio.TaskGroup() as _: | ||
yield 1 # error: 8 | ||
|
||
|
||
@contextmanager | ||
def safe_1(): | ||
with asyncio.TaskGroup() as _: | ||
yield 1 # safe | ||
|
||
|
||
@asynccontextmanager | ||
async def safe_2(): | ||
async with asyncio.TaskGroup() as _: | ||
yield 1 # safe | ||
|
||
|
||
@contextlib.asynccontextmanager | ||
async def safe_3(): | ||
async with asyncio.TaskGroup() as _: | ||
yield 1 # safe | ||
|
||
|
||
@bla.contextmanager | ||
def safe_4(): | ||
with asyncio.TaskGroup() as _: | ||
yield 1 # safe | ||
|
||
|
||
@blahabla | ||
def test_unrelated_decorator(): | ||
with asyncio.TaskGroup() as _: | ||
yield 1 # error: 8 | ||
|
||
|
||
@pytest.fixture() | ||
def foo_false_alarm(): | ||
with asyncio.TaskGroup() as _: | ||
yield 1 | ||
|
||
|
||
@pytest.fixture | ||
def foo_false_alarm_2(): | ||
with asyncio.TaskGroup() as _: | ||
yield 1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# ASYNCIO_NO_ERROR | ||
# ANYIO_NO_ERROR | ||
|
||
from contextlib import asynccontextmanager | ||
|
||
import trio | ||
|
||
|
||
async def foo_open_nursery(): | ||
async with trio.open_nursery() as _: | ||
yield 1 # error: 8 | ||
|
||
|
||
@asynccontextmanager | ||
async def foo_open_nursery_contextmanager(): | ||
async with trio.open_nursery() as _: | ||
yield 1 # safe |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters