From 4b2a69fae38aac24f37349c8c8d6ee46df43dd33 Mon Sep 17 00:00:00 2001 From: aatle <168398276+aatle@users.noreply.github.com> Date: Tue, 8 Apr 2025 17:28:40 -0700 Subject: [PATCH 1/4] Add stubs __buffer__ and __release_buffer__ to pygame buffer types --- buildconfig/stubs/pygame/bufferproxy.pyi | 2 ++ buildconfig/stubs/pygame/color.pyi | 1 + buildconfig/stubs/pygame/mask.pyi | 2 ++ buildconfig/stubs/pygame/mixer.pyi | 2 ++ buildconfig/stubs/pygame/pixelarray.pyi | 1 + 5 files changed, 8 insertions(+) diff --git a/buildconfig/stubs/pygame/bufferproxy.pyi b/buildconfig/stubs/pygame/bufferproxy.pyi index 58624cabdb..e9c70346cd 100644 --- a/buildconfig/stubs/pygame/bufferproxy.pyi +++ b/buildconfig/stubs/pygame/bufferproxy.pyi @@ -13,5 +13,7 @@ class BufferProxy: def __array_interface__(self) -> dict[str, Any]: ... @property def __array_struct__(self) -> Any: ... + def __buffer__(self, flags: int, /) -> memoryview[int]: ... + def __release_buffer__(self, view: memoryview[int], /) -> None: ... def __init__(self, parent: Any) -> None: ... # TODO: parent: TypedDict | Protocol def write(self, buffer: bytes, offset: int = 0) -> None: ... diff --git a/buildconfig/stubs/pygame/color.pyi b/buildconfig/stubs/pygame/color.pyi index 127c3225f7..fc11e7f0a1 100644 --- a/buildconfig/stubs/pygame/color.pyi +++ b/buildconfig/stubs/pygame/color.pyi @@ -21,6 +21,7 @@ class Color(Collection[int]): __hash__: ClassVar[None] # type: ignore[assignment] @property def __array_struct__(self) -> Any: ... + def __buffer__(self, flags: int, /) -> memoryview[int]: ... @overload def __init__(self, r: int, g: int, b: int, a: int = 255) -> None: ... @overload diff --git a/buildconfig/stubs/pygame/mask.pyi b/buildconfig/stubs/pygame/mask.pyi index 3dd1b109f2..47ab835330 100644 --- a/buildconfig/stubs/pygame/mask.pyi +++ b/buildconfig/stubs/pygame/mask.pyi @@ -53,6 +53,8 @@ class Mask: unsetcolor: Optional[ColorLike] = (0, 0, 0, 255), dest: Union[RectLike, Point] = (0, 0), ) -> Surface: ... + def __buffer__(self, flags: int, /) -> memoryview[int]: ... + def __release_buffer__(self, view: memoryview[int], /) -> None: ... @deprecated("Use `Mask` instead (MaskType is an old alias)") class MaskType(Mask): ... diff --git a/buildconfig/stubs/pygame/mixer.pyi b/buildconfig/stubs/pygame/mixer.pyi index 445b3c77cf..985448f824 100644 --- a/buildconfig/stubs/pygame/mixer.pyi +++ b/buildconfig/stubs/pygame/mixer.pyi @@ -65,6 +65,8 @@ class Sound: def __array_interface__(self) -> dict[str, Any]: ... @property def __array_struct__(self) -> Any: ... + def __buffer__(self, flags: int, /) -> memoryview[int]: ... + def __release_buffer__(self, view: memoryview[int], /) -> None: ... def stop(self) -> None: ... def fadeout(self, time: int, /) -> None: ... def set_volume(self, value: float, /) -> None: ... diff --git a/buildconfig/stubs/pygame/pixelarray.pyi b/buildconfig/stubs/pygame/pixelarray.pyi index 5df752c495..e0a140e6a6 100644 --- a/buildconfig/stubs/pygame/pixelarray.pyi +++ b/buildconfig/stubs/pygame/pixelarray.pyi @@ -31,6 +31,7 @@ class PixelArray: def __array_interface__(self) -> dict[str, Any]: ... @property def __array_struct__(self) -> Any: ... + def __buffer__(self, flags: int, /) -> memoryview[int]: ... def __init__(self, surface: Surface) -> None: ... def __enter__(self) -> PixelArray: ... def __exit__(self, *args, **kwargs) -> None: ... From 41f11ed141c4dda6b5308a894f22bd322f8e8f26 Mon Sep 17 00:00:00 2001 From: aatle <168398276+aatle@users.noreply.github.com> Date: Tue, 8 Apr 2025 17:49:03 -0700 Subject: [PATCH 2/4] Fix Bufferyproxy.write stub buffer arg --- buildconfig/stubs/pygame/bufferproxy.pyi | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/buildconfig/stubs/pygame/bufferproxy.pyi b/buildconfig/stubs/pygame/bufferproxy.pyi index e9c70346cd..337a9ac7a5 100644 --- a/buildconfig/stubs/pygame/bufferproxy.pyi +++ b/buildconfig/stubs/pygame/bufferproxy.pyi @@ -16,4 +16,8 @@ class BufferProxy: def __buffer__(self, flags: int, /) -> memoryview[int]: ... def __release_buffer__(self, view: memoryview[int], /) -> None: ... def __init__(self, parent: Any) -> None: ... # TODO: parent: TypedDict | Protocol - def write(self, buffer: bytes, offset: int = 0) -> None: ... + def write( + self, + buffer: str | bytes, # See https://docs.python.org/3/c-api/arg.html at s# + offset: int = 0, + ) -> None: ... From 19ee3d4fe46b9764ed0a9e76dbba8decb12c0a09 Mon Sep 17 00:00:00 2001 From: aatle <168398276+aatle@users.noreply.github.com> Date: Tue, 8 Apr 2025 17:54:14 -0700 Subject: [PATCH 3/4] Use typing_extensions.Buffer in stubs --- buildconfig/stubs/pygame/image.pyi | 8 +++++--- buildconfig/stubs/pygame/mixer.pyi | 14 +++++--------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/buildconfig/stubs/pygame/image.pyi b/buildconfig/stubs/pygame/image.pyi index 599ae07cb9..db44a8c4ea 100644 --- a/buildconfig/stubs/pygame/image.pyi +++ b/buildconfig/stubs/pygame/image.pyi @@ -3,9 +3,11 @@ from typing import Literal, Optional, Union from pygame.bufferproxy import BufferProxy from pygame.surface import Surface from pygame.typing import FileLike, IntPoint, Point -from typing_extensions import deprecated # added in 3.13 +from typing_extensions import ( + Buffer, # collections.abc 3.12 + deprecated, # added in 3.13 +) -_BufferLike = Union[BufferProxy, bytes, bytearray, memoryview] _from_buffer_format = Literal["P", "RGB", "BGR", "BGRA", "RGBX", "RGBA", "ARGB"] _to_bytes_format = Literal[ "P", "RGB", "RGBX", "RGBA", "ARGB", "BGRA", "ABGR", "RGBA_PREMULT", "ARGB_PREMULT" @@ -47,7 +49,7 @@ def frombytes( pitch: int = -1, ) -> Surface: ... def frombuffer( - buffer: _BufferLike, + buffer: Buffer, size: IntPoint, format: _from_buffer_format, pitch: int = -1, diff --git a/buildconfig/stubs/pygame/mixer.pyi b/buildconfig/stubs/pygame/mixer.pyi index 985448f824..658f09cf9c 100644 --- a/buildconfig/stubs/pygame/mixer.pyi +++ b/buildconfig/stubs/pygame/mixer.pyi @@ -1,9 +1,11 @@ from typing import Any, Optional, Union, overload -import numpy from pygame.event import Event from pygame.typing import FileLike -from typing_extensions import deprecated # added in 3.13 +from typing_extensions import ( + Buffer, # collections.abc 3.12 + deprecated, # added in 3.13 +) from . import mixer_music @@ -46,13 +48,7 @@ class Sound: @overload def __init__(self, file: FileLike) -> None: ... @overload - def __init__( - self, buffer: Any - ) -> None: ... # Buffer protocol is still not implemented in typing - @overload - def __init__( - self, array: numpy.ndarray - ) -> None: ... # Buffer protocol is still not implemented in typing + def __init__(self, buffer: Buffer) -> None: ... def play( self, loops: int = 0, From d3a44071b6f9b8fd0cfed4e92636dbcfb0757444 Mon Sep 17 00:00:00 2001 From: aatle <168398276+aatle@users.noreply.github.com> Date: Thu, 10 Apr 2025 13:06:08 -0700 Subject: [PATCH 4/4] Add version conditional to __buffer__ methods in stubs --- buildconfig/stubs/pygame/bufferproxy.pyi | 6 ++++-- buildconfig/stubs/pygame/color.pyi | 4 +++- buildconfig/stubs/pygame/mask.pyi | 6 ++++-- buildconfig/stubs/pygame/mixer.pyi | 6 ++++-- buildconfig/stubs/pygame/pixelarray.pyi | 3 ++- 5 files changed, 17 insertions(+), 8 deletions(-) diff --git a/buildconfig/stubs/pygame/bufferproxy.pyi b/buildconfig/stubs/pygame/bufferproxy.pyi index 337a9ac7a5..3275ffac53 100644 --- a/buildconfig/stubs/pygame/bufferproxy.pyi +++ b/buildconfig/stubs/pygame/bufferproxy.pyi @@ -1,3 +1,4 @@ +import sys from typing import Any class BufferProxy: @@ -13,8 +14,9 @@ class BufferProxy: def __array_interface__(self) -> dict[str, Any]: ... @property def __array_struct__(self) -> Any: ... - def __buffer__(self, flags: int, /) -> memoryview[int]: ... - def __release_buffer__(self, view: memoryview[int], /) -> None: ... + if sys.version_info >= (3, 12): + def __buffer__(self, flags: int, /) -> memoryview[int]: ... + def __release_buffer__(self, view: memoryview[int], /) -> None: ... def __init__(self, parent: Any) -> None: ... # TODO: parent: TypedDict | Protocol def write( self, diff --git a/buildconfig/stubs/pygame/color.pyi b/buildconfig/stubs/pygame/color.pyi index fc11e7f0a1..ab3560971c 100644 --- a/buildconfig/stubs/pygame/color.pyi +++ b/buildconfig/stubs/pygame/color.pyi @@ -1,3 +1,4 @@ +import sys from collections.abc import Collection, Iterator from typing import Any, ClassVar, SupportsIndex, Union, overload @@ -21,7 +22,8 @@ class Color(Collection[int]): __hash__: ClassVar[None] # type: ignore[assignment] @property def __array_struct__(self) -> Any: ... - def __buffer__(self, flags: int, /) -> memoryview[int]: ... + if sys.version_info >= (3, 12): + def __buffer__(self, flags: int, /) -> memoryview[int]: ... @overload def __init__(self, r: int, g: int, b: int, a: int = 255) -> None: ... @overload diff --git a/buildconfig/stubs/pygame/mask.pyi b/buildconfig/stubs/pygame/mask.pyi index 47ab835330..722b9c67cc 100644 --- a/buildconfig/stubs/pygame/mask.pyi +++ b/buildconfig/stubs/pygame/mask.pyi @@ -1,3 +1,4 @@ +import sys from typing import Any, Optional, Union from pygame.rect import Rect @@ -53,8 +54,9 @@ class Mask: unsetcolor: Optional[ColorLike] = (0, 0, 0, 255), dest: Union[RectLike, Point] = (0, 0), ) -> Surface: ... - def __buffer__(self, flags: int, /) -> memoryview[int]: ... - def __release_buffer__(self, view: memoryview[int], /) -> None: ... + if sys.version_info >= (3, 12): + def __buffer__(self, flags: int, /) -> memoryview[int]: ... + def __release_buffer__(self, view: memoryview[int], /) -> None: ... @deprecated("Use `Mask` instead (MaskType is an old alias)") class MaskType(Mask): ... diff --git a/buildconfig/stubs/pygame/mixer.pyi b/buildconfig/stubs/pygame/mixer.pyi index 658f09cf9c..555375c1fd 100644 --- a/buildconfig/stubs/pygame/mixer.pyi +++ b/buildconfig/stubs/pygame/mixer.pyi @@ -1,3 +1,4 @@ +import sys from typing import Any, Optional, Union, overload from pygame.event import Event @@ -61,8 +62,9 @@ class Sound: def __array_interface__(self) -> dict[str, Any]: ... @property def __array_struct__(self) -> Any: ... - def __buffer__(self, flags: int, /) -> memoryview[int]: ... - def __release_buffer__(self, view: memoryview[int], /) -> None: ... + if sys.version_info >= (3, 12): + def __buffer__(self, flags: int, /) -> memoryview[int]: ... + def __release_buffer__(self, view: memoryview[int], /) -> None: ... def stop(self) -> None: ... def fadeout(self, time: int, /) -> None: ... def set_volume(self, value: float, /) -> None: ... diff --git a/buildconfig/stubs/pygame/pixelarray.pyi b/buildconfig/stubs/pygame/pixelarray.pyi index e0a140e6a6..c51e2fe1a4 100644 --- a/buildconfig/stubs/pygame/pixelarray.pyi +++ b/buildconfig/stubs/pygame/pixelarray.pyi @@ -31,7 +31,8 @@ class PixelArray: def __array_interface__(self) -> dict[str, Any]: ... @property def __array_struct__(self) -> Any: ... - def __buffer__(self, flags: int, /) -> memoryview[int]: ... + if sys.version_info >= (3, 12): + def __buffer__(self, flags: int, /) -> memoryview[int]: ... def __init__(self, surface: Surface) -> None: ... def __enter__(self) -> PixelArray: ... def __exit__(self, *args, **kwargs) -> None: ...