diff --git a/README.rst b/README.rst index 31d4f7b..f3b7ec7 100644 --- a/README.rst +++ b/README.rst @@ -70,7 +70,7 @@ Install trio-typing with mypy extras:: pip install trio-typing[mypy] -Note that due to recent plugin API changes, trio-typing 0.7.0+ requires mypy 0.920+. +Note that due to recent plugin API changes, trio-typing 0.10.0+ requires mypy 1.0+. Enable the plugin in your ``mypy.ini``:: diff --git a/allowlist.txt b/allowlist.txt index 4b7602e..cac67b9 100644 --- a/allowlist.txt +++ b/allowlist.txt @@ -173,6 +173,8 @@ trio.Process.__aenter__ .*_AttrsAttributes__ .*__attrs_own_setattr__ .*__attrs_post_init__ +.*_AT +.*__slots__ # Probably invalid __match_args__ trio.MemoryReceiveChannel.__match_args__ diff --git a/ci.sh b/ci.sh index c055193..62a882d 100755 --- a/ci.sh +++ b/ci.sh @@ -3,7 +3,7 @@ set -ex -o pipefail BLACK_VERSION=22.3 -MYPY_VERSION=1.4 +MYPY_VERSION=1.7 pip install -U pip setuptools wheel diff --git a/trio-stubs/__init__.pyi b/trio-stubs/__init__.pyi index c764744..030bc79 100644 --- a/trio-stubs/__init__.pyi +++ b/trio-stubs/__init__.pyi @@ -221,7 +221,7 @@ class Event(metaclass=ABCMeta): class CapacityLimiterStatistics: borrowed_tokens: int = attr.ib() total_tokens: int | float = attr.ib() - borrowers: list[Task | object] = attr.ib() + borrowers: list[trio.lowlevel.Task | object] = attr.ib() tasks_waiting: int = attr.ib() @final @@ -271,7 +271,7 @@ class Semaphore(metaclass=ABCMeta): @attr.s(frozen=True, slots=True) class LockStatistics: locked: bool = attr.ib() - owner: Task | None = attr.ib() + owner: trio.lowlevel.Task | None = attr.ib() tasks_waiting: int = attr.ib() @final @@ -375,7 +375,7 @@ class MemoryReceiveChannel(trio.abc.ReceiveChannel[_T_co]): async def receive(self) -> _T_co: ... def clone(self: _T) -> _T: ... async def aclose(self) -> None: ... - def statistics(self) -> _Statistics: ... + def statistics(self) -> _MemoryChannelStats: ... def close(self) -> None: ... def __enter__(self) -> MemoryReceiveChannel[_T_co]: ... def __exit__( @@ -403,7 +403,7 @@ class SocketStream(trio.abc.HalfCloseableStream): socket: trio.socket.SocketType def __init__(self, socket: trio.socket.SocketType) -> None: ... @overload - def setsockopt(self, level: int, option: int, value: int | Buffer) -> None: ... + def setsockopt(self, level: int, option: int, value: int | Buffer, length: None = None) -> None: ... @overload def setsockopt(self, level: int, option: int, value: None, length: int) -> None: ... @overload diff --git a/trio-stubs/abc.pyi b/trio-stubs/abc.pyi index 79b7be7..8e8034e 100644 --- a/trio-stubs/abc.pyi +++ b/trio-stubs/abc.pyi @@ -1,6 +1,8 @@ +import socket import trio from abc import ABCMeta, abstractmethod from typing import List, Tuple, Union, Any, Optional, Generic, TypeVar, AsyncIterator +from types import TracebackType _T = TypeVar("_T") @@ -52,7 +54,12 @@ class AsyncResource(metaclass=ABCMeta): @abstractmethod async def aclose(self) -> None: ... async def __aenter__(self: _T) -> _T: ... - async def __aexit__(self, *exc: object) -> None: ... + async def __aexit__( + self, + exc_type: type[BaseException] | None, + exc_value: BaseException | None, + traceback: TracebackType | None, + ) -> None: ... class SendStream(AsyncResource): @abstractmethod diff --git a/trio-stubs/lowlevel.pyi b/trio-stubs/lowlevel.pyi index 2ba4c3a..2e45d76 100644 --- a/trio-stubs/lowlevel.pyi +++ b/trio-stubs/lowlevel.pyi @@ -75,7 +75,7 @@ class UnboundedQueue(Generic[_T], metaclass=ABCMeta): # _core._run if sys.platform == "win32": @attr.frozen - class IOStatistics: + class _IOStatistics: tasks_waiting_read: int = attr.ib() tasks_waiting_write: int = attr.ib() tasks_waiting_overlapped: int = attr.ib() @@ -84,14 +84,14 @@ if sys.platform == "win32": elif sys.platform == "linux": @attr.frozen - class IOStatistics: + class _IOStatistics: tasks_waiting_read: int = attr.ib() tasks_waiting_write: int = attr.ib() backend: Literal["epoll"] = attr.ib(init=False, default="epoll") else: # kqueue @attr.frozen - class IOStatistics: + class _IOStatistics: tasks_waiting: int = attr.ib() monitors: int = attr.ib() backend: Literal["kqueue"] = attr.ib(init=False, default="kqueue") @@ -101,7 +101,7 @@ class RunStatistics: tasks_living: int tasks_runnable: int seconds_to_next_deadline: float - io_statistics: IOStatistics + io_statistics: _IOStatistics run_sync_soon_queue_size: int @final @@ -213,9 +213,12 @@ class ParkingLot(metaclass=ABCMeta): # _core._local class _NoValue: ... -class RunVarToken(Generic[_T]): - previous_value: T | type[_NoValue] - redeemed: bool +@final +@attr.s(eq=False, hash=False, slots=True) +class RunVarToken(Generic[_T], metaclass=ABCMeta): + _var: RunVar[_T] = attr.ib() + previous_value: _T | type[_NoValue] = attr.ib(default=_NoValue) + redeemed: bool = attr.ib(init=False) @final @attr.s(eq=False, hash=False, slots=True) diff --git a/trio_typing/_tests/test-data/async_generator.test b/trio_typing/_tests/test-data/async_generator.test index c60cf90..c1b1852 100644 --- a/trio_typing/_tests/test-data/async_generator.test +++ b/trio_typing/_tests/test-data/async_generator.test @@ -61,7 +61,7 @@ async def dummy(): firstiter = agen.get_asyncgen_hooks().firstiter if firstiter is not None: - firstiter(iter([])) # E: Argument 1 has incompatible type "Iterator[]"; expected "AsyncGenerator[Any, Any]" + firstiter(iter([])) # E: Argument 1 has incompatible type "Iterator[Never]"; expected "AsyncGenerator[Any, Any]" reveal_type(firstiter(dummy())) # N: Revealed type is "Any" agen.set_asyncgen_hooks(firstiter) agen.set_asyncgen_hooks(firstiter, finalizer=firstiter) diff --git a/trio_typing/_tests/test-data/outcome.test b/trio_typing/_tests/test-data/outcome.test index eb9575e..86093d9 100644 --- a/trio_typing/_tests/test-data/outcome.test +++ b/trio_typing/_tests/test-data/outcome.test @@ -32,4 +32,4 @@ async def test() -> None: reveal_type(test_outcome.unwrap()) # N: Revealed type is "builtins.str" reveal_type(test_outcome.send(calc_lengths())) # N: Revealed type is "builtins.int" reveal_type(await test_outcome.asend(calc_lengths_async())) # N: Revealed type is "builtins.int" - test_outcome.send(wrong_type_gen()) # E: Argument 1 to "send" of "Value" has incompatible type "Iterator[int]"; expected "Generator[, str, Any]" # E: Argument 1 to "send" of "Error" has incompatible type "Iterator[int]"; expected "Generator[, Any, Any]" + test_outcome.send(wrong_type_gen()) # E: Argument 1 to "send" of "Value" has incompatible type "Iterator[int]"; expected "Generator[Never, str, Any]" # E: Argument 1 to "send" of "Error" has incompatible type "Iterator[int]"; expected "Generator[Never, Any, Any]" diff --git a/trio_typing/_tests/test-data/taskstatus.test b/trio_typing/_tests/test-data/taskstatus.test index 071b1a2..6400b20 100644 --- a/trio_typing/_tests/test-data/taskstatus.test +++ b/trio_typing/_tests/test-data/taskstatus.test @@ -21,10 +21,10 @@ async def parent() -> None: nursery.start_soon(child2) # E: Argument 1 to "start_soon" of "Nursery" has incompatible type "Callable[[int, DefaultNamedArg(TaskStatus[None], 'task_status')], Coroutine[Any, Any, None]]"; expected "Callable[[], Awaitable[Any]]" nursery.start_soon(child2, "hi") # E: Argument 1 to "start_soon" of "Nursery" has incompatible type "Callable[[int, DefaultNamedArg(TaskStatus[None], 'task_status')], Coroutine[Any, Any, None]]"; expected "Callable[[str], Awaitable[Any]]" nursery.start_soon(child2, 50) - await nursery.start(child) # E: Argument 1 to "start" of "Nursery" has incompatible type "Callable[[int, NamedArg(TaskStatus[int], 'task_status')], Coroutine[Any, Any, None]]"; expected "Callable[[NamedArg(TaskStatus[], 'task_status')], Awaitable[Any]]" + await nursery.start(child) # E: Argument 1 to "start" of "Nursery" has incompatible type "Callable[[int, NamedArg(TaskStatus[int], 'task_status')], Coroutine[Any, Any, None]]"; expected "Callable[[NamedArg(TaskStatus[int], 'task_status')], Awaitable[Any]]" await nursery.start(child, "hi") # E: Argument 1 to "start" of "Nursery" has incompatible type "Callable[[int, NamedArg(TaskStatus[int], 'task_status')], Coroutine[Any, Any, None]]"; expected "Callable[[str, NamedArg(TaskStatus[int], 'task_status')], Awaitable[Any]]" result = await nursery.start(child, 10) - result2 = await nursery.start(child2, 10) # E: Function does not return a value + result2 = await nursery.start(child2, 10) # E: Function does not return a value (it only ever returns None) await nursery.start(child2, 10) reveal_type(result) # N: Revealed type is "builtins.int" @@ -54,6 +54,6 @@ async def parent() -> None: await nursery.start(child) await nursery.start(child, "hi") result = await nursery.start(child, 10) - result2 = await nursery.start(child2, 10) # E: Function does not return a value + result2 = await nursery.start(child2, 10) # E: Function does not return a value (it only ever returns None) await nursery.start(child2, 10) reveal_type(result) # N: Revealed type is "builtins.int" diff --git a/trio_typing/_tests/test-data/trio-basic.test b/trio_typing/_tests/test-data/trio-basic.test index e57df21..fc12aae 100644 --- a/trio_typing/_tests/test-data/trio-basic.test +++ b/trio_typing/_tests/test-data/trio-basic.test @@ -26,7 +26,7 @@ reveal_type(val) # N: Revealed type is "builtins.list[builtins.float]" trio.run(sleep_sort, ["hi", "there"]) # E: Argument 1 to "run" has incompatible type "Callable[[Sequence[float]], Coroutine[Any, Any, List[float]]]"; expected "Callable[[List[str]], Awaitable[List[float]]]" -reveal_type(trio.Event().statistics().anything) # N: Revealed type is "Any" +reveal_type(trio.Event().statistics().tasks_waiting) # N: Revealed type is "builtins.int" [case testTrioBasic_NoPlugin] import trio @@ -55,7 +55,7 @@ val = trio.run(sleep_sort, (1, 3, 5, 2, 4), clock=trio.testing.MockClock(autojum reveal_type(val) # N: Revealed type is "builtins.list[builtins.float]" trio.run(sleep_sort, ["hi", "there"]) -reveal_type(trio.Event().statistics().anything) # N: Revealed type is "Any" +reveal_type(trio.Event().statistics().tasks_waiting) # N: Revealed type is "builtins.int" [case testExceptions] import trio @@ -75,11 +75,6 @@ def filter_exc(exc: BaseException): with trio.MultiError.catch(filter_exc): pass -try: - trio.run(trio.sleep, 3) -except trio.MultiError as ex: - reveal_type(ex.exceptions[0]) # N: Revealed type is "builtins.BaseException" - [case testOverloaded] from typing import overload, Any