From ff4df777d63d6db2fb34f16a8b1f5dec79c21954 Mon Sep 17 00:00:00 2001 From: Damiano Ricciardi Date: Tue, 16 Jul 2024 19:28:53 +0200 Subject: [PATCH 01/18] Add pygame.typing --- buildconfig/stubs/gen_stubs.py | 5 ++ buildconfig/stubs/mypy_allow_list.txt | 4 - buildconfig/stubs/pygame/__init__.pyi | 1 + buildconfig/stubs/pygame/_common.pyi | 101 ----------------------- buildconfig/stubs/pygame/_sdl2/video.pyi | 70 ++++++++-------- buildconfig/stubs/pygame/camera.pyi | 4 +- buildconfig/stubs/pygame/color.pyi | 8 +- buildconfig/stubs/pygame/cursors.pyi | 20 ++--- buildconfig/stubs/pygame/display.pyi | 36 ++++---- buildconfig/stubs/pygame/draw.pyi | 48 +++++------ buildconfig/stubs/pygame/event.pyi | 4 +- buildconfig/stubs/pygame/font.pyi | 8 +- buildconfig/stubs/pygame/freetype.pyi | 20 ++--- buildconfig/stubs/pygame/geometry.pyi | 29 ++++--- buildconfig/stubs/pygame/gfxdraw.pyi | 46 +++++------ buildconfig/stubs/pygame/image.pyi | 20 ++--- buildconfig/stubs/pygame/key.pyi | 4 +- buildconfig/stubs/pygame/mask.pyi | 34 ++++---- buildconfig/stubs/pygame/math.pyi | 68 +++++++-------- buildconfig/stubs/pygame/midi.pyi | 4 +- buildconfig/stubs/pygame/mixer.pyi | 4 +- buildconfig/stubs/pygame/mixer_music.pyi | 8 +- buildconfig/stubs/pygame/mouse.pyi | 14 ++-- buildconfig/stubs/pygame/pixelarray.pyi | 14 ++-- buildconfig/stubs/pygame/rect.pyi | 100 +++++++++++----------- buildconfig/stubs/pygame/rwobject.pyi | 6 +- buildconfig/stubs/pygame/sprite.pyi | 8 +- buildconfig/stubs/pygame/surface.pyi | 70 ++++++++-------- buildconfig/stubs/pygame/transform.pyi | 22 ++--- buildconfig/stubs/pygame/typing.pyi | 31 +++++++ buildconfig/stubs/pygame/window.pyi | 16 ++-- src_py/meson.build | 1 + src_py/typing.py | 31 +++++++ 33 files changed, 411 insertions(+), 448 deletions(-) delete mode 100644 buildconfig/stubs/pygame/_common.pyi create mode 100644 buildconfig/stubs/pygame/typing.pyi create mode 100644 src_py/typing.py diff --git a/buildconfig/stubs/gen_stubs.py b/buildconfig/stubs/gen_stubs.py index 670db2f951..92d0099d38 100644 --- a/buildconfig/stubs/gen_stubs.py +++ b/buildconfig/stubs/gen_stubs.py @@ -4,6 +4,7 @@ """ import pathlib +import shutil from typing import Any import pygame.constants @@ -51,6 +52,7 @@ "system", "geometry", "window", + "typing", ] # pygame classes that are autoimported into main namespace are kept in this dict @@ -151,3 +153,6 @@ def get_all(mod: Any): for element in get_all(pygame.locals): constant_type = getattr(pygame.locals, element).__class__.__name__ f.write(f"{element}: {constant_type}\n") + +# copy typing.py to typing.pyi for type checkers +shutil.copyfile("src_py/typing.py", "buildconfig/stubs/pygame/typing.pyi") diff --git a/buildconfig/stubs/mypy_allow_list.txt b/buildconfig/stubs/mypy_allow_list.txt index c6f3ffa15b..4f2ef7834d 100644 --- a/buildconfig/stubs/mypy_allow_list.txt +++ b/buildconfig/stubs/mypy_allow_list.txt @@ -2,10 +2,6 @@ # listed here are not checked by the mypy stubtest program # This allowlist supports regex -# This is not a real typestub file, it is used only in the typestubs to export -# a few utility typestub definitions -pygame\._common - # cython files have this top level dunder pygame\._sdl2\..*\.__test__ diff --git a/buildconfig/stubs/pygame/__init__.pyi b/buildconfig/stubs/pygame/__init__.pyi index c05a428fb4..570a6e0b5e 100644 --- a/buildconfig/stubs/pygame/__init__.pyi +++ b/buildconfig/stubs/pygame/__init__.pyi @@ -38,6 +38,7 @@ from pygame import ( system as system, geometry as geometry, window as window, + typing as typing, ) from .rect import Rect as Rect, FRect as FRect diff --git a/buildconfig/stubs/pygame/_common.pyi b/buildconfig/stubs/pygame/_common.pyi deleted file mode 100644 index 0fba00a0bf..0000000000 --- a/buildconfig/stubs/pygame/_common.pyi +++ /dev/null @@ -1,101 +0,0 @@ -from os import PathLike -from typing import IO, Callable, Tuple, Union, TypeVar, Protocol, SupportsIndex - -# For functions that take a file name -AnyPath = Union[str, bytes, PathLike[str], PathLike[bytes]] - -# Most pygame functions that take a file argument should be able to handle -# a FileArg type -FileArg = Union[AnyPath, IO[bytes], IO[str]] - -_T = TypeVar("_T", covariant=True) - -class Sequence(Protocol[_T]): - """ - This is different from the standard python 'Sequence' abc. This is used in places - where only __getitem__ and __len__ is actually needed (basically almost all places - where a sequence is used). The standard 'Sequence' abc has some extra methods. - """ - def __getitem__(self, __i: SupportsIndex) -> _T: ... - def __len__(self) -> int: ... - -# Right now, it isn't possible to annotate sizes (popular tools don't support it) but -# when it is, the below types should be appropriately annotated - -# Yes, float. The reason being, pygame handles float without erroring in a lot of places -# where a coordinate is expected (usually by rounding to int). -# Also, 'Union[int, float] == float' -Coordinate = Sequence[float] - -# This is used in places where ints are strictly required -IntCoordinate = Sequence[int] - -# This typehint is used when a function would return an RGBA tuple -RGBAOutput = Tuple[int, int, int, int] -ColorValue = Union[int, str, Sequence[int]] - -_CanBeRect = Sequence[Union[float, Coordinate]] - -class _HasRectAttribute(Protocol): - # An object that has a rect attribute that is either a rect, or a function - # that returns a rect confirms to the rect protocol - rect: Union[RectValue, Callable[[], RectValue]] - -RectValue = Union[_CanBeRect, _HasRectAttribute] - -""" -# testing code -def a(b: Coordinate): - b[0] - b[1] - len(b) - e1, e2 = b - for i in b: - i -= 1 - - -import numpy -from pygame import Vector2 - -class MyAmoger: - def __init__(self): - pass - - def __getitem__(self, index): - if index not in (0, 1): - raise IndexError() - - return 42 if index else 69 - - def __len__(self): - return 2 - - -# should pass -a([1, 2]) -a([4.2, 5.2]) -a((1, 2)) -a((1.4, 2.8)) -a(MyAmoger()) -a(range(2, 4)) # yes, range object is a 'Sequence' -a(numpy.array([1.3, 2.1])) -a(b"ab") # weird but this actually works in code (this represents (97, 98) btw) -a(bytearray([1, 2])) -a(Vector2()) - -print("Done testing the passes!") - -# should technically error, but right now we can't annotate sizes so they pass on -# type testing -a([1, 2, 3]) -a([4.2, 5.2, 2, 4]) -a((1,)) -a(numpy.array([1.3, 2.1, 4.2])) - -# all of the below should always error -a({}) -a({1: 2}) -a("abc") -a({1, 2}) - -""" diff --git a/buildconfig/stubs/pygame/_sdl2/video.pyi b/buildconfig/stubs/pygame/_sdl2/video.pyi index dd12ae5f80..42bfcb277b 100644 --- a/buildconfig/stubs/pygame/_sdl2/video.pyi +++ b/buildconfig/stubs/pygame/_sdl2/video.pyi @@ -5,7 +5,7 @@ from pygame.rect import Rect from pygame.surface import Surface from pygame.window import Window as Window -from .._common import ColorValue, RectValue, Coordinate +from pygame.typing import ColorLike, RectLike, CoordinateLike WINDOWPOS_UNDEFINED: int WINDOWPOS_CENTERED: int @@ -60,13 +60,13 @@ class Texture: @property def color(self) -> Color: ... @color.setter - def color(self, value: ColorValue) -> None: ... + def color(self, value: ColorLike) -> None: ... def get_rect(self, **kwargs: Any) -> Rect: ... def draw( self, - srcrect: Optional[RectValue] = None, - dstrect: Optional[RectValue] = None, + srcrect: Optional[RectLike] = None, + dstrect: Optional[RectLike] = None, angle: float = 0.0, origin: Optional[Iterable[int]] = None, flip_x: bool = False, @@ -74,42 +74,42 @@ class Texture: ) -> None: ... def draw_triangle( self, - p1_xy: Coordinate, - p2_xy: Coordinate, - p3_xy: Coordinate, - p1_uv: Coordinate = (0.0, 0.0), - p2_uv: Coordinate = (1.0, 1.0), - p3_uv: Coordinate = (0.0, 1.0), + p1_xy: CoordinateLike, + p2_xy: CoordinateLike, + p3_xy: CoordinateLike, + p1_uv: CoordinateLike = (0.0, 0.0), + p2_uv: CoordinateLike = (1.0, 1.0), + p3_uv: CoordinateLike = (0.0, 1.0), p1_mod: Iterable[int] = (255, 255, 255, 255), p2_mod: Iterable[int] = (255, 255, 255, 255), p3_mod: Iterable[int] = (255, 255, 255, 255), ) -> None: ... def draw_quad( self, - p1_xy: Coordinate, - p2_xy: Coordinate, - p3_xy: Coordinate, - p4_xy: Coordinate, - p1_uv: Coordinate = (0.0, 0.0), - p2_uv: Coordinate = (1.0, 0.0), - p3_uv: Coordinate = (1.0, 1.0), - p4_uv: Coordinate = (0.0, 1.0), + p1_xy: CoordinateLike, + p2_xy: CoordinateLike, + p3_xy: CoordinateLike, + p4_xy: CoordinateLike, + p1_uv: CoordinateLike = (0.0, 0.0), + p2_uv: CoordinateLike = (1.0, 0.0), + p3_uv: CoordinateLike = (1.0, 1.0), + p4_uv: CoordinateLike = (0.0, 1.0), p1_mod: Iterable[int] = (255, 255, 255, 255), p2_mod: Iterable[int] = (255, 255, 255, 255), p3_mod: Iterable[int] = (255, 255, 255, 255), p4_mod: Iterable[int] = (255, 255, 255, 255), ) -> None: ... - def update(self, surface: Surface, area: Optional[RectValue] = None) -> None: ... + def update(self, surface: Surface, area: Optional[RectLike] = None) -> None: ... class Image: def __init__( self, texture_or_image: Union[Texture, Image], - srcrect: Optional[RectValue] = None, + srcrect: Optional[RectLike] = None, ) -> None: ... def get_rect(self) -> Rect: ... def draw( - self, srcrect: Optional[RectValue] = None, dstrect: Optional[RectValue] = None + self, srcrect: Optional[RectLike] = None, dstrect: Optional[RectLike] = None ) -> None: ... angle: float origin: Optional[Iterable[float]] @@ -123,7 +123,7 @@ class Image: @property def color(self) -> Color: ... @color.setter - def color(self, value: ColorValue) -> None: ... + def color(self, value: ColorLike) -> None: ... class Renderer: def __init__( @@ -140,39 +140,39 @@ class Renderer: @property def draw_color(self) -> Color: ... @draw_color.setter - def draw_color(self, value: ColorValue) -> None: ... + def draw_color(self, value: ColorLike) -> None: ... def clear(self) -> None: ... def present(self) -> None: ... def get_viewport(self) -> Rect: ... - def set_viewport(self, area: Optional[RectValue]) -> None: ... + def set_viewport(self, area: Optional[RectLike]) -> None: ... logical_size: Iterable[int] scale: Iterable[float] target: Optional[Texture] def blit( self, source: Union[Texture, Image], - dest: Optional[RectValue] = None, - area: Optional[RectValue] = None, + dest: Optional[RectLike] = None, + area: Optional[RectLike] = None, special_flags: int = 0, ) -> Rect: ... - def draw_line(self, p1: Coordinate, p2: Coordinate) -> None: ... - def draw_point(self, point: Coordinate) -> None: ... - def draw_rect(self, rect: RectValue) -> None: ... - def fill_rect(self, rect: RectValue) -> None: ... + def draw_line(self, p1: CoordinateLike, p2: CoordinateLike) -> None: ... + def draw_point(self, point: CoordinateLike) -> None: ... + def draw_rect(self, rect: RectLike) -> None: ... + def fill_rect(self, rect: RectLike) -> None: ... def draw_triangle( - self, p1: Coordinate, p2: Coordinate, p3: Coordinate + self, p1: CoordinateLike, p2: CoordinateLike, p3: CoordinateLike ) -> None: ... def fill_triangle( - self, p1: Coordinate, p2: Coordinate, p3: Coordinate + self, p1: CoordinateLike, p2: CoordinateLike, p3: CoordinateLike ) -> None: ... def draw_quad( - self, p1: Coordinate, p2: Coordinate, p3: Coordinate, p4: Coordinate + self, p1: CoordinateLike, p2: CoordinateLike, p3: CoordinateLike, p4: CoordinateLike ) -> None: ... def fill_quad( - self, p1: Coordinate, p2: Coordinate, p3: Coordinate, p4: Coordinate + self, p1: CoordinateLike, p2: CoordinateLike, p3: CoordinateLike, p4: CoordinateLike ) -> None: ... def to_surface( - self, surface: Optional[Surface] = None, area: Optional[RectValue] = None + self, surface: Optional[Surface] = None, area: Optional[RectLike] = None ) -> Surface: ... @staticmethod def compose_custom_blend_mode( diff --git a/buildconfig/stubs/pygame/camera.pyi b/buildconfig/stubs/pygame/camera.pyi index 5de3a41194..5b481e5e72 100644 --- a/buildconfig/stubs/pygame/camera.pyi +++ b/buildconfig/stubs/pygame/camera.pyi @@ -1,7 +1,7 @@ from abc import ABC, abstractmethod from typing import List, Optional, Tuple, Union, Literal -from ._common import IntCoordinate +from pygame.typing import IntCoordinateLike from pygame.surface import Surface @@ -36,7 +36,7 @@ class Camera(AbstractCamera): def __init__( self, device: Union[str, int] = 0, - size: IntCoordinate = (640, 480), + size: IntCoordinateLike = (640, 480), format: str = "RGB", ) -> None: ... def start(self) -> None: ... diff --git a/buildconfig/stubs/pygame/color.pyi b/buildconfig/stubs/pygame/color.pyi index d9c2ef2ea7..635b05d4ea 100644 --- a/buildconfig/stubs/pygame/color.pyi +++ b/buildconfig/stubs/pygame/color.pyi @@ -2,7 +2,7 @@ import sys from typing import Any, Dict, Iterator, SupportsIndex, Tuple, Union, overload from typing_extensions import deprecated # added in 3.13 -from ._common import ColorValue +from pygame.typing import ColorLike if sys.version_info >= (3, 9): from collections.abc import Collection @@ -28,7 +28,7 @@ class Color(Collection[int]): @overload def __init__(self, r: int, g: int, b: int, a: int = 255) -> None: ... @overload - def __init__(self, rgbvalue: ColorValue) -> None: ... + def __init__(self, rgbvalue: ColorLike) -> None: ... @overload def __getitem__(self, i: SupportsIndex) -> int: ... @overload @@ -82,10 +82,10 @@ class Color(Collection[int]): def correct_gamma(self, gamma: float, /) -> Color: ... @deprecated("since 2.1.3. Use unpacking instead") def set_length(self, length: int, /) -> None: ... - def lerp(self, color: ColorValue, amount: float) -> Color: ... + def lerp(self, color: ColorLike, amount: float) -> Color: ... def premul_alpha(self) -> Color: ... def grayscale(self) -> Color: ... @overload def update(self, r: int, g: int, b: int, a: int = 255, /) -> None: ... @overload - def update(self, rgbvalue: ColorValue, /) -> None: ... + def update(self, rgbvalue: ColorLike, /) -> None: ... diff --git a/buildconfig/stubs/pygame/cursors.pyi b/buildconfig/stubs/pygame/cursors.pyi index 8ab51b003d..d0207fde2b 100644 --- a/buildconfig/stubs/pygame/cursors.pyi +++ b/buildconfig/stubs/pygame/cursors.pyi @@ -2,7 +2,7 @@ from typing import Any, Iterator, Literal, Tuple, Union, overload from pygame.surface import Surface -from ._common import FileArg, IntCoordinate, Sequence +from pygame.typing import FileLike, IntCoordinateLike, SequenceLike _Small_string = Tuple[ str, str, str, str, str, str, str, str, str, str, str, str, str, str, str, str @@ -47,13 +47,13 @@ sizer_xy_strings: _Small_string textmarker_strings: _Small_string def compile( - strings: Sequence[str], + strings: SequenceLike[str], black: str = "X", white: str = ".", xor: str = "o", ) -> Tuple[Tuple[int, ...], Tuple[int, ...]]: ... def load_xbm( - curs: FileArg, mask: FileArg + curs: FileLike, mask: FileLike ) -> Tuple[Tuple[int, int], Tuple[int, int], Tuple[int, ...], Tuple[int, ...]]: ... class Cursor: @@ -64,15 +64,15 @@ class Cursor: @overload def __init__( self, - size: IntCoordinate, - hotspot: IntCoordinate, - xormasks: Sequence[int], - andmasks: Sequence[int], + size: IntCoordinateLike, + hotspot: IntCoordinateLike, + xormasks: SequenceLike[int], + andmasks: SequenceLike[int], ) -> None: ... @overload def __init__( self, - hotspot: IntCoordinate, + hotspot: IntCoordinateLike, surface: Surface, ) -> None: ... def __iter__(self) -> Iterator[Any]: ... @@ -81,11 +81,11 @@ class Cursor: def __hash__(self) -> int: ... def __getitem__( self, index: int - ) -> Union[int, IntCoordinate, Surface]: ... + ) -> Union[int, IntCoordinateLike, Surface]: ... copy = __copy__ type: Literal["system", "color", "bitmap"] data: Union[ Tuple[int], Tuple[Tuple[int, int], Tuple[int, int], Tuple[int, ...], Tuple[int, ...]], - Tuple[IntCoordinate, Surface], + Tuple[IntCoordinateLike, Surface], ] diff --git a/buildconfig/stubs/pygame/display.pyi b/buildconfig/stubs/pygame/display.pyi index 06842fa78e..0c41bc77b6 100644 --- a/buildconfig/stubs/pygame/display.pyi +++ b/buildconfig/stubs/pygame/display.pyi @@ -6,13 +6,13 @@ from pygame.surface import Surface from pygame._sdl2 import Window -from ._common import ( - ColorValue, - Coordinate, - IntCoordinate, - RectValue, - RGBAOutput, - Sequence, +from pygame.typing import ( + ColorLike, + CoordinateLike, + IntCoordinateLike, + RectLike, + RGBALike, + SequenceLike, ) class _VidInfo: @@ -21,9 +21,9 @@ class _VidInfo: video_mem: int bitsize: int bytesize: int - masks: RGBAOutput - shifts: RGBAOutput - losses: RGBAOutput + masks: RGBALike + shifts: RGBALike + losses: RGBALike blit_hw: int blit_hw_CC: int blit_hw_A: int @@ -38,7 +38,7 @@ def init() -> None: ... def quit() -> None: ... def get_init() -> bool: ... def set_mode( - size: Coordinate = (0, 0), + size: CoordinateLike = (0, 0), flags: int = 0, depth: int = 0, display: int = 0, @@ -48,12 +48,12 @@ def get_surface() -> Surface: ... def flip() -> None: ... @overload def update( - rectangle: Optional[Union[RectValue, Sequence[Optional[RectValue]]]] = None, / + rectangle: Optional[Union[RectLike, SequenceLike[Optional[RectLike]]]] = None, / ) -> None: ... @overload def update(x: int, y: int, w: int, h: int, /) -> None: ... @overload -def update(xy: Coordinate, wh: Coordinate, /) -> None: ... +def update(xy: CoordinateLike, wh: CoordinateLike, /) -> None: ... def get_driver() -> str: ... def Info() -> _VidInfo: ... def get_wm_info() -> Dict[str, int]: ... @@ -63,7 +63,7 @@ def list_modes( display: int = 0, ) -> List[Tuple[int, int]]: ... def mode_ok( - size: IntCoordinate, + size: IntCoordinateLike, flags: int = 0, depth: int = 0, display: int = 0, @@ -77,16 +77,16 @@ def toggle_fullscreen() -> int: ... def set_gamma(red: float, green: float = ..., blue: float = ..., /) -> int: ... @deprecated("since 2.1.4. Removed in SDL3") def set_gamma_ramp( - red: Sequence[int], green: Sequence[int], blue: Sequence[int], / + red: SequenceLike[int], green: SequenceLike[int], blue: SequenceLike[int], / ) -> int: ... def set_icon(surface: Surface, /) -> None: ... def set_caption(title: str, icontitle: Optional[str] = None, /) -> None: ... def get_caption() -> Tuple[str, str]: ... -def set_palette(palette: Sequence[ColorValue], /) -> None: ... +def set_palette(palette: SequenceLike[ColorLike], /) -> None: ... def get_num_displays() -> int: ... def get_window_size() -> Tuple[int, int]: ... def get_window_position() -> Tuple[int, int]:... -def set_window_position(position: Coordinate) -> None:... +def set_window_position(position: CoordinateLike) -> None:... def get_allow_screensaver() -> bool: ... def set_allow_screensaver(value: bool = True) -> None: ... def get_desktop_sizes() -> List[Tuple[int, int]]: ... @@ -99,7 +99,7 @@ def message_box( message: Optional[str] = None, message_type: Literal["info", "warn", "error"] = "info", parent_window: Optional[Window] = None, - buttons: Sequence[str] = ("OK",), + buttons: SequenceLike[str] = ("OK",), return_button: int = 0, escape_button: Optional[int] = None, ) -> int: ... diff --git a/buildconfig/stubs/pygame/draw.pyi b/buildconfig/stubs/pygame/draw.pyi index db2c345a4d..80f023f84a 100644 --- a/buildconfig/stubs/pygame/draw.pyi +++ b/buildconfig/stubs/pygame/draw.pyi @@ -2,12 +2,12 @@ from pygame.rect import Rect from pygame.surface import Surface from typing import overload -from ._common import ColorValue, Coordinate, RectValue, Sequence +from pygame.typing import ColorLike, CoordinateLike, RectLike, SequenceLike def rect( surface: Surface, - color: ColorValue, - rect: RectValue, + color: ColorLike, + rect: RectLike, width: int = 0, border_radius: int = -1, border_top_left_radius: int = -1, @@ -17,14 +17,14 @@ def rect( ) -> Rect: ... def polygon( surface: Surface, - color: ColorValue, - points: Sequence[Coordinate], + color: ColorLike, + points: SequenceLike[CoordinateLike], width: int = 0, ) -> Rect: ... def circle( surface: Surface, - color: ColorValue, - center: Coordinate, + color: ColorLike, + center: CoordinateLike, radius: float, width: int = 0, draw_top_right: bool = False, @@ -35,16 +35,16 @@ def circle( @overload def aacircle( surface: Surface, - color: ColorValue, - center: Coordinate, + color: ColorLike, + center: CoordinateLike, radius: float, width: int = 0, ) -> Rect: ... @overload def aacircle( surface: Surface, - color: ColorValue, - center: Coordinate, + color: ColorLike, + center: CoordinateLike, radius: float, width: int = 0, draw_top_right: bool = False, @@ -53,39 +53,39 @@ def aacircle( draw_bottom_right: bool = False, ) -> Rect: ... def ellipse( - surface: Surface, color: ColorValue, rect: RectValue, width: int = 0 + surface: Surface, color: ColorLike, rect: RectLike, width: int = 0 ) -> Rect: ... def arc( surface: Surface, - color: ColorValue, - rect: RectValue, + color: ColorLike, + rect: RectLike, start_angle: float, stop_angle: float, width: int = 1, ) -> Rect: ... def line( surface: Surface, - color: ColorValue, - start_pos: Coordinate, - end_pos: Coordinate, + color: ColorLike, + start_pos: CoordinateLike, + end_pos: CoordinateLike, width: int = 1, ) -> Rect: ... def lines( surface: Surface, - color: ColorValue, + color: ColorLike, closed: bool, - points: Sequence[Coordinate], + points: SequenceLike[CoordinateLike], width: int = 1, ) -> Rect: ... def aaline( surface: Surface, - color: ColorValue, - start_pos: Coordinate, - end_pos: Coordinate, + color: ColorLike, + start_pos: CoordinateLike, + end_pos: CoordinateLike, ) -> Rect: ... def aalines( surface: Surface, - color: ColorValue, + color: ColorLike, closed: bool, - points: Sequence[Coordinate], + points: SequenceLike[CoordinateLike], ) -> Rect: ... diff --git a/buildconfig/stubs/pygame/event.pyi b/buildconfig/stubs/pygame/event.pyi index dc9a1c852f..1987f96de9 100644 --- a/buildconfig/stubs/pygame/event.pyi +++ b/buildconfig/stubs/pygame/event.pyi @@ -7,7 +7,7 @@ from typing import ( final, ) -from ._common import Sequence +from pygame.typing import SequenceLike @final class Event: @@ -23,7 +23,7 @@ class Event: def __delattr__(self, name: str) -> None: ... def __bool__(self) -> bool: ... -_EventTypes = Union[int, Sequence[int]] +_EventTypes = Union[int, SequenceLike[int]] def pump() -> None: ... def get( diff --git a/buildconfig/stubs/pygame/font.pyi b/buildconfig/stubs/pygame/font.pyi index 0312136de1..ea1074cee7 100644 --- a/buildconfig/stubs/pygame/font.pyi +++ b/buildconfig/stubs/pygame/font.pyi @@ -2,7 +2,7 @@ from typing import Callable, Hashable, Iterable, List, Literal, Optional, Tuple, from pygame.surface import Surface -from ._common import ColorValue, FileArg +from pygame.typing import ColorLike, FileLike # TODO: Figure out a way to type this attribute such that mypy knows it's not # always defined at runtime @@ -56,13 +56,13 @@ class Font: def point_size(self) -> int: ... @point_size.setter def point_size(self, value: int) -> None: ... - def __init__(self, filename: Optional[FileArg] = None, size: int = 20) -> None: ... + def __init__(self, filename: Optional[FileLike] = None, size: int = 20) -> None: ... def render( self, text: Union[str, bytes, None], antialias: bool, - color: ColorValue, - bgcolor: Optional[ColorValue] = None, + color: ColorLike, + bgcolor: Optional[ColorLike] = None, wraplength: int = 0, ) -> Surface: ... def size(self, text: Union[str, bytes], /) -> Tuple[int, int]: ... diff --git a/buildconfig/stubs/pygame/freetype.pyi b/buildconfig/stubs/pygame/freetype.pyi index 5f690d3150..8ce24499b8 100644 --- a/buildconfig/stubs/pygame/freetype.pyi +++ b/buildconfig/stubs/pygame/freetype.pyi @@ -5,7 +5,7 @@ from pygame.color import Color from pygame.rect import Rect from pygame.surface import Surface -from ._common import ColorValue, FileArg, RectValue +from pygame.typing import ColorLike, FileLike, RectLike def get_error() -> str: ... def get_version(linked: bool = True) -> Tuple[int, int, int]: ... @@ -123,18 +123,18 @@ class Font: @property def fgcolor(self) -> Color: ... @fgcolor.setter - def fgcolor(self, value: ColorValue) -> None: ... + def fgcolor(self, value: ColorLike) -> None: ... @property def bgcolor(self) -> Color: ... @bgcolor.setter - def bgcolor(self, value: ColorValue) -> None: ... + def bgcolor(self, value: ColorLike) -> None: ... @property def origin(self) -> bool: ... @origin.setter def origin(self, value: bool) -> None: ... def __init__( self, - file: Optional[FileArg], + file: Optional[FileLike], size: float = 0, font_index: int = 0, resolution: int = 0, @@ -158,8 +158,8 @@ class Font: def render( self, text: str, - fgcolor: Optional[ColorValue] = None, - bgcolor: Optional[ColorValue] = None, + fgcolor: Optional[ColorLike] = None, + bgcolor: Optional[ColorLike] = None, style: int = STYLE_DEFAULT, rotation: int = 0, size: float = 0, @@ -167,10 +167,10 @@ class Font: def render_to( self, surf: Surface, - dest: RectValue, + dest: RectLike, text: str, - fgcolor: Optional[ColorValue] = None, - bgcolor: Optional[ColorValue] = None, + fgcolor: Optional[ColorLike] = None, + bgcolor: Optional[ColorLike] = None, style: int = STYLE_DEFAULT, rotation: int = 0, size: float = 0, @@ -187,7 +187,7 @@ class Font: self, array: Any, text: str, - dest: Optional[RectValue] = None, + dest: Optional[RectLike] = None, style: int = STYLE_DEFAULT, rotation: int = 0, size: float = 0, diff --git a/buildconfig/stubs/pygame/geometry.pyi b/buildconfig/stubs/pygame/geometry.pyi index fb7c8de850..05c5881d27 100644 --- a/buildconfig/stubs/pygame/geometry.pyi +++ b/buildconfig/stubs/pygame/geometry.pyi @@ -4,15 +4,14 @@ from typing import ( Callable, Protocol, Tuple, - Sequence, ) from pygame import Rect, FRect -from ._common import Coordinate, RectValue +from pygame.typing import CoordinateLike, RectLike, SequenceLike from .rect import Rect, FRect from .math import Vector2 -_CanBeCircle = Union[Circle, Tuple[Coordinate, float], Sequence[float]] +_CanBeCircle = Union[Circle, Tuple[CoordinateLike, float], SequenceLike[float]] class _HasCirclettribute(Protocol): # An object that has a circle attribute that is either a circle, or a function @@ -20,7 +19,7 @@ class _HasCirclettribute(Protocol): circle: Union[_CanBeCircle, Callable[[], _CanBeCircle]] _CircleValue = Union[_CanBeCircle, _HasCirclettribute] -_CanBeCollided = Union[Circle, Rect, FRect, Coordinate, Vector2] +_CanBeCollided = Union[Circle, Rect, FRect, CoordinateLike, Vector2] class Circle: @property @@ -62,37 +61,37 @@ class Circle: @property def center(self) -> Tuple[float, float]: ... @center.setter - def center(self, value: Coordinate) -> None: ... + def center(self, value: CoordinateLike) -> None: ... @overload def __init__(self, x: float, y: float, r: float) -> None: ... @overload - def __init__(self, pos: Coordinate, r: float) -> None: ... + def __init__(self, pos: CoordinateLike, r: float) -> None: ... @overload def __init__(self, circle: _CircleValue) -> None: ... @overload def move(self, x: float, y: float, /) -> Circle: ... @overload - def move(self, move_by: Coordinate, /) -> Circle: ... + def move(self, move_by: CoordinateLike, /) -> Circle: ... @overload def move_ip(self, x: float, y: float, /) -> None: ... @overload - def move_ip(self, move_by: Coordinate, /) -> None: ... + def move_ip(self, move_by: CoordinateLike, /) -> None: ... @overload def collidepoint(self, x: float, y: float, /) -> bool: ... @overload - def collidepoint(self, point: Coordinate, /) -> bool: ... + def collidepoint(self, point: CoordinateLike, /) -> bool: ... @overload def collidecircle(self, circle: _CircleValue, /) -> bool: ... @overload def collidecircle(self, x: float, y: float, r: float, /) -> bool: ... @overload - def collidecircle(self, center: Coordinate, r: float, /) -> bool: ... + def collidecircle(self, center: CoordinateLike, r: float, /) -> bool: ... @overload - def colliderect(self, rect: RectValue, /) -> bool: ... + def colliderect(self, rect: RectLike, /) -> bool: ... @overload def colliderect(self, x: float, y: float, w: float, h: float, /) -> bool: ... @overload - def colliderect(self, topleft: Coordinate, size: Coordinate, /) -> bool: ... + def colliderect(self, topleft: CoordinateLike, size: CoordinateLike, /) -> bool: ... def collideswith(self, other: _CanBeCollided, /) -> bool: ... def contains(self, shape: _CanBeCollided) -> bool: ... @overload @@ -100,13 +99,13 @@ class Circle: @overload def update(self, x: float, y: float, r: float, /) -> None: ... @overload - def update(self, center: Coordinate, r: float, /) -> None: ... + def update(self, center: CoordinateLike, r: float, /) -> None: ... @overload - def rotate(self, angle: float, rotation_point: Coordinate, /) -> Circle: ... + def rotate(self, angle: float, rotation_point: CoordinateLike, /) -> Circle: ... @overload def rotate(self, angle: float, /) -> Circle: ... @overload - def rotate_ip(self, angle: float, rotation_point: Coordinate, /) -> None: ... + def rotate_ip(self, angle: float, rotation_point: CoordinateLike, /) -> None: ... @overload def rotate_ip(self, angle: float, /) -> None: ... def as_rect(self) -> Rect: ... diff --git a/buildconfig/stubs/pygame/gfxdraw.pyi b/buildconfig/stubs/pygame/gfxdraw.pyi index d3592e6b7c..062481e61d 100644 --- a/buildconfig/stubs/pygame/gfxdraw.pyi +++ b/buildconfig/stubs/pygame/gfxdraw.pyi @@ -1,28 +1,28 @@ from pygame.surface import Surface -from ._common import ColorValue, Coordinate, RectValue, Sequence +from pygame.typing import ColorLike, CoordinateLike, RectLike, SequenceLike -def pixel(surface: Surface, x: int, y: int, color: ColorValue, /) -> None: ... -def hline(surface: Surface, x1: int, x2: int, y: int, color: ColorValue, /) -> None: ... -def vline(surface: Surface, x: int, y1: int, y2: int, color: ColorValue, /) -> None: ... +def pixel(surface: Surface, x: int, y: int, color: ColorLike, /) -> None: ... +def hline(surface: Surface, x1: int, x2: int, y: int, color: ColorLike, /) -> None: ... +def vline(surface: Surface, x: int, y1: int, y2: int, color: ColorLike, /) -> None: ... def line( - surface: Surface, x1: int, y1: int, x2: int, y2: int, color: ColorValue, / + surface: Surface, x1: int, y1: int, x2: int, y2: int, color: ColorLike, / ) -> None: ... -def rectangle(surface: Surface, rect: RectValue, color: ColorValue, /) -> None: ... -def box(surface: Surface, rect: RectValue, color: ColorValue, /) -> None: ... -def circle(surface: Surface, x: int, y: int, r: int, color: ColorValue, /) -> None: ... -def aacircle(surface: Surface, x: int, y: int, r: int, color: ColorValue, /) -> None: ... +def rectangle(surface: Surface, rect: RectLike, color: ColorLike, /) -> None: ... +def box(surface: Surface, rect: RectLike, color: ColorLike, /) -> None: ... +def circle(surface: Surface, x: int, y: int, r: int, color: ColorLike, /) -> None: ... +def aacircle(surface: Surface, x: int, y: int, r: int, color: ColorLike, /) -> None: ... def filled_circle( - surface: Surface, x: int, y: int, r: int, color: ColorValue, / + surface: Surface, x: int, y: int, r: int, color: ColorLike, / ) -> None: ... def ellipse( - surface: Surface, x: int, y: int, rx: int, ry: int, color: ColorValue, / + surface: Surface, x: int, y: int, rx: int, ry: int, color: ColorLike, / ) -> None: ... def aaellipse( - surface: Surface, x: int, y: int, rx: int, ry: int, color: ColorValue, / + surface: Surface, x: int, y: int, rx: int, ry: int, color: ColorLike, / ) -> None: ... def filled_ellipse( - surface: Surface, x: int, y: int, rx: int, ry: int, color: ColorValue, / + surface: Surface, x: int, y: int, rx: int, ry: int, color: ColorLike, / ) -> None: ... def arc( surface: Surface, @@ -31,7 +31,7 @@ def arc( r: int, start_angle: int, atp_angle: int, - color: ColorValue, / + color: ColorLike, / ) -> None: ... def pie( surface: Surface, @@ -40,7 +40,7 @@ def pie( r: int, start_angle: int, atp_angle: int, - color: ColorValue, / + color: ColorLike, / ) -> None: ... def trigon( surface: Surface, @@ -50,7 +50,7 @@ def trigon( y2: int, x3: int, y3: int, - color: ColorValue, / + color: ColorLike, / ) -> None: ... def aatrigon( surface: Surface, @@ -60,7 +60,7 @@ def aatrigon( y2: int, x3: int, y3: int, - color: ColorValue, / + color: ColorLike, / ) -> None: ... def filled_trigon( surface: Surface, @@ -70,20 +70,20 @@ def filled_trigon( y2: int, x3: int, y3: int, - color: ColorValue, / + color: ColorLike, / ) -> None: ... def polygon( - surface: Surface, points: Sequence[Coordinate], color: ColorValue, / + surface: Surface, points: SequenceLike[CoordinateLike], color: ColorLike, / ) -> None: ... def aapolygon( - surface: Surface, points: Sequence[Coordinate], color: ColorValue, / + surface: Surface, points: SequenceLike[CoordinateLike], color: ColorLike, / ) -> None: ... def filled_polygon( - surface: Surface, points: Sequence[Coordinate], color: ColorValue, / + surface: Surface, points: SequenceLike[CoordinateLike], color: ColorLike, / ) -> None: ... def textured_polygon( - surface: Surface, points: Sequence[Coordinate], texture: Surface, tx: int, ty: int, / + surface: Surface, points: SequenceLike[CoordinateLike], texture: Surface, tx: int, ty: int, / ) -> None: ... def bezier( - surface: Surface, points: Sequence[Coordinate], steps: int, color: ColorValue, / + surface: Surface, points: SequenceLike[CoordinateLike], steps: int, color: ColorLike, / ) -> None: ... diff --git a/buildconfig/stubs/pygame/image.pyi b/buildconfig/stubs/pygame/image.pyi index 7145b2ccd8..36ded0b1ff 100644 --- a/buildconfig/stubs/pygame/image.pyi +++ b/buildconfig/stubs/pygame/image.pyi @@ -4,7 +4,7 @@ from typing_extensions import deprecated # added in 3.13 from pygame.bufferproxy import BufferProxy from pygame.surface import Surface -from ._common import FileArg, IntCoordinate, Coordinate +from pygame.typing import FileLike, IntCoordinateLike, CoordinateLike _BufferStyle = Union[BufferProxy, bytes, bytearray, memoryview] _to_bytes_format = Literal[ @@ -13,9 +13,9 @@ _to_bytes_format = Literal[ _from_buffer_format = Literal["P", "RGB", "BGR", "BGRA", "RGBX", "RGBA", "ARGB"] _from_bytes_format = Literal["P", "RGB", "RGBX", "RGBA", "ARGB", "BGRA", "ABGR"] -def load(file: FileArg, namehint: str = "") -> Surface: ... -def load_sized_svg(file: FileArg, size: Coordinate) -> Surface: ... -def save(surface: Surface, file: FileArg, namehint: str = "") -> None: ... +def load(file: FileLike, namehint: str = "") -> Surface: ... +def load_sized_svg(file: FileLike, size: CoordinateLike) -> Surface: ... +def save(surface: Surface, file: FileLike, namehint: str = "") -> None: ... def get_sdl_image_version(linked: bool = True) -> Optional[Tuple[int, int, int]]: ... def get_extended() -> bool: ... @deprecated("since 2.3.0. Use `pygame.image.tobytes` instead") @@ -28,7 +28,7 @@ def tostring( @deprecated("since 2.3.0. Use `pygame.image.frombytes` instead") def fromstring( bytes: bytes, - size: IntCoordinate, + size: IntCoordinateLike, format: _from_bytes_format, flipped: bool = False, pitch: int = -1, @@ -41,17 +41,17 @@ def tobytes( ) -> bytes: ... def frombytes( bytes: bytes, - size: IntCoordinate, + size: IntCoordinateLike, format: _from_bytes_format, flipped: bool = False, pitch: int = -1, ) -> Surface: ... def frombuffer( bytes: _BufferStyle, - size: IntCoordinate, + size: IntCoordinateLike, format: _from_buffer_format, pitch: int = -1, ) -> Surface: ... -def load_basic(file: FileArg, /) -> Surface: ... -def load_extended(file: FileArg, namehint: str = "") -> Surface: ... -def save_extended(surface: Surface, file: FileArg, namehint: str = "") -> None: ... +def load_basic(file: FileLike, /) -> Surface: ... +def load_extended(file: FileLike, namehint: str = "") -> Surface: ... +def save_extended(surface: Surface, file: FileLike, namehint: str = "") -> None: ... diff --git a/buildconfig/stubs/pygame/key.pyi b/buildconfig/stubs/pygame/key.pyi index c55f1500d1..09aa380b35 100644 --- a/buildconfig/stubs/pygame/key.pyi +++ b/buildconfig/stubs/pygame/key.pyi @@ -1,6 +1,6 @@ from typing import Tuple -from ._common import RectValue +from pygame.typing import RectLike class ScancodeWrapper(Tuple[bool, ...]): ... @@ -16,4 +16,4 @@ def name(key: int, use_compat: bool = True) -> str: ... def key_code(name: str) -> int: ... def start_text_input() -> None: ... def stop_text_input() -> None: ... -def set_text_input_rect(rect: RectValue, /) -> None: ... +def set_text_input_rect(rect: RectLike, /) -> None: ... diff --git a/buildconfig/stubs/pygame/mask.pyi b/buildconfig/stubs/pygame/mask.pyi index 9ee01c9c07..7d3fbc076c 100644 --- a/buildconfig/stubs/pygame/mask.pyi +++ b/buildconfig/stubs/pygame/mask.pyi @@ -3,34 +3,34 @@ from typing import Any, List, Optional, Tuple, Union from pygame.rect import Rect from pygame.surface import Surface -from ._common import ColorValue, Coordinate, RectValue +from pygame.typing import ColorLike, CoordinateLike, RectLike def from_surface(surface: Surface, threshold: int = 127) -> Mask: ... def from_threshold( surface: Surface, - color: ColorValue, - threshold: ColorValue = (0, 0, 0, 255), + color: ColorLike, + threshold: ColorLike = (0, 0, 0, 255), othersurface: Optional[Surface] = None, palette_colors: int = 1, ) -> Mask: ... class Mask: - def __init__(self, size: Coordinate, fill: bool = False) -> None: ... + def __init__(self, size: CoordinateLike, fill: bool = False) -> None: ... def __copy__(self) -> Mask: ... copy = __copy__ def get_size(self) -> Tuple[int, int]: ... def get_rect(self, **kwargs: Any) -> Rect: ... # Dict type needs to be completed - def get_at(self, pos: Coordinate) -> int: ... - def set_at(self, pos: Coordinate, value: int = 1) -> None: ... - def overlap(self, other: Mask, offset: Coordinate) -> Optional[Tuple[int, int]]: ... - def overlap_area(self, other: Mask, offset: Coordinate) -> int: ... - def overlap_mask(self, other: Mask, offset: Coordinate) -> Mask: ... + def get_at(self, pos: CoordinateLike) -> int: ... + def set_at(self, pos: CoordinateLike, value: int = 1) -> None: ... + def overlap(self, other: Mask, offset: CoordinateLike) -> Optional[Tuple[int, int]]: ... + def overlap_area(self, other: Mask, offset: CoordinateLike) -> int: ... + def overlap_mask(self, other: Mask, offset: CoordinateLike) -> Mask: ... def fill(self) -> None: ... def clear(self) -> None: ... def invert(self) -> None: ... - def scale(self, scale: Coordinate) -> Mask: ... - def draw(self, other: Mask, offset: Coordinate) -> None: ... - def erase(self, other: Mask, offset: Coordinate) -> None: ... + def scale(self, scale: CoordinateLike) -> Mask: ... + def draw(self, other: Mask, offset: CoordinateLike) -> None: ... + def erase(self, other: Mask, offset: CoordinateLike) -> None: ... def count(self) -> int: ... def centroid(self) -> Tuple[int, int]: ... def angle(self) -> float: ... @@ -39,9 +39,9 @@ class Mask: self, other: Mask, output: Optional[Mask] = None, - offset: Coordinate = (0, 0), + offset: CoordinateLike = (0, 0), ) -> Mask: ... - def connected_component(self, pos: Coordinate = ...) -> Mask: ... + def connected_component(self, pos: CoordinateLike = ...) -> Mask: ... def connected_components(self, minimum: int = 0) -> List[Mask]: ... def get_bounding_rects(self) -> List[Rect]: ... def to_surface( @@ -49,9 +49,9 @@ class Mask: surface: Optional[Surface] = None, setsurface: Optional[Surface] = None, unsetsurface: Optional[Surface] = None, - setcolor: Optional[ColorValue] = (255, 255, 255, 255), - unsetcolor: Optional[ColorValue] = (0, 0, 0, 255), - dest: Union[RectValue, Coordinate] = (0, 0), + setcolor: Optional[ColorLike] = (255, 255, 255, 255), + unsetcolor: Optional[ColorLike] = (0, 0, 0, 255), + dest: Union[RectLike, CoordinateLike] = (0, 0), ) -> Surface: ... MaskType = Mask diff --git a/buildconfig/stubs/pygame/math.pyi b/buildconfig/stubs/pygame/math.pyi index f307599c76..b994bcdab4 100644 --- a/buildconfig/stubs/pygame/math.pyi +++ b/buildconfig/stubs/pygame/math.pyi @@ -21,7 +21,7 @@ if sys.version_info >= (3, 9): else: from typing import Collection -from ._common import Sequence +from pygame.typing import SequenceLike def clamp(value: float, min: float, max: float, /) -> float: ... @@ -37,18 +37,18 @@ class _GenericVector(Collection[float]): @overload def __setitem__(self, key: int, value: float) -> None: ... @overload - def __setitem__(self, key: slice, value: Union[Sequence[float], _TVec]) -> None: ... + def __setitem__(self, key: slice, value: Union[SequenceLike[float], _TVec]) -> None: ... @overload def __getitem__(self, i: SupportsIndex) -> float: ... @overload def __getitem__(self, s: slice) -> List[float]: ... def __iter__(self) -> VectorIterator: ... - def __add__(self: _TVec, other: Union[Sequence[float], _TVec]) -> _TVec: ... - def __radd__(self: _TVec, other: Union[Sequence[float], _TVec]) -> _TVec: ... - def __sub__(self: _TVec, other: Union[Sequence[float], _TVec]) -> _TVec: ... - def __rsub__(self: _TVec, other: Union[Sequence[float], _TVec]) -> _TVec: ... + def __add__(self: _TVec, other: Union[SequenceLike[float], _TVec]) -> _TVec: ... + def __radd__(self: _TVec, other: Union[SequenceLike[float], _TVec]) -> _TVec: ... + def __sub__(self: _TVec, other: Union[SequenceLike[float], _TVec]) -> _TVec: ... + def __rsub__(self: _TVec, other: Union[SequenceLike[float], _TVec]) -> _TVec: ... @overload - def __mul__(self: _TVec, other: Union[Sequence[float], _TVec]) -> float: ... + def __mul__(self: _TVec, other: Union[SequenceLike[float], _TVec]) -> float: ... @overload def __mul__(self: _TVec, other: float) -> _TVec: ... def __rmul__(self: _TVec, other: float) -> _TVec: ... @@ -58,17 +58,17 @@ class _GenericVector(Collection[float]): def __neg__(self: _TVec) -> _TVec: ... def __pos__(self: _TVec) -> _TVec: ... def __bool__(self) -> bool: ... - def __iadd__(self: _TVec, other: Union[Sequence[float], _TVec]) -> _TVec: ... - def __isub__(self: _TVec, other: Union[Sequence[float], _TVec]) -> _TVec: ... + def __iadd__(self: _TVec, other: Union[SequenceLike[float], _TVec]) -> _TVec: ... + def __isub__(self: _TVec, other: Union[SequenceLike[float], _TVec]) -> _TVec: ... @overload - def __imul__(self: _TVec, other: Union[Sequence[float], _TVec]) -> float: ... + def __imul__(self: _TVec, other: Union[SequenceLike[float], _TVec]) -> float: ... @overload def __imul__(self: _TVec, other: float) -> _TVec: ... def __copy__(self: _TVec) -> _TVec: ... copy = __copy__ def __safe_for_unpickling__(self) -> Literal[True]: ... def __contains__(self, other: float) -> bool: ... # type: ignore[override] - def dot(self: _TVec, other: Union[Sequence[float], _TVec], /) -> float: ... + def dot(self: _TVec, other: Union[SequenceLike[float], _TVec], /) -> float: ... def magnitude(self) -> float: ... def magnitude_squared(self) -> float: ... def length(self) -> float: ... @@ -77,37 +77,37 @@ class _GenericVector(Collection[float]): def normalize_ip(self) -> None: ... def is_normalized(self) -> bool: ... def scale_to_length(self, value: float, /) -> None: ... - def reflect(self: _TVec, other: Union[Sequence[float], _TVec], /) -> _TVec: ... - def reflect_ip(self: _TVec, other: Union[Sequence[float], _TVec], /) -> None: ... - def distance_to(self: _TVec, other: Union[Sequence[float], _TVec], /) -> float: ... + def reflect(self: _TVec, other: Union[SequenceLike[float], _TVec], /) -> _TVec: ... + def reflect_ip(self: _TVec, other: Union[SequenceLike[float], _TVec], /) -> None: ... + def distance_to(self: _TVec, other: Union[SequenceLike[float], _TVec], /) -> float: ... def distance_squared_to( - self: _TVec, other: Union[Sequence[float], _TVec], / + self: _TVec, other: Union[SequenceLike[float], _TVec], / ) -> float: ... def lerp( self: _TVec, - other: Union[Sequence[float], _TVec], + other: Union[SequenceLike[float], _TVec], value: float, / ) -> _TVec: ... def slerp( self: _TVec, - other: Union[Sequence[float], _TVec], + other: Union[SequenceLike[float], _TVec], value: float, / ) -> _TVec: ... def smoothstep( self: _TVec, - other: Union[Sequence[float], _TVec], + other: Union[SequenceLike[float], _TVec], value: float, / ) -> _TVec: ... def elementwise(self: _TVec) -> VectorElementwiseProxy[_TVec]: ... - def angle_to(self: _TVec, other: Union[Sequence[float], _TVec], /) -> float: ... + def angle_to(self: _TVec, other: Union[SequenceLike[float], _TVec], /) -> float: ... def move_towards( self: _TVec, - target: Union[Sequence[float], _TVec], + target: Union[SequenceLike[float], _TVec], max_distance: float, / ) -> _TVec: ... def move_towards_ip( self: _TVec, - target: Union[Sequence[float], _TVec], + target: Union[SequenceLike[float], _TVec], max_distance: float, / ) -> None: ... @overload @@ -120,7 +120,7 @@ class _GenericVector(Collection[float]): def clamp_magnitude_ip(self, max_length: float, /) -> None: ... @overload def clamp_magnitude_ip(self, min_length: float, max_length: float, /) -> None: ... - def project(self: _TVec, other: Union[Sequence[float], _TVec], /) -> _TVec: ... + def project(self: _TVec, other: Union[SequenceLike[float], _TVec], /) -> _TVec: ... def __round__(self: _TVec, ndigits: Optional[int] = None, /) -> _TVec: ... # VectorElementwiseProxy is a generic, it can be an elementwiseproxy object for @@ -224,7 +224,7 @@ class Vector2(_GenericVector): @overload def __init__( self: _TVec, - x: Union[str, float, Sequence[float], _TVec] = 0, + x: Union[str, float, SequenceLike[float], _TVec] = 0, ) -> None: ... @overload def __init__(self, x: float, y: float) -> None: ... @@ -235,13 +235,13 @@ class Vector2(_GenericVector): def rotate_rad_ip(self, angle: float, /) -> None: ... @deprecated("since 2.1.1. Use `pygame.Vector2.rotate_rad_ip` instead") def rotate_ip_rad(self, angle: float, /) -> None: ... - def cross(self: _TVec, other: Union[Sequence[float], _TVec], /) -> float: ... + def cross(self: _TVec, other: Union[SequenceLike[float], _TVec], /) -> float: ... def as_polar(self) -> Tuple[float, float]: ... - def from_polar(self, polar_value: Sequence[float], /) -> None: ... + def from_polar(self, polar_value: SequenceLike[float], /) -> None: ... @overload def update( self: _TVec, - x: Union[str, float, Sequence[float], _TVec] = 0, + x: Union[str, float, SequenceLike[float], _TVec] = 0, ) -> None: ... @overload def update(self, x: float = 0, y: float = 0) -> None: ... @@ -289,27 +289,27 @@ class Vector3(_GenericVector): @overload def __init__( self: _TVec, - x: Union[str, float, Sequence[float], _TVec] = 0, + x: Union[str, float, SequenceLike[float], _TVec] = 0, ) -> None: ... @overload def __init__(self, x: float, y: float, z: float) -> None: ... def __reduce__(self: _TVec) -> Tuple[Type[_TVec], Tuple[float, float, float]]: ... - def cross(self: _TVec, other: Union[Sequence[float], _TVec], /) -> _TVec: ... + def cross(self: _TVec, other: Union[SequenceLike[float], _TVec], /) -> _TVec: ... def rotate( - self: _TVec, angle: float, axis: Union[Sequence[float], _TVec], / + self: _TVec, angle: float, axis: Union[SequenceLike[float], _TVec], / ) -> _TVec: ... def rotate_rad( - self: _TVec, angle: float, axis: Union[Sequence[float], _TVec], / + self: _TVec, angle: float, axis: Union[SequenceLike[float], _TVec], / ) -> _TVec: ... def rotate_ip( - self: _TVec, angle: float, axis: Union[Sequence[float], _TVec], / + self: _TVec, angle: float, axis: Union[SequenceLike[float], _TVec], / ) -> None: ... def rotate_rad_ip( - self: _TVec, angle: float, axis: Union[Sequence[float], _TVec], / + self: _TVec, angle: float, axis: Union[SequenceLike[float], _TVec], / ) -> None: ... @deprecated("since 2.1.1. Use `pygame.Vector3.rotate_rad_ip` instead") def rotate_ip_rad( - self: _TVec, angle: float, axis: Union[Sequence[float], _TVec], / + self: _TVec, angle: float, axis: Union[SequenceLike[float], _TVec], / ) -> None: ... def rotate_x(self: _TVec, angle: float, /) -> _TVec: ... def rotate_x_rad(self: _TVec, angle: float, /) -> _TVec: ... @@ -334,7 +334,7 @@ class Vector3(_GenericVector): @overload def update( self: _TVec, - x: Union[str, float, Sequence[float], _TVec] = 0, + x: Union[str, float, SequenceLike[float], _TVec] = 0, ) -> None: ... @overload def update(self, x: int, y: int, z: int) -> None: ... diff --git a/buildconfig/stubs/pygame/midi.pyi b/buildconfig/stubs/pygame/midi.pyi index 028342508c..22fc749f80 100644 --- a/buildconfig/stubs/pygame/midi.pyi +++ b/buildconfig/stubs/pygame/midi.pyi @@ -1,7 +1,7 @@ from typing import List, Tuple, Union from pygame.event import Event -from ._common import Sequence +from pygame.typing import SequenceLike MIDIIN: int MIDIOUT: int @@ -17,7 +17,7 @@ def get_default_input_id() -> int: ... def get_default_output_id() -> int: ... def get_device_info(an_id: int) -> Tuple[str, str, int, int, int]: ... def midis2events( - midis: Sequence[Sequence[Union[Sequence[int], int]]], device_id: int + midis: SequenceLike[SequenceLike[Union[SequenceLike[int], int]]], device_id: int ) -> List[Event]: ... def time() -> int: ... def frequency_to_midi(frequency: float) -> int: ... diff --git a/buildconfig/stubs/pygame/mixer.pyi b/buildconfig/stubs/pygame/mixer.pyi index 4d1cafc830..84646b419b 100644 --- a/buildconfig/stubs/pygame/mixer.pyi +++ b/buildconfig/stubs/pygame/mixer.pyi @@ -5,7 +5,7 @@ import numpy from pygame.event import Event from . import mixer_music -from ._common import FileArg +from pygame.typing import FileLike # export mixer_music as mixer.music music = mixer_music @@ -44,7 +44,7 @@ def get_sdl_mixer_version(linked: bool = True) -> Tuple[int, int, int]: ... class Sound: @overload - def __init__(self, file: FileArg) -> None: ... + def __init__(self, file: FileLike) -> None: ... @overload def __init__( self, buffer: Any diff --git a/buildconfig/stubs/pygame/mixer_music.pyi b/buildconfig/stubs/pygame/mixer_music.pyi index 08b2e8a11a..40cf46e2a9 100644 --- a/buildconfig/stubs/pygame/mixer_music.pyi +++ b/buildconfig/stubs/pygame/mixer_music.pyi @@ -1,8 +1,8 @@ from typing import Optional, Dict -from ._common import FileArg +from pygame.typing import FileLike -def load(filename: FileArg, namehint: Optional[str] = "") -> None: ... +def load(filename: FileLike, namehint: Optional[str] = "") -> None: ... def unload() -> None: ... def play(loops: int = 0, start: float = 0.0, fade_ms: int = 0) -> None: ... def rewind() -> None: ... @@ -15,7 +15,7 @@ def get_volume() -> float: ... def get_busy() -> bool: ... def set_pos(pos: float, /) -> None: ... def get_pos() -> int: ... -def queue(filename: FileArg, namehint: str = "", loops: int = 0) -> None: ... +def queue(filename: FileLike, namehint: str = "", loops: int = 0) -> None: ... def set_endevent(event_type: int, /) -> None: ... def get_endevent() -> int: ... -def get_metadata(filename: Optional[FileArg] = None, namehint: str = "") -> Dict[str, str]: ... +def get_metadata(filename: Optional[FileLike] = None, namehint: str = "") -> Dict[str, str]: ... diff --git a/buildconfig/stubs/pygame/mouse.pyi b/buildconfig/stubs/pygame/mouse.pyi index c3d3a64548..9319024070 100644 --- a/buildconfig/stubs/pygame/mouse.pyi +++ b/buildconfig/stubs/pygame/mouse.pyi @@ -4,7 +4,7 @@ from typing_extensions import deprecated # added in 3.13 from pygame.cursors import Cursor from pygame.surface import Surface -from ._common import Coordinate, Sequence, IntCoordinate +from pygame.typing import CoordinateLike, SequenceLike, IntCoordinateLike @overload def get_pressed(num_buttons: Literal[3] = 3) -> Tuple[bool, bool, bool]: ... @@ -15,7 +15,7 @@ def get_just_released() -> Tuple[bool, bool, bool, bool, bool]: ... def get_pos() -> Tuple[int, int]: ... def get_rel() -> Tuple[int, int]: ... @overload -def set_pos(pos: Coordinate, /) -> None: ... +def set_pos(pos: CoordinateLike, /) -> None: ... @overload def set_pos(x: float, y: float, /) -> None: ... def set_visible(value: bool, /) -> int: ... @@ -27,13 +27,13 @@ def set_cursor(cursor: Cursor) -> None: ... def set_cursor(constant: int) -> None: ... @overload def set_cursor( - size: IntCoordinate, - hotspot: IntCoordinate, - xormasks: Sequence[int], - andmasks: Sequence[int], + size: IntCoordinateLike, + hotspot: IntCoordinateLike, + xormasks: SequenceLike[int], + andmasks: SequenceLike[int], ) -> None: ... @overload -def set_cursor(hotspot: IntCoordinate, surface: Surface) -> None: ... +def set_cursor(hotspot: IntCoordinateLike, surface: Surface) -> None: ... def get_cursor() -> Cursor: ... @deprecated("since 2.2.0. Use `pygame.mouse.set_cursor` instead") def set_system_cursor(cursor: int, /) -> None: ... diff --git a/buildconfig/stubs/pygame/pixelarray.pyi b/buildconfig/stubs/pygame/pixelarray.pyi index 935d4c01d6..a10bb66e42 100644 --- a/buildconfig/stubs/pygame/pixelarray.pyi +++ b/buildconfig/stubs/pygame/pixelarray.pyi @@ -2,7 +2,7 @@ from typing import Any, Dict, Tuple, Union, overload from pygame.surface import Surface -from ._common import ColorValue, Sequence +from pygame.typing import ColorLike, SequenceLike class PixelArray: surface: Surface @@ -34,22 +34,22 @@ class PixelArray: def make_surface(self) -> Surface: ... def replace( self, - color: ColorValue, - repcolor: ColorValue, + color: ColorLike, + repcolor: ColorLike, distance: float = 0, - weights: Sequence[float] = (0.299, 0.587, 0.114), + weights: SequenceLike[float] = (0.299, 0.587, 0.114), ) -> None: ... def extract( self, - color: ColorValue, + color: ColorLike, distance: float = 0, - weights: Sequence[float] = (0.299, 0.587, 0.114), + weights: SequenceLike[float] = (0.299, 0.587, 0.114), ) -> PixelArray: ... def compare( self, array: PixelArray, distance: float = 0, - weights: Sequence[float] = (0.299, 0.587, 0.114), + weights: SequenceLike[float] = (0.299, 0.587, 0.114), ) -> PixelArray: ... def transpose(self) -> PixelArray: ... def close(self) -> PixelArray: ... diff --git a/buildconfig/stubs/pygame/rect.pyi b/buildconfig/stubs/pygame/rect.pyi index 6cb28ca201..81facde978 100644 --- a/buildconfig/stubs/pygame/rect.pyi +++ b/buildconfig/stubs/pygame/rect.pyi @@ -12,7 +12,7 @@ from typing import ( Optional, ) -from ._common import Coordinate, RectValue, Sequence +from pygame.typing import CoordinateLike, RectLike, SequenceLike if sys.version_info >= (3, 11): from typing import Self @@ -29,7 +29,7 @@ _K = TypeVar("_K") _V = TypeVar("_V") _T = TypeVar("_T") -_RectTypeCompatible_co = TypeVar("_RectTypeCompatible_co", bound=RectValue, covariant=True) +_RectTypeCompatible_co = TypeVar("_RectTypeCompatible_co", bound=RectLike, covariant=True) class _GenericRect(Collection[_N]): @property @@ -59,39 +59,39 @@ class _GenericRect(Collection[_N]): @property def topleft(self) -> Tuple[_N, _N]: ... @topleft.setter - def topleft(self, value: Coordinate) -> None: ... + def topleft(self, value: CoordinateLike) -> None: ... @property def bottomleft(self) -> Tuple[_N, _N]: ... @bottomleft.setter - def bottomleft(self, value: Coordinate) -> None: ... + def bottomleft(self, value: CoordinateLike) -> None: ... @property def topright(self) -> Tuple[_N, _N]: ... @topright.setter - def topright(self, value: Coordinate) -> None: ... + def topright(self, value: CoordinateLike) -> None: ... @property def bottomright(self) -> Tuple[_N, _N]: ... @bottomright.setter - def bottomright(self, value: Coordinate) -> None: ... + def bottomright(self, value: CoordinateLike) -> None: ... @property def midtop(self) -> Tuple[_N, _N]: ... @midtop.setter - def midtop(self, value: Coordinate) -> None: ... + def midtop(self, value: CoordinateLike) -> None: ... @property def midleft(self) -> Tuple[_N, _N]: ... @midleft.setter - def midleft(self, value: Coordinate) -> None: ... + def midleft(self, value: CoordinateLike) -> None: ... @property def midbottom(self) -> Tuple[_N, _N]: ... @midbottom.setter - def midbottom(self, value: Coordinate) -> None: ... + def midbottom(self, value: CoordinateLike) -> None: ... @property def midright(self) -> Tuple[_N, _N]: ... @midright.setter - def midright(self, value: Coordinate) -> None: ... + def midright(self, value: CoordinateLike) -> None: ... @property def center(self) -> Tuple[_N, _N]: ... @center.setter - def center(self, value: Coordinate) -> None: ... + def center(self, value: CoordinateLike) -> None: ... @property def centerx(self) -> _N: ... @centerx.setter @@ -103,7 +103,7 @@ class _GenericRect(Collection[_N]): @property def size(self) -> Tuple[_N, _N]: ... @size.setter - def size(self, value: Coordinate) -> None: ... + def size(self, value: CoordinateLike) -> None: ... @property def width(self) -> _N: ... @width.setter @@ -127,9 +127,9 @@ class _GenericRect(Collection[_N]): self, left: float, top: float, width: float, height: float ) -> None: ... @overload - def __init__(self, left_top: Coordinate, width_height: Coordinate) -> None: ... + def __init__(self, left_top: CoordinateLike, width_height: CoordinateLike) -> None: ... @overload - def __init__(self, single_arg: RectValue) -> None: ... + def __init__(self, single_arg: RectLike) -> None: ... @overload def __init__(self) -> None: ... def __len__(self) -> Literal[4]: ... @@ -141,58 +141,58 @@ class _GenericRect(Collection[_N]): @overload def __setitem__(self, key: int, value: float) -> None: ... @overload - def __setitem__(self, key: slice, value: Union[float, RectValue]) -> None: ... + def __setitem__(self, key: slice, value: Union[float, RectLike]) -> None: ... def __copy__(self) -> Self: ... copy = __copy__ @overload def move(self, x: float, y: float, /) -> Self: ... @overload - def move(self, move_by: Coordinate, /) -> Self: ... + def move(self, move_by: CoordinateLike, /) -> Self: ... @overload def move_ip(self, x: float, y: float, /) -> None: ... @overload - def move_ip(self, move_by: Coordinate, /) -> None: ... - def move_to(self, **kwargs: Union[float, Coordinate]) -> Self: ... + def move_ip(self, move_by: CoordinateLike, /) -> None: ... + def move_to(self, **kwargs: Union[float, CoordinateLike]) -> Self: ... @overload def inflate(self, x: float, y: float, /) -> Self: ... @overload - def inflate(self, inflate_by: Coordinate, /) -> Self: ... + def inflate(self, inflate_by: CoordinateLike, /) -> Self: ... @overload def inflate_ip(self, x: float, y: float, /) -> None: ... @overload - def inflate_ip(self, inflate_by: Coordinate, /) -> None: ... + def inflate_ip(self, inflate_by: CoordinateLike, /) -> None: ... @overload def scale_by(self, x: float, y: float = ...) -> Self: ... @overload - def scale_by(self, scale_by: Coordinate) -> Self: ... + def scale_by(self, scale_by: CoordinateLike) -> Self: ... @overload def scale_by_ip(self, x: float, y: float = ...) -> None: ... @overload - def scale_by_ip(self, scale_by: Coordinate) -> None: ... + def scale_by_ip(self, scale_by: CoordinateLike) -> None: ... @overload def update(self, left: float, top: float, width: float, height: float, /) -> None: ... @overload - def update(self, left_top: Coordinate, width_height: Coordinate, /) -> None: ... + def update(self, left_top: CoordinateLike, width_height: CoordinateLike, /) -> None: ... @overload - def update(self, single_arg: RectValue, /) -> None: ... + def update(self, single_arg: RectLike, /) -> None: ... @overload - def clamp(self, rect: RectValue, /) -> Self: ... + def clamp(self, rect: RectLike, /) -> Self: ... @overload - def clamp(self, left_top: Coordinate, width_height: Coordinate, /) -> Self: ... + def clamp(self, left_top: CoordinateLike, width_height: CoordinateLike, /) -> Self: ... @overload def clamp(self, left: float, top: float, width: float, height: float, /) -> Self: ... @overload - def clamp_ip(self, rect: RectValue, /) -> None: ... + def clamp_ip(self, rect: RectLike, /) -> None: ... @overload - def clamp_ip(self, left_top: Coordinate, width_height: Coordinate, /) -> None: ... + def clamp_ip(self, left_top: CoordinateLike, width_height: CoordinateLike, /) -> None: ... @overload def clamp_ip( self, left: float, top: float, width: float, height: float, / ) -> None: ... @overload - def clip(self, rect: RectValue, /) -> Self: ... + def clip(self, rect: RectLike, /) -> Self: ... @overload - def clip(self, left_top: Coordinate, width_height: Coordinate, /) -> Self: ... + def clip(self, left_top: CoordinateLike, width_height: CoordinateLike, /) -> Self: ... @overload def clip(self, left: float, top: float, width: float, height: float, /) -> Self: ... @overload @@ -201,40 +201,40 @@ class _GenericRect(Collection[_N]): ) -> Union[Tuple[Tuple[_N, _N], Tuple[_N, _N]], Tuple[()]]: ... @overload def clipline( - self, first_coordinate: Coordinate, second_coordinate: Coordinate, / + self, first_coordinate: CoordinateLike, second_coordinate: CoordinateLike, / ) -> Union[Tuple[Tuple[_N, _N], Tuple[_N, _N]], Tuple[()]]: ... @overload def clipline( - self, rect_arg: RectValue, / + self, rect_arg: RectLike, / ) -> Union[Tuple[Tuple[_N, _N], Tuple[_N, _N]], Tuple[()]]: ... @overload - def union(self, rect: RectValue, /) -> Self: ... + def union(self, rect: RectLike, /) -> Self: ... @overload - def union(self, left_top: Coordinate, width_height: Coordinate, /) -> Self: ... + def union(self, left_top: CoordinateLike, width_height: CoordinateLike, /) -> Self: ... @overload def union(self, left: float, top: float, width: float, height: float, /) -> Self: ... @overload - def union_ip(self, rect: RectValue, /) -> None: ... + def union_ip(self, rect: RectLike, /) -> None: ... @overload - def union_ip(self, left_top: Coordinate, width_height: Coordinate, /) -> None: ... + def union_ip(self, left_top: CoordinateLike, width_height: CoordinateLike, /) -> None: ... @overload def union_ip( self, left: float, top: float, width: float, height: float, / ) -> None: ... - def unionall(self, rect: Sequence[_RectTypeCompatible_co], /) -> Self: ... - def unionall_ip(self, rect_sequence: Sequence[_RectTypeCompatible_co], /) -> None: ... + def unionall(self, rect: SequenceLike[_RectTypeCompatible_co], /) -> Self: ... + def unionall_ip(self, rect_SequenceLike: SequenceLike[_RectTypeCompatible_co], /) -> None: ... @overload - def fit(self, rect: RectValue, /) -> Self: ... + def fit(self, rect: RectLike, /) -> Self: ... @overload - def fit(self, left_top: Coordinate, width_height: Coordinate, /) -> Self: ... + def fit(self, left_top: CoordinateLike, width_height: CoordinateLike, /) -> Self: ... @overload def fit(self, left: float, top: float, width: float, height: float, /) -> Self: ... def normalize(self) -> None: ... - def __contains__(self, rect: Union[RectValue, _N], /) -> bool: ... # type: ignore[override] + def __contains__(self, rect: Union[RectLike, _N], /) -> bool: ... # type: ignore[override] @overload - def contains(self, rect: RectValue, /) -> bool: ... + def contains(self, rect: RectLike, /) -> bool: ... @overload - def contains(self, left_top: Coordinate, width_height: Coordinate, /) -> bool: ... + def contains(self, left_top: CoordinateLike, width_height: CoordinateLike, /) -> bool: ... @overload def contains( self, left: float, top: float, width: float, height: float, / @@ -242,22 +242,22 @@ class _GenericRect(Collection[_N]): @overload def collidepoint(self, x: float, y: float, /) -> bool: ... @overload - def collidepoint(self, x_y: Coordinate, /) -> bool: ... + def collidepoint(self, x_y: CoordinateLike, /) -> bool: ... @overload - def colliderect(self, rect: RectValue, /) -> bool: ... + def colliderect(self, rect: RectLike, /) -> bool: ... @overload - def colliderect(self, left_top: Coordinate, width_height: Coordinate, /) -> bool: ... + def colliderect(self, left_top: CoordinateLike, width_height: CoordinateLike, /) -> bool: ... @overload def colliderect( self, left: float, top: float, width: float, height: float, / ) -> bool: ... - def collidelist(self, rect_list: Sequence[_RectTypeCompatible_co], /) -> int: ... - def collidelistall(self, rect_list: Sequence[_RectTypeCompatible_co], /) -> List[int]: ... + def collidelist(self, rect_list: SequenceLike[_RectTypeCompatible_co], /) -> int: ... + def collidelistall(self, rect_list: SequenceLike[_RectTypeCompatible_co], /) -> List[int]: ... def collideobjectsall( - self, objects: Sequence[_T], key: Optional[Callable[[_T], RectValue]] = None + self, objects: SequenceLike[_T], key: Optional[Callable[[_T], RectLike]] = None ) -> List[_T]: ... def collideobjects( - self, objects: Sequence[_T], key: Optional[Callable[[_T], RectValue]] = None + self, objects: SequenceLike[_T], key: Optional[Callable[[_T], RectLike]] = None ) -> Optional[_T]: ... @overload def collidedict( diff --git a/buildconfig/stubs/pygame/rwobject.pyi b/buildconfig/stubs/pygame/rwobject.pyi index 3688279b6c..38161fab81 100644 --- a/buildconfig/stubs/pygame/rwobject.pyi +++ b/buildconfig/stubs/pygame/rwobject.pyi @@ -1,16 +1,16 @@ from typing import Any, Optional, overload, Type -from ._common import AnyPath +from pygame.typing import PathLike def encode_string( - obj: Optional[AnyPath], + obj: Optional[PathLike], encoding: Optional[str] = "unicode_escape", errors: Optional[str] = "backslashreplace", etype: Optional[Type[Exception]] = UnicodeEncodeError, ) -> bytes: ... @overload def encode_file_path( - obj: Optional[AnyPath], etype: Optional[Type[Exception]] = UnicodeEncodeError + obj: Optional[PathLike], etype: Optional[Type[Exception]] = UnicodeEncodeError ) -> bytes: ... @overload def encode_file_path( diff --git a/buildconfig/stubs/pygame/sprite.pyi b/buildconfig/stubs/pygame/sprite.pyi index 7a96dadc44..8fc3c4239f 100644 --- a/buildconfig/stubs/pygame/sprite.pyi +++ b/buildconfig/stubs/pygame/sprite.pyi @@ -19,7 +19,7 @@ from pygame.rect import FRect, Rect from pygame.surface import Surface from pygame.mask import Mask -from ._common import RectValue, Coordinate +from pygame.typing import RectLike, CoordinateLike # non-generic Group, used in Sprite _Group = AbstractGroup[_SpriteSupportsGroup] @@ -211,7 +211,7 @@ class LayeredUpdates(AbstractGroup[_TSprite]): ], **kwargs: Any ) -> None: ... - def get_sprites_at(self, pos: Coordinate) -> List[_TSprite]: ... + def get_sprites_at(self, pos: CoordinateLike) -> List[_TSprite]: ... def get_sprite(self, idx: int) -> _TSprite: ... def remove_sprites_of_layer(self, layer_nr: int) -> List[_TSprite]: ... def layers(self) -> List[int]: ... @@ -232,8 +232,8 @@ class LayeredDirty(LayeredUpdates[_TDirtySprite]): ) -> List[Union[FRect, Rect]]: ... # clear breaks Liskov substitution principle in code def clear(self, surface: Surface, bgd: Surface) -> None: ... # type: ignore[override] - def repaint_rect(self, screen_rect: RectValue) -> None: ... - def set_clip(self, screen_rect: Optional[RectValue] = None) -> None: ... + def repaint_rect(self, screen_rect: RectLike) -> None: ... + def set_clip(self, screen_rect: Optional[RectLike] = None) -> None: ... def get_clip(self) -> Union[FRect, Rect]: ... def set_timing_threshold( self, time_ms: SupportsFloat diff --git a/buildconfig/stubs/pygame/surface.pyi b/buildconfig/stubs/pygame/surface.pyi index 7539ea9311..f73cbf1993 100644 --- a/buildconfig/stubs/pygame/surface.pyi +++ b/buildconfig/stubs/pygame/surface.pyi @@ -5,12 +5,12 @@ from pygame.bufferproxy import BufferProxy from pygame.color import Color from pygame.rect import FRect, Rect -from ._common import ( - ColorValue, - Coordinate, - RectValue, - RGBAOutput, - Sequence, +from pygame.typing import ( + ColorLike, + CoordinateLike, + RectLike, + RGBALike, + SequenceLike, ) _ViewKind = Literal[ @@ -51,15 +51,15 @@ class Surface: @overload def __init__( self, - size: Coordinate, + size: CoordinateLike, flags: int = 0, depth: int = 0, - masks: Optional[ColorValue] = None, + masks: Optional[ColorLike] = None, ) -> None: ... @overload def __init__( self, - size: Coordinate, + size: CoordinateLike, flags: int = 0, surface: Surface = ..., ) -> None: ... @@ -69,24 +69,24 @@ class Surface: def blit( self, source: Surface, - dest: Union[Coordinate, RectValue] = (0, 0), - area: Optional[RectValue] = None, + dest: Union[CoordinateLike, RectLike] = (0, 0), + area: Optional[RectLike] = None, special_flags: int = 0, ) -> Rect: ... def blits( self, - blit_sequence: Iterable[ + blit_SequenceLike: Iterable[ Union[ - Tuple[Surface, Union[Coordinate, RectValue]], - Tuple[Surface, Union[Coordinate, RectValue], Union[RectValue, int]], - Tuple[Surface, Union[Coordinate, RectValue], RectValue, int], + Tuple[Surface, Union[CoordinateLike, RectLike]], + Tuple[Surface, Union[CoordinateLike, RectLike], Union[RectLike, int]], + Tuple[Surface, Union[CoordinateLike, RectLike], RectLike, int], ] ], doreturn: Union[int, bool] = 1, ) -> Union[List[Rect], None]: ... def fblits( self, - blit_sequence: Iterable[Tuple[Surface, Union[Coordinate, RectValue]]], + blit_SequenceLike: Iterable[Tuple[Surface, Union[CoordinateLike, RectLike]]], special_flags: int = 0, / ) -> None: ... @overload @@ -94,22 +94,22 @@ class Surface: @overload def convert(self, depth: int, flags: int = 0, /) -> Surface: ... @overload - def convert(self, masks: ColorValue, flags: int = 0, /) -> Surface: ... + def convert(self, masks: ColorLike, flags: int = 0, /) -> Surface: ... @overload def convert(self) -> Surface: ... def convert_alpha(self) -> Surface: ... def fill( self, - color: ColorValue, - rect: Optional[RectValue] = None, + color: ColorLike, + rect: Optional[RectLike] = None, special_flags: int = 0, ) -> Rect: ... def scroll(self, dx: int = 0, dy: int = 0, /) -> None: ... @overload - def set_colorkey(self, color: ColorValue, flags: int = 0, /) -> None: ... + def set_colorkey(self, color: ColorLike, flags: int = 0, /) -> None: ... @overload def set_colorkey(self, color: None, /) -> None: ... - def get_colorkey(self) -> Optional[RGBAOutput]: ... + def get_colorkey(self) -> Optional[RGBALike]: ... @overload def set_alpha(self, value: int, flags: int = 0, /) -> None: ... @overload @@ -120,21 +120,21 @@ class Surface: def mustlock(self) -> bool: ... def get_locked(self) -> bool: ... def get_locks(self) -> Tuple[Any, ...]: ... - def get_at(self, x_y: Coordinate, /) -> Color: ... - def set_at(self, x_y: Coordinate, color: ColorValue, /) -> None: ... - def get_at_mapped(self, x_y: Coordinate, /) -> int: ... + def get_at(self, x_y: CoordinateLike, /) -> Color: ... + def set_at(self, x_y: CoordinateLike, color: ColorLike, /) -> None: ... + def get_at_mapped(self, x_y: CoordinateLike, /) -> int: ... def get_palette(self) -> List[Color]: ... def get_palette_at(self, index: int, /) -> Color: ... - def set_palette(self, palette: Sequence[ColorValue], /) -> None: ... - def set_palette_at(self, index: int, color: ColorValue, /) -> None: ... - def map_rgb(self, color: ColorValue, /) -> int: ... + def set_palette(self, palette: SequenceLike[ColorLike], /) -> None: ... + def set_palette_at(self, index: int, color: ColorLike, /) -> None: ... + def map_rgb(self, color: ColorLike, /) -> int: ... def unmap_rgb(self, mapped_int: int, /) -> Color: ... - def set_clip(self, rect: Optional[RectValue], /) -> None: ... + def set_clip(self, rect: Optional[RectLike], /) -> None: ... def get_clip(self) -> Rect: ... @overload - def subsurface(self, rect: RectValue, /) -> Surface: ... + def subsurface(self, rect: RectLike, /) -> Surface: ... @overload - def subsurface(self, left_top: Coordinate, width_height: Coordinate, /) -> Surface: ... + def subsurface(self, left_top: CoordinateLike, width_height: CoordinateLike, /) -> Surface: ... @overload def subsurface( self, left: float, top: float, width: float, height: float, / @@ -152,13 +152,13 @@ class Surface: def get_bytesize(self) -> int: ... def get_flags(self) -> int: ... def get_pitch(self) -> int: ... - def get_masks(self) -> RGBAOutput: ... + def get_masks(self) -> RGBALike: ... @deprecated("since 2.0.0. Immutable in SDL2") - def set_masks(self, color: ColorValue, /) -> None: ... - def get_shifts(self) -> RGBAOutput: ... + def set_masks(self, color: ColorLike, /) -> None: ... + def get_shifts(self) -> RGBALike: ... @deprecated("since 2.0.0. Immutable in SDL2") - def set_shifts(self, color: ColorValue, /) -> None: ... - def get_losses(self) -> RGBAOutput: ... + def set_shifts(self, color: ColorLike, /) -> None: ... + def get_losses(self) -> RGBALike: ... def get_bounding_rect(self, min_alpha: int = 1) -> Rect: ... def get_view(self, kind: _ViewKind = "2", /) -> BufferProxy: ... def get_buffer(self) -> BufferProxy: ... diff --git a/buildconfig/stubs/pygame/transform.pyi b/buildconfig/stubs/pygame/transform.pyi index fd412ec948..279df43b53 100644 --- a/buildconfig/stubs/pygame/transform.pyi +++ b/buildconfig/stubs/pygame/transform.pyi @@ -3,17 +3,17 @@ from typing import Optional, Union, Literal from pygame.color import Color from pygame.surface import Surface -from ._common import ColorValue, Coordinate, RectValue, Sequence +from pygame.typing import ColorLike, CoordinateLike, RectLike, SequenceLike def flip(surface: Surface, flip_x: bool, flip_y: bool) -> Surface: ... def scale( surface: Surface, - size: Coordinate, + size: CoordinateLike, dest_surface: Optional[Surface] = None, ) -> Surface: ... def scale_by( surface: Surface, - factor: Union[float, Sequence[float]], + factor: Union[float, SequenceLike[float]], dest_surface: Optional[Surface] = None, ) -> Surface: ... def rotate(surface: Surface, angle: float) -> Surface: ... @@ -22,33 +22,33 @@ def scale2x(surface: Surface, dest_surface: Optional[Surface] = None) -> Surface def grayscale(surface: Surface, dest_surface: Optional[Surface] = None) -> Surface: ... def smoothscale( surface: Surface, - size: Coordinate, + size: CoordinateLike, dest_surface: Optional[Surface] = None, ) -> Surface: ... def smoothscale_by( surface: Surface, - factor: Union[float, Sequence[float]], + factor: Union[float, SequenceLike[float]], dest_surface: Optional[Surface] = None, ) -> Surface: ... def get_smoothscale_backend() -> Literal["GENERIC", "SSE2", "NEON"]: ... def set_smoothscale_backend(backend: Literal["GENERIC", "SSE2", "NEON"]) -> None: ... -def chop(surface: Surface, rect: RectValue) -> Surface: ... +def chop(surface: Surface, rect: RectLike) -> Surface: ... def laplacian(surface: Surface, dest_surface: Optional[Surface] = None) -> Surface: ... def invert(surface: Surface, dest_surface: Optional[Surface] = None) -> Surface: ... def average_surfaces( - surfaces: Sequence[Surface], + surfaces: SequenceLike[Surface], dest_surface: Optional[Surface] = None, palette_colors: Union[bool, int] = 1, ) -> Surface: ... def average_color( - surface: Surface, rect: Optional[RectValue] = None, consider_alpha: bool = False + surface: Surface, rect: Optional[RectLike] = None, consider_alpha: bool = False ) -> Color: ... def threshold( dest_surface: Optional[Surface], surface: Surface, - search_color: Optional[ColorValue], - threshold: ColorValue = (0, 0, 0, 0), - set_color: Optional[ColorValue] = (0, 0, 0, 0), + search_color: Optional[ColorLike], + threshold: ColorLike = (0, 0, 0, 0), + set_color: Optional[ColorLike] = (0, 0, 0, 0), set_behavior: int = 1, search_surf: Optional[Surface] = None, inverse_set: bool = False, diff --git a/buildconfig/stubs/pygame/typing.pyi b/buildconfig/stubs/pygame/typing.pyi new file mode 100644 index 0000000000..3a56213a9c --- /dev/null +++ b/buildconfig/stubs/pygame/typing.pyi @@ -0,0 +1,31 @@ +from os import PathLike as PathProtocol +from typing import IO, Callable, Tuple, Union, TypeVar, Protocol, SupportsIndex + +PathLike = Union[str, bytes, PathProtocol[str], PathProtocol[bytes]] +FileLike = Union[PathLike, IO[bytes], IO[str]] + +_T = TypeVar("_T", covariant=True) + +class SequenceLike(Protocol[_T]): + """ + Variant of the standard `Sequence` ABC that only requires `__getitem__` and `__len__`. + """ + def __getitem__(self, __i: SupportsIndex) -> _T: ... + def __len__(self) -> int: ... + +# Right now, it isn't possible to annotate sizes (popular tools don't support it) but +# when it is, the below types should be appropriately annotated +CoordinateLike = SequenceLike[float] # floats are supported even if integers are usually expected +IntCoordinateLike = SequenceLike[int] # integers are strictly required + +RGBALike = Tuple[int, int, int, int] +ColorLike = Union[int, str, SequenceLike[int]] + +_CanBeRect = SequenceLike[Union[float, CoordinateLike]] + +class _HasRectAttribute(Protocol): + # An object that has a rect attribute that is either a rect, or a function + # that returns a rect confirms to the rect protocol + rect: Union["RectLike", Callable[[], "RectLike"]] + +RectLike = Union[_CanBeRect, _HasRectAttribute] diff --git a/buildconfig/stubs/pygame/window.pyi b/buildconfig/stubs/pygame/window.pyi index 1b18fa06cd..4124ed5d25 100644 --- a/buildconfig/stubs/pygame/window.pyi +++ b/buildconfig/stubs/pygame/window.pyi @@ -1,7 +1,7 @@ from typing import Optional, Tuple, Union from typing_extensions import deprecated # added in 3.13 -from pygame._common import Coordinate, RectValue +from pygame.typing import CoordinateLike, RectLike from pygame.locals import WINDOWPOS_UNDEFINED from pygame.rect import Rect from pygame.surface import Surface @@ -12,8 +12,8 @@ class Window: def __init__( self, title: str = "pygame window", - size: Coordinate = (640, 480), - position: Union[int, Coordinate] = WINDOWPOS_UNDEFINED, + size: CoordinateLike = (640, 480), + position: Union[int, CoordinateLike] = WINDOWPOS_UNDEFINED, **flags: bool ) -> None: ... def destroy(self) -> None: ... @@ -48,23 +48,23 @@ class Window: @property def mouse_rect(self) -> Optional[Rect]: ... @mouse_rect.setter - def mouse_rect(self, value: Optional[RectValue]) -> None: ... + def mouse_rect(self, value: Optional[RectLike]) -> None: ... @property def size(self) -> Tuple[int, int]: ... @size.setter - def size(self, value: Coordinate) -> None: ... + def size(self, value: CoordinateLike) -> None: ... @property def minimum_size(self) -> Tuple[int, int]: ... @minimum_size.setter - def minimum_size(self, value: Coordinate) -> None: ... + def minimum_size(self, value: CoordinateLike) -> None: ... @property def maximum_size(self) -> Tuple[int, int]: ... @maximum_size.setter - def maximum_size(self, value: Coordinate) -> None: ... + def maximum_size(self, value: CoordinateLike) -> None: ... @property def position(self) -> Tuple[int, int]: ... @position.setter - def position(self, value: Union[int, Coordinate]) -> None: ... + def position(self, value: Union[int, CoordinateLike]) -> None: ... @property def opengl(self) -> bool: ... @classmethod diff --git a/src_py/meson.build b/src_py/meson.build index 561aebaadb..541c54cd69 100644 --- a/src_py/meson.build +++ b/src_py/meson.build @@ -18,6 +18,7 @@ python_sources = files( 'sprite.py', 'surfarray.py', 'sysfont.py', + 'typing.py', 'version.py', ) py.install_sources(python_sources, subdir: pg) diff --git a/src_py/typing.py b/src_py/typing.py new file mode 100644 index 0000000000..3a56213a9c --- /dev/null +++ b/src_py/typing.py @@ -0,0 +1,31 @@ +from os import PathLike as PathProtocol +from typing import IO, Callable, Tuple, Union, TypeVar, Protocol, SupportsIndex + +PathLike = Union[str, bytes, PathProtocol[str], PathProtocol[bytes]] +FileLike = Union[PathLike, IO[bytes], IO[str]] + +_T = TypeVar("_T", covariant=True) + +class SequenceLike(Protocol[_T]): + """ + Variant of the standard `Sequence` ABC that only requires `__getitem__` and `__len__`. + """ + def __getitem__(self, __i: SupportsIndex) -> _T: ... + def __len__(self) -> int: ... + +# Right now, it isn't possible to annotate sizes (popular tools don't support it) but +# when it is, the below types should be appropriately annotated +CoordinateLike = SequenceLike[float] # floats are supported even if integers are usually expected +IntCoordinateLike = SequenceLike[int] # integers are strictly required + +RGBALike = Tuple[int, int, int, int] +ColorLike = Union[int, str, SequenceLike[int]] + +_CanBeRect = SequenceLike[Union[float, CoordinateLike]] + +class _HasRectAttribute(Protocol): + # An object that has a rect attribute that is either a rect, or a function + # that returns a rect confirms to the rect protocol + rect: Union["RectLike", Callable[[], "RectLike"]] + +RectLike = Union[_CanBeRect, _HasRectAttribute] From 18726951c721294ec2dd349393fdf535ea819370 Mon Sep 17 00:00:00 2001 From: Damiano Ricciardi Date: Tue, 16 Jul 2024 22:20:25 +0200 Subject: [PATCH 02/18] Update relative path; add typing to __init__ --- buildconfig/stubs/gen_stubs.py | 4 +++- buildconfig/stubs/pygame/typing.pyi | 12 ++++++++---- src_py/__init__.py | 6 ++++++ src_py/typing.py | 12 ++++++++---- 4 files changed, 25 insertions(+), 9 deletions(-) diff --git a/buildconfig/stubs/gen_stubs.py b/buildconfig/stubs/gen_stubs.py index 92d0099d38..a762693f41 100644 --- a/buildconfig/stubs/gen_stubs.py +++ b/buildconfig/stubs/gen_stubs.py @@ -155,4 +155,6 @@ def get_all(mod: Any): f.write(f"{element}: {constant_type}\n") # copy typing.py to typing.pyi for type checkers -shutil.copyfile("src_py/typing.py", "buildconfig/stubs/pygame/typing.pyi") +typing_py_file = pathlib.Path(__file__).parent.parent.parent / "src_py" / "typing.py" +typing_stub_file = pathlib.Path(__file__).parent / "pygame" / "typing.pyi" +shutil.copyfile(typing_py_file, typing_stub_file) diff --git a/buildconfig/stubs/pygame/typing.pyi b/buildconfig/stubs/pygame/typing.pyi index 3a56213a9c..79e512c1be 100644 --- a/buildconfig/stubs/pygame/typing.pyi +++ b/buildconfig/stubs/pygame/typing.pyi @@ -6,26 +6,30 @@ FileLike = Union[PathLike, IO[bytes], IO[str]] _T = TypeVar("_T", covariant=True) + class SequenceLike(Protocol[_T]): """ Variant of the standard `Sequence` ABC that only requires `__getitem__` and `__len__`. """ + def __getitem__(self, __i: SupportsIndex) -> _T: ... def __len__(self) -> int: ... -# Right now, it isn't possible to annotate sizes (popular tools don't support it) but -# when it is, the below types should be appropriately annotated -CoordinateLike = SequenceLike[float] # floats are supported even if integers are usually expected -IntCoordinateLike = SequenceLike[int] # integers are strictly required + +# Modify typehints when it is possible to annotate sizes +CoordinateLike = SequenceLike[float] +IntCoordinateLike = SequenceLike[int] RGBALike = Tuple[int, int, int, int] ColorLike = Union[int, str, SequenceLike[int]] _CanBeRect = SequenceLike[Union[float, CoordinateLike]] + class _HasRectAttribute(Protocol): # An object that has a rect attribute that is either a rect, or a function # that returns a rect confirms to the rect protocol rect: Union["RectLike", Callable[[], "RectLike"]] + RectLike = Union[_CanBeRect, _HasRectAttribute] diff --git a/src_py/__init__.py b/src_py/__init__.py index 9cc924420c..ac29abd3c8 100644 --- a/src_py/__init__.py +++ b/src_py/__init__.py @@ -315,6 +315,12 @@ def Window(title="pygame window", size=(640, 480), position=None, **kwargs): # _attribute_undefined("pygame.Window") +try: + import pygame.typing +except (ImportError, OSError): + typing = MissingModule("typing", urgent=0) + + # there's also a couple "internal" modules not needed # by users, but putting them here helps "dependency finder" # programs get everything they need (like py2exe) diff --git a/src_py/typing.py b/src_py/typing.py index 3a56213a9c..79e512c1be 100644 --- a/src_py/typing.py +++ b/src_py/typing.py @@ -6,26 +6,30 @@ _T = TypeVar("_T", covariant=True) + class SequenceLike(Protocol[_T]): """ Variant of the standard `Sequence` ABC that only requires `__getitem__` and `__len__`. """ + def __getitem__(self, __i: SupportsIndex) -> _T: ... def __len__(self) -> int: ... -# Right now, it isn't possible to annotate sizes (popular tools don't support it) but -# when it is, the below types should be appropriately annotated -CoordinateLike = SequenceLike[float] # floats are supported even if integers are usually expected -IntCoordinateLike = SequenceLike[int] # integers are strictly required + +# Modify typehints when it is possible to annotate sizes +CoordinateLike = SequenceLike[float] +IntCoordinateLike = SequenceLike[int] RGBALike = Tuple[int, int, int, int] ColorLike = Union[int, str, SequenceLike[int]] _CanBeRect = SequenceLike[Union[float, CoordinateLike]] + class _HasRectAttribute(Protocol): # An object that has a rect attribute that is either a rect, or a function # that returns a rect confirms to the rect protocol rect: Union["RectLike", Callable[[], "RectLike"]] + RectLike = Union[_CanBeRect, _HasRectAttribute] From cf84baf177e4b9ca8a28a5f55a6e560a995d4b07 Mon Sep 17 00:00:00 2001 From: Damiano Ricciardi Date: Tue, 16 Jul 2024 22:23:26 +0200 Subject: [PATCH 03/18] add _co to _T as required by the lint checker --- buildconfig/stubs/pygame/typing.pyi | 6 +++--- src_py/typing.py | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/buildconfig/stubs/pygame/typing.pyi b/buildconfig/stubs/pygame/typing.pyi index 79e512c1be..77a3cdf66e 100644 --- a/buildconfig/stubs/pygame/typing.pyi +++ b/buildconfig/stubs/pygame/typing.pyi @@ -4,15 +4,15 @@ from typing import IO, Callable, Tuple, Union, TypeVar, Protocol, SupportsIndex PathLike = Union[str, bytes, PathProtocol[str], PathProtocol[bytes]] FileLike = Union[PathLike, IO[bytes], IO[str]] -_T = TypeVar("_T", covariant=True) +_T_co = TypeVar("_T_co", covariant=True) -class SequenceLike(Protocol[_T]): +class SequenceLike(Protocol[_T_co]): """ Variant of the standard `Sequence` ABC that only requires `__getitem__` and `__len__`. """ - def __getitem__(self, __i: SupportsIndex) -> _T: ... + def __getitem__(self, __i: SupportsIndex) -> _T_co: ... def __len__(self) -> int: ... diff --git a/src_py/typing.py b/src_py/typing.py index 79e512c1be..77a3cdf66e 100644 --- a/src_py/typing.py +++ b/src_py/typing.py @@ -4,15 +4,15 @@ PathLike = Union[str, bytes, PathProtocol[str], PathProtocol[bytes]] FileLike = Union[PathLike, IO[bytes], IO[str]] -_T = TypeVar("_T", covariant=True) +_T_co = TypeVar("_T_co", covariant=True) -class SequenceLike(Protocol[_T]): +class SequenceLike(Protocol[_T_co]): """ Variant of the standard `Sequence` ABC that only requires `__getitem__` and `__len__`. """ - def __getitem__(self, __i: SupportsIndex) -> _T: ... + def __getitem__(self, __i: SupportsIndex) -> _T_co: ... def __len__(self) -> int: ... From 55d132dfb29f2d2101f7f7b394a6e265e1da78f6 Mon Sep 17 00:00:00 2001 From: Damiano Ricciardi Date: Wed, 17 Jul 2024 09:53:44 +0200 Subject: [PATCH 04/18] Modify PathProtocol to pass checks --- buildconfig/stubs/pygame/typing.pyi | 16 +++++++++++----- src_py/typing.py | 16 +++++++++++----- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/buildconfig/stubs/pygame/typing.pyi b/buildconfig/stubs/pygame/typing.pyi index 77a3cdf66e..c1913cf682 100644 --- a/buildconfig/stubs/pygame/typing.pyi +++ b/buildconfig/stubs/pygame/typing.pyi @@ -1,18 +1,24 @@ -from os import PathLike as PathProtocol from typing import IO, Callable, Tuple, Union, TypeVar, Protocol, SupportsIndex -PathLike = Union[str, bytes, PathProtocol[str], PathProtocol[bytes]] +_T1_co = TypeVar("_T1_co", covariant=True) + + +class _PathProtocol(Protocol[_T1_co]): + def __fspath__(self) -> _T1_co: ... + + +PathLike = Union[str, bytes, _PathProtocol[str], _PathProtocol[bytes]] FileLike = Union[PathLike, IO[bytes], IO[str]] -_T_co = TypeVar("_T_co", covariant=True) +_T2_co = TypeVar("_T2_co", covariant=True) -class SequenceLike(Protocol[_T_co]): +class SequenceLike(Protocol[_T2_co]): """ Variant of the standard `Sequence` ABC that only requires `__getitem__` and `__len__`. """ - def __getitem__(self, __i: SupportsIndex) -> _T_co: ... + def __getitem__(self, __i: SupportsIndex) -> _T2_co: ... def __len__(self) -> int: ... diff --git a/src_py/typing.py b/src_py/typing.py index 77a3cdf66e..c1913cf682 100644 --- a/src_py/typing.py +++ b/src_py/typing.py @@ -1,18 +1,24 @@ -from os import PathLike as PathProtocol from typing import IO, Callable, Tuple, Union, TypeVar, Protocol, SupportsIndex -PathLike = Union[str, bytes, PathProtocol[str], PathProtocol[bytes]] +_T1_co = TypeVar("_T1_co", covariant=True) + + +class _PathProtocol(Protocol[_T1_co]): + def __fspath__(self) -> _T1_co: ... + + +PathLike = Union[str, bytes, _PathProtocol[str], _PathProtocol[bytes]] FileLike = Union[PathLike, IO[bytes], IO[str]] -_T_co = TypeVar("_T_co", covariant=True) +_T2_co = TypeVar("_T2_co", covariant=True) -class SequenceLike(Protocol[_T_co]): +class SequenceLike(Protocol[_T2_co]): """ Variant of the standard `Sequence` ABC that only requires `__getitem__` and `__len__`. """ - def __getitem__(self, __i: SupportsIndex) -> _T_co: ... + def __getitem__(self, __i: SupportsIndex) -> _T2_co: ... def __len__(self) -> int: ... From 23a9006972464d5c0b44783e02849e63ffbd6311 Mon Sep 17 00:00:00 2001 From: Damiano Ricciardi Date: Wed, 17 Jul 2024 13:10:14 +0200 Subject: [PATCH 05/18] Add test --- buildconfig/stubs/stubcheck.py | 36 +++++++++- buildconfig/stubs/typing_sample_app.py | 92 ++++++++++++++++++++++++++ 2 files changed, 126 insertions(+), 2 deletions(-) create mode 100644 buildconfig/stubs/typing_sample_app.py diff --git a/buildconfig/stubs/stubcheck.py b/buildconfig/stubs/stubcheck.py index 14477a31d5..d023e42057 100644 --- a/buildconfig/stubs/stubcheck.py +++ b/buildconfig/stubs/stubcheck.py @@ -11,9 +11,33 @@ STUBS_BASE_DIR = Path(__file__).parent -def main(): +def typing_check(): """ - Main entrypoint + Ensure type aliases in typing.py work as expected with type checkers + """ + mypy_version_args = [sys.executable, "-m", "mypy"] + try: + version = subprocess.run( + [*mypy_version_args, "--version"], capture_output=True, check=True, text=True + ).stdout.strip() + except subprocess.CalledProcessError: + print("ERROR: could not validate typing.py, make sure you have mypy installed") + return + + mypy_args = [*mypy_version_args, "typing_sample_app.py"] + cmd = " ".join(mypy_args) + print(f"Using mypy invocation: `{cmd}` (version: {version})") + prev_dir = os.getcwd() + try: + os.chdir(STUBS_BASE_DIR) + returncode = subprocess.run([*mypy_args]).returncode + print(f"mypy process finished with return code {returncode}") + finally: + os.chdir(prev_dir) + +def stubs_check(): + """ + Validate the stubs files """ for stubtest in ([sys.executable, "-m", "mypy.stubtest"], ["stubtest"]): try: @@ -41,5 +65,13 @@ def main(): sys.exit(1) +def main(): + """ + Main entrypoint + """ + typing_check() + stubs_check() + + if __name__ == "__main__": main() diff --git a/buildconfig/stubs/typing_sample_app.py b/buildconfig/stubs/typing_sample_app.py new file mode 100644 index 0000000000..4112e6a24d --- /dev/null +++ b/buildconfig/stubs/typing_sample_app.py @@ -0,0 +1,92 @@ +""" +Sample app run by mypy to ensure typing.py aliases work as expected +""" +from pygame import typing +import pygame + +# validate SequenceLike +class MySequence: + def __getitem__(self, index): + if index > 20: + raise IndexError() + if index % 2 == 0: + return 1 + return 0 + + def __len__(self): + return 20 + +def validator_SequenceLike(sequence: typing.SequenceLike) -> int: + return 0 + +# must pass +validator_SequenceLike(MySequence()) +validator_SequenceLike([0, 1, 2, 3]) +validator_SequenceLike((0, 1, 2, 3)) +validator_SequenceLike(pygame.Rect(-10, 10, 40, 40)) +validator_SequenceLike(pygame.Vector2()) +validator_SequenceLike("1234567890") + +# validate PathLike +class MyPath: + def __fspath__(self) -> str: + return "file.py" + +def validator_PathLike(path: typing.PathLike) -> int: + return 0 + +# must pass +validator_PathLike("file.py") +validator_PathLike(b"file.py") +validator_PathLike(MyPath()) + +# validate CoordinateLike, IntCoordinateLike + +def validator_CoordinateLike(coordinate: typing.CoordinateLike) -> int: + return 0 + +def validator_IntCoordinateLike(coordinate: typing.IntCoordinateLike) -> int: + return 0 + +# must pass +validator_CoordinateLike((1, 2)) +validator_CoordinateLike([3, -4]) +validator_CoordinateLike((5, -6.5)) +validator_CoordinateLike((-6.7, 8.9)) +validator_CoordinateLike(pygame.Vector2()) + +validator_IntCoordinateLike((3, 4)) +validator_IntCoordinateLike([-4, -3]) + +# validate RGBALike, ColorLike +def validator_RGBALike(rgba: typing.RGBALike) -> int: + return 0 + +def validator_ColorLike(color: typing.ColorLike) -> int: + return 0 + +# must pass +validator_RGBALike((100, 200, 50, 20)) +validator_ColorLike("green") +validator_ColorLike(1) +validator_ColorLike((255, 255, 255, 30)) +validator_ColorLike(pygame.Color(100, 100, 100, 100)) + +# validate RectLike +class MyObject1: + def __init__(self): + self.rect = pygame.Rect(10, 10, 20, 20) + +class MyObject2: + def __init__(self): + self.rect = lambda: pygame.Rect(5, 5, 10, 10) + +def validator_RectLike(rect: typing.RectLike) -> int: + return 0 + +# must pass +validator_RectLike((10, 10, 10, 10)) +validator_RectLike(((5, 5), (30, 30))) +validator_RectLike(pygame.Rect(1, 2, 3, 4)) +validator_RectLike(MyObject1()) +validator_RectLike(MyObject2()) From 9d99d6eabfca203683d2d7d787e98cb92399c8bb Mon Sep 17 00:00:00 2001 From: Damiano Ricciardi Date: Wed, 17 Jul 2024 22:24:46 +0200 Subject: [PATCH 06/18] Refactor module, add temporary docs, rename some typehints --- buildconfig/stubs/pygame/_sdl2/video.pyi | 42 ++++++++--------- buildconfig/stubs/pygame/camera.pyi | 4 +- buildconfig/stubs/pygame/cursors.pyi | 12 ++--- buildconfig/stubs/pygame/display.pyi | 20 ++++---- buildconfig/stubs/pygame/draw.pyi | 22 ++++----- buildconfig/stubs/pygame/geometry.pyi | 26 +++++----- buildconfig/stubs/pygame/gfxdraw.pyi | 12 ++--- buildconfig/stubs/pygame/image.pyi | 10 ++-- buildconfig/stubs/pygame/mask.pyi | 26 +++++----- buildconfig/stubs/pygame/mouse.pyi | 10 ++-- buildconfig/stubs/pygame/rect.pyi | 60 ++++++++++++------------ buildconfig/stubs/pygame/sprite.pyi | 4 +- buildconfig/stubs/pygame/surface.pyi | 34 +++++++------- buildconfig/stubs/pygame/transform.pyi | 6 +-- buildconfig/stubs/pygame/typing.pyi | 32 ++++++++----- buildconfig/stubs/pygame/window.pyi | 14 +++--- buildconfig/stubs/typing_sample_app.py | 26 +++++----- docs/reST/index.rst | 3 ++ docs/reST/ref/typing.rst | 47 +++++++++++++++++++ src_c/doc/typing_doc.h | 2 + src_py/typing.py | 32 ++++++++----- 21 files changed, 258 insertions(+), 186 deletions(-) create mode 100644 docs/reST/ref/typing.rst create mode 100644 src_c/doc/typing_doc.h diff --git a/buildconfig/stubs/pygame/_sdl2/video.pyi b/buildconfig/stubs/pygame/_sdl2/video.pyi index 42bfcb277b..b34970d4eb 100644 --- a/buildconfig/stubs/pygame/_sdl2/video.pyi +++ b/buildconfig/stubs/pygame/_sdl2/video.pyi @@ -5,7 +5,7 @@ from pygame.rect import Rect from pygame.surface import Surface from pygame.window import Window as Window -from pygame.typing import ColorLike, RectLike, CoordinateLike +from pygame.typing import ColorLike, RectLike, Coordinate WINDOWPOS_UNDEFINED: int WINDOWPOS_CENTERED: int @@ -74,26 +74,26 @@ class Texture: ) -> None: ... def draw_triangle( self, - p1_xy: CoordinateLike, - p2_xy: CoordinateLike, - p3_xy: CoordinateLike, - p1_uv: CoordinateLike = (0.0, 0.0), - p2_uv: CoordinateLike = (1.0, 1.0), - p3_uv: CoordinateLike = (0.0, 1.0), + p1_xy: Coordinate, + p2_xy: Coordinate, + p3_xy: Coordinate, + p1_uv: Coordinate = (0.0, 0.0), + p2_uv: Coordinate = (1.0, 1.0), + p3_uv: Coordinate = (0.0, 1.0), p1_mod: Iterable[int] = (255, 255, 255, 255), p2_mod: Iterable[int] = (255, 255, 255, 255), p3_mod: Iterable[int] = (255, 255, 255, 255), ) -> None: ... def draw_quad( self, - p1_xy: CoordinateLike, - p2_xy: CoordinateLike, - p3_xy: CoordinateLike, - p4_xy: CoordinateLike, - p1_uv: CoordinateLike = (0.0, 0.0), - p2_uv: CoordinateLike = (1.0, 0.0), - p3_uv: CoordinateLike = (1.0, 1.0), - p4_uv: CoordinateLike = (0.0, 1.0), + p1_xy: Coordinate, + p2_xy: Coordinate, + p3_xy: Coordinate, + p4_xy: Coordinate, + p1_uv: Coordinate = (0.0, 0.0), + p2_uv: Coordinate = (1.0, 0.0), + p3_uv: Coordinate = (1.0, 1.0), + p4_uv: Coordinate = (0.0, 1.0), p1_mod: Iterable[int] = (255, 255, 255, 255), p2_mod: Iterable[int] = (255, 255, 255, 255), p3_mod: Iterable[int] = (255, 255, 255, 255), @@ -155,21 +155,21 @@ class Renderer: area: Optional[RectLike] = None, special_flags: int = 0, ) -> Rect: ... - def draw_line(self, p1: CoordinateLike, p2: CoordinateLike) -> None: ... - def draw_point(self, point: CoordinateLike) -> None: ... + def draw_line(self, p1: Coordinate, p2: Coordinate) -> None: ... + def draw_point(self, point: Coordinate) -> None: ... def draw_rect(self, rect: RectLike) -> None: ... def fill_rect(self, rect: RectLike) -> None: ... def draw_triangle( - self, p1: CoordinateLike, p2: CoordinateLike, p3: CoordinateLike + self, p1: Coordinate, p2: Coordinate, p3: Coordinate ) -> None: ... def fill_triangle( - self, p1: CoordinateLike, p2: CoordinateLike, p3: CoordinateLike + self, p1: Coordinate, p2: Coordinate, p3: Coordinate ) -> None: ... def draw_quad( - self, p1: CoordinateLike, p2: CoordinateLike, p3: CoordinateLike, p4: CoordinateLike + self, p1: Coordinate, p2: Coordinate, p3: Coordinate, p4: Coordinate ) -> None: ... def fill_quad( - self, p1: CoordinateLike, p2: CoordinateLike, p3: CoordinateLike, p4: CoordinateLike + self, p1: Coordinate, p2: Coordinate, p3: Coordinate, p4: Coordinate ) -> None: ... def to_surface( self, surface: Optional[Surface] = None, area: Optional[RectLike] = None diff --git a/buildconfig/stubs/pygame/camera.pyi b/buildconfig/stubs/pygame/camera.pyi index 5b481e5e72..de5eac1767 100644 --- a/buildconfig/stubs/pygame/camera.pyi +++ b/buildconfig/stubs/pygame/camera.pyi @@ -1,7 +1,7 @@ from abc import ABC, abstractmethod from typing import List, Optional, Tuple, Union, Literal -from pygame.typing import IntCoordinateLike +from pygame.typing import IntCoordinate from pygame.surface import Surface @@ -36,7 +36,7 @@ class Camera(AbstractCamera): def __init__( self, device: Union[str, int] = 0, - size: IntCoordinateLike = (640, 480), + size: IntCoordinate = (640, 480), format: str = "RGB", ) -> None: ... def start(self) -> None: ... diff --git a/buildconfig/stubs/pygame/cursors.pyi b/buildconfig/stubs/pygame/cursors.pyi index d0207fde2b..d75a66cc77 100644 --- a/buildconfig/stubs/pygame/cursors.pyi +++ b/buildconfig/stubs/pygame/cursors.pyi @@ -2,7 +2,7 @@ from typing import Any, Iterator, Literal, Tuple, Union, overload from pygame.surface import Surface -from pygame.typing import FileLike, IntCoordinateLike, SequenceLike +from pygame.typing import FileLike, IntCoordinate, SequenceLike _Small_string = Tuple[ str, str, str, str, str, str, str, str, str, str, str, str, str, str, str, str @@ -64,15 +64,15 @@ class Cursor: @overload def __init__( self, - size: IntCoordinateLike, - hotspot: IntCoordinateLike, + size: IntCoordinate, + hotspot: IntCoordinate, xormasks: SequenceLike[int], andmasks: SequenceLike[int], ) -> None: ... @overload def __init__( self, - hotspot: IntCoordinateLike, + hotspot: IntCoordinate, surface: Surface, ) -> None: ... def __iter__(self) -> Iterator[Any]: ... @@ -81,11 +81,11 @@ class Cursor: def __hash__(self) -> int: ... def __getitem__( self, index: int - ) -> Union[int, IntCoordinateLike, Surface]: ... + ) -> Union[int, IntCoordinate, Surface]: ... copy = __copy__ type: Literal["system", "color", "bitmap"] data: Union[ Tuple[int], Tuple[Tuple[int, int], Tuple[int, int], Tuple[int, ...], Tuple[int, ...]], - Tuple[IntCoordinateLike, Surface], + Tuple[IntCoordinate, Surface], ] diff --git a/buildconfig/stubs/pygame/display.pyi b/buildconfig/stubs/pygame/display.pyi index 0c41bc77b6..2b6e952377 100644 --- a/buildconfig/stubs/pygame/display.pyi +++ b/buildconfig/stubs/pygame/display.pyi @@ -8,10 +8,10 @@ from pygame._sdl2 import Window from pygame.typing import ( ColorLike, - CoordinateLike, - IntCoordinateLike, + Coordinate, + IntCoordinate, RectLike, - RGBALike, + RGBATuple, SequenceLike, ) @@ -21,9 +21,9 @@ class _VidInfo: video_mem: int bitsize: int bytesize: int - masks: RGBALike - shifts: RGBALike - losses: RGBALike + masks: RGBATuple + shifts: RGBATuple + losses: RGBATuple blit_hw: int blit_hw_CC: int blit_hw_A: int @@ -38,7 +38,7 @@ def init() -> None: ... def quit() -> None: ... def get_init() -> bool: ... def set_mode( - size: CoordinateLike = (0, 0), + size: Coordinate = (0, 0), flags: int = 0, depth: int = 0, display: int = 0, @@ -53,7 +53,7 @@ def update( @overload def update(x: int, y: int, w: int, h: int, /) -> None: ... @overload -def update(xy: CoordinateLike, wh: CoordinateLike, /) -> None: ... +def update(xy: Coordinate, wh: Coordinate, /) -> None: ... def get_driver() -> str: ... def Info() -> _VidInfo: ... def get_wm_info() -> Dict[str, int]: ... @@ -63,7 +63,7 @@ def list_modes( display: int = 0, ) -> List[Tuple[int, int]]: ... def mode_ok( - size: IntCoordinateLike, + size: IntCoordinate, flags: int = 0, depth: int = 0, display: int = 0, @@ -86,7 +86,7 @@ def set_palette(palette: SequenceLike[ColorLike], /) -> None: ... def get_num_displays() -> int: ... def get_window_size() -> Tuple[int, int]: ... def get_window_position() -> Tuple[int, int]:... -def set_window_position(position: CoordinateLike) -> None:... +def set_window_position(position: Coordinate) -> None:... def get_allow_screensaver() -> bool: ... def set_allow_screensaver(value: bool = True) -> None: ... def get_desktop_sizes() -> List[Tuple[int, int]]: ... diff --git a/buildconfig/stubs/pygame/draw.pyi b/buildconfig/stubs/pygame/draw.pyi index 80f023f84a..57bae66712 100644 --- a/buildconfig/stubs/pygame/draw.pyi +++ b/buildconfig/stubs/pygame/draw.pyi @@ -2,7 +2,7 @@ from pygame.rect import Rect from pygame.surface import Surface from typing import overload -from pygame.typing import ColorLike, CoordinateLike, RectLike, SequenceLike +from pygame.typing import ColorLike, Coordinate, RectLike, SequenceLike def rect( surface: Surface, @@ -18,13 +18,13 @@ def rect( def polygon( surface: Surface, color: ColorLike, - points: SequenceLike[CoordinateLike], + points: SequenceLike[Coordinate], width: int = 0, ) -> Rect: ... def circle( surface: Surface, color: ColorLike, - center: CoordinateLike, + center: Coordinate, radius: float, width: int = 0, draw_top_right: bool = False, @@ -36,7 +36,7 @@ def circle( def aacircle( surface: Surface, color: ColorLike, - center: CoordinateLike, + center: Coordinate, radius: float, width: int = 0, ) -> Rect: ... @@ -44,7 +44,7 @@ def aacircle( def aacircle( surface: Surface, color: ColorLike, - center: CoordinateLike, + center: Coordinate, radius: float, width: int = 0, draw_top_right: bool = False, @@ -66,26 +66,26 @@ def arc( def line( surface: Surface, color: ColorLike, - start_pos: CoordinateLike, - end_pos: CoordinateLike, + start_pos: Coordinate, + end_pos: Coordinate, width: int = 1, ) -> Rect: ... def lines( surface: Surface, color: ColorLike, closed: bool, - points: SequenceLike[CoordinateLike], + points: SequenceLike[Coordinate], width: int = 1, ) -> Rect: ... def aaline( surface: Surface, color: ColorLike, - start_pos: CoordinateLike, - end_pos: CoordinateLike, + start_pos: Coordinate, + end_pos: Coordinate, ) -> Rect: ... def aalines( surface: Surface, color: ColorLike, closed: bool, - points: SequenceLike[CoordinateLike], + points: SequenceLike[Coordinate], ) -> Rect: ... diff --git a/buildconfig/stubs/pygame/geometry.pyi b/buildconfig/stubs/pygame/geometry.pyi index 05c5881d27..c82da74b2c 100644 --- a/buildconfig/stubs/pygame/geometry.pyi +++ b/buildconfig/stubs/pygame/geometry.pyi @@ -7,11 +7,11 @@ from typing import ( ) from pygame import Rect, FRect -from pygame.typing import CoordinateLike, RectLike, SequenceLike +from pygame.typing import Coordinate, RectLike, SequenceLike from .rect import Rect, FRect from .math import Vector2 -_CanBeCircle = Union[Circle, Tuple[CoordinateLike, float], SequenceLike[float]] +_CanBeCircle = Union[Circle, Tuple[Coordinate, float], SequenceLike[float]] class _HasCirclettribute(Protocol): # An object that has a circle attribute that is either a circle, or a function @@ -19,7 +19,7 @@ class _HasCirclettribute(Protocol): circle: Union[_CanBeCircle, Callable[[], _CanBeCircle]] _CircleValue = Union[_CanBeCircle, _HasCirclettribute] -_CanBeCollided = Union[Circle, Rect, FRect, CoordinateLike, Vector2] +_CanBeCollided = Union[Circle, Rect, FRect, Coordinate, Vector2] class Circle: @property @@ -61,37 +61,37 @@ class Circle: @property def center(self) -> Tuple[float, float]: ... @center.setter - def center(self, value: CoordinateLike) -> None: ... + def center(self, value: Coordinate) -> None: ... @overload def __init__(self, x: float, y: float, r: float) -> None: ... @overload - def __init__(self, pos: CoordinateLike, r: float) -> None: ... + def __init__(self, pos: Coordinate, r: float) -> None: ... @overload def __init__(self, circle: _CircleValue) -> None: ... @overload def move(self, x: float, y: float, /) -> Circle: ... @overload - def move(self, move_by: CoordinateLike, /) -> Circle: ... + def move(self, move_by: Coordinate, /) -> Circle: ... @overload def move_ip(self, x: float, y: float, /) -> None: ... @overload - def move_ip(self, move_by: CoordinateLike, /) -> None: ... + def move_ip(self, move_by: Coordinate, /) -> None: ... @overload def collidepoint(self, x: float, y: float, /) -> bool: ... @overload - def collidepoint(self, point: CoordinateLike, /) -> bool: ... + def collidepoint(self, point: Coordinate, /) -> bool: ... @overload def collidecircle(self, circle: _CircleValue, /) -> bool: ... @overload def collidecircle(self, x: float, y: float, r: float, /) -> bool: ... @overload - def collidecircle(self, center: CoordinateLike, r: float, /) -> bool: ... + def collidecircle(self, center: Coordinate, r: float, /) -> bool: ... @overload def colliderect(self, rect: RectLike, /) -> bool: ... @overload def colliderect(self, x: float, y: float, w: float, h: float, /) -> bool: ... @overload - def colliderect(self, topleft: CoordinateLike, size: CoordinateLike, /) -> bool: ... + def colliderect(self, topleft: Coordinate, size: Coordinate, /) -> bool: ... def collideswith(self, other: _CanBeCollided, /) -> bool: ... def contains(self, shape: _CanBeCollided) -> bool: ... @overload @@ -99,13 +99,13 @@ class Circle: @overload def update(self, x: float, y: float, r: float, /) -> None: ... @overload - def update(self, center: CoordinateLike, r: float, /) -> None: ... + def update(self, center: Coordinate, r: float, /) -> None: ... @overload - def rotate(self, angle: float, rotation_point: CoordinateLike, /) -> Circle: ... + def rotate(self, angle: float, rotation_point: Coordinate, /) -> Circle: ... @overload def rotate(self, angle: float, /) -> Circle: ... @overload - def rotate_ip(self, angle: float, rotation_point: CoordinateLike, /) -> None: ... + def rotate_ip(self, angle: float, rotation_point: Coordinate, /) -> None: ... @overload def rotate_ip(self, angle: float, /) -> None: ... def as_rect(self) -> Rect: ... diff --git a/buildconfig/stubs/pygame/gfxdraw.pyi b/buildconfig/stubs/pygame/gfxdraw.pyi index 062481e61d..44a02d7d82 100644 --- a/buildconfig/stubs/pygame/gfxdraw.pyi +++ b/buildconfig/stubs/pygame/gfxdraw.pyi @@ -1,6 +1,6 @@ from pygame.surface import Surface -from pygame.typing import ColorLike, CoordinateLike, RectLike, SequenceLike +from pygame.typing import ColorLike, Coordinate, RectLike, SequenceLike def pixel(surface: Surface, x: int, y: int, color: ColorLike, /) -> None: ... def hline(surface: Surface, x1: int, x2: int, y: int, color: ColorLike, /) -> None: ... @@ -73,17 +73,17 @@ def filled_trigon( color: ColorLike, / ) -> None: ... def polygon( - surface: Surface, points: SequenceLike[CoordinateLike], color: ColorLike, / + surface: Surface, points: SequenceLike[Coordinate], color: ColorLike, / ) -> None: ... def aapolygon( - surface: Surface, points: SequenceLike[CoordinateLike], color: ColorLike, / + surface: Surface, points: SequenceLike[Coordinate], color: ColorLike, / ) -> None: ... def filled_polygon( - surface: Surface, points: SequenceLike[CoordinateLike], color: ColorLike, / + surface: Surface, points: SequenceLike[Coordinate], color: ColorLike, / ) -> None: ... def textured_polygon( - surface: Surface, points: SequenceLike[CoordinateLike], texture: Surface, tx: int, ty: int, / + surface: Surface, points: SequenceLike[Coordinate], texture: Surface, tx: int, ty: int, / ) -> None: ... def bezier( - surface: Surface, points: SequenceLike[CoordinateLike], steps: int, color: ColorLike, / + surface: Surface, points: SequenceLike[Coordinate], steps: int, color: ColorLike, / ) -> None: ... diff --git a/buildconfig/stubs/pygame/image.pyi b/buildconfig/stubs/pygame/image.pyi index 36ded0b1ff..0e02f02271 100644 --- a/buildconfig/stubs/pygame/image.pyi +++ b/buildconfig/stubs/pygame/image.pyi @@ -4,7 +4,7 @@ from typing_extensions import deprecated # added in 3.13 from pygame.bufferproxy import BufferProxy from pygame.surface import Surface -from pygame.typing import FileLike, IntCoordinateLike, CoordinateLike +from pygame.typing import FileLike, IntCoordinate, Coordinate _BufferStyle = Union[BufferProxy, bytes, bytearray, memoryview] _to_bytes_format = Literal[ @@ -14,7 +14,7 @@ _from_buffer_format = Literal["P", "RGB", "BGR", "BGRA", "RGBX", "RGBA", "ARGB"] _from_bytes_format = Literal["P", "RGB", "RGBX", "RGBA", "ARGB", "BGRA", "ABGR"] def load(file: FileLike, namehint: str = "") -> Surface: ... -def load_sized_svg(file: FileLike, size: CoordinateLike) -> Surface: ... +def load_sized_svg(file: FileLike, size: Coordinate) -> Surface: ... def save(surface: Surface, file: FileLike, namehint: str = "") -> None: ... def get_sdl_image_version(linked: bool = True) -> Optional[Tuple[int, int, int]]: ... def get_extended() -> bool: ... @@ -28,7 +28,7 @@ def tostring( @deprecated("since 2.3.0. Use `pygame.image.frombytes` instead") def fromstring( bytes: bytes, - size: IntCoordinateLike, + size: IntCoordinate, format: _from_bytes_format, flipped: bool = False, pitch: int = -1, @@ -41,14 +41,14 @@ def tobytes( ) -> bytes: ... def frombytes( bytes: bytes, - size: IntCoordinateLike, + size: IntCoordinate, format: _from_bytes_format, flipped: bool = False, pitch: int = -1, ) -> Surface: ... def frombuffer( bytes: _BufferStyle, - size: IntCoordinateLike, + size: IntCoordinate, format: _from_buffer_format, pitch: int = -1, ) -> Surface: ... diff --git a/buildconfig/stubs/pygame/mask.pyi b/buildconfig/stubs/pygame/mask.pyi index 7d3fbc076c..0ea50adeb6 100644 --- a/buildconfig/stubs/pygame/mask.pyi +++ b/buildconfig/stubs/pygame/mask.pyi @@ -3,7 +3,7 @@ from typing import Any, List, Optional, Tuple, Union from pygame.rect import Rect from pygame.surface import Surface -from pygame.typing import ColorLike, CoordinateLike, RectLike +from pygame.typing import ColorLike, Coordinate, RectLike def from_surface(surface: Surface, threshold: int = 127) -> Mask: ... def from_threshold( @@ -15,22 +15,22 @@ def from_threshold( ) -> Mask: ... class Mask: - def __init__(self, size: CoordinateLike, fill: bool = False) -> None: ... + def __init__(self, size: Coordinate, fill: bool = False) -> None: ... def __copy__(self) -> Mask: ... copy = __copy__ def get_size(self) -> Tuple[int, int]: ... def get_rect(self, **kwargs: Any) -> Rect: ... # Dict type needs to be completed - def get_at(self, pos: CoordinateLike) -> int: ... - def set_at(self, pos: CoordinateLike, value: int = 1) -> None: ... - def overlap(self, other: Mask, offset: CoordinateLike) -> Optional[Tuple[int, int]]: ... - def overlap_area(self, other: Mask, offset: CoordinateLike) -> int: ... - def overlap_mask(self, other: Mask, offset: CoordinateLike) -> Mask: ... + def get_at(self, pos: Coordinate) -> int: ... + def set_at(self, pos: Coordinate, value: int = 1) -> None: ... + def overlap(self, other: Mask, offset: Coordinate) -> Optional[Tuple[int, int]]: ... + def overlap_area(self, other: Mask, offset: Coordinate) -> int: ... + def overlap_mask(self, other: Mask, offset: Coordinate) -> Mask: ... def fill(self) -> None: ... def clear(self) -> None: ... def invert(self) -> None: ... - def scale(self, scale: CoordinateLike) -> Mask: ... - def draw(self, other: Mask, offset: CoordinateLike) -> None: ... - def erase(self, other: Mask, offset: CoordinateLike) -> None: ... + def scale(self, scale: Coordinate) -> Mask: ... + def draw(self, other: Mask, offset: Coordinate) -> None: ... + def erase(self, other: Mask, offset: Coordinate) -> None: ... def count(self) -> int: ... def centroid(self) -> Tuple[int, int]: ... def angle(self) -> float: ... @@ -39,9 +39,9 @@ class Mask: self, other: Mask, output: Optional[Mask] = None, - offset: CoordinateLike = (0, 0), + offset: Coordinate = (0, 0), ) -> Mask: ... - def connected_component(self, pos: CoordinateLike = ...) -> Mask: ... + def connected_component(self, pos: Coordinate = ...) -> Mask: ... def connected_components(self, minimum: int = 0) -> List[Mask]: ... def get_bounding_rects(self) -> List[Rect]: ... def to_surface( @@ -51,7 +51,7 @@ class Mask: unsetsurface: Optional[Surface] = None, setcolor: Optional[ColorLike] = (255, 255, 255, 255), unsetcolor: Optional[ColorLike] = (0, 0, 0, 255), - dest: Union[RectLike, CoordinateLike] = (0, 0), + dest: Union[RectLike, Coordinate] = (0, 0), ) -> Surface: ... MaskType = Mask diff --git a/buildconfig/stubs/pygame/mouse.pyi b/buildconfig/stubs/pygame/mouse.pyi index 9319024070..42ea298b45 100644 --- a/buildconfig/stubs/pygame/mouse.pyi +++ b/buildconfig/stubs/pygame/mouse.pyi @@ -4,7 +4,7 @@ from typing_extensions import deprecated # added in 3.13 from pygame.cursors import Cursor from pygame.surface import Surface -from pygame.typing import CoordinateLike, SequenceLike, IntCoordinateLike +from pygame.typing import Coordinate, SequenceLike, IntCoordinate @overload def get_pressed(num_buttons: Literal[3] = 3) -> Tuple[bool, bool, bool]: ... @@ -15,7 +15,7 @@ def get_just_released() -> Tuple[bool, bool, bool, bool, bool]: ... def get_pos() -> Tuple[int, int]: ... def get_rel() -> Tuple[int, int]: ... @overload -def set_pos(pos: CoordinateLike, /) -> None: ... +def set_pos(pos: Coordinate, /) -> None: ... @overload def set_pos(x: float, y: float, /) -> None: ... def set_visible(value: bool, /) -> int: ... @@ -27,13 +27,13 @@ def set_cursor(cursor: Cursor) -> None: ... def set_cursor(constant: int) -> None: ... @overload def set_cursor( - size: IntCoordinateLike, - hotspot: IntCoordinateLike, + size: IntCoordinate, + hotspot: IntCoordinate, xormasks: SequenceLike[int], andmasks: SequenceLike[int], ) -> None: ... @overload -def set_cursor(hotspot: IntCoordinateLike, surface: Surface) -> None: ... +def set_cursor(hotspot: IntCoordinate, surface: Surface) -> None: ... def get_cursor() -> Cursor: ... @deprecated("since 2.2.0. Use `pygame.mouse.set_cursor` instead") def set_system_cursor(cursor: int, /) -> None: ... diff --git a/buildconfig/stubs/pygame/rect.pyi b/buildconfig/stubs/pygame/rect.pyi index 81facde978..9899c84270 100644 --- a/buildconfig/stubs/pygame/rect.pyi +++ b/buildconfig/stubs/pygame/rect.pyi @@ -12,7 +12,7 @@ from typing import ( Optional, ) -from pygame.typing import CoordinateLike, RectLike, SequenceLike +from pygame.typing import Coordinate, RectLike, SequenceLike if sys.version_info >= (3, 11): from typing import Self @@ -59,39 +59,39 @@ class _GenericRect(Collection[_N]): @property def topleft(self) -> Tuple[_N, _N]: ... @topleft.setter - def topleft(self, value: CoordinateLike) -> None: ... + def topleft(self, value: Coordinate) -> None: ... @property def bottomleft(self) -> Tuple[_N, _N]: ... @bottomleft.setter - def bottomleft(self, value: CoordinateLike) -> None: ... + def bottomleft(self, value: Coordinate) -> None: ... @property def topright(self) -> Tuple[_N, _N]: ... @topright.setter - def topright(self, value: CoordinateLike) -> None: ... + def topright(self, value: Coordinate) -> None: ... @property def bottomright(self) -> Tuple[_N, _N]: ... @bottomright.setter - def bottomright(self, value: CoordinateLike) -> None: ... + def bottomright(self, value: Coordinate) -> None: ... @property def midtop(self) -> Tuple[_N, _N]: ... @midtop.setter - def midtop(self, value: CoordinateLike) -> None: ... + def midtop(self, value: Coordinate) -> None: ... @property def midleft(self) -> Tuple[_N, _N]: ... @midleft.setter - def midleft(self, value: CoordinateLike) -> None: ... + def midleft(self, value: Coordinate) -> None: ... @property def midbottom(self) -> Tuple[_N, _N]: ... @midbottom.setter - def midbottom(self, value: CoordinateLike) -> None: ... + def midbottom(self, value: Coordinate) -> None: ... @property def midright(self) -> Tuple[_N, _N]: ... @midright.setter - def midright(self, value: CoordinateLike) -> None: ... + def midright(self, value: Coordinate) -> None: ... @property def center(self) -> Tuple[_N, _N]: ... @center.setter - def center(self, value: CoordinateLike) -> None: ... + def center(self, value: Coordinate) -> None: ... @property def centerx(self) -> _N: ... @centerx.setter @@ -103,7 +103,7 @@ class _GenericRect(Collection[_N]): @property def size(self) -> Tuple[_N, _N]: ... @size.setter - def size(self, value: CoordinateLike) -> None: ... + def size(self, value: Coordinate) -> None: ... @property def width(self) -> _N: ... @width.setter @@ -127,7 +127,7 @@ class _GenericRect(Collection[_N]): self, left: float, top: float, width: float, height: float ) -> None: ... @overload - def __init__(self, left_top: CoordinateLike, width_height: CoordinateLike) -> None: ... + def __init__(self, left_top: Coordinate, width_height: Coordinate) -> None: ... @overload def __init__(self, single_arg: RectLike) -> None: ... @overload @@ -147,44 +147,44 @@ class _GenericRect(Collection[_N]): @overload def move(self, x: float, y: float, /) -> Self: ... @overload - def move(self, move_by: CoordinateLike, /) -> Self: ... + def move(self, move_by: Coordinate, /) -> Self: ... @overload def move_ip(self, x: float, y: float, /) -> None: ... @overload - def move_ip(self, move_by: CoordinateLike, /) -> None: ... - def move_to(self, **kwargs: Union[float, CoordinateLike]) -> Self: ... + def move_ip(self, move_by: Coordinate, /) -> None: ... + def move_to(self, **kwargs: Union[float, Coordinate]) -> Self: ... @overload def inflate(self, x: float, y: float, /) -> Self: ... @overload - def inflate(self, inflate_by: CoordinateLike, /) -> Self: ... + def inflate(self, inflate_by: Coordinate, /) -> Self: ... @overload def inflate_ip(self, x: float, y: float, /) -> None: ... @overload - def inflate_ip(self, inflate_by: CoordinateLike, /) -> None: ... + def inflate_ip(self, inflate_by: Coordinate, /) -> None: ... @overload def scale_by(self, x: float, y: float = ...) -> Self: ... @overload - def scale_by(self, scale_by: CoordinateLike) -> Self: ... + def scale_by(self, scale_by: Coordinate) -> Self: ... @overload def scale_by_ip(self, x: float, y: float = ...) -> None: ... @overload - def scale_by_ip(self, scale_by: CoordinateLike) -> None: ... + def scale_by_ip(self, scale_by: Coordinate) -> None: ... @overload def update(self, left: float, top: float, width: float, height: float, /) -> None: ... @overload - def update(self, left_top: CoordinateLike, width_height: CoordinateLike, /) -> None: ... + def update(self, left_top: Coordinate, width_height: Coordinate, /) -> None: ... @overload def update(self, single_arg: RectLike, /) -> None: ... @overload def clamp(self, rect: RectLike, /) -> Self: ... @overload - def clamp(self, left_top: CoordinateLike, width_height: CoordinateLike, /) -> Self: ... + def clamp(self, left_top: Coordinate, width_height: Coordinate, /) -> Self: ... @overload def clamp(self, left: float, top: float, width: float, height: float, /) -> Self: ... @overload def clamp_ip(self, rect: RectLike, /) -> None: ... @overload - def clamp_ip(self, left_top: CoordinateLike, width_height: CoordinateLike, /) -> None: ... + def clamp_ip(self, left_top: Coordinate, width_height: Coordinate, /) -> None: ... @overload def clamp_ip( self, left: float, top: float, width: float, height: float, / @@ -192,7 +192,7 @@ class _GenericRect(Collection[_N]): @overload def clip(self, rect: RectLike, /) -> Self: ... @overload - def clip(self, left_top: CoordinateLike, width_height: CoordinateLike, /) -> Self: ... + def clip(self, left_top: Coordinate, width_height: Coordinate, /) -> Self: ... @overload def clip(self, left: float, top: float, width: float, height: float, /) -> Self: ... @overload @@ -201,7 +201,7 @@ class _GenericRect(Collection[_N]): ) -> Union[Tuple[Tuple[_N, _N], Tuple[_N, _N]], Tuple[()]]: ... @overload def clipline( - self, first_coordinate: CoordinateLike, second_coordinate: CoordinateLike, / + self, first_coordinate: Coordinate, second_coordinate: Coordinate, / ) -> Union[Tuple[Tuple[_N, _N], Tuple[_N, _N]], Tuple[()]]: ... @overload def clipline( @@ -210,13 +210,13 @@ class _GenericRect(Collection[_N]): @overload def union(self, rect: RectLike, /) -> Self: ... @overload - def union(self, left_top: CoordinateLike, width_height: CoordinateLike, /) -> Self: ... + def union(self, left_top: Coordinate, width_height: Coordinate, /) -> Self: ... @overload def union(self, left: float, top: float, width: float, height: float, /) -> Self: ... @overload def union_ip(self, rect: RectLike, /) -> None: ... @overload - def union_ip(self, left_top: CoordinateLike, width_height: CoordinateLike, /) -> None: ... + def union_ip(self, left_top: Coordinate, width_height: Coordinate, /) -> None: ... @overload def union_ip( self, left: float, top: float, width: float, height: float, / @@ -226,7 +226,7 @@ class _GenericRect(Collection[_N]): @overload def fit(self, rect: RectLike, /) -> Self: ... @overload - def fit(self, left_top: CoordinateLike, width_height: CoordinateLike, /) -> Self: ... + def fit(self, left_top: Coordinate, width_height: Coordinate, /) -> Self: ... @overload def fit(self, left: float, top: float, width: float, height: float, /) -> Self: ... def normalize(self) -> None: ... @@ -234,7 +234,7 @@ class _GenericRect(Collection[_N]): @overload def contains(self, rect: RectLike, /) -> bool: ... @overload - def contains(self, left_top: CoordinateLike, width_height: CoordinateLike, /) -> bool: ... + def contains(self, left_top: Coordinate, width_height: Coordinate, /) -> bool: ... @overload def contains( self, left: float, top: float, width: float, height: float, / @@ -242,11 +242,11 @@ class _GenericRect(Collection[_N]): @overload def collidepoint(self, x: float, y: float, /) -> bool: ... @overload - def collidepoint(self, x_y: CoordinateLike, /) -> bool: ... + def collidepoint(self, x_y: Coordinate, /) -> bool: ... @overload def colliderect(self, rect: RectLike, /) -> bool: ... @overload - def colliderect(self, left_top: CoordinateLike, width_height: CoordinateLike, /) -> bool: ... + def colliderect(self, left_top: Coordinate, width_height: Coordinate, /) -> bool: ... @overload def colliderect( self, left: float, top: float, width: float, height: float, / diff --git a/buildconfig/stubs/pygame/sprite.pyi b/buildconfig/stubs/pygame/sprite.pyi index 8fc3c4239f..9185018c1c 100644 --- a/buildconfig/stubs/pygame/sprite.pyi +++ b/buildconfig/stubs/pygame/sprite.pyi @@ -19,7 +19,7 @@ from pygame.rect import FRect, Rect from pygame.surface import Surface from pygame.mask import Mask -from pygame.typing import RectLike, CoordinateLike +from pygame.typing import RectLike, Coordinate # non-generic Group, used in Sprite _Group = AbstractGroup[_SpriteSupportsGroup] @@ -211,7 +211,7 @@ class LayeredUpdates(AbstractGroup[_TSprite]): ], **kwargs: Any ) -> None: ... - def get_sprites_at(self, pos: CoordinateLike) -> List[_TSprite]: ... + def get_sprites_at(self, pos: Coordinate) -> List[_TSprite]: ... def get_sprite(self, idx: int) -> _TSprite: ... def remove_sprites_of_layer(self, layer_nr: int) -> List[_TSprite]: ... def layers(self) -> List[int]: ... diff --git a/buildconfig/stubs/pygame/surface.pyi b/buildconfig/stubs/pygame/surface.pyi index f73cbf1993..03bb9360db 100644 --- a/buildconfig/stubs/pygame/surface.pyi +++ b/buildconfig/stubs/pygame/surface.pyi @@ -7,9 +7,9 @@ from pygame.rect import FRect, Rect from pygame.typing import ( ColorLike, - CoordinateLike, + Coordinate, RectLike, - RGBALike, + RGBATuple, SequenceLike, ) @@ -51,7 +51,7 @@ class Surface: @overload def __init__( self, - size: CoordinateLike, + size: Coordinate, flags: int = 0, depth: int = 0, masks: Optional[ColorLike] = None, @@ -59,7 +59,7 @@ class Surface: @overload def __init__( self, - size: CoordinateLike, + size: Coordinate, flags: int = 0, surface: Surface = ..., ) -> None: ... @@ -69,7 +69,7 @@ class Surface: def blit( self, source: Surface, - dest: Union[CoordinateLike, RectLike] = (0, 0), + dest: Union[Coordinate, RectLike] = (0, 0), area: Optional[RectLike] = None, special_flags: int = 0, ) -> Rect: ... @@ -77,16 +77,16 @@ class Surface: self, blit_SequenceLike: Iterable[ Union[ - Tuple[Surface, Union[CoordinateLike, RectLike]], - Tuple[Surface, Union[CoordinateLike, RectLike], Union[RectLike, int]], - Tuple[Surface, Union[CoordinateLike, RectLike], RectLike, int], + Tuple[Surface, Union[Coordinate, RectLike]], + Tuple[Surface, Union[Coordinate, RectLike], Union[RectLike, int]], + Tuple[Surface, Union[Coordinate, RectLike], RectLike, int], ] ], doreturn: Union[int, bool] = 1, ) -> Union[List[Rect], None]: ... def fblits( self, - blit_SequenceLike: Iterable[Tuple[Surface, Union[CoordinateLike, RectLike]]], + blit_SequenceLike: Iterable[Tuple[Surface, Union[Coordinate, RectLike]]], special_flags: int = 0, / ) -> None: ... @overload @@ -109,7 +109,7 @@ class Surface: def set_colorkey(self, color: ColorLike, flags: int = 0, /) -> None: ... @overload def set_colorkey(self, color: None, /) -> None: ... - def get_colorkey(self) -> Optional[RGBALike]: ... + def get_colorkey(self) -> Optional[RGBATuple]: ... @overload def set_alpha(self, value: int, flags: int = 0, /) -> None: ... @overload @@ -120,9 +120,9 @@ class Surface: def mustlock(self) -> bool: ... def get_locked(self) -> bool: ... def get_locks(self) -> Tuple[Any, ...]: ... - def get_at(self, x_y: CoordinateLike, /) -> Color: ... - def set_at(self, x_y: CoordinateLike, color: ColorLike, /) -> None: ... - def get_at_mapped(self, x_y: CoordinateLike, /) -> int: ... + def get_at(self, x_y: Coordinate, /) -> Color: ... + def set_at(self, x_y: Coordinate, color: ColorLike, /) -> None: ... + def get_at_mapped(self, x_y: Coordinate, /) -> int: ... def get_palette(self) -> List[Color]: ... def get_palette_at(self, index: int, /) -> Color: ... def set_palette(self, palette: SequenceLike[ColorLike], /) -> None: ... @@ -134,7 +134,7 @@ class Surface: @overload def subsurface(self, rect: RectLike, /) -> Surface: ... @overload - def subsurface(self, left_top: CoordinateLike, width_height: CoordinateLike, /) -> Surface: ... + def subsurface(self, left_top: Coordinate, width_height: Coordinate, /) -> Surface: ... @overload def subsurface( self, left: float, top: float, width: float, height: float, / @@ -152,13 +152,13 @@ class Surface: def get_bytesize(self) -> int: ... def get_flags(self) -> int: ... def get_pitch(self) -> int: ... - def get_masks(self) -> RGBALike: ... + def get_masks(self) -> RGBATuple: ... @deprecated("since 2.0.0. Immutable in SDL2") def set_masks(self, color: ColorLike, /) -> None: ... - def get_shifts(self) -> RGBALike: ... + def get_shifts(self) -> RGBATuple: ... @deprecated("since 2.0.0. Immutable in SDL2") def set_shifts(self, color: ColorLike, /) -> None: ... - def get_losses(self) -> RGBALike: ... + def get_losses(self) -> RGBATuple: ... def get_bounding_rect(self, min_alpha: int = 1) -> Rect: ... def get_view(self, kind: _ViewKind = "2", /) -> BufferProxy: ... def get_buffer(self) -> BufferProxy: ... diff --git a/buildconfig/stubs/pygame/transform.pyi b/buildconfig/stubs/pygame/transform.pyi index 279df43b53..64a6fabf16 100644 --- a/buildconfig/stubs/pygame/transform.pyi +++ b/buildconfig/stubs/pygame/transform.pyi @@ -3,12 +3,12 @@ from typing import Optional, Union, Literal from pygame.color import Color from pygame.surface import Surface -from pygame.typing import ColorLike, CoordinateLike, RectLike, SequenceLike +from pygame.typing import ColorLike, Coordinate, RectLike, SequenceLike def flip(surface: Surface, flip_x: bool, flip_y: bool) -> Surface: ... def scale( surface: Surface, - size: CoordinateLike, + size: Coordinate, dest_surface: Optional[Surface] = None, ) -> Surface: ... def scale_by( @@ -22,7 +22,7 @@ def scale2x(surface: Surface, dest_surface: Optional[Surface] = None) -> Surface def grayscale(surface: Surface, dest_surface: Optional[Surface] = None) -> Surface: ... def smoothscale( surface: Surface, - size: CoordinateLike, + size: Coordinate, dest_surface: Optional[Surface] = None, ) -> Surface: ... def smoothscale_by( diff --git a/buildconfig/stubs/pygame/typing.pyi b/buildconfig/stubs/pygame/typing.pyi index c1913cf682..cd407d3bc2 100644 --- a/buildconfig/stubs/pygame/typing.pyi +++ b/buildconfig/stubs/pygame/typing.pyi @@ -1,35 +1,45 @@ +import sys from typing import IO, Callable, Tuple, Union, TypeVar, Protocol, SupportsIndex -_T1_co = TypeVar("_T1_co", covariant=True) +if sys.version_info > (3, 8): + from os import PathLike as _PathProtocol +else: + _T = TypeVar("_T", bound=Union[str, bytes]) - -class _PathProtocol(Protocol[_T1_co]): - def __fspath__(self) -> _T1_co: ... + class _PathProtocol(Protocol[_T]): + def __fspath__(self) -> _T: ... +# For functions that take a file name PathLike = Union[str, bytes, _PathProtocol[str], _PathProtocol[bytes]] +# Most pygame functions that take a file argument should be able to handle a FileLike type FileLike = Union[PathLike, IO[bytes], IO[str]] -_T2_co = TypeVar("_T2_co", covariant=True) +_T_co = TypeVar("_T_co", covariant=True) -class SequenceLike(Protocol[_T2_co]): +class SequenceLike(Protocol[_T_co]): """ Variant of the standard `Sequence` ABC that only requires `__getitem__` and `__len__`. """ - def __getitem__(self, __i: SupportsIndex) -> _T2_co: ... + def __getitem__(self, __i: SupportsIndex) -> _T_co: ... def __len__(self) -> int: ... # Modify typehints when it is possible to annotate sizes -CoordinateLike = SequenceLike[float] -IntCoordinateLike = SequenceLike[int] -RGBALike = Tuple[int, int, int, int] +# Pygame handles float without errors in most cases where a coordinate is expected, +# usually rounding to int. Also, 'Union[int, float] == float' +Coordinate = SequenceLike[float] +# This is used where ints are strictly required +IntCoordinate = SequenceLike[int] + +# Used for functions that return an RGBA tuple +RGBATuple = Tuple[int, int, int, int] ColorLike = Union[int, str, SequenceLike[int]] -_CanBeRect = SequenceLike[Union[float, CoordinateLike]] +_CanBeRect = SequenceLike[Union[float, Coordinate]] class _HasRectAttribute(Protocol): diff --git a/buildconfig/stubs/pygame/window.pyi b/buildconfig/stubs/pygame/window.pyi index 4124ed5d25..ab3e6aff30 100644 --- a/buildconfig/stubs/pygame/window.pyi +++ b/buildconfig/stubs/pygame/window.pyi @@ -1,7 +1,7 @@ from typing import Optional, Tuple, Union from typing_extensions import deprecated # added in 3.13 -from pygame.typing import CoordinateLike, RectLike +from pygame.typing import Coordinate, RectLike from pygame.locals import WINDOWPOS_UNDEFINED from pygame.rect import Rect from pygame.surface import Surface @@ -12,8 +12,8 @@ class Window: def __init__( self, title: str = "pygame window", - size: CoordinateLike = (640, 480), - position: Union[int, CoordinateLike] = WINDOWPOS_UNDEFINED, + size: Coordinate = (640, 480), + position: Union[int, Coordinate] = WINDOWPOS_UNDEFINED, **flags: bool ) -> None: ... def destroy(self) -> None: ... @@ -52,19 +52,19 @@ class Window: @property def size(self) -> Tuple[int, int]: ... @size.setter - def size(self, value: CoordinateLike) -> None: ... + def size(self, value: Coordinate) -> None: ... @property def minimum_size(self) -> Tuple[int, int]: ... @minimum_size.setter - def minimum_size(self, value: CoordinateLike) -> None: ... + def minimum_size(self, value: Coordinate) -> None: ... @property def maximum_size(self) -> Tuple[int, int]: ... @maximum_size.setter - def maximum_size(self, value: CoordinateLike) -> None: ... + def maximum_size(self, value: Coordinate) -> None: ... @property def position(self) -> Tuple[int, int]: ... @position.setter - def position(self, value: Union[int, CoordinateLike]) -> None: ... + def position(self, value: Union[int, Coordinate]) -> None: ... @property def opengl(self) -> bool: ... @classmethod diff --git a/buildconfig/stubs/typing_sample_app.py b/buildconfig/stubs/typing_sample_app.py index 4112e6a24d..bfab2e8ed7 100644 --- a/buildconfig/stubs/typing_sample_app.py +++ b/buildconfig/stubs/typing_sample_app.py @@ -40,33 +40,33 @@ def validator_PathLike(path: typing.PathLike) -> int: validator_PathLike(b"file.py") validator_PathLike(MyPath()) -# validate CoordinateLike, IntCoordinateLike +# validate Coordinate, IntCoordinate -def validator_CoordinateLike(coordinate: typing.CoordinateLike) -> int: +def validator_Coordinate(coordinate: typing.Coordinate) -> int: return 0 -def validator_IntCoordinateLike(coordinate: typing.IntCoordinateLike) -> int: +def validator_IntCoordinate(coordinate: typing.IntCoordinate) -> int: return 0 # must pass -validator_CoordinateLike((1, 2)) -validator_CoordinateLike([3, -4]) -validator_CoordinateLike((5, -6.5)) -validator_CoordinateLike((-6.7, 8.9)) -validator_CoordinateLike(pygame.Vector2()) +validator_Coordinate((1, 2)) +validator_Coordinate([3, -4]) +validator_Coordinate((5, -6.5)) +validator_Coordinate((-6.7, 8.9)) +validator_Coordinate(pygame.Vector2()) -validator_IntCoordinateLike((3, 4)) -validator_IntCoordinateLike([-4, -3]) +validator_IntCoordinate((3, 4)) +validator_IntCoordinate([-4, -3]) -# validate RGBALike, ColorLike -def validator_RGBALike(rgba: typing.RGBALike) -> int: +# validate RGBATuple, ColorLike +def validator_RGBATuple(rgba: typing.RGBATuple) -> int: return 0 def validator_ColorLike(color: typing.ColorLike) -> int: return 0 # must pass -validator_RGBALike((100, 200, 50, 20)) +validator_RGBATuple((100, 200, 50, 20)) validator_ColorLike("green") validator_ColorLike(1) validator_ColorLike((255, 255, 255, 30)) diff --git a/docs/reST/index.rst b/docs/reST/index.rst index 53121de17a..9bbbf3ac68 100644 --- a/docs/reST/index.rst +++ b/docs/reST/index.rst @@ -206,6 +206,9 @@ Reference :doc:`ref/transform` Resize and move images. +:doc:`ref/typing` + Provide common typehints + :doc:`pygame C API ` The C api shared amongst pygame extension modules. diff --git a/docs/reST/ref/typing.rst b/docs/reST/ref/typing.rst new file mode 100644 index 0000000000..52d001d68e --- /dev/null +++ b/docs/reST/ref/typing.rst @@ -0,0 +1,47 @@ +.. include:: common.txt + +:mod:`pygame.typing` +==================== + +.. module:: pygame.typing + :synopsis: pygame module providing common typehints + +| :sl:`pygame module providing common typehints` + +A lot of pygame functions and methods allow the user to provide different types +for the same value like colors or coordinates. This module exports the most common +type aliases for proper typehint annotations. + +.. versionadded:: 2.5.1 + + * ``pygame.typing.PathLike``: An object representing a file path + + + * ``pygame.typing.FileLike``: An object representing a file + + + * ``pygame.typing.SequenceLike``: A variant of the standard ``Sequence`` ABC + only requiring ``__getitem__`` and ``__len__`` + + + * ``pygame.typing.Coordinate``: A sequence of two numbers (``pygame.Vector2`` included) + + + * ``pygame.typing.IntCoordinate``: A sequence of strictly two integers + + + * ``pygame.typing.RGBATuple``: A tuple of four integers in range 0-255 + + + * ``pygame.typing.ColorLike``: An object representing a color such as a mapped integer, + a string or a sequence of three or four integers in range 0-255 (``pygame.Color`` included), + types supported by every function accepting a color argument + + + * ``pygame.typing.RectLike``: An ibject representing a rect such as a sequence + of numbers or coordinates (``pygame.Rect`` included) or an object with a rect attribute + or a method returning a rect. This types are supported by every function accepting + a rect as argument. + + +.. ## pygame.typing ## diff --git a/src_c/doc/typing_doc.h b/src_c/doc/typing_doc.h new file mode 100644 index 0000000000..8aedf246db --- /dev/null +++ b/src_c/doc/typing_doc.h @@ -0,0 +1,2 @@ +/* Auto generated file: with make_docs.py . Docs go in docs/reST/ref/ . */ +#define DOC_TYPING "pygame module providing common typehints" diff --git a/src_py/typing.py b/src_py/typing.py index c1913cf682..cd407d3bc2 100644 --- a/src_py/typing.py +++ b/src_py/typing.py @@ -1,35 +1,45 @@ +import sys from typing import IO, Callable, Tuple, Union, TypeVar, Protocol, SupportsIndex -_T1_co = TypeVar("_T1_co", covariant=True) +if sys.version_info > (3, 8): + from os import PathLike as _PathProtocol +else: + _T = TypeVar("_T", bound=Union[str, bytes]) - -class _PathProtocol(Protocol[_T1_co]): - def __fspath__(self) -> _T1_co: ... + class _PathProtocol(Protocol[_T]): + def __fspath__(self) -> _T: ... +# For functions that take a file name PathLike = Union[str, bytes, _PathProtocol[str], _PathProtocol[bytes]] +# Most pygame functions that take a file argument should be able to handle a FileLike type FileLike = Union[PathLike, IO[bytes], IO[str]] -_T2_co = TypeVar("_T2_co", covariant=True) +_T_co = TypeVar("_T_co", covariant=True) -class SequenceLike(Protocol[_T2_co]): +class SequenceLike(Protocol[_T_co]): """ Variant of the standard `Sequence` ABC that only requires `__getitem__` and `__len__`. """ - def __getitem__(self, __i: SupportsIndex) -> _T2_co: ... + def __getitem__(self, __i: SupportsIndex) -> _T_co: ... def __len__(self) -> int: ... # Modify typehints when it is possible to annotate sizes -CoordinateLike = SequenceLike[float] -IntCoordinateLike = SequenceLike[int] -RGBALike = Tuple[int, int, int, int] +# Pygame handles float without errors in most cases where a coordinate is expected, +# usually rounding to int. Also, 'Union[int, float] == float' +Coordinate = SequenceLike[float] +# This is used where ints are strictly required +IntCoordinate = SequenceLike[int] + +# Used for functions that return an RGBA tuple +RGBATuple = Tuple[int, int, int, int] ColorLike = Union[int, str, SequenceLike[int]] -_CanBeRect = SequenceLike[Union[float, CoordinateLike]] +_CanBeRect = SequenceLike[Union[float, Coordinate]] class _HasRectAttribute(Protocol): From 41d0dfe1c92488937b2147db8b91df5c1be0fdc6 Mon Sep 17 00:00:00 2001 From: Damiano Ricciardi Date: Wed, 17 Jul 2024 22:43:19 +0200 Subject: [PATCH 07/18] Hold on let me try to say 3, 9 --- buildconfig/stubs/pygame/typing.pyi | 4 ++-- src_py/typing.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/buildconfig/stubs/pygame/typing.pyi b/buildconfig/stubs/pygame/typing.pyi index cd407d3bc2..b522cc3494 100644 --- a/buildconfig/stubs/pygame/typing.pyi +++ b/buildconfig/stubs/pygame/typing.pyi @@ -1,10 +1,10 @@ import sys from typing import IO, Callable, Tuple, Union, TypeVar, Protocol, SupportsIndex -if sys.version_info > (3, 8): +if sys.version_info > (3, 9): from os import PathLike as _PathProtocol else: - _T = TypeVar("_T", bound=Union[str, bytes]) + _T = TypeVar("_T", bound = Union[str, bytes]) class _PathProtocol(Protocol[_T]): def __fspath__(self) -> _T: ... diff --git a/src_py/typing.py b/src_py/typing.py index cd407d3bc2..b522cc3494 100644 --- a/src_py/typing.py +++ b/src_py/typing.py @@ -1,10 +1,10 @@ import sys from typing import IO, Callable, Tuple, Union, TypeVar, Protocol, SupportsIndex -if sys.version_info > (3, 8): +if sys.version_info > (3, 9): from os import PathLike as _PathProtocol else: - _T = TypeVar("_T", bound=Union[str, bytes]) + _T = TypeVar("_T", bound = Union[str, bytes]) class _PathProtocol(Protocol[_T]): def __fspath__(self) -> _T: ... From 69f6394134e1bb724ff48724db0179b215b410b6 Mon Sep 17 00:00:00 2001 From: Damiano Ricciardi Date: Wed, 17 Jul 2024 22:48:21 +0200 Subject: [PATCH 08/18] Fix format --- buildconfig/stubs/pygame/typing.pyi | 2 +- src_py/typing.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/buildconfig/stubs/pygame/typing.pyi b/buildconfig/stubs/pygame/typing.pyi index b522cc3494..a05b8cb080 100644 --- a/buildconfig/stubs/pygame/typing.pyi +++ b/buildconfig/stubs/pygame/typing.pyi @@ -4,7 +4,7 @@ from typing import IO, Callable, Tuple, Union, TypeVar, Protocol, SupportsIndex if sys.version_info > (3, 9): from os import PathLike as _PathProtocol else: - _T = TypeVar("_T", bound = Union[str, bytes]) + _T = TypeVar("_T", bound=Union[str, bytes]) class _PathProtocol(Protocol[_T]): def __fspath__(self) -> _T: ... diff --git a/src_py/typing.py b/src_py/typing.py index b522cc3494..a05b8cb080 100644 --- a/src_py/typing.py +++ b/src_py/typing.py @@ -4,7 +4,7 @@ if sys.version_info > (3, 9): from os import PathLike as _PathProtocol else: - _T = TypeVar("_T", bound = Union[str, bytes]) + _T = TypeVar("_T", bound=Union[str, bytes]) class _PathProtocol(Protocol[_T]): def __fspath__(self) -> _T: ... From ff2b0e938e4be555750f208e047f3f6f017759ef Mon Sep 17 00:00:00 2001 From: Damiano Ricciardi Date: Thu, 18 Jul 2024 09:19:17 +0200 Subject: [PATCH 09/18] Cleanup namespace --- buildconfig/stubs/pygame/typing.pyi | 3 +++ src_py/typing.py | 3 +++ 2 files changed, 6 insertions(+) diff --git a/buildconfig/stubs/pygame/typing.pyi b/buildconfig/stubs/pygame/typing.pyi index a05b8cb080..a320f6f2e4 100644 --- a/buildconfig/stubs/pygame/typing.pyi +++ b/buildconfig/stubs/pygame/typing.pyi @@ -49,3 +49,6 @@ class _HasRectAttribute(Protocol): RectLike = Union[_CanBeRect, _HasRectAttribute] + +# cleanup namespace +del sys, IO, Callable, Tuple, Union, TypeVar, Protocol, SupportsIndex diff --git a/src_py/typing.py b/src_py/typing.py index a05b8cb080..a320f6f2e4 100644 --- a/src_py/typing.py +++ b/src_py/typing.py @@ -49,3 +49,6 @@ class _HasRectAttribute(Protocol): RectLike = Union[_CanBeRect, _HasRectAttribute] + +# cleanup namespace +del sys, IO, Callable, Tuple, Union, TypeVar, Protocol, SupportsIndex From 776c65f8d02223aa097a1bd381d4f71a45e1db7f Mon Sep 17 00:00:00 2001 From: Damiano Ricciardi Date: Thu, 18 Jul 2024 09:47:57 +0200 Subject: [PATCH 10/18] Modify version check --- buildconfig/stubs/pygame/typing.pyi | 2 +- src_py/typing.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/buildconfig/stubs/pygame/typing.pyi b/buildconfig/stubs/pygame/typing.pyi index a320f6f2e4..237ac37dcd 100644 --- a/buildconfig/stubs/pygame/typing.pyi +++ b/buildconfig/stubs/pygame/typing.pyi @@ -1,7 +1,7 @@ import sys from typing import IO, Callable, Tuple, Union, TypeVar, Protocol, SupportsIndex -if sys.version_info > (3, 9): +if sys.version_info >= (3, 9): from os import PathLike as _PathProtocol else: _T = TypeVar("_T", bound=Union[str, bytes]) diff --git a/src_py/typing.py b/src_py/typing.py index a320f6f2e4..237ac37dcd 100644 --- a/src_py/typing.py +++ b/src_py/typing.py @@ -1,7 +1,7 @@ import sys from typing import IO, Callable, Tuple, Union, TypeVar, Protocol, SupportsIndex -if sys.version_info > (3, 9): +if sys.version_info >= (3, 9): from os import PathLike as _PathProtocol else: _T = TypeVar("_T", bound=Union[str, bytes]) From 4f70ed66528caf16d84920e156e6208db959e66f Mon Sep 17 00:00:00 2001 From: Damiano Ricciardi Date: Sat, 20 Jul 2024 17:53:46 +0200 Subject: [PATCH 11/18] Format --- docs/reST/ref/typing.rst | 7 ------- 1 file changed, 7 deletions(-) diff --git a/docs/reST/ref/typing.rst b/docs/reST/ref/typing.rst index 52d001d68e..363ca579d9 100644 --- a/docs/reST/ref/typing.rst +++ b/docs/reST/ref/typing.rst @@ -16,28 +16,21 @@ type aliases for proper typehint annotations. * ``pygame.typing.PathLike``: An object representing a file path - * ``pygame.typing.FileLike``: An object representing a file - * ``pygame.typing.SequenceLike``: A variant of the standard ``Sequence`` ABC only requiring ``__getitem__`` and ``__len__`` - * ``pygame.typing.Coordinate``: A sequence of two numbers (``pygame.Vector2`` included) - * ``pygame.typing.IntCoordinate``: A sequence of strictly two integers - * ``pygame.typing.RGBATuple``: A tuple of four integers in range 0-255 - * ``pygame.typing.ColorLike``: An object representing a color such as a mapped integer, a string or a sequence of three or four integers in range 0-255 (``pygame.Color`` included), types supported by every function accepting a color argument - * ``pygame.typing.RectLike``: An ibject representing a rect such as a sequence of numbers or coordinates (``pygame.Rect`` included) or an object with a rect attribute or a method returning a rect. This types are supported by every function accepting From c1eda4456e5c08d3aa10c00739085c0989134acf Mon Sep 17 00:00:00 2001 From: Damiano Ricciardi Date: Sun, 21 Jul 2024 15:29:17 +0200 Subject: [PATCH 12/18] Format --- docs/reST/ref/typing.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/reST/ref/typing.rst b/docs/reST/ref/typing.rst index 363ca579d9..8f8c2385a6 100644 --- a/docs/reST/ref/typing.rst +++ b/docs/reST/ref/typing.rst @@ -36,5 +36,4 @@ type aliases for proper typehint annotations. or a method returning a rect. This types are supported by every function accepting a rect as argument. - .. ## pygame.typing ## From 1c5ca92a756f616f18022a4ce5a8f3a57afe2c65 Mon Sep 17 00:00:00 2001 From: Damiano Ricciardi Date: Sun, 21 Jul 2024 19:55:37 +0200 Subject: [PATCH 13/18] Requested changes --- buildconfig/stubs/pygame/typing.pyi | 5 +++++ buildconfig/stubs/stubcheck.py | 3 ++- buildconfig/stubs/typing_sample_app.py | 17 +++++++++++++++++ src_py/typing.py | 5 +++++ 4 files changed, 29 insertions(+), 1 deletion(-) diff --git a/buildconfig/stubs/pygame/typing.pyi b/buildconfig/stubs/pygame/typing.pyi index 237ac37dcd..ad5a77deba 100644 --- a/buildconfig/stubs/pygame/typing.pyi +++ b/buildconfig/stubs/pygame/typing.pyi @@ -1,3 +1,8 @@ +"""Set of common pygame type aliases for correct type annotations""" + +# NOTE: `src_py/typing.py` and `buildconfig/stubs/pygame/typing.pyi` must be duplicates. +# Use the command `python buildconfig/stubs/gen_stubs.py` to copy typing.py to typing.pyi + import sys from typing import IO, Callable, Tuple, Union, TypeVar, Protocol, SupportsIndex diff --git a/buildconfig/stubs/stubcheck.py b/buildconfig/stubs/stubcheck.py index d023e42057..1389e07595 100644 --- a/buildconfig/stubs/stubcheck.py +++ b/buildconfig/stubs/stubcheck.py @@ -31,7 +31,8 @@ def typing_check(): try: os.chdir(STUBS_BASE_DIR) returncode = subprocess.run([*mypy_args]).returncode - print(f"mypy process finished with return code {returncode}") + if returncode != 0: + raise RuntimeError(f"mypy process finished with unsuccessful return code {returncode}") finally: os.chdir(prev_dir) diff --git a/buildconfig/stubs/typing_sample_app.py b/buildconfig/stubs/typing_sample_app.py index bfab2e8ed7..dae94bd0ac 100644 --- a/buildconfig/stubs/typing_sample_app.py +++ b/buildconfig/stubs/typing_sample_app.py @@ -3,6 +3,7 @@ """ from pygame import typing import pygame +import pathlib # validate SequenceLike class MySequence: @@ -19,6 +20,14 @@ def __len__(self): def validator_SequenceLike(sequence: typing.SequenceLike) -> int: return 0 +def validator_SequenceLikeTypes( + sequence_float: typing.SequenceLike[float], + sequence_int: typing.SequenceLike[int], + sequence_str: typing.SequenceLike[str], + sequence_sequence: typing.SequenceLike[typing.SequenceLike], +) -> int: + return 0 + # must pass validator_SequenceLike(MySequence()) validator_SequenceLike([0, 1, 2, 3]) @@ -27,6 +36,13 @@ def validator_SequenceLike(sequence: typing.SequenceLike) -> int: validator_SequenceLike(pygame.Vector2()) validator_SequenceLike("1234567890") +validator_SequenceLikeTypes( + (-1.5, -0.5, 0, 0.5, 2.5, 10), + (-2, -1, 0, 1, 2, 3), + "abcdefghijklmnopqrstuvwxyz", + [(0.5, 1.5), (-1, 1), "123", [(), (), ()]] +) + # validate PathLike class MyPath: def __fspath__(self) -> str: @@ -38,6 +54,7 @@ def validator_PathLike(path: typing.PathLike) -> int: # must pass validator_PathLike("file.py") validator_PathLike(b"file.py") +validator_PathLike(pathlib.Path("file.py")) validator_PathLike(MyPath()) # validate Coordinate, IntCoordinate diff --git a/src_py/typing.py b/src_py/typing.py index 237ac37dcd..ad5a77deba 100644 --- a/src_py/typing.py +++ b/src_py/typing.py @@ -1,3 +1,8 @@ +"""Set of common pygame type aliases for correct type annotations""" + +# NOTE: `src_py/typing.py` and `buildconfig/stubs/pygame/typing.pyi` must be duplicates. +# Use the command `python buildconfig/stubs/gen_stubs.py` to copy typing.py to typing.pyi + import sys from typing import IO, Callable, Tuple, Union, TypeVar, Protocol, SupportsIndex From f2598e33a33160c53791b6180170e94c4545b28e Mon Sep 17 00:00:00 2001 From: Damiano Ricciardi Date: Mon, 22 Jul 2024 22:14:29 +0200 Subject: [PATCH 14/18] Fix typo --- buildconfig/stubs/pygame/typing.pyi | 2 +- src_py/typing.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/buildconfig/stubs/pygame/typing.pyi b/buildconfig/stubs/pygame/typing.pyi index ad5a77deba..4f6e635e31 100644 --- a/buildconfig/stubs/pygame/typing.pyi +++ b/buildconfig/stubs/pygame/typing.pyi @@ -49,7 +49,7 @@ _CanBeRect = SequenceLike[Union[float, Coordinate]] class _HasRectAttribute(Protocol): # An object that has a rect attribute that is either a rect, or a function - # that returns a rect confirms to the rect protocol + # that returns a rect conforms to the rect protocol rect: Union["RectLike", Callable[[], "RectLike"]] diff --git a/src_py/typing.py b/src_py/typing.py index ad5a77deba..4f6e635e31 100644 --- a/src_py/typing.py +++ b/src_py/typing.py @@ -49,7 +49,7 @@ def __len__(self) -> int: ... class _HasRectAttribute(Protocol): # An object that has a rect attribute that is either a rect, or a function - # that returns a rect confirms to the rect protocol + # that returns a rect conforms to the rect protocol rect: Union["RectLike", Callable[[], "RectLike"]] From da6deb72aa4607fc9fabd7e305f4c88a86516274 Mon Sep 17 00:00:00 2001 From: Damiano Ricciardi Date: Thu, 1 Aug 2024 09:55:13 +0200 Subject: [PATCH 15/18] Documentation refactor --- buildconfig/stubs/pygame/typing.pyi | 2 +- docs/reST/ref/typing.rst | 78 +++++++++++++++++++++++------ src_c/doc/typing_doc.h | 8 +++ src_py/typing.py | 2 +- 4 files changed, 72 insertions(+), 18 deletions(-) diff --git a/buildconfig/stubs/pygame/typing.pyi b/buildconfig/stubs/pygame/typing.pyi index 4f6e635e31..883fe2def1 100644 --- a/buildconfig/stubs/pygame/typing.pyi +++ b/buildconfig/stubs/pygame/typing.pyi @@ -1,4 +1,4 @@ -"""Set of common pygame type aliases for correct type annotations""" +"""Set of common pygame type aliases for proper typehint annotations""" # NOTE: `src_py/typing.py` and `buildconfig/stubs/pygame/typing.pyi` must be duplicates. # Use the command `python buildconfig/stubs/gen_stubs.py` to copy typing.py to typing.pyi diff --git a/docs/reST/ref/typing.rst b/docs/reST/ref/typing.rst index 8f8c2385a6..787bee617a 100644 --- a/docs/reST/ref/typing.rst +++ b/docs/reST/ref/typing.rst @@ -8,32 +8,78 @@ | :sl:`pygame module providing common typehints` +.. versionadded:: 2.5.1 + A lot of pygame functions and methods allow the user to provide different types for the same value like colors or coordinates. This module exports the most common type aliases for proper typehint annotations. -.. versionadded:: 2.5.1 + .. attribute:: PathLike + + An object representing a file path, i.e.: + + * ``"my/string/path.txt"`` + * ``pathlib.Path("my/pathlib/path.txt")`` + * ``b"my/bytes/path.txt"`` + * Any object implementing the path protocol (with a ``__fspath__`` magic method) + + .. attribute:: FileLike + + An object representing a file. Same as :mod:`pygame.typing.PathLike` with + the addition of file buffers (``IO`` of strings and bytes) such as the + return value of ``open()``. + + .. attribute:: SequenceLike + + A variant of the standard ``Sequence`` ABC only requiring ``__getitem__`` + and ``__len__``. This includes custom sequences or builtin ones, i.e.: + + * ``"abcdefg"`` + * ``[a, b, c, d, ...]`` + * ``(a, b, c, d, ...)`` + + Being a generic, subscribing it will signal further precision such as + ``SequenceLike[str]`` or ``SequenceLike[float]``. + + .. attribute:: Coordinate + + A sequence of two numbers (floats or ints), i.e: + + * ``pygame.Vector2(a, b)`` + * ``[a, b]`` + * ``(a, b)`` + + .. attribute:: IntCoordinate + + A sequence of strictly two integers such as ``[a, b]`` or ``(a, b)``. - * ``pygame.typing.PathLike``: An object representing a file path + .. attribute:: RGBATuple - * ``pygame.typing.FileLike``: An object representing a file + A tuple of four integers ``(r, g, b, a)`` in range 0-255 such as ``(20, 255, 0, 100)``. - * ``pygame.typing.SequenceLike``: A variant of the standard ``Sequence`` ABC - only requiring ``__getitem__`` and ``__len__`` + .. attribute:: ColorLike - * ``pygame.typing.Coordinate``: A sequence of two numbers (``pygame.Vector2`` included) + An object representing a color such as a mapped integer, a string or + a sequence of three or four integers in range 0-255, types supported by + every function accepting a color argument. i.e.: - * ``pygame.typing.IntCoordinate``: A sequence of strictly two integers + * ``pygame.Color(ColorLike)`` + * ``(r, g, b)`` + * ``(r, g, b, a)`` + * ``[r, g, b, a]`` + * ``"green"`` + * ``0`` (mapped color) - * ``pygame.typing.RGBATuple``: A tuple of four integers in range 0-255 - - * ``pygame.typing.ColorLike``: An object representing a color such as a mapped integer, - a string or a sequence of three or four integers in range 0-255 (``pygame.Color`` included), - types supported by every function accepting a color argument + .. attribute:: RectLike + + An object representing a rect such as a sequence of numbers or coordinates + or an object with a rect attribute or a method returning a rect. This types + are supported by every function accepting a rect as argument. i.e.: - * ``pygame.typing.RectLike``: An ibject representing a rect such as a sequence - of numbers or coordinates (``pygame.Rect`` included) or an object with a rect attribute - or a method returning a rect. This types are supported by every function accepting - a rect as argument. + * ``(x, y, w, h)`` + * ``(Coordinate, Coordinate)`` + * ``pygame.Rect(RectLike)`` + * Any object with a ``.rect`` attribute which is a ``RectLike`` or a function + returning a ``RectLike`` .. ## pygame.typing ## diff --git a/src_c/doc/typing_doc.h b/src_c/doc/typing_doc.h index 8aedf246db..ed354c8439 100644 --- a/src_c/doc/typing_doc.h +++ b/src_c/doc/typing_doc.h @@ -1,2 +1,10 @@ /* Auto generated file: with make_docs.py . Docs go in docs/reST/ref/ . */ #define DOC_TYPING "pygame module providing common typehints" +#define DOC_TYPING_PATHLIKE "" +#define DOC_TYPING_FILELIKE "" +#define DOC_TYPING_SEQUENCELIKE "" +#define DOC_TYPING_COORDINATE "" +#define DOC_TYPING_INTCOORDINATE "" +#define DOC_TYPING_RGBATUPLE "" +#define DOC_TYPING_COLORLIKE "" +#define DOC_TYPING_RECTLIKE "" diff --git a/src_py/typing.py b/src_py/typing.py index 4f6e635e31..883fe2def1 100644 --- a/src_py/typing.py +++ b/src_py/typing.py @@ -1,4 +1,4 @@ -"""Set of common pygame type aliases for correct type annotations""" +"""Set of common pygame type aliases for proper typehint annotations""" # NOTE: `src_py/typing.py` and `buildconfig/stubs/pygame/typing.pyi` must be duplicates. # Use the command `python buildconfig/stubs/gen_stubs.py` to copy typing.py to typing.pyi From 4721d6f6dbb2ac77d422bf874cdd5f3af8f6dcfe Mon Sep 17 00:00:00 2001 From: Damiano Ricciardi Date: Thu, 1 Aug 2024 09:58:53 +0200 Subject: [PATCH 16/18] Use data instead of attrubute --- docs/reST/ref/typing.rst | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/reST/ref/typing.rst b/docs/reST/ref/typing.rst index 787bee617a..1d42ca8619 100644 --- a/docs/reST/ref/typing.rst +++ b/docs/reST/ref/typing.rst @@ -14,7 +14,7 @@ A lot of pygame functions and methods allow the user to provide different types for the same value like colors or coordinates. This module exports the most common type aliases for proper typehint annotations. - .. attribute:: PathLike + .. data:: PathLike An object representing a file path, i.e.: @@ -23,13 +23,13 @@ type aliases for proper typehint annotations. * ``b"my/bytes/path.txt"`` * Any object implementing the path protocol (with a ``__fspath__`` magic method) - .. attribute:: FileLike + .. data:: FileLike An object representing a file. Same as :mod:`pygame.typing.PathLike` with the addition of file buffers (``IO`` of strings and bytes) such as the return value of ``open()``. - .. attribute:: SequenceLike + .. data:: SequenceLike A variant of the standard ``Sequence`` ABC only requiring ``__getitem__`` and ``__len__``. This includes custom sequences or builtin ones, i.e.: @@ -41,7 +41,7 @@ type aliases for proper typehint annotations. Being a generic, subscribing it will signal further precision such as ``SequenceLike[str]`` or ``SequenceLike[float]``. - .. attribute:: Coordinate + .. data:: Coordinate A sequence of two numbers (floats or ints), i.e: @@ -49,15 +49,15 @@ type aliases for proper typehint annotations. * ``[a, b]`` * ``(a, b)`` - .. attribute:: IntCoordinate + .. data:: IntCoordinate A sequence of strictly two integers such as ``[a, b]`` or ``(a, b)``. - .. attribute:: RGBATuple + .. data:: RGBATuple A tuple of four integers ``(r, g, b, a)`` in range 0-255 such as ``(20, 255, 0, 100)``. - .. attribute:: ColorLike + .. data:: ColorLike An object representing a color such as a mapped integer, a string or a sequence of three or four integers in range 0-255, types supported by @@ -70,7 +70,7 @@ type aliases for proper typehint annotations. * ``"green"`` * ``0`` (mapped color) - .. attribute:: RectLike + .. data:: RectLike An object representing a rect such as a sequence of numbers or coordinates or an object with a rect attribute or a method returning a rect. This types From 08aa1f49e6a39248900e5bffd0e8717e214579ab Mon Sep 17 00:00:00 2001 From: Damiano Ricciardi Date: Thu, 1 Aug 2024 10:02:40 +0200 Subject: [PATCH 17/18] typo --- docs/reST/ref/typing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/reST/ref/typing.rst b/docs/reST/ref/typing.rst index 1d42ca8619..7f336bd3d6 100644 --- a/docs/reST/ref/typing.rst +++ b/docs/reST/ref/typing.rst @@ -26,7 +26,7 @@ type aliases for proper typehint annotations. .. data:: FileLike An object representing a file. Same as :mod:`pygame.typing.PathLike` with - the addition of file buffers (``IO`` of strings and bytes) such as the + the addition of file buffers (``IO`` of strings or bytes) such as the return value of ``open()``. .. data:: SequenceLike From e0fcdc223bf84daacc5c5736884e1ec71f502aae Mon Sep 17 00:00:00 2001 From: Damiano Ricciardi Date: Tue, 13 Aug 2024 10:31:38 +0200 Subject: [PATCH 18/18] Fix docs --- docs/reST/ref/typing.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/reST/ref/typing.rst b/docs/reST/ref/typing.rst index 7f336bd3d6..764f05a28d 100644 --- a/docs/reST/ref/typing.rst +++ b/docs/reST/ref/typing.rst @@ -8,7 +8,7 @@ | :sl:`pygame module providing common typehints` -.. versionadded:: 2.5.1 +.. versionadded:: 2.5.2 A lot of pygame functions and methods allow the user to provide different types for the same value like colors or coordinates. This module exports the most common @@ -73,7 +73,7 @@ type aliases for proper typehint annotations. .. data:: RectLike An object representing a rect such as a sequence of numbers or coordinates - or an object with a rect attribute or a method returning a rect. This types + or an object with a rect attribute or a method returning a rect. These types are supported by every function accepting a rect as argument. i.e.: * ``(x, y, w, h)``