From c1e1fe808fb7d23167081d8515db027b4a19faa4 Mon Sep 17 00:00:00 2001 From: Maxwell Muoto <41130755+max-muoto@users.noreply.github.com> Date: Sun, 30 Jun 2024 21:32:32 -0500 Subject: [PATCH 01/11] Make MemoryView generic --- stdlib/builtins.pyi | 51 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 5 deletions(-) diff --git a/stdlib/builtins.pyi b/stdlib/builtins.pyi index ef5d7f305eb9..8c56446370fe 100644 --- a/stdlib/builtins.pyi +++ b/stdlib/builtins.pyi @@ -51,7 +51,6 @@ from typing import ( # noqa: Y022 SupportsComplex, SupportsFloat, SupportsIndex, - TypeVar, final, overload, type_check_only, @@ -67,6 +66,7 @@ from typing_extensions import ( # noqa: Y023 TypeAlias, TypeGuard, TypeIs, + TypeVar, TypeVarTuple, deprecated, ) @@ -75,6 +75,7 @@ if sys.version_info >= (3, 9): from types import GenericAlias _T = TypeVar("_T") +_I = TypeVar("_I", default=int) _T_co = TypeVar("_T_co", covariant=True) _T_contra = TypeVar("_T_contra", contravariant=True) _R_co = TypeVar("_R_co", covariant=True) @@ -823,8 +824,38 @@ class bytearray(MutableSequence[int]): def __buffer__(self, flags: int, /) -> memoryview: ... def __release_buffer__(self, buffer: memoryview, /) -> None: ... +_IntegerFormats: TypeAlias = Literal[ + "b", + "B", + "@b", + "@B", + "h", + "H", + "@h", + "@H", + "i", + "I", + "@i", + "@I", + "l", + "L", + "@l", + "@L", + "q", + "Q", + "@q", + "@Q", + "P", + "@P", + "q", + "Q", + "@q", + "@Q", +] +_FloatFormats: TypeAlias = Literal["f", "F", "@f", "@F", "d", "D", "@d"] + @final -class memoryview(Sequence[int]): +class memoryview(Sequence[_I]): @property def format(self) -> str: ... @property @@ -854,13 +885,23 @@ class memoryview(Sequence[int]): def __exit__( self, exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: TracebackType | None, / ) -> None: ... + @overload + def cast(self, format: Literal["c", "@c"], shape: list[int] | tuple[int, ...] = ...) -> memoryview[bytes]: ... + @overload + def cast(self, format: _FloatFormats, shape: list[int] | tuple[int, ...] = ...) -> memoryview[float]: ... + @overload + def cast(self, format: Literal["?"], shape: list[int] | tuple[int, ...] = ...) -> memoryview[bool]: ... + @overload + def cast(self, format: _IntegerFormats, shape: list[int] | tuple[int, ...] = ...) -> memoryview: ... + # Fallback to ensure backwards compatability. + @overload def cast(self, format: str, shape: list[int] | tuple[int, ...] = ...) -> memoryview: ... @overload - def __getitem__(self, key: SupportsIndex | tuple[SupportsIndex, ...], /) -> int: ... + def __getitem__(self, key: SupportsIndex | tuple[SupportsIndex, ...], /) -> _I: ... @overload - def __getitem__(self, key: slice, /) -> memoryview: ... + def __getitem__(self, key: slice, /) -> memoryview[_I]: ... def __contains__(self, x: object, /) -> bool: ... - def __iter__(self) -> Iterator[int]: ... + def __iter__(self) -> Iterator[_I]: ... def __len__(self) -> int: ... def __eq__(self, value: object, /) -> bool: ... def __hash__(self) -> int: ... From 2ab244f312f3f6cb316ebde7601ba30400406eab Mon Sep 17 00:00:00 2001 From: Maxwell Muoto <41130755+max-muoto@users.noreply.github.com> Date: Sun, 30 Jun 2024 21:49:52 -0500 Subject: [PATCH 02/11] Remove fallback --- stdlib/builtins.pyi | 3 --- 1 file changed, 3 deletions(-) diff --git a/stdlib/builtins.pyi b/stdlib/builtins.pyi index 8c56446370fe..0631cb518854 100644 --- a/stdlib/builtins.pyi +++ b/stdlib/builtins.pyi @@ -893,9 +893,6 @@ class memoryview(Sequence[_I]): def cast(self, format: Literal["?"], shape: list[int] | tuple[int, ...] = ...) -> memoryview[bool]: ... @overload def cast(self, format: _IntegerFormats, shape: list[int] | tuple[int, ...] = ...) -> memoryview: ... - # Fallback to ensure backwards compatability. - @overload - def cast(self, format: str, shape: list[int] | tuple[int, ...] = ...) -> memoryview: ... @overload def __getitem__(self, key: SupportsIndex | tuple[SupportsIndex, ...], /) -> _I: ... @overload From 324958d821870493f6ed4421c774d781ce3bbaae Mon Sep 17 00:00:00 2001 From: Maxwell Muoto <41130755+max-muoto@users.noreply.github.com> Date: Sun, 30 Jun 2024 21:50:36 -0500 Subject: [PATCH 03/11] Explicit --- stdlib/builtins.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/builtins.pyi b/stdlib/builtins.pyi index 0631cb518854..e2ee09ad4ced 100644 --- a/stdlib/builtins.pyi +++ b/stdlib/builtins.pyi @@ -892,7 +892,7 @@ class memoryview(Sequence[_I]): @overload def cast(self, format: Literal["?"], shape: list[int] | tuple[int, ...] = ...) -> memoryview[bool]: ... @overload - def cast(self, format: _IntegerFormats, shape: list[int] | tuple[int, ...] = ...) -> memoryview: ... + def cast(self, format: _IntegerFormats, shape: list[int] | tuple[int, ...] = ...) -> memoryview[int]: ... @overload def __getitem__(self, key: SupportsIndex | tuple[SupportsIndex, ...], /) -> _I: ... @overload From 0c1a4c346ec241dfe75660f30107eec06416e861 Mon Sep 17 00:00:00 2001 From: Maxwell Muoto <41130755+max-muoto@users.noreply.github.com> Date: Sun, 30 Jun 2024 22:01:15 -0500 Subject: [PATCH 04/11] Fix --- stdlib/builtins.pyi | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/stdlib/builtins.pyi b/stdlib/builtins.pyi index e2ee09ad4ced..7e3d041aad97 100644 --- a/stdlib/builtins.pyi +++ b/stdlib/builtins.pyi @@ -847,10 +847,6 @@ _IntegerFormats: TypeAlias = Literal[ "@Q", "P", "@P", - "q", - "Q", - "@q", - "@Q", ] _FloatFormats: TypeAlias = Literal["f", "F", "@f", "@F", "d", "D", "@d"] @@ -892,7 +888,7 @@ class memoryview(Sequence[_I]): @overload def cast(self, format: Literal["?"], shape: list[int] | tuple[int, ...] = ...) -> memoryview[bool]: ... @overload - def cast(self, format: _IntegerFormats, shape: list[int] | tuple[int, ...] = ...) -> memoryview[int]: ... + def cast(self, format: _IntegerFormats, shape: list[int] | tuple[int, ...] = ...) -> memoryview: ... @overload def __getitem__(self, key: SupportsIndex | tuple[SupportsIndex, ...], /) -> _I: ... @overload From f0f890e020f33aa6bf50e3a29ee1e764c3afa7d2 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 03:02:52 +0000 Subject: [PATCH 05/11] [pre-commit.ci] auto fixes from pre-commit.com hooks --- stdlib/builtins.pyi | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/stdlib/builtins.pyi b/stdlib/builtins.pyi index 7e3d041aad97..49196f4e4f09 100644 --- a/stdlib/builtins.pyi +++ b/stdlib/builtins.pyi @@ -825,28 +825,7 @@ class bytearray(MutableSequence[int]): def __release_buffer__(self, buffer: memoryview, /) -> None: ... _IntegerFormats: TypeAlias = Literal[ - "b", - "B", - "@b", - "@B", - "h", - "H", - "@h", - "@H", - "i", - "I", - "@i", - "@I", - "l", - "L", - "@l", - "@L", - "q", - "Q", - "@q", - "@Q", - "P", - "@P", + "b", "B", "@b", "@B", "h", "H", "@h", "@H", "i", "I", "@i", "@I", "l", "L", "@l", "@L", "q", "Q", "@q", "@Q", "P", "@P" ] _FloatFormats: TypeAlias = Literal["f", "F", "@f", "@F", "d", "D", "@d"] From a12b494acd646a42322c914e9b4107e5a6b0fa3b Mon Sep 17 00:00:00 2001 From: Maxwell Muoto <41130755+max-muoto@users.noreply.github.com> Date: Sun, 30 Jun 2024 22:08:58 -0500 Subject: [PATCH 06/11] Tweak? --- stdlib/builtins.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/builtins.pyi b/stdlib/builtins.pyi index 49196f4e4f09..0f6ff41fbf28 100644 --- a/stdlib/builtins.pyi +++ b/stdlib/builtins.pyi @@ -51,6 +51,7 @@ from typing import ( # noqa: Y022 SupportsComplex, SupportsFloat, SupportsIndex, + TypeVar, final, overload, type_check_only, @@ -66,7 +67,6 @@ from typing_extensions import ( # noqa: Y023 TypeAlias, TypeGuard, TypeIs, - TypeVar, TypeVarTuple, deprecated, ) From 2f53e1af834a4e7b3c7eb20f2451615c5c6addae Mon Sep 17 00:00:00 2001 From: Maxwell Muoto <41130755+max-muoto@users.noreply.github.com> Date: Sun, 30 Jun 2024 22:19:35 -0500 Subject: [PATCH 07/11] Add tests --- .../test_cases/builtins/check_memoryview.py | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 stdlib/@tests/test_cases/builtins/check_memoryview.py diff --git a/stdlib/@tests/test_cases/builtins/check_memoryview.py b/stdlib/@tests/test_cases/builtins/check_memoryview.py new file mode 100644 index 000000000000..1c28846aa29e --- /dev/null +++ b/stdlib/@tests/test_cases/builtins/check_memoryview.py @@ -0,0 +1,54 @@ +from __future__ import annotations +import array +from typing_extensions import assert_type + + +# Castying to bytes. +buf = b"abcdefg" +view = memoryview(buf).cast("c") +elm = view[0] +assert_type(elm, bytes) +assert_type(view[0:2], memoryview[bytes]) + +# Casting to a bool. +a = array.array("B", [0, 1, 2, 3]) +mv = memoryview(a) +bool_mv = mv.cast("?") +assert_type(bool_mv[0], bool) +assert_type(bool_mv[0:2], memoryview[bool]) + + +# Casting to a signed char. +a = array.array("B", [0, 1, 2, 3]) +mv = memoryview(a) +signed_mv = mv.cast("b") +assert_type(signed_mv[0], int) +assert_type(signed_mv[0:2], memoryview[int]) + +# Casting to a signed short. +a = array.array("B", [0, 1, 2, 3]) +mv = memoryview(a) +signed_mv = mv.cast("h") +assert_type(signed_mv[0], int) +assert_type(signed_mv[0:2], memoryview[int]) + +# Casting to a signed int. +a = array.array("B", [0, 1, 2, 3]) +mv = memoryview(a) +signed_mv = mv.cast("i") +assert_type(signed_mv[0], int) +assert_type(signed_mv[0:2], memoryview[int]) + +# Casting to a signed long. +a = array.array("B", [0, 1, 2, 3]) +mv = memoryview(a) +signed_mv = mv.cast("l") +assert_type(signed_mv[0], int) +assert_type(signed_mv[0:2], memoryview[int]) + +# Casting to a float. +a = array.array("B", [0, 1, 2, 3]) +mv = memoryview(a) +float_mv = mv.cast("f") +assert_type(float_mv[0], float) +assert_type(float_mv[0:2], memoryview[float]) From 4a5d91711039679be0e6d8057e7d80a6e8ce155b Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 03:21:11 +0000 Subject: [PATCH 08/11] [pre-commit.ci] auto fixes from pre-commit.com hooks --- stdlib/@tests/test_cases/builtins/check_memoryview.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/@tests/test_cases/builtins/check_memoryview.py b/stdlib/@tests/test_cases/builtins/check_memoryview.py index 1c28846aa29e..f0400faaeaa7 100644 --- a/stdlib/@tests/test_cases/builtins/check_memoryview.py +++ b/stdlib/@tests/test_cases/builtins/check_memoryview.py @@ -1,8 +1,8 @@ from __future__ import annotations + import array from typing_extensions import assert_type - # Castying to bytes. buf = b"abcdefg" view = memoryview(buf).cast("c") From 1960c196cd539e965d37fb06d6690de648c8e65b Mon Sep 17 00:00:00 2001 From: Maxwell Muoto <41130755+max-muoto@users.noreply.github.com> Date: Sun, 30 Jun 2024 22:29:07 -0500 Subject: [PATCH 09/11] Fix float formats --- stdlib/builtins.pyi | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/stdlib/builtins.pyi b/stdlib/builtins.pyi index 0f6ff41fbf28..c128ec6fd704 100644 --- a/stdlib/builtins.pyi +++ b/stdlib/builtins.pyi @@ -827,7 +827,6 @@ class bytearray(MutableSequence[int]): _IntegerFormats: TypeAlias = Literal[ "b", "B", "@b", "@B", "h", "H", "@h", "@H", "i", "I", "@i", "@I", "l", "L", "@l", "@L", "q", "Q", "@q", "@Q", "P", "@P" ] -_FloatFormats: TypeAlias = Literal["f", "F", "@f", "@F", "d", "D", "@d"] @final class memoryview(Sequence[_I]): @@ -863,7 +862,7 @@ class memoryview(Sequence[_I]): @overload def cast(self, format: Literal["c", "@c"], shape: list[int] | tuple[int, ...] = ...) -> memoryview[bytes]: ... @overload - def cast(self, format: _FloatFormats, shape: list[int] | tuple[int, ...] = ...) -> memoryview[float]: ... + def cast(self, format: Literal["f", "@f", "d", "@d"], shape: list[int] | tuple[int, ...] = ...) -> memoryview[float]: ... @overload def cast(self, format: Literal["?"], shape: list[int] | tuple[int, ...] = ...) -> memoryview[bool]: ... @overload From f01fc40e23223960bb4d017ff34643c2539f9e4f Mon Sep 17 00:00:00 2001 From: Maxwell Muoto <41130755+max-muoto@users.noreply.github.com> Date: Sun, 30 Jun 2024 22:30:43 -0500 Subject: [PATCH 10/11] Add test case --- stdlib/@tests/test_cases/builtins/check_memoryview.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/stdlib/@tests/test_cases/builtins/check_memoryview.py b/stdlib/@tests/test_cases/builtins/check_memoryview.py index f0400faaeaa7..45216c236db4 100644 --- a/stdlib/@tests/test_cases/builtins/check_memoryview.py +++ b/stdlib/@tests/test_cases/builtins/check_memoryview.py @@ -52,3 +52,7 @@ float_mv = mv.cast("f") assert_type(float_mv[0], float) assert_type(float_mv[0:2], memoryview[float]) + +# An invalid literal should raise an error. +mv = memoryview(b"abc") +mv.cast("abc") # type: ignore From ba70c571cbb4d11a0db94da2a77ac4a8bc6ca887 Mon Sep 17 00:00:00 2001 From: Maxwell Muoto <41130755+max-muoto@users.noreply.github.com> Date: Sun, 30 Jun 2024 22:43:10 -0500 Subject: [PATCH 11/11] Grammar --- stdlib/@tests/test_cases/builtins/check_memoryview.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/@tests/test_cases/builtins/check_memoryview.py b/stdlib/@tests/test_cases/builtins/check_memoryview.py index 45216c236db4..108fc8395cc7 100644 --- a/stdlib/@tests/test_cases/builtins/check_memoryview.py +++ b/stdlib/@tests/test_cases/builtins/check_memoryview.py @@ -3,7 +3,7 @@ import array from typing_extensions import assert_type -# Castying to bytes. +# Casting to bytes. buf = b"abcdefg" view = memoryview(buf).cast("c") elm = view[0]