Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions check.sh
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ fi
flake8 trio/ || EXIT_STATUS=$?

# Run mypy on all supported platforms
mypy -m trio -m trio.testing --platform linux || EXIT_STATUS=$?
mypy -m trio -m trio.testing --platform darwin || EXIT_STATUS=$? # tests FreeBSD too
mypy -m trio -m trio.testing --platform win32 || EXIT_STATUS=$?
mypy trio --platform linux || EXIT_STATUS=$?
mypy trio --platform darwin || EXIT_STATUS=$? # tests FreeBSD too
mypy trio --platform win32 || EXIT_STATUS=$?

# Check pip compile is consistent
pip-compile test-requirements.in
Expand Down
100 changes: 44 additions & 56 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,70 +34,58 @@ warn_redundant_casts = true
warn_return_any = true

# Avoid subtle backsliding
#disallow_any_decorated = true
#disallow_incomplete_defs = true
#disallow_subclassing_any = true
disallow_any_decorated = true
disallow_any_generics = true
disallow_any_unimported = false # Enable once Outcome has stubs.
disallow_incomplete_defs = true
disallow_subclassing_any = true
disallow_untyped_decorators = true
disallow_untyped_defs = true

# Enable gradually / for new modules
# Enable once other problems are dealt with
check_untyped_defs = false
disallow_untyped_calls = false
disallow_untyped_defs = false

# DO NOT use `ignore_errors`; it doesn't apply
# downstream and users have to deal with them.
[[tool.mypy.overrides]]
# Fully typed, enable stricter checks
module = [
"trio._abc",
"trio._core._asyncgens",
"trio._core._entry_queue",
"trio._core._generated_io_epoll",
"trio._core._generated_io_kqueue",
"trio._core._generated_run",
"trio._core._io_epoll",
"trio._core._io_kqueue",
"trio._core._local",
"trio._core._multierror",
"trio._core._run",
"trio._core._thread_cache",
"trio._core._traps",
"trio._core._unbounded_queue",
"trio._core._unbounded_queue",
"trio._deprecate",
"trio._dtls",
"trio._file_io",
"trio._highlevel_open_tcp_stream",
"trio._ki",
"trio._socket",
"trio._subprocess",
"trio._subprocess_platform",
"trio._subprocess_platform.kqueue",
"trio._subprocess_platform.waitid",
"trio._subprocess_platform.windows",
"trio._sync",
"trio._threads",
"trio._tools.gen_exports",
"trio._util",
]
disallow_incomplete_defs = true
disallow_untyped_defs = true
disallow_untyped_decorators = true
disallow_any_generics = true
disallow_any_decorated = true
disallow_any_unimported = false # Enable once outcome has stubs.
disallow_subclassing_any = true

# files not yet fully typed
[[tool.mypy.overrides]]
# Needs to use Any due to some complex introspection.
module = [
"trio._path",
# 2747
"trio/testing/_network",
"trio/testing/_trio_test",
"trio/testing/_checkpoints",
"trio/testing/_check_streams",
"trio/testing/_memory_streams",
# 2745
"trio/_ssl",
# 2756
"trio/_highlevel_open_unix_stream",
"trio/_highlevel_serve_listeners",
"trio/_highlevel_ssl_helpers",
"trio/_highlevel_socket",
# 2755
"trio/_core/_windows_cffi",
"trio/_wait_for_object",
# 2761
"trio/_core/_generated_io_windows",
"trio/_core/_io_windows",


"trio/_signals",

# internal
"trio/_windows_pipes",

# tests
"trio/_core/_tests/*",
"trio/_tests/*",
"trio/testing/_fake_net", # 30
]
disallow_incomplete_defs = true
disallow_untyped_defs = true
#disallow_any_generics = true
#disallow_any_decorated = true
disallow_any_unimported = true
disallow_subclassing_any = true
disallow_any_decorated = false
disallow_any_generics = false
disallow_any_unimported = false
disallow_incomplete_defs = false
disallow_untyped_defs = false

[tool.pytest.ini_options]
addopts = ["--strict-markers", "--strict-config"]
Expand Down
2 changes: 1 addition & 1 deletion trio/_core/_generated_run.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 7 additions & 1 deletion trio/_core/_io_common.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
from __future__ import annotations

import copy
from typing import TYPE_CHECKING

import outcome

from .. import _core

if TYPE_CHECKING:
from ._io_epoll import EpollWaiters


# Utility function shared between _io_epoll and _io_windows
def wake_all(waiters, exc):
def wake_all(waiters: EpollWaiters, exc: BaseException) -> None:
try:
current_task = _core.current_task()
except RuntimeError:
Expand Down
8 changes: 5 additions & 3 deletions trio/_core/_ki.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ def currently_ki_protected() -> bool:
# see python-trio/async_generator/async_generator/_impl.py
def legacy_isasyncgenfunction(
obj: object,
) -> TypeGuard[Callable[..., types.AsyncGeneratorType]]:
) -> TypeGuard[Callable[..., types.AsyncGeneratorType[object, object]]]:
return getattr(obj, "_async_gen_function", None) == id(obj)


Expand Down Expand Up @@ -196,7 +196,9 @@ def wrapper(*args: ArgsT.args, **kwargs: ArgsT.kwargs) -> RetT:

@attr.s
class KIManager:
handler = attr.ib(default=None)
handler: Callable[[int, types.FrameType | None], None] | None = attr.ib(
default=None
)

def install(
self,
Expand All @@ -221,7 +223,7 @@ def handler(signum: int, frame: types.FrameType | None) -> None:
self.handler = handler
signal.signal(signal.SIGINT, handler)

def close(self):
def close(self) -> None:
if self.handler is not None:
if signal.getsignal(signal.SIGINT) is self.handler:
signal.signal(signal.SIGINT, signal.default_int_handler)
Expand Down
2 changes: 1 addition & 1 deletion trio/_core/_parking_lot.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ async def park(self) -> None:
self._parked[task] = None
task.custom_sleep_data = self

def abort_fn(_):
def abort_fn(_: _core.RaiseCancelT) -> _core.Abort:
del task.custom_sleep_data._parked[task]
return _core.Abort.SUCCEEDED

Expand Down
13 changes: 8 additions & 5 deletions trio/_core/_tests/test_io.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
from __future__ import annotations

import random
import socket as stdlib_socket
from collections.abc import Callable
from contextlib import suppress

import pytest
Expand Down Expand Up @@ -47,15 +50,15 @@ def fileno_wrapper(fileobj):
return fileno_wrapper


wait_readable_options = [trio.lowlevel.wait_readable]
wait_writable_options = [trio.lowlevel.wait_writable]
notify_closing_options = [trio.lowlevel.notify_closing]
wait_readable_options: list[Callable] = [trio.lowlevel.wait_readable]
wait_writable_options: list[Callable] = [trio.lowlevel.wait_writable]
notify_closing_options: list[Callable] = [trio.lowlevel.notify_closing]

for options_list in [
for options_list in (
wait_readable_options,
wait_writable_options,
notify_closing_options,
]:
):
options_list += [using_fileno(f) for f in options_list]

# Decorators that feed in different settings for wait_readable / wait_writable
Expand Down
10 changes: 8 additions & 2 deletions trio/_core/_tests/test_ki.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
from __future__ import annotations

import contextlib
import inspect
import signal
import threading
from typing import TYPE_CHECKING

import outcome
import pytest
Expand All @@ -16,6 +19,9 @@
from ..._util import signal_raise
from ...testing import wait_all_tasks_blocked

if TYPE_CHECKING:
from ..._core import Abort, RaiseCancelT


def ki_self():
signal_raise(signal.SIGINT)
Expand Down Expand Up @@ -375,7 +381,7 @@ async def main():
ki_self()
task = _core.current_task()

def abort(_):
def abort(_: RaiseCancelT) -> Abort:
_core.reschedule(task, outcome.Value(1))
return _core.Abort.FAILED

Expand All @@ -394,7 +400,7 @@ async def main():
ki_self()
task = _core.current_task()

def abort(raise_cancel):
def abort(raise_cancel: RaiseCancelT) -> Abort:
result = outcome.capture(raise_cancel)
_core.reschedule(task, result)
return _core.Abort.FAILED
Expand Down
2 changes: 1 addition & 1 deletion trio/_core/_tests/test_multierror.py
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,7 @@ def test_apport_excepthook_monkeypatch_interaction():


@pytest.mark.parametrize("protocol", range(0, pickle.HIGHEST_PROTOCOL + 1))
def test_pickle_multierror(protocol) -> None:
def test_pickle_multierror(protocol: int) -> None:
# use trio.MultiError to make sure that pickle works through the deprecation layer
import trio

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
# make sure it's on sys.path.
import sys

import _common
import _common # isort: split

sys.path.append("/usr/lib/python3/dist-packages")
import apport_python_hook

apport_python_hook.install()

import trio
from trio._core._multierror import MultiError # Bypass deprecation warnings

raise trio.MultiError([KeyError("key_error"), ValueError("value_error")])
raise MultiError([KeyError("key_error"), ValueError("value_error")])
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# about it.
import sys

import _common
import _common # isort: split


def custom_excepthook(*args):
Expand All @@ -29,8 +29,8 @@ def custom_exc_hook(etype, value, tb, tb_offset=None):

ip.set_custom_exc((SomeError,), custom_exc_hook)

import trio
from trio._core._multierror import MultiError # Bypass deprecation warnings.

# The custom excepthook should run, because Trio was polite and didn't
# override it
raise trio.MultiError([ValueError(), KeyError()])
raise MultiError([ValueError(), KeyError()])
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import _common
import _common # isort: split

import trio
from trio._core._multierror import MultiError # Bypass deprecation warnings


def exc1_fn():
Expand All @@ -18,4 +18,4 @@ def exc2_fn():


# This should be printed nicely, because Trio overrode sys.excepthook
raise trio.MultiError([exc1_fn(), exc2_fn()])
raise MultiError([exc1_fn(), exc2_fn()])
4 changes: 2 additions & 2 deletions trio/_core/_tests/test_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -1954,7 +1954,7 @@ async def test_Nursery_private_init():
def test_Nursery_subclass():
with pytest.raises(TypeError):

class Subclass(_core._run.Nursery):
class Subclass(_core._run.Nursery): # type: ignore[misc]
pass


Expand Down Expand Up @@ -1984,7 +1984,7 @@ class Subclass(_core.Cancelled):
def test_CancelScope_subclass():
with pytest.raises(TypeError):

class Subclass(_core.CancelScope):
class Subclass(_core.CancelScope): # type: ignore[misc]
pass


Expand Down
16 changes: 9 additions & 7 deletions trio/_core/_wakeup_socketpair.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from __future__ import annotations

import signal
import socket
import warnings
Expand All @@ -7,7 +9,7 @@


class WakeupSocketpair:
def __init__(self):
def __init__(self) -> None:
self.wakeup_sock, self.write_sock = socket.socketpair()
self.wakeup_sock.setblocking(False)
self.write_sock.setblocking(False)
Expand All @@ -27,26 +29,26 @@ def __init__(self):
self.write_sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
except OSError:
pass
self.old_wakeup_fd = None
self.old_wakeup_fd: int | None = None

def wakeup_thread_and_signal_safe(self):
def wakeup_thread_and_signal_safe(self) -> None:
try:
self.write_sock.send(b"\x00")
except BlockingIOError:
pass

async def wait_woken(self):
async def wait_woken(self) -> None:
await _core.wait_readable(self.wakeup_sock)
self.drain()

def drain(self):
def drain(self) -> None:
try:
while True:
self.wakeup_sock.recv(2**16)
except BlockingIOError:
pass

def wakeup_on_signals(self):
def wakeup_on_signals(self) -> None:
assert self.old_wakeup_fd is None
if not is_main_thread():
return
Expand All @@ -64,7 +66,7 @@ def wakeup_on_signals(self):
)
)

def close(self):
def close(self) -> None:
self.wakeup_sock.close()
self.write_sock.close()
if self.old_wakeup_fd is not None:
Expand Down
Loading