Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
6d6af4d
mypy the entire trio package
altendky Jan 22, 2021
082f656
update mypy to 0.800
altendky Jan 22, 2021
1c00364
more specific ignores, etc
altendky Jan 23, 2021
9f94c1e
disallow_incomplete_defs = True
altendky Jan 23, 2021
c5d0170
just os.PathLike without [str] for now
altendky Jan 23, 2021
874eea1
get Literal from typing_extensions
altendky Jan 23, 2021
778b425
cleanup
altendky Jan 23, 2021
b0a5e9e
work on Windows specific issues
altendky Jan 23, 2021
5366d37
a couple more details
altendky Jan 23, 2021
7b38047
black
altendky Jan 23, 2021
8371daf
maybe this time
altendky Jan 23, 2021
0f313e5
correct to AssertionError
altendky Jan 23, 2021
8da7514
flake8
altendky Jan 23, 2021
e4fc53c
fixup docs requirements
altendky Jan 23, 2021
55fad66
disallow_subclassing_any = True
altendky Jan 24, 2021
ce44c04
disallow_any_decorated = True
altendky Jan 26, 2021
f8e83c6
fixup tests
altendky Jan 26, 2021
83600f8
fix import loop
altendky Jan 27, 2021
e478503
get Protocol from typing_extensions
altendky Jan 27, 2021
c34029b
queue.Queue isn't typing.Queue
altendky Jan 27, 2021
0ec01a1
queue.Queue isn't typing.Queue (again)
altendky Jan 27, 2021
b33978a
try again
altendky Jan 27, 2021
2d1882e
some workarounds for 3.6
altendky Jan 27, 2021
b77b3cb
another 3.6 (only windows) workaround
altendky Jan 27, 2021
b9dc659
circular import fix for macos
altendky Jan 27, 2021
44e60ea
circular import fix for macos (again)
altendky Jan 27, 2021
490cccd
handle some more win32 stuff
altendky Feb 8, 2021
c3db271
more
altendky Feb 8, 2021
897272f
Merge branch 'master' into merge_hints
altendky Feb 8, 2021
1915661
catch up
altendky Feb 9, 2021
2d70fa0
separate type checking
altendky Feb 9, 2021
4cf386e
black
altendky Feb 9, 2021
c1dd0d9
type check 3.6 - 3.9 on each platform
altendky Feb 9, 2021
2623aff
oops
altendky Feb 10, 2021
6dbb496
misc
altendky Feb 10, 2021
65e8572
generate generated files
altendky Feb 10, 2021
74543e0
update generated imports
altendky Feb 10, 2021
7e8aed5
more imports for the generated files
altendky Feb 10, 2021
8a7ce74
always more
altendky Feb 11, 2021
8075233
reformat imports for generated code
altendky Feb 11, 2021
6e58b9d
some doc stuff
altendky Feb 11, 2021
928f9dc
Merge branch 'master' into merge_hints
altendky Feb 13, 2021
3ecd3df
drop the SocketType ABCMeta change for now
altendky Feb 13, 2021
37b21c1
nitpick ignore
altendky Feb 13, 2021
f3c02e4
a start at disallow_untyped_defs = True
altendky Feb 14, 2021
49289ab
piles, upon piles
altendky Feb 15, 2021
a0abc2d
flake8
altendky Feb 15, 2021
8ca2719
flake8
altendky Feb 15, 2021
ca44f08
-> None (and more)
altendky Feb 15, 2021
b1e2fb7
black
altendky Feb 15, 2021
55d1915
again
altendky Feb 16, 2021
9ecbc1d
black
altendky Feb 16, 2021
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
5 changes: 5 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,16 @@ jobs:
matrix:
python: ['pypy-3.6', 'pypy-3.7', '3.6', '3.7', '3.8', '3.9', '3.6-dev', '3.7-dev', '3.8-dev', '3.9-dev']
check_formatting: ['0']
check_typing: ['0']
pypy_nightly_branch: ['']
extra_name: ['']
include:
- python: '3.8'
check_formatting: '1'
extra_name: ', check formatting'
- python: '3.8'
check_typing: '1'
extra_name: ', check typing'
- python: '3.7' # <- not actually used
pypy_nightly_branch: 'py3.7'
extra_name: ', pypy 3.7 nightly'
Expand All @@ -88,6 +92,7 @@ jobs:
env:
PYPY_NIGHTLY_BRANCH: '${{ matrix.pypy_nightly_branch }}'
CHECK_FORMATTING: '${{ matrix.check_formatting }}'
CHECK_TYPING: '${{ matrix.check_typing }}'
# Should match 'name:' up above
JOB_NAME: 'Ubuntu (${{ matrix.python }}${{ matrix.extra_name }})'

Expand Down
5 changes: 0 additions & 5 deletions check.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,6 @@ flake8 trio/ \
--ignore=D,E,W,F401,F403,F405,F821,F822\
|| 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=$?

# Finally, leave a really clear warning of any issues and exit
if [ $EXIT_STATUS -ne 0 ]; then
cat <<EOF
Expand Down
3 changes: 3 additions & 0 deletions ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ fi
if [ "$CHECK_FORMATTING" = "1" ]; then
python -m pip install -r test-requirements.txt
source check.sh
elif [ "$CHECK_TYPING" = "1" ]; then
python -m pip install -r test-requirements.txt
source typing.sh
else
# Actual tests
python -m pip install -r test-requirements.txt
Expand Down
1 change: 1 addition & 0 deletions docs-requirements.in
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ async_generator >= 1.9
idna
outcome
sniffio
typing-extensions

# See note in test-requirements.in
immutables >= 0.6
7 changes: 6 additions & 1 deletion docs-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# This file is autogenerated by pip-compile
# To update, run:
#
# pip-compile --output-file docs-requirements.txt docs-requirements.in
# pip-compile --output-file=docs-requirements.txt docs-requirements.in
#
alabaster==0.7.12
# via sphinx
Expand Down Expand Up @@ -81,5 +81,10 @@ toml==0.10.2
# via towncrier
towncrier==19.2.0
# via -r docs-requirements.in
typing-extensions==3.7.4.3
# via -r docs-requirements.in
urllib3==1.26.3
# via requests

# The following packages are considered to be unsafe in a requirements file:
# setuptools
12 changes: 12 additions & 0 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,18 @@
# https://github.com/sphinx-doc/sphinx/issues/7722
("py:class", "SendType"),
("py:class", "ReceiveType"),
("py:class", "_T_contra"),
("py:class", "_T_co"),
("py:class", "_T"),
("py:class", "T_resource"),
("py:class", "AbstractContextManager"),
("py:class", "_socket.socket"),
("py:class", "signal.Signals"),
("py:class", "trio._signals.SignalReceiver"),
("py:class", "socket.socket"),
("py:class", "trio._core._run._RunStatistics"),
("py:class", "socket.AddressFamily"),
("py:class", "socket.SocketKind"),
]
autodoc_inherit_docstrings = False
default_role = "obj"
Expand Down
8 changes: 4 additions & 4 deletions mypy.ini
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ 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_incomplete_defs = True
disallow_subclassing_any = True

# Enable gradually / for new modules
check_untyped_defs = False
disallow_untyped_calls = False
disallow_untyped_defs = False
disallow_untyped_defs = True

# DO NOT use `ignore_errors`; it doesn't apply
# downstream and users have to deal with them.
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
"idna",
"outcome",
"sniffio",
"typing-extensions",
# cffi 1.12 adds from_buffer(require_writable=True) and ffi.release()
# cffi 1.14 fixes memory leak inside ffi.getwinerror()
# cffi is required on Windows, except on PyPy where it is built-in
Expand Down
5 changes: 4 additions & 1 deletion test-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# This file is autogenerated by pip-compile
# To update, run:
#
# pip-compile --output-file test-requirements.txt test-requirements.in
# pip-compile --output-file=test-requirements.txt test-requirements.in
#
appdirs==1.4.4
# via black
Expand Down Expand Up @@ -139,3 +139,6 @@ wcwidth==0.2.5
# via prompt-toolkit
wrapt==1.12.1
# via astroid

# The following packages are considered to be unsafe in a requirements file:
# setuptools
84 changes: 57 additions & 27 deletions trio/_abc.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
# coding: utf-8

from abc import ABCMeta, abstractmethod
from typing import Generic, TypeVar
from typing import Generic, List, Optional, Text, Tuple, TYPE_CHECKING, TypeVar, Union
import socket
import trio
from ._core import _run

_T = TypeVar("_T")
_TSelf = TypeVar("_TSelf")


# We use ABCMeta instead of ABC, plus set __slots__=(), so as not to force a
Expand All @@ -13,15 +18,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 @@ -33,7 +38,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 @@ -67,21 +72,21 @@ class Instrument(metaclass=ABCMeta):

__slots__ = ()

def before_run(self):
def before_run(self) -> None:
"""Called at the beginning of :func:`trio.run`."""

def after_run(self):
def after_run(self) -> None:
"""Called just before :func:`trio.run` returns."""

def task_spawned(self, task):
def task_spawned(self, task: "_run.Task") -> None:
"""Called when the given task is created.

Args:
task (trio.lowlevel.Task): The new task.

"""

def task_scheduled(self, task):
def task_scheduled(self, task: "_run.Task") -> None:
"""Called when the given task becomes runnable.

It may still be some time before it actually runs, if there are other
Expand All @@ -92,39 +97,39 @@ def task_scheduled(self, task):

"""

def before_task_step(self, task):
def before_task_step(self, task: "_run.Task") -> None:
"""Called immediately before we resume running the given task.

Args:
task (trio.lowlevel.Task): The task that is about to run.

"""

def after_task_step(self, task):
def after_task_step(self, task: "_run.Task") -> None:
"""Called when we return to the main run loop after a task has yielded.

Args:
task (trio.lowlevel.Task): The task that just ran.

"""

def task_exited(self, task):
def task_exited(self, task: "_run.Task") -> None:
"""Called when the given task exits.

Args:
task (trio.lowlevel.Task): The finished task.

"""

def before_io_wait(self, timeout):
def before_io_wait(self, timeout: float) -> None:
"""Called before blocking to wait for I/O readiness.

Args:
timeout (float): The number of seconds we are willing to wait.

"""

def after_io_wait(self, timeout):
def after_io_wait(self, timeout: float) -> None:
"""Called after handling pending I/O.

Args:
Expand All @@ -146,7 +151,23 @@ class HostnameResolver(metaclass=ABCMeta):
__slots__ = ()

@abstractmethod
async def getaddrinfo(self, host, port, family=0, type=0, proto=0, flags=0):
async def getaddrinfo(
self,
host: Optional[Union[bytearray, bytes, Text]],
port: Union[str, int, None],
family: int = 0,
type: int = 0,
proto: int = 0,
flags: int = 0,
) -> List[
Tuple[
socket.AddressFamily,
socket.SocketKind,
int,
str,
Union[Tuple[str, int], Tuple[str, int, int, int]],
]
]:
"""A custom implementation of :func:`~trio.socket.getaddrinfo`.

Called by :func:`trio.socket.getaddrinfo`.
Expand All @@ -163,7 +184,11 @@ async def getaddrinfo(self, host, port, family=0, type=0, proto=0, flags=0):
"""

@abstractmethod
async def getnameinfo(self, sockaddr, flags):
async def getnameinfo(
self,
sockaddr: Union[Tuple[str, int], Tuple[str, int, int, int]],
flags: int,
) -> Tuple[str, str]:
"""A custom implementation of :func:`~trio.socket.getnameinfo`.

Called by :func:`trio.socket.getnameinfo`.
Expand All @@ -180,7 +205,12 @@ class SocketFactory(metaclass=ABCMeta):
"""

@abstractmethod
def socket(self, family=None, type=None, proto=None):
def socket(
self,
family: Optional[int] = None,
type: Optional[int] = None,
proto: Optional[int] = None,
) -> "trio.socket.SocketType":
"""Create and return a socket object.

Your socket object must inherit from :class:`trio.socket.SocketType`,
Expand Down Expand Up @@ -226,7 +256,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 @@ -254,10 +284,10 @@ async def aclose(self):

"""

async def __aenter__(self):
async def __aenter__(self: _T) -> _T:
return self

async def __aexit__(self, *args):
async def __aexit__(self, *args: object) -> None:
Copy link

Choose a reason for hiding this comment

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

shouldn't that be

async def __aexit__(self, exc_type: Optional[Type[BaseException]],
        exc_value: Optional[BaseException],
        exc_trackback: Optional[TracebackType]) -> Optional[bool]:

As that is the type the contextmanager protocol uses
(Maybe with added = Nones, not sure about that)

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't think this helps anything, but it does seem more proper. Though I think -> None is an accurate and good expression of the behavior. Thanks.

Added to the list in the OP.

Copy link

Choose a reason for hiding this comment

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

using -> None would disallow subclasses from returning True if they have some reason for that
(returning None and False have the same effect)

Copy link
Member Author

Choose a reason for hiding this comment

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

Good point. Thanks for following up.

await self.aclose()


Expand All @@ -280,7 +310,7 @@ class SendStream(AsyncResource):
__slots__ = ()

@abstractmethod
async def send_all(self, data):
async def send_all(self, data: Union[bytes, bytearray, memoryview]) -> None:
"""Sends the given data through the stream, blocking if necessary.

Args:
Expand All @@ -306,7 +336,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 @@ -386,7 +416,7 @@ class ReceiveStream(AsyncResource):
__slots__ = ()

@abstractmethod
async def receive_some(self, max_bytes=None):
async def receive_some(self, max_bytes: Optional[int] = ...) -> bytes:
"""Wait until there is data available on this stream, and then return
some of it.

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

"""

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

async def __anext__(self):
async def __anext__(self) -> bytes:
data = await self.receive_some()
if not data:
raise StopAsyncIteration
Expand Down Expand Up @@ -447,7 +477,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 @@ -526,7 +556,7 @@ class Listener(AsyncResource, Generic[T_resource]):
__slots__ = ()

@abstractmethod
async def accept(self):
async def accept(self) -> T_resource:
"""Wait until an incoming connection arrives, and then return it.

Returns:
Expand Down Expand Up @@ -633,7 +663,7 @@ async def receive(self) -> ReceiveType:

"""

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

async def __anext__(self) -> ReceiveType:
Expand Down
Loading