From 80502bf0365eeacef112499069572df8170ecf63 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Mon, 21 Oct 2024 14:09:03 -0500 Subject: [PATCH] Fix typing issues around Range/RangeValue MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In order for the `_RangeValue` protocol to type check properly, it needs to reference `Self`, not itself. Both pyright and mypy show a ton of errors when type checking this before these changes. (I've omitted non-relevant errors here): ``` % pyright tests/test_types.py /Users/dmcgee/projects/sbl/asyncpg/tests/test_types.py /Users/dmcgee/projects/sbl/asyncpg/tests/test_types.py:18:25 - error: Argument of type "Literal[1]" cannot be assigned to parameter "lower" of type "_RV@Range | None" in function "__init__"   Type "Literal[1]" is not assignable to type "_RV@Range | None"     Type "Literal[1]" is not assignable to type "_RangeValue"       "Literal[1]" is incompatible with protocol "_RangeValue"         "__lt__" is an incompatible type           Type "(value: int, /) -> bool" is not assignable to type "(__other: _RV@__lt__, /) -> bool"         "__gt__" is an incompatible type           Type "(value: int, /) -> bool" is not assignable to type "(__other: _RV@__gt__, /) -> bool"     "Literal[1]" is not assignable to "None" (reportArgumentType) /Users/dmcgee/projects/sbl/asyncpg/tests/test_types.py:18:34 - error: Argument of type "Literal[5]" cannot be assigned to parameter "upper" of type "_RV@Range | None" in function "__init__"   Type "Literal[5]" is not assignable to type "_RV@Range | None"     Type "Literal[5]" is not assignable to type "_RangeValue"       "Literal[5]" is incompatible with protocol "_RangeValue"         "__lt__" is an incompatible type           Type "(value: int, /) -> bool" is not assignable to type "(__other: _RV@__lt__, /) -> bool"         "__gt__" is an incompatible type           Type "(value: int, /) -> bool" is not assignable to type "(__other: _RV@__gt__, /) -> bool"     "Literal[5]" is not assignable to "None" (reportArgumentType) ... % mypy tests/test_types.py | grep arg-type tests/test_types.py:18: error: Argument "lower" to "Range" has incompatible type "int"; expected "None" [arg-type] tests/test_types.py:18: error: Argument "upper" to "Range" has incompatible type "int"; expected "None" [arg-type] ... (19 more errors) ``` After this change, the type checking comes back clean: ``` % pyright tests/test_types.py 0 errors, 0 warnings, 0 informations % mypy tests/test_types.py | grep arg-type ``` --- asyncpg/types.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/asyncpg/types.py b/asyncpg/types.py index 7a24e24c..c4b66b4a 100644 --- a/asyncpg/types.py +++ b/asyncpg/types.py @@ -63,10 +63,10 @@ class _RangeValue(typing.Protocol): def __eq__(self, __value: object) -> bool: ... - def __lt__(self, __other: _RangeValue) -> bool: + def __lt__(self, __other: Self, /) -> bool: ... - def __gt__(self, __other: _RangeValue) -> bool: + def __gt__(self, __other: Self, /) -> bool: ...