From 4e6293937ad6d1602923590c03b2dae8fff47045 Mon Sep 17 00:00:00 2001 From: EXPLOSION Date: Sat, 9 Sep 2023 01:56:41 -0400 Subject: [PATCH 01/18] Replace public usages of `functools.wraps` --- trio/_path.py | 1 + trio/_socket.py | 11 +++++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/trio/_path.py b/trio/_path.py index c2763e03af..8cc52d738b 100644 --- a/trio/_path.py +++ b/trio/_path.py @@ -320,6 +320,7 @@ def open( ) -> _AsyncIOWrapper[IO[Any]]: ... + # TODO: check the following is AOK with pyright @wraps(pathlib.Path.open) # type: ignore[misc] # Overload return mismatch. async def open(self, *args: Any, **kwargs: Any) -> _AsyncIOWrapper[IO[Any]]: """Open the file pointed to by the path, like the :func:`trio.open_file` diff --git a/trio/_socket.py b/trio/_socket.py index 2834a5b055..0a4ec390b5 100644 --- a/trio/_socket.py +++ b/trio/_socket.py @@ -4,7 +4,6 @@ import select import socket as _stdlib_socket import sys -from functools import wraps as _wraps from operator import index from socket import AddressFamily, SocketKind from typing import ( @@ -37,9 +36,17 @@ P = ParamSpec("P") - T = TypeVar("T") +# work around a pyright error +if TYPE_CHECKING: + Fn = TypeVar("Fn", bound=Callable[..., object]) + def _wraps(f: Fn) -> Fn: + ... + +else: + from functools import wraps as _wraps + # must use old-style typing because it's evaluated at runtime Address: TypeAlias = Union[ str, bytes, Tuple[str, int], Tuple[str, int, int], Tuple[str, int, int, int] From 1ba1940da8a46ba5e3b2242e153ffad1754579c0 Mon Sep 17 00:00:00 2001 From: EXPLOSION Date: Sat, 9 Sep 2023 02:05:31 -0400 Subject: [PATCH 02/18] Fix a couple CI errors --- trio/_socket.py | 5 ++++- trio/_tests/verify_types_windows.json | 6 +++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/trio/_socket.py b/trio/_socket.py index 0a4ec390b5..263467ef26 100644 --- a/trio/_socket.py +++ b/trio/_socket.py @@ -40,8 +40,11 @@ # work around a pyright error if TYPE_CHECKING: + from typing import Sequence + Fn = TypeVar("Fn", bound=Callable[..., object]) - def _wraps(f: Fn) -> Fn: + + def _wraps(wrapped: Fn, assigned: Sequence[str] = ..., updated: Sequence[str]=...) -> Fn: ... else: diff --git a/trio/_tests/verify_types_windows.json b/trio/_tests/verify_types_windows.json index fff290e159..be2bb3650c 100644 --- a/trio/_tests/verify_types_windows.json +++ b/trio/_tests/verify_types_windows.json @@ -137,6 +137,10 @@ "message": "No docstring found for function \"trio.run_process\"", "name": "trio.run_process" }, + { + "message": "No docstring found for class \"trio.socket.fromshare\"", + "name": "trio.socket.fromshare" + }, { "message": "No docstring found for class \"trio.tests.TestsDeprecationWrapper\"", "name": "trio.tests.TestsDeprecationWrapper" @@ -150,7 +154,7 @@ "ignoreUnknownTypesFromImports": true, "missingClassDocStringCount": 1, "missingDefaultParamCount": 0, - "missingFunctionDocStringCount": 11, + "missingFunctionDocStringCount": 12, "moduleName": "trio", "modules": [ { From 9e3bac2d3f6fdb6be5ab957479627eb87c24e899 Mon Sep 17 00:00:00 2001 From: EXPLOSION Date: Sat, 9 Sep 2023 02:09:36 -0400 Subject: [PATCH 03/18] Don't blank out on how `wraps` actually works.... --- trio/_socket.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/trio/_socket.py b/trio/_socket.py index 263467ef26..f3b9682a94 100644 --- a/trio/_socket.py +++ b/trio/_socket.py @@ -44,7 +44,9 @@ Fn = TypeVar("Fn", bound=Callable[..., object]) - def _wraps(wrapped: Fn, assigned: Sequence[str] = ..., updated: Sequence[str]=...) -> Fn: + def _wraps( + wrapped: Fn, assigned: Sequence[str] = ..., updated: Sequence[str] = ... + ) -> Callable[..., Fn]: ... else: From 9998355d5be1e222ad274c4f241b807b5028cf56 Mon Sep 17 00:00:00 2001 From: A5rocks Date: Wed, 13 Sep 2023 06:06:23 +0900 Subject: [PATCH 04/18] Don't try to pretend wrapped functions are what they wrap --- trio/_socket.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/trio/_socket.py b/trio/_socket.py index f3b9682a94..96694dcc33 100644 --- a/trio/_socket.py +++ b/trio/_socket.py @@ -45,8 +45,10 @@ Fn = TypeVar("Fn", bound=Callable[..., object]) def _wraps( - wrapped: Fn, assigned: Sequence[str] = ..., updated: Sequence[str] = ... - ) -> Callable[..., Fn]: + wrapped: Callable[..., object], + assigned: Sequence[str] = ..., + updated: Sequence[str] = ..., + ) -> Callable[[Fn], Fn]: ... else: From 87e8348fdcd55ed7b7dae444f4905f3383038e09 Mon Sep 17 00:00:00 2001 From: A5rocks Date: Wed, 13 Sep 2023 06:09:47 +0900 Subject: [PATCH 05/18] Fix pyright type completeness --- trio/_tests/verify_types_windows.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/trio/_tests/verify_types_windows.json b/trio/_tests/verify_types_windows.json index be2bb3650c..d795180c80 100644 --- a/trio/_tests/verify_types_windows.json +++ b/trio/_tests/verify_types_windows.json @@ -138,7 +138,7 @@ "name": "trio.run_process" }, { - "message": "No docstring found for class \"trio.socket.fromshare\"", + "message": "No docstring found for function \"trio.socket.fromshare\"", "name": "trio.socket.fromshare" }, { From 9c2a38681b619ca53c9725184ae806772549a717 Mon Sep 17 00:00:00 2001 From: EXPLOSION Date: Fri, 22 Sep 2023 01:32:54 -0400 Subject: [PATCH 06/18] Finish off TODO --- trio/_path.py | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/trio/_path.py b/trio/_path.py index 8cc52d738b..652efe8f87 100644 --- a/trio/_path.py +++ b/trio/_path.py @@ -6,7 +6,7 @@ import sys import types from collections.abc import Awaitable, Callable, Iterable -from functools import partial, wraps +from functools import partial from io import BufferedRandom, BufferedReader, BufferedWriter, FileIO, TextIOWrapper from typing import ( IO, @@ -36,6 +36,22 @@ P = ParamSpec("P") +# work around a pyright error +if TYPE_CHECKING: + from typing import Sequence + + Fn = TypeVar("Fn", bound=Callable[..., object]) + + def wraps( + wrapped: Callable[..., object], + assigned: Sequence[str] = ..., + updated: Sequence[str] = ..., + ) -> Callable[[Fn], Fn]: + ... + +else: + from functools import wraps + T = TypeVar("T") StrPath: TypeAlias = Union[str, "os.PathLike[str]"] # Only subscriptable in 3.9+ @@ -320,7 +336,6 @@ def open( ) -> _AsyncIOWrapper[IO[Any]]: ... - # TODO: check the following is AOK with pyright @wraps(pathlib.Path.open) # type: ignore[misc] # Overload return mismatch. async def open(self, *args: Any, **kwargs: Any) -> _AsyncIOWrapper[IO[Any]]: """Open the file pointed to by the path, like the :func:`trio.open_file` From b0d2725050e6c227407372cd31ab8ff3995f72ed Mon Sep 17 00:00:00 2001 From: A5rocks Date: Tue, 26 Sep 2023 15:41:54 +0900 Subject: [PATCH 07/18] Basic type test framework --- trio/_socket.py | 2 +- trio/_tests/test_types.py | 82 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 trio/_tests/test_types.py diff --git a/trio/_socket.py b/trio/_socket.py index 96694dcc33..b0fa628a0a 100644 --- a/trio/_socket.py +++ b/trio/_socket.py @@ -997,7 +997,7 @@ async def sendto( @_wraps(_stdlib_socket.socket.sendto, assigned=(), updated=()) # type: ignore[misc] async def sendto(self, *args: Any) -> int: """Similar to :meth:`socket.socket.sendto`, but async.""" - # args is: data[, flags], address) + # args is: data[, flags], address # and kwargs are not accepted args_list = list(args) args_list[-1] = await self._resolve_address_nocp(args[-1], local=False) diff --git a/trio/_tests/test_types.py b/trio/_tests/test_types.py new file mode 100644 index 0000000000..908f796387 --- /dev/null +++ b/trio/_tests/test_types.py @@ -0,0 +1,82 @@ +# this file should only check *small* portions of trio's API. +# (it would be unproductive to write out the API twice :^) + +type_checkers = [] +import os +import subprocess +import tempfile +import textwrap + +import pytest + +try: + import pyright +except: + pass +else: + type_checkers.append("pyright") + del pyright + +try: + import mypy +except: + pass +else: + type_checkers.append("mypy") + del mypy + + +def check_file(checker: str, contents: str) -> bool: + contents = textwrap.dedent(contents) + if checker == "mypy": + p = subprocess.run(["mypy", "-c", contents]) + return not p.returncode + elif checker == "pyright": + with tempfile.TemporaryDirectory() as tdir: + path = os.path.join(tdir, "check.py") + with open(path, "w") as f: + f.write(contents) + p = subprocess.run(["pyright", path, "--verbose"]) + return not p.returncode + else: + raise AssertionError(f"unknown checker {checker}") + + +@pytest.mark.skipif(type_checkers != ["pyright", "mypy"]) +def test_harness() -> None: + # mypy error only! + file = """ + import typing_extensions + import typing + + x = 1 + typing_extensions.assert_type(x, typing.Literal[1]) + """ + assert not check_file("mypy", file) + assert check_file("pyright", file) + + # pyright error only! + file = file.replace("typing.Literal[1]", "int") + assert check_file("mypy", file) + assert not check_file("pyright", file) + + +@pytest.mark.parametrize("checker", type_checkers) +def test_socket_functools_wrap(checker) -> None: + # https://github.com/python-trio/trio/issues/2775#issuecomment-1702267589 + # (except platform independent...) + assert check_file( + checker, + """ + import array + import socket + + import trio + import typing_extensions + + + async def fn(s: trio.SocketStream) -> None: + result = await s.socket.sendto(b"a", "h") + typing_extensions.assert_type(result, int) + """, + ) From 1dfe84a202c35ea6d06261af8fec12b6c396c6ac Mon Sep 17 00:00:00 2001 From: A5rocks Date: Tue, 26 Sep 2023 15:43:00 +0900 Subject: [PATCH 08/18] Small cleanup --- trio/_tests/test_types.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/trio/_tests/test_types.py b/trio/_tests/test_types.py index 908f796387..4aff843d3c 100644 --- a/trio/_tests/test_types.py +++ b/trio/_tests/test_types.py @@ -1,7 +1,6 @@ # this file should only check *small* portions of trio's API. # (it would be unproductive to write out the API twice :^) -type_checkers = [] import os import subprocess import tempfile @@ -9,6 +8,7 @@ import pytest +type_checkers = [] try: import pyright except: From b5fbc06ee2494222b03c6dc8a89902e708cf5da1 Mon Sep 17 00:00:00 2001 From: A5rocks Date: Tue, 26 Sep 2023 15:44:19 +0900 Subject: [PATCH 09/18] Also make sure to pass type checking on the type tests! --- trio/_tests/test_types.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/trio/_tests/test_types.py b/trio/_tests/test_types.py index 4aff843d3c..5fa93dccdc 100644 --- a/trio/_tests/test_types.py +++ b/trio/_tests/test_types.py @@ -62,7 +62,7 @@ def test_harness() -> None: @pytest.mark.parametrize("checker", type_checkers) -def test_socket_functools_wrap(checker) -> None: +def test_socket_functools_wrap(checker: str) -> None: # https://github.com/python-trio/trio/issues/2775#issuecomment-1702267589 # (except platform independent...) assert check_file( From 7bcdeee2d13e1e9b2d67a7c5857621000ab5a63d Mon Sep 17 00:00:00 2001 From: A5rocks Date: Tue, 26 Sep 2023 15:46:31 +0900 Subject: [PATCH 10/18] Remove some unnecessary imports; oops --- trio/_tests/test_types.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/trio/_tests/test_types.py b/trio/_tests/test_types.py index 5fa93dccdc..8eb703294b 100644 --- a/trio/_tests/test_types.py +++ b/trio/_tests/test_types.py @@ -68,9 +68,6 @@ def test_socket_functools_wrap(checker: str) -> None: assert check_file( checker, """ - import array - import socket - import trio import typing_extensions From d31e545f91302b042a16652e1a3a7dce55c110c9 Mon Sep 17 00:00:00 2001 From: A5rocks Date: Tue, 26 Sep 2023 15:50:45 +0900 Subject: [PATCH 11/18] Fix a pytest skipif mistake --- trio/_tests/test_types.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/trio/_tests/test_types.py b/trio/_tests/test_types.py index 8eb703294b..8efe34082f 100644 --- a/trio/_tests/test_types.py +++ b/trio/_tests/test_types.py @@ -42,7 +42,9 @@ def check_file(checker: str, contents: str) -> bool: raise AssertionError(f"unknown checker {checker}") -@pytest.mark.skipif(type_checkers != ["pyright", "mypy"]) +@pytest.mark.skipif( + type_checkers != ["pyright", "mypy"], reason="uses both pyright and mypy" +) def test_harness() -> None: # mypy error only! file = """ From b2b45634116f19751f5563fba71ccb016504e0d2 Mon Sep 17 00:00:00 2001 From: EXPLOSION Date: Sat, 30 Sep 2023 01:05:36 -0400 Subject: [PATCH 12/18] PR review changes --- check.sh | 4 ++ trio/_path.py | 18 +----- trio/_socket.py | 18 +----- trio/_tests/test_types.py | 81 --------------------------- trio/_tests/type_tests/check_wraps.py | 9 +++ trio/_util.py | 15 +++++ 6 files changed, 31 insertions(+), 114 deletions(-) delete mode 100644 trio/_tests/test_types.py create mode 100644 trio/_tests/type_tests/check_wraps.py diff --git a/check.sh b/check.sh index 95049080f3..e76bee295d 100755 --- a/check.sh +++ b/check.sh @@ -62,6 +62,10 @@ mypy trio --show-error-end --platform darwin | python ./trio/_tools/mypy_annotat || { echo "* Mypy (Mac) found type errors." >> $GITHUB_STEP_SUMMARY; MYPY=1; } mypy trio --show-error-end --platform win32 | python ./trio/_tools/mypy_annotate.py --dumpfile mypy_annotate.dat --platform Windows \ || { echo "* Mypy (Windows) found type errors." >> $GITHUB_STEP_SUMMARY; MYPY=1; } + +# for now, just run interface typing checks on the native platform... +mypy trio/_tests/type_tests --show-error-end | python ./trio/_tools/mypy_annotate.py --dumpfile mypy_annotate.dat --platform Interface \ + || { echo "* Mypy (Interface) found type errors." >> $GITHUB_STEP_SUMMARY; MYPY=1; } set +o pipefail # Re-display errors using Github's syntax, read out of mypy_annotate.dat python ./trio/_tools/mypy_annotate.py --dumpfile mypy_annotate.dat diff --git a/trio/_path.py b/trio/_path.py index 652efe8f87..5c65b68fd3 100644 --- a/trio/_path.py +++ b/trio/_path.py @@ -22,7 +22,7 @@ import trio from trio._file_io import AsyncIOWrapper as _AsyncIOWrapper -from trio._util import Final, async_wraps +from trio._util import Final, async_wraps, wraps if TYPE_CHECKING: from _typeshed import ( @@ -36,22 +36,6 @@ P = ParamSpec("P") -# work around a pyright error -if TYPE_CHECKING: - from typing import Sequence - - Fn = TypeVar("Fn", bound=Callable[..., object]) - - def wraps( - wrapped: Callable[..., object], - assigned: Sequence[str] = ..., - updated: Sequence[str] = ..., - ) -> Callable[[Fn], Fn]: - ... - -else: - from functools import wraps - T = TypeVar("T") StrPath: TypeAlias = Union[str, "os.PathLike[str]"] # Only subscriptable in 3.9+ diff --git a/trio/_socket.py b/trio/_socket.py index b0fa628a0a..0e46246c24 100644 --- a/trio/_socket.py +++ b/trio/_socket.py @@ -23,6 +23,7 @@ import idna as _idna import trio +from trio._util import wraps as _wraps from . import _core @@ -36,23 +37,8 @@ P = ParamSpec("P") -T = TypeVar("T") - -# work around a pyright error -if TYPE_CHECKING: - from typing import Sequence - - Fn = TypeVar("Fn", bound=Callable[..., object]) - def _wraps( - wrapped: Callable[..., object], - assigned: Sequence[str] = ..., - updated: Sequence[str] = ..., - ) -> Callable[[Fn], Fn]: - ... - -else: - from functools import wraps as _wraps +T = TypeVar("T") # must use old-style typing because it's evaluated at runtime Address: TypeAlias = Union[ diff --git a/trio/_tests/test_types.py b/trio/_tests/test_types.py deleted file mode 100644 index 8efe34082f..0000000000 --- a/trio/_tests/test_types.py +++ /dev/null @@ -1,81 +0,0 @@ -# this file should only check *small* portions of trio's API. -# (it would be unproductive to write out the API twice :^) - -import os -import subprocess -import tempfile -import textwrap - -import pytest - -type_checkers = [] -try: - import pyright -except: - pass -else: - type_checkers.append("pyright") - del pyright - -try: - import mypy -except: - pass -else: - type_checkers.append("mypy") - del mypy - - -def check_file(checker: str, contents: str) -> bool: - contents = textwrap.dedent(contents) - if checker == "mypy": - p = subprocess.run(["mypy", "-c", contents]) - return not p.returncode - elif checker == "pyright": - with tempfile.TemporaryDirectory() as tdir: - path = os.path.join(tdir, "check.py") - with open(path, "w") as f: - f.write(contents) - p = subprocess.run(["pyright", path, "--verbose"]) - return not p.returncode - else: - raise AssertionError(f"unknown checker {checker}") - - -@pytest.mark.skipif( - type_checkers != ["pyright", "mypy"], reason="uses both pyright and mypy" -) -def test_harness() -> None: - # mypy error only! - file = """ - import typing_extensions - import typing - - x = 1 - typing_extensions.assert_type(x, typing.Literal[1]) - """ - assert not check_file("mypy", file) - assert check_file("pyright", file) - - # pyright error only! - file = file.replace("typing.Literal[1]", "int") - assert check_file("mypy", file) - assert not check_file("pyright", file) - - -@pytest.mark.parametrize("checker", type_checkers) -def test_socket_functools_wrap(checker: str) -> None: - # https://github.com/python-trio/trio/issues/2775#issuecomment-1702267589 - # (except platform independent...) - assert check_file( - checker, - """ - import trio - import typing_extensions - - - async def fn(s: trio.SocketStream) -> None: - result = await s.socket.sendto(b"a", "h") - typing_extensions.assert_type(result, int) - """, - ) diff --git a/trio/_tests/type_tests/check_wraps.py b/trio/_tests/type_tests/check_wraps.py new file mode 100644 index 0000000000..5692738be4 --- /dev/null +++ b/trio/_tests/type_tests/check_wraps.py @@ -0,0 +1,9 @@ +# https://github.com/python-trio/trio/issues/2775#issuecomment-1702267589 +# (except platform independent...) +import trio +import typing_extensions + + +async def fn(s: trio.SocketStream) -> None: + result = await s.socket.sendto(b"a", "h") + typing_extensions.assert_type(result, int) diff --git a/trio/_util.py b/trio/_util.py index 73fc024831..40f1ac498b 100644 --- a/trio/_util.py +++ b/trio/_util.py @@ -384,3 +384,18 @@ def name_asyncgen(agen: AsyncGeneratorType[object, t.NoReturn]) -> str: except AttributeError: qualname = agen.ag_code.co_name return f"{module}.{qualname}" + +# work around a pyright error +if TYPE_CHECKING: + from typing import Sequence + + Fn = TypeVar("Fn", bound=Callable[..., object]) + + def wraps( + wrapped: Callable[..., object], + assigned: Sequence[str] = ..., + updated: Sequence[str] = ..., + ) -> Callable[[Fn], Fn]: + ... +else: + from functools import wraps From 0bc5d02c56e747999dce255321b8234908ae3dc2 Mon Sep 17 00:00:00 2001 From: EXPLOSION Date: Sat, 30 Sep 2023 01:09:22 -0400 Subject: [PATCH 13/18] Forgot to check against pyright too --- check.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/check.sh b/check.sh index e76bee295d..7b8cc36ff3 100755 --- a/check.sh +++ b/check.sh @@ -98,6 +98,7 @@ fi codespell || EXIT_STATUS=$? +echo "::group::Pyright interface tests" python trio/_tests/check_type_completeness.py --overwrite-file || EXIT_STATUS=$? if git status --porcelain trio/_tests/verify_types*.json | grep -q "M"; then echo "* Type completeness changed, please update!" >> $GITHUB_STEP_SUMMARY @@ -106,6 +107,9 @@ if git status --porcelain trio/_tests/verify_types*.json | grep -q "M"; then EXIT_STATUS=1 fi +pyright trio/_tests/type_tests || EXIT_STATUS=$? +echo "::endgroup::" + # Finally, leave a really clear warning of any issues and exit if [ $EXIT_STATUS -ne 0 ]; then cat < Date: Sat, 30 Sep 2023 01:11:18 -0400 Subject: [PATCH 14/18] Mark wraps as a re-export from `_util` (hopefully flake8 likes this) --- trio/_util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/trio/_util.py b/trio/_util.py index 66b3080561..4a97a47081 100644 --- a/trio/_util.py +++ b/trio/_util.py @@ -403,4 +403,4 @@ def wraps( ) -> Callable[[Fn], Fn]: ... else: - from functools import wraps + from functools import wraps as wraps From a46258532e846b91fde9865253344edb1559cae6 Mon Sep 17 00:00:00 2001 From: EXPLOSION Date: Sat, 30 Sep 2023 01:13:41 -0400 Subject: [PATCH 15/18] Fix CI errors :( --- trio/_util.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/trio/_util.py b/trio/_util.py index 4a97a47081..5fb798c04d 100644 --- a/trio/_util.py +++ b/trio/_util.py @@ -391,16 +391,14 @@ def name_asyncgen(agen: AsyncGeneratorType[object, t.NoReturn]) -> str: return f"{module}.{qualname}" # work around a pyright error -if TYPE_CHECKING: - from typing import Sequence - - Fn = TypeVar("Fn", bound=Callable[..., object]) +if t.TYPE_CHECKING: + Fn = TypeVar("Fn", bound=t.Callable[..., object]) def wraps( - wrapped: Callable[..., object], - assigned: Sequence[str] = ..., - updated: Sequence[str] = ..., - ) -> Callable[[Fn], Fn]: + wrapped: t.Callable[..., object], + assigned: t.Sequence[str] = ..., + updated: t.Sequence[str] = ..., + ) -> t.Callable[[Fn], Fn]: ... else: - from functools import wraps as wraps + from functools import wraps # noqa: F401 # this is re-exported From dee395ea31a2c13b5cec5731ea1947072b32e711 Mon Sep 17 00:00:00 2001 From: A5rocks Date: Sat, 30 Sep 2023 14:29:50 +0900 Subject: [PATCH 16/18] Possibly last fixes --- trio/_tests/type_tests/check_wraps.py | 3 ++- trio/_util.py | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/trio/_tests/type_tests/check_wraps.py b/trio/_tests/type_tests/check_wraps.py index 5692738be4..456aa3dffb 100644 --- a/trio/_tests/type_tests/check_wraps.py +++ b/trio/_tests/type_tests/check_wraps.py @@ -1,8 +1,9 @@ # https://github.com/python-trio/trio/issues/2775#issuecomment-1702267589 # (except platform independent...) -import trio import typing_extensions +import trio + async def fn(s: trio.SocketStream) -> None: result = await s.socket.sendto(b"a", "h") diff --git a/trio/_util.py b/trio/_util.py index 5fb798c04d..36020ca2d7 100644 --- a/trio/_util.py +++ b/trio/_util.py @@ -390,9 +390,10 @@ def name_asyncgen(agen: AsyncGeneratorType[object, t.NoReturn]) -> str: qualname = agen.ag_code.co_name return f"{module}.{qualname}" + # work around a pyright error if t.TYPE_CHECKING: - Fn = TypeVar("Fn", bound=t.Callable[..., object]) + Fn = t.TypeVar("Fn", bound=t.Callable[..., object]) def wraps( wrapped: t.Callable[..., object], @@ -400,5 +401,6 @@ def wraps( updated: t.Sequence[str] = ..., ) -> t.Callable[[Fn], Fn]: ... + else: from functools import wraps # noqa: F401 # this is re-exported From 3d54ac594ab56ff552f6bb6a7c75151b90fb1e0b Mon Sep 17 00:00:00 2001 From: A5rocks Date: Sat, 30 Sep 2023 14:38:16 +0900 Subject: [PATCH 17/18] Fix weird mypy errors --- trio/_core/_run.py | 2 +- trio/_highlevel_open_tcp_stream.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/trio/_core/_run.py b/trio/_core/_run.py index ecef4f4b06..a9faa20589 100644 --- a/trio/_core/_run.py +++ b/trio/_core/_run.py @@ -72,7 +72,7 @@ DEADLINE_HEAP_MIN_PRUNE_THRESHOLD: Final = 1000 # Passed as a sentinel -_NO_SEND: Final = cast("Outcome[Any]", object()) +_NO_SEND: Final["Outcome[Any]"] = cast("Outcome[Any]", object()) FnT = TypeVar("FnT", bound="Callable[..., Any]") StatusT = TypeVar("StatusT") diff --git a/trio/_highlevel_open_tcp_stream.py b/trio/_highlevel_open_tcp_stream.py index c3dc157827..43c0ee2b45 100644 --- a/trio/_highlevel_open_tcp_stream.py +++ b/trio/_highlevel_open_tcp_stream.py @@ -288,7 +288,7 @@ async def open_tcp_stream( reorder_for_rfc_6555_section_5_4(targets) # This list records all the connection failures that we ignored. - oserrors = [] + oserrors: list[OSError] = [] # Keeps track of the socket that we're going to complete with, # need to make sure this isn't automatically closed From 93e7d800757af1c86276fd1455e457cad98110b7 Mon Sep 17 00:00:00 2001 From: EXPLOSION Date: Mon, 2 Oct 2023 21:16:25 -0400 Subject: [PATCH 18/18] Remove redundent mypy run --- check.sh | 4 ---- 1 file changed, 4 deletions(-) diff --git a/check.sh b/check.sh index 7b8cc36ff3..8d14f82fb9 100755 --- a/check.sh +++ b/check.sh @@ -62,10 +62,6 @@ mypy trio --show-error-end --platform darwin | python ./trio/_tools/mypy_annotat || { echo "* Mypy (Mac) found type errors." >> $GITHUB_STEP_SUMMARY; MYPY=1; } mypy trio --show-error-end --platform win32 | python ./trio/_tools/mypy_annotate.py --dumpfile mypy_annotate.dat --platform Windows \ || { echo "* Mypy (Windows) found type errors." >> $GITHUB_STEP_SUMMARY; MYPY=1; } - -# for now, just run interface typing checks on the native platform... -mypy trio/_tests/type_tests --show-error-end | python ./trio/_tools/mypy_annotate.py --dumpfile mypy_annotate.dat --platform Interface \ - || { echo "* Mypy (Interface) found type errors." >> $GITHUB_STEP_SUMMARY; MYPY=1; } set +o pipefail # Re-display errors using Github's syntax, read out of mypy_annotate.dat python ./trio/_tools/mypy_annotate.py --dumpfile mypy_annotate.dat