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

lots of typing improvements #2682

Merged
merged 25 commits into from
Jul 13, 2023
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
af601ac
lots of typing improvements
jakkdl Jul 3, 2023
0050ca2
changes after review
jakkdl Jul 4, 2023
8b8383b
fix tests, reverting accidentally removing a default param
jakkdl Jul 4, 2023
b1f9f6f
fix all __aexit
jakkdl Jul 4, 2023
ba64565
rename exc_val to exc_value to match official data model
jakkdl Jul 4, 2023
adb8782
rename exc_tb to traceback to match python data model
jakkdl Jul 4, 2023
3c9583c
fix format check CI
jakkdl Jul 4, 2023
0f29a1a
changes after review from TeamSpen210
jakkdl Jul 5, 2023
c2012a7
Apply suggestions from code review
jakkdl Jul 6, 2023
3628fc6
Merge branch 'main' into typing_improvements
jakkdl Jul 6, 2023
9a0c3e2
fixes after review
jakkdl Jul 6, 2023
3094d06
attempt to fix readthedocs build, (temp) ignore errors on custom_slee…
jakkdl Jul 6, 2023
f83373b
revent custom_sleep_data to Any, add docstring to some Statistics to …
jakkdl Jul 7, 2023
ac4b357
fix CI errors
jakkdl Jul 7, 2023
8f89519
Merge branch 'main' into typing_improvements
jakkdl Jul 7, 2023
77a3706
don't require *Statistics to be Final
jakkdl Jul 7, 2023
50ce72f
fix CI
jakkdl Jul 7, 2023
f34787b
fix codecov and formatting
jakkdl Jul 7, 2023
1265024
Merge branch 'main' into typing_improvements
jakkdl Jul 7, 2023
a8751bb
ValueError, not TypeError
jakkdl Jul 7, 2023
ed05e13
fix pragma: no cover
jakkdl Jul 7, 2023
67166a5
fixes from CI review, mainly from Zac-HD
jakkdl Jul 10, 2023
8e5ba0b
Merge remote-tracking branch 'origin/master' into typing_improvements
jakkdl Jul 10, 2023
89f308f
small fixes after review from A5Rocks
jakkdl Jul 11, 2023
2536843
fix read the docs references
jakkdl Jul 11, 2023
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
39 changes: 25 additions & 14 deletions trio/_abc.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
from __future__ import annotations

from abc import ABCMeta, abstractmethod
from typing import Generic, TypeVar
from typing import Generic, TypeVar, TYPE_CHECKING
import trio

if TYPE_CHECKING:
from typing_extensions import Self
from types import TracebackType


# We use ABCMeta instead of ABC, plus set __slots__=(), so as not to force a
# __dict__ onto subclasses.
Expand All @@ -11,15 +17,15 @@ class Clock(metaclass=ABCMeta):
__slots__ = ()

@abstractmethod
def start_clock(self):
def start_clock(self) -> None:
"""Do any setup this clock might need.

Called at the beginning of the run.

"""

@abstractmethod
def current_time(self):
def current_time(self) -> float:
"""Return the current time, according to this clock.

This is used to implement functions like :func:`trio.current_time` and
Expand All @@ -31,7 +37,7 @@ def current_time(self):
"""

@abstractmethod
def deadline_to_sleep_time(self, deadline):
def deadline_to_sleep_time(self, deadline: float) -> float:
"""Compute the real time until the given deadline.

This is called before we enter a system-specific wait function like
Expand Down Expand Up @@ -224,7 +230,7 @@ class AsyncResource(metaclass=ABCMeta):
__slots__ = ()

@abstractmethod
async def aclose(self):
async def aclose(self) -> None:
"""Close this resource, possibly blocking.

IMPORTANT: This method may block in order to perform a "graceful"
Expand Down Expand Up @@ -252,10 +258,15 @@ async def aclose(self):

"""

async def __aenter__(self):
async def __aenter__(self) -> AsyncResource:
jakkdl marked this conversation as resolved.
Show resolved Hide resolved
return self

async def __aexit__(self, *args):
async def __aexit__(
self,
exc_type: type[BaseException] | None,
exc_value: BaseException | None,
traceback: TracebackType | None,
) -> None:
await self.aclose()


Expand All @@ -278,7 +289,7 @@ class SendStream(AsyncResource):
__slots__ = ()

@abstractmethod
async def send_all(self, data):
async def send_all(self, data: bytes | bytearray | memoryview) -> None:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably should be typing_extensions.Buffer, perhaps? Might be worth discussing in an issue on its own though, since it changes this core interface, widening it to any buffer-supporting class.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're very welcome to open it for discussion! I'm not aware of the nuances here at all, just copy-pasting types.

"""Sends the given data through the stream, blocking if necessary.

Args:
Expand All @@ -304,7 +315,7 @@ async def send_all(self, data):
"""

@abstractmethod
async def wait_send_all_might_not_block(self):
async def wait_send_all_might_not_block(self) -> None:
"""Block until it's possible that :meth:`send_all` might not block.

This method may return early: it's possible that after it returns,
Expand Down Expand Up @@ -384,7 +395,7 @@ class ReceiveStream(AsyncResource):
__slots__ = ()

@abstractmethod
async def receive_some(self, max_bytes=None):
async def receive_some(self, max_bytes: int | None = None) -> bytes | bytearray:
A5rocks marked this conversation as resolved.
Show resolved Hide resolved
"""Wait until there is data available on this stream, and then return
some of it.

Expand Down Expand Up @@ -412,10 +423,10 @@ async def receive_some(self, max_bytes=None):

"""

def __aiter__(self):
def __aiter__(self) -> Self:
return self

async def __anext__(self):
async def __anext__(self) -> bytes | bytearray:
data = await self.receive_some()
if not data:
raise StopAsyncIteration
Expand Down Expand Up @@ -445,7 +456,7 @@ class HalfCloseableStream(Stream):
__slots__ = ()

@abstractmethod
async def send_eof(self):
async def send_eof(self) -> None:
"""Send an end-of-file indication on this stream, if possible.

The difference between :meth:`send_eof` and
Expand Down Expand Up @@ -631,7 +642,7 @@ async def receive(self) -> ReceiveType:

"""

def __aiter__(self):
def __aiter__(self) -> Self:
return self

async def __anext__(self) -> ReceiveType:
Expand Down
8 changes: 4 additions & 4 deletions trio/_channel.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,8 +249,8 @@ def __enter__(self: SelfT) -> SelfT:
def __exit__(
self,
exc_type: type[BaseException] | None,
exc_val: BaseException | None,
exc_tb: TracebackType | None,
exc_value: BaseException | None,
traceback: TracebackType | None,
) -> None:
self.close()

Expand Down Expand Up @@ -395,8 +395,8 @@ def __enter__(self: SelfT) -> SelfT:
def __exit__(
self,
exc_type: type[BaseException] | None,
exc_val: BaseException | None,
exc_tb: TracebackType | None,
exc_value: BaseException | None,
traceback: TracebackType | None,
) -> None:
self.close()

Expand Down
26 changes: 13 additions & 13 deletions trio/_core/_mock_clock.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class MockClock(Clock, metaclass=Final):

"""

def __init__(self, rate=0.0, autojump_threshold=inf):
def __init__(self, rate: float = 0.0, autojump_threshold: float = inf):
# when the real clock said 'real_base', the virtual time was
# 'virtual_base', and since then it's advanced at 'rate' virtual
# seconds per real second.
Expand All @@ -77,17 +77,17 @@ def __init__(self, rate=0.0, autojump_threshold=inf):
self.rate = rate
self.autojump_threshold = autojump_threshold

def __repr__(self):
def __repr__(self) -> str:
return "<MockClock, time={:.7f}, rate={} @ {:#x}>".format(
self.current_time(), self._rate, id(self)
)

@property
def rate(self):
def rate(self) -> float:
return self._rate

@rate.setter
def rate(self, new_rate):
def rate(self, new_rate: float) -> None:
if new_rate < 0:
raise ValueError("rate must be >= 0")
else:
Expand All @@ -98,11 +98,11 @@ def rate(self, new_rate):
self._rate = float(new_rate)

@property
def autojump_threshold(self):
def autojump_threshold(self) -> float:
return self._autojump_threshold

@autojump_threshold.setter
def autojump_threshold(self, new_autojump_threshold):
def autojump_threshold(self, new_autojump_threshold: float) -> None:
self._autojump_threshold = float(new_autojump_threshold)
self._try_resync_autojump_threshold()

Expand All @@ -112,7 +112,7 @@ def autojump_threshold(self, new_autojump_threshold):
# API. Discussion:
#
# https://github.com/python-trio/trio/issues/1587
def _try_resync_autojump_threshold(self):
def _try_resync_autojump_threshold(self) -> None:
try:
runner = GLOBAL_RUN_CONTEXT.runner
if runner.is_guest:
Expand All @@ -124,24 +124,24 @@ def _try_resync_autojump_threshold(self):

# Invoked by the run loop when runner.clock_autojump_threshold is
# exceeded.
def _autojump(self):
def _autojump(self) -> None:
statistics = _core.current_statistics()
jump = statistics.seconds_to_next_deadline
if 0 < jump < inf:
self.jump(jump)

def _real_to_virtual(self, real):
def _real_to_virtual(self, real: float) -> float:
real_offset = real - self._real_base
virtual_offset = self._rate * real_offset
return self._virtual_base + virtual_offset

def start_clock(self):
def start_clock(self) -> None:
self._try_resync_autojump_threshold()

def current_time(self):
def current_time(self) -> float:
return self._real_to_virtual(self._real_clock())

def deadline_to_sleep_time(self, deadline):
def deadline_to_sleep_time(self, deadline: float) -> float:
virtual_timeout = deadline - self.current_time()
if virtual_timeout <= 0:
return 0
Expand All @@ -150,7 +150,7 @@ def deadline_to_sleep_time(self, deadline):
else:
return 999999999

def jump(self, seconds):
def jump(self, seconds) -> None:
"""Manually advance the clock by the given number of seconds.

Args:
Expand Down
18 changes: 14 additions & 4 deletions trio/_core/_multierror.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
from __future__ import annotations
import sys
import warnings

import attr

from trio._deprecate import warn_deprecated
from typing import TYPE_CHECKING

if sys.version_info < (3, 11):
from exceptiongroup import BaseExceptionGroup, ExceptionGroup, print_exception
else:
from traceback import print_exception

if TYPE_CHECKING:
from types import TracebackType
################################################################
# MultiError
################################################################
Expand Down Expand Up @@ -130,11 +134,16 @@ class MultiErrorCatcher:
def __enter__(self):
pass

def __exit__(self, etype, exc, tb):
if exc is not None:
filtered_exc = _filter_impl(self._handler, exc)
def __exit__(
self,
exc_type: type[BaseException] | None,
exc_value: BaseException | None,
traceback: TracebackType | None,
) -> bool | None:
if exc_value is not None:
filtered_exc = _filter_impl(self._handler, exc_value)

if filtered_exc is exc:
if filtered_exc is exc_value:
# Let the interpreter re-raise it
return False
if filtered_exc is None:
Expand All @@ -154,6 +163,7 @@ def __exit__(self, etype, exc, tb):
# delete references from locals to avoid creating cycles
# see test_MultiError_catch_doesnt_create_cyclic_garbage
del _, filtered_exc, value
return False


class MultiError(BaseExceptionGroup):
Expand Down
Loading