Skip to content
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

Update to mypy 1.15 #3201

Merged
merged 8 commits into from
Feb 11, 2025
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
3 changes: 3 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ repos:
rev: v2.4.1
hooks:
- id: codespell
additional_dependencies:
# tomli needed on 3.10. tomllib is available in stdlib on 3.11+
- tomli
- repo: https://github.com/crate-ci/typos
rev: typos-dict-v0.12.4
hooks:
Expand Down
9 changes: 9 additions & 0 deletions newsfragments/3201.misc.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
The typing of :func:`trio.abc.HostnameResolver.getaddrinfo` has been corrected to
match that of the stdlib `socket.getaddrinfo`, which was updated in mypy 1.15 (via
a typeshed update) to include the possibility of ``tuple[int, bytes]`` for the
``sockaddr`` field of the result. This happens in situations where Python was compiled
with ``--disable-ipv6``.
tjstum marked this conversation as resolved.
Show resolved Hide resolved

Additionally, the static typing of :func:`trio.to_thread.run_sync`,
:func:`trio.from_thread.run` and :func:`trio.from_thread.run_sync` has been
improved and should reflect the underlying function being run.
2 changes: 1 addition & 1 deletion src/trio/_abc.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ async def getaddrinfo(
socket.SocketKind,
int,
str,
tuple[str, int] | tuple[str, int, int, int],
tuple[str, int] | tuple[str, int, int, int] | tuple[int, bytes],
]
]:
"""A custom implementation of :func:`~trio.socket.getaddrinfo`.
Expand Down
3 changes: 1 addition & 2 deletions src/trio/_core/_entry_queue.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@

PosArgsT = TypeVarTuple("PosArgsT")

# Explicit "Any" is not allowed
Function = Callable[..., object] # type: ignore[misc]
Function = Callable[..., object] # type: ignore[explicit-any]
Job = tuple[Function, tuple[object, ...]]


Expand Down
11 changes: 5 additions & 6 deletions src/trio/_core/_instrumentation.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,22 @@

import logging
import types
from collections.abc import Callable, Sequence
from typing import TypeVar
from typing import TYPE_CHECKING, TypeVar

from .._abc import Instrument

# Used to log exceptions in instruments
INSTRUMENT_LOGGER = logging.getLogger("trio.abc.Instrument")

if TYPE_CHECKING:
from collections.abc import Sequence

# Explicit "Any" is not allowed
F = TypeVar("F", bound=Callable[..., object]) # type: ignore[misc]
T = TypeVar("T")


# Decorator to mark methods public. This does nothing by itself, but
# trio/_tools/gen_exports.py looks for it.
# Explicit "Any" is not allowed
def _public(fn: F) -> F: # type: ignore[misc]
def _public(fn: T) -> T:
return fn


Expand Down
41 changes: 15 additions & 26 deletions src/trio/_core/_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@
from collections.abc import (
Awaitable,
Callable,
Coroutine,
Generator,
Iterator,
Sequence,
Expand Down Expand Up @@ -1303,8 +1302,7 @@ def start_soon(
GLOBAL_RUN_CONTEXT.runner.spawn_impl(async_fn, args, self, name)

# Typing changes blocked by https://github.com/python/mypy/pull/17512
# Explicit "Any" is not allowed
async def start( # type: ignore[misc]
async def start( # type: ignore[explicit-any]
self,
async_fn: Callable[..., Awaitable[object]],
*args: object,
Expand Down Expand Up @@ -1404,10 +1402,9 @@ def __del__(self) -> None:

@final
@attrs.define(eq=False, repr=False)
class Task(metaclass=NoPublicConstructor): # type: ignore[misc]
class Task(metaclass=NoPublicConstructor): # type: ignore[explicit-any]
_parent_nursery: Nursery | None
# Explicit "Any" is not allowed
coro: Coroutine[Any, Outcome[object], Any] # type: ignore[misc]
coro: types.CoroutineType[Any, Outcome[object], Any] # type: ignore[explicit-any]
tjstum marked this conversation as resolved.
Show resolved Hide resolved
_runner: Runner
name: str
context: contextvars.Context
Expand All @@ -1425,11 +1422,10 @@ class Task(metaclass=NoPublicConstructor): # type: ignore[misc]
# tracebacks with extraneous frames.
# - for scheduled tasks, custom_sleep_data is None
# Tasks start out unscheduled.
# Explicit "Any" is not allowed
_next_send_fn: Callable[[Any], object] | None = None # type: ignore[misc]
_next_send: Outcome[Any] | BaseException | None = None # type: ignore[misc]
_next_send_fn: Callable[[Any], object] | None = None # type: ignore[explicit-any]
_next_send: Outcome[Any] | BaseException | None = None # type: ignore[explicit-any]
_abort_func: Callable[[_core.RaiseCancelT], Abort] | None = None
custom_sleep_data: Any = None # type: ignore[misc]
custom_sleep_data: Any = None # type: ignore[explicit-any]

# For introspection and nursery.start()
_child_nurseries: list[Nursery] = attrs.Factory(list)
Expand Down Expand Up @@ -1497,7 +1493,7 @@ def print_stack_for_task(task):

"""
# Ignore static typing as we're doing lots of dynamic introspection
coro: Any = self.coro # type: ignore[misc]
coro: Any = self.coro # type: ignore[explicit-any]
while coro is not None:
if hasattr(coro, "cr_frame"):
# A real coroutine
Expand Down Expand Up @@ -1642,16 +1638,13 @@ class RunStatistics:


@attrs.define(eq=False)
# Explicit "Any" is not allowed
class GuestState: # type: ignore[misc]
class GuestState: # type: ignore[explicit-any]
runner: Runner
run_sync_soon_threadsafe: Callable[[Callable[[], object]], object]
run_sync_soon_not_threadsafe: Callable[[Callable[[], object]], object]
# Explicit "Any" is not allowed
done_callback: Callable[[Outcome[Any]], object] # type: ignore[misc]
done_callback: Callable[[Outcome[Any]], object] # type: ignore[explicit-any]
unrolled_run_gen: Generator[float, EventResult, None]
# Explicit "Any" is not allowed
unrolled_run_next_send: Outcome[Any] = attrs.Factory(lambda: Value(None)) # type: ignore[misc]
unrolled_run_next_send: Outcome[Any] = attrs.Factory(lambda: Value(None)) # type: ignore[explicit-any]

def guest_tick(self) -> None:
prev_library, sniffio_library.name = sniffio_library.name, "trio"
Expand Down Expand Up @@ -1696,17 +1689,15 @@ def in_main_thread() -> None:


@attrs.define(eq=False)
# Explicit "Any" is not allowed
class Runner: # type: ignore[misc]
class Runner: # type: ignore[explicit-any]
clock: Clock
instruments: Instruments
io_manager: TheIOManager
ki_manager: KIManager
strict_exception_groups: bool

# Run-local values, see _local.py
# Explicit "Any" is not allowed
_locals: dict[_core.RunVar[Any], object] = attrs.Factory(dict) # type: ignore[misc]
_locals: dict[_core.RunVar[Any], object] = attrs.Factory(dict) # type: ignore[explicit-any]

runq: deque[Task] = attrs.Factory(deque)
tasks: set[Task] = attrs.Factory(set)
Expand Down Expand Up @@ -1895,7 +1886,7 @@ async def python_wrapper(orig_coro: Awaitable[RetT]) -> RetT:
return await orig_coro

coro = python_wrapper(coro)
assert coro.cr_frame is not None, "Coroutine frame should exist"
assert coro.cr_frame is not None, "Coroutine frame should exist" # type: ignore[attr-defined]
tjstum marked this conversation as resolved.
Show resolved Hide resolved

######
# Set up the Task object
Expand Down Expand Up @@ -2133,8 +2124,7 @@ def _deliver_ki_cb(self) -> None:

# sortedcontainers doesn't have types, and is reportedly very hard to type:
# https://github.com/grantjenks/python-sortedcontainers/issues/68
# Explicit "Any" is not allowed
waiting_for_idle: Any = attrs.Factory(SortedDict) # type: ignore[misc]
waiting_for_idle: Any = attrs.Factory(SortedDict) # type: ignore[explicit-any]

@_public
async def wait_all_tasks_blocked(self, cushion: float = 0.0) -> None:
Expand Down Expand Up @@ -2435,8 +2425,7 @@ def run(
raise AssertionError(runner.main_task_outcome)


# Explicit .../"Any" not allowed
def start_guest_run( # type: ignore[misc]
def start_guest_run( # type: ignore[explicit-any]
async_fn: Callable[..., Awaitable[RetT]],
*args: object,
run_sync_soon_threadsafe: Callable[[Callable[[], object]], object],
Expand Down
4 changes: 4 additions & 0 deletions src/trio/_core/_tests/test_asyncgen.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import sys
import weakref
from math import inf
from types import AsyncGeneratorType
from typing import TYPE_CHECKING, NoReturn

import pytest
Expand Down Expand Up @@ -88,6 +89,7 @@ async def async_main() -> None:
_core.run(async_main)
assert collected.pop() == "outlived run"
for agen in saved:
assert isinstance(agen, AsyncGeneratorType)
assert agen.ag_frame is None # all should now be exhausted


Expand Down Expand Up @@ -301,9 +303,11 @@ def test_delegation_to_existing_hooks() -> None:
record = []

def my_firstiter(agen: AsyncGenerator[object, NoReturn]) -> None:
assert isinstance(agen, AsyncGeneratorType)
record.append("firstiter " + agen.ag_frame.f_locals["arg"])

def my_finalizer(agen: AsyncGenerator[object, NoReturn]) -> None:
assert isinstance(agen, AsyncGeneratorType)
record.append("finalizer " + agen.ag_frame.f_locals["arg"])

async def example(arg: str) -> AsyncGenerator[int, None]:
Expand Down
13 changes: 6 additions & 7 deletions src/trio/_core/_tests/test_ki.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ def protected_manager() -> Iterator[None]:
async def test_async_generator_agen_protection() -> None:
@_core.enable_ki_protection
@async_generator # type: ignore[misc] # untyped generator
async def agen_protected1() -> None:
async def agen_protected1() -> None: # type: ignore[misc] # untyped generator
tjstum marked this conversation as resolved.
Show resolved Hide resolved
assert _core.currently_ki_protected()
try:
await yield_()
Expand All @@ -174,7 +174,7 @@ async def agen_protected1() -> None:

@_core.disable_ki_protection
@async_generator # type: ignore[misc] # untyped generator
async def agen_unprotected1() -> None:
async def agen_unprotected1() -> None: # type: ignore[misc] # untyped generator
assert not _core.currently_ki_protected()
try:
await yield_()
Expand All @@ -184,7 +184,7 @@ async def agen_unprotected1() -> None:
# Swap the order of the decorators:
@async_generator # type: ignore[misc] # untyped generator
@_core.enable_ki_protection
async def agen_protected2() -> None:
async def agen_protected2() -> None: # type: ignore[misc] # untyped generator
assert _core.currently_ki_protected()
try:
await yield_()
Expand All @@ -193,7 +193,7 @@ async def agen_protected2() -> None:

@async_generator # type: ignore[misc] # untyped generator
@_core.disable_ki_protection
async def agen_unprotected2() -> None:
async def agen_unprotected2() -> None: # type: ignore[misc] # untyped generator
assert not _core.currently_ki_protected()
try:
await yield_()
Expand Down Expand Up @@ -677,9 +677,8 @@ async def _consume_async_generator(agen: AsyncGenerator[None, None]) -> None:
await agen.aclose()


# Explicit .../"Any" is not allowed
def _consume_function_for_coverage( # type: ignore[misc]
fn: Callable[..., object],
def _consume_function_for_coverage(
fn: Callable[[], object],
) -> None:
result = fn()
if inspect.isasyncgen(result):
Expand Down
8 changes: 3 additions & 5 deletions src/trio/_core/_tests/test_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -1658,8 +1658,7 @@ async def func1(expected: str) -> None:
async def func2() -> None: # pragma: no cover
pass

# Explicit .../"Any" is not allowed
async def check( # type: ignore[misc]
async def check( # type: ignore[explicit-any]
spawn_fn: Callable[..., object],
) -> None:
spawn_fn(func1, "func1")
Expand Down Expand Up @@ -1696,14 +1695,13 @@ async def test_current_effective_deadline(mock_clock: _core.MockClock) -> None:


def test_nice_error_on_bad_calls_to_run_or_spawn() -> None:
# Explicit .../"Any" is not allowed
def bad_call_run( # type: ignore[misc]
def bad_call_run( # type: ignore[explicit-any]
func: Callable[..., Awaitable[object]],
*args: tuple[object, ...],
) -> None:
_core.run(func, *args)

def bad_call_spawn( # type: ignore[misc]
def bad_call_spawn( # type: ignore[explicit-any]
func: Callable[..., Awaitable[object]],
*args: tuple[object, ...],
) -> None:
Expand Down
3 changes: 1 addition & 2 deletions src/trio/_core/_thread_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,7 @@ class ThreadCache:
__slots__ = ("_idle_workers",)

def __init__(self) -> None:
# Explicit "Any" not allowed
self._idle_workers: dict[WorkerThread[Any], None] = {} # type: ignore[misc]
self._idle_workers: dict[WorkerThread[Any], None] = {} # type: ignore[explicit-any]

def start_thread_soon(
self,
Expand Down
3 changes: 1 addition & 2 deletions src/trio/_core/_traps.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,7 @@ class Abort(enum.Enum):

# Should always return the type a Task "expects", unless you willfully reschedule it
# with a bad value.
# Explicit "Any" is not allowed
async def wait_task_rescheduled( # type: ignore[misc]
async def wait_task_rescheduled( # type: ignore[explicit-any]
abort_func: Callable[[RaiseCancelT], Abort],
) -> Any:
"""Put the current task to sleep, with cancellation support.
Expand Down
2 changes: 1 addition & 1 deletion src/trio/_file_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,7 @@ async def open_file(


@overload
async def open_file( # type: ignore[misc] # Any usage matches builtins.open().
async def open_file( # type: ignore[explicit-any, misc] # Any usage matches builtins.open().
file: _OpenFile,
mode: str,
buffering: int = -1,
Expand Down
7 changes: 3 additions & 4 deletions src/trio/_highlevel_open_tcp_stream.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from trio.socket import SOCK_STREAM, SocketType, getaddrinfo, socket

if TYPE_CHECKING:
from collections.abc import Generator
from collections.abc import Generator, MutableSequence
from socket import AddressFamily, SocketKind

from trio._socket import AddressFormat
Expand Down Expand Up @@ -134,9 +134,8 @@ def close_all() -> Generator[set[SocketType], None, None]:
raise BaseExceptionGroup("", errs)


# Explicit "Any" is not allowed
def reorder_for_rfc_6555_section_5_4( # type: ignore[misc]
targets: list[tuple[AddressFamily, SocketKind, int, str, Any]],
def reorder_for_rfc_6555_section_5_4( # type: ignore[explicit-any]
targets: MutableSequence[tuple[AddressFamily, SocketKind, int, str, Any]],
) -> None:
# RFC 6555 section 5.4 says that if getaddrinfo returns multiple address
# families (e.g. IPv4 and IPv6), then you should make sure that your first
Expand Down
6 changes: 2 additions & 4 deletions src/trio/_highlevel_serve_listeners.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@


StreamT = TypeVar("StreamT", bound=trio.abc.AsyncResource)
# Explicit "Any" is not allowed
ListenerT = TypeVar("ListenerT", bound=trio.abc.Listener[Any]) # type: ignore[misc]
ListenerT = TypeVar("ListenerT", bound=trio.abc.Listener[Any]) # type: ignore[explicit-any]
Handler = Callable[[StreamT], Awaitable[object]]


Expand Down Expand Up @@ -68,8 +67,7 @@ async def _serve_one_listener(
# https://github.com/python/typing/issues/548


# Explicit "Any" is not allowed
async def serve_listeners( # type: ignore[misc]
async def serve_listeners( # type: ignore[explicit-any]
handler: Handler[StreamT],
listeners: list[ListenerT],
*,
Expand Down
9 changes: 4 additions & 5 deletions src/trio/_path.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@
T = TypeVar("T")


# Explicit .../"Any" is not allowed
def _wraps_async( # type: ignore[misc]
def _wraps_async( # type: ignore[explicit-any]
wrapped: Callable[..., object],
) -> Callable[[Callable[P, T]], Callable[P, Awaitable[T]]]:
def decorator(fn: Callable[P, T]) -> Callable[P, Awaitable[T]]:
Expand Down Expand Up @@ -184,7 +183,7 @@ async def open(
) -> AsyncIOWrapper[BinaryIO]: ...

@overload
async def open( # type: ignore[misc] # Any usage matches builtins.open().
async def open( # type: ignore[misc, explicit-any] # Any usage matches builtins.open().
self,
mode: str,
buffering: int = -1,
Expand All @@ -193,8 +192,8 @@ async def open( # type: ignore[misc] # Any usage matches builtins.open().
newline: str | None = None,
) -> AsyncIOWrapper[IO[Any]]: ...

@_wraps_async(pathlib.Path.open) # type: ignore[misc] # Overload return mismatch.
def open(self, *args: Any, **kwargs: Any) -> AsyncIOWrapper[IO[Any]]:
@_wraps_async(pathlib.Path.open)
def open(self, *args: Any, **kwargs: Any) -> AsyncIOWrapper[IO[Any]]: # type: ignore[misc, explicit-any] # Overload return mismatch.
return wrap_file(self._wrapped_cls(self).open(*args, **kwargs))

def __repr__(self) -> str:
Expand Down
Loading
Loading