From 3e364cd547bc77120de7777467449da3a5f5b7fc Mon Sep 17 00:00:00 2001 From: Houda222 Date: Tue, 26 Dec 2023 18:38:03 +0100 Subject: [PATCH 01/44] added todo_test_arc --- test/draw_test.py | 50 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/test/draw_test.py b/test/draw_test.py index 4429740b28..4c08f9dd3e 100644 --- a/test/draw_test.py +++ b/test/draw_test.py @@ -6160,9 +6160,55 @@ def test_arc__invalid_color_formats(self): with self.assertRaises(TypeError): bounds_rect = self.draw_arc(**kwargs) - def todo_test_arc(self): + def test_arc__correct_drawing(self): """Ensure draw arc works correctly.""" - self.fail() + surfw, surfh = 500, 500 + surface = pygame.Surface((surfw, surfh)) + surface_color = pygame.Color("black") + surface.fill(surface_color) + arc_color = pygame.Color("white") + rectangles = [ + pygame.Rect((200, 200), (300 + i, 200 + i)) for i in range(-100, 50, 30) + ] # Test on different bounding rectangles + start = 0 + stop = 2 + + for rect in rectangles: + kwargs = { + "surface": surface, + "color": arc_color, + "rect": rect, + "start_angle": start, + "stop_angle": stop, + "width": 1, + } + + pygame.draw.arc(**kwargs) + + a, b = rect.width / 2, rect.height / 2 + number_of_valid_arc_points = 0 + number_of_invalid_arc_points = 0 + # Define a threshold for comparison + eps = 0.1 + center_x = rect.centerx + center_y = rect.centery + + for x in range(surfw): + for y in range(surfh): + # Check whether the point on the arc belongs to the ellipse defined by the bounding rectangle + if (surface.get_at((x, y)) == arc_color) and abs( + ((x - center_x) / a) ** 2 + ((y - center_y) / b) ** 2 - 1 + ) <= eps: + number_of_valid_arc_points += 1 + elif surface.get_at((x, y)) == arc_color: + number_of_invalid_arc_points += 1 + + surface.fill(surface_color) # Clear for the next test + + self.assertEqual( + number_of_valid_arc_points, + number_of_invalid_arc_points + number_of_valid_arc_points, + ) def test_arc__bounding_rect(self): """Ensures draw arc returns the correct bounding rect. From 409c679ea6841befef48714f539e077f886c9f6c Mon Sep 17 00:00:00 2001 From: Dan Lawrence Date: Mon, 12 Feb 2024 15:12:41 +0000 Subject: [PATCH 02/44] adjust test assertion on test review feedback. --- test/draw_test.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/test/draw_test.py b/test/draw_test.py index 4c08f9dd3e..7a048267b0 100644 --- a/test/draw_test.py +++ b/test/draw_test.py @@ -6205,10 +6205,7 @@ def test_arc__correct_drawing(self): surface.fill(surface_color) # Clear for the next test - self.assertEqual( - number_of_valid_arc_points, - number_of_invalid_arc_points + number_of_valid_arc_points, - ) + self.assertEqual(number_of_invalid_arc_points, 0) def test_arc__bounding_rect(self): """Ensures draw arc returns the correct bounding rect. From 7d3eda08d53eec00775787c5c8aab12b885bea7f Mon Sep 17 00:00:00 2001 From: Damiano <97639432+damusss@users.noreply.github.com> Date: Thu, 10 Oct 2024 18:50:08 +0200 Subject: [PATCH 03/44] Add _get_color_from_object_all --- src_c/pixelarray_methods.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src_c/pixelarray_methods.c b/src_c/pixelarray_methods.c index 8ecbebdb91..62f33a796a 100644 --- a/src_c/pixelarray_methods.c +++ b/src_c/pixelarray_methods.c @@ -46,6 +46,16 @@ _get_color_from_object(PyObject *val, SDL_Surface *surf, Uint32 *color) val, surf, color, PG_COLOR_HANDLE_INT | PG_COLOR_HANDLE_RESTRICT_SEQ); } +static int +_get_color_from_object_all(PyObject *val, SDL_Surface *surf, Uint32 *color) +{ + if (!val) { + return 0; + } + + return pg_MappedColorFromObj(val, surf, color, PG_COLOR_HANDLE_ALL); +} + /** * Retrieves a single pixel located at index from the surface pixel * array. @@ -375,8 +385,8 @@ _replace_color(pgPixelArrayObject *array, PyObject *args, PyObject *kwds) format = surf->format; bpp = PG_SURF_BytesPerPixel(surf); - if (!_get_color_from_object(delcolor, surf, &dcolor) || - !_get_color_from_object(replcolor, surf, &rcolor)) { + if (!_get_color_from_object_all(delcolor, surf, &dcolor) || + !_get_color_from_object_all(replcolor, surf, &rcolor)) { return 0; } @@ -581,7 +591,7 @@ _extract_color(pgPixelArrayObject *array, PyObject *args, PyObject *kwds) black = SDL_MapRGBA(format, 0, 0, 0, 255); white = SDL_MapRGBA(format, 255, 255, 255, 255); - if (!_get_color_from_object(excolor, surf, &color)) { + if (!_get_color_from_object_all(excolor, surf, &color)) { Py_DECREF(new_array); return 0; } From 5dd9193c00233e9928cd2f8c0a25aed074ef6746 Mon Sep 17 00:00:00 2001 From: Damiano <97639432+damusss@users.noreply.github.com> Date: Thu, 10 Oct 2024 18:54:22 +0200 Subject: [PATCH 04/44] Add tests --- test/pixelarray_test.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/test/pixelarray_test.py b/test/pixelarray_test.py index 942931c2ad..e56f11ed0e 100644 --- a/test/pixelarray_test.py +++ b/test/pixelarray_test.py @@ -1020,7 +1020,6 @@ def test_iter(self): self.assertEqual(iterations, 5) def test_replace(self): - # print("replace start") for bpp in (8, 16, 24, 32): sf = pygame.Surface((10, 10), 0, bpp) sf.fill((255, 0, 0)) @@ -1041,10 +1040,13 @@ def test_replace(self): self.assertEqual(ar[3][6], oval) self.assertEqual(ar[8][9], oval) self.assertEqual(ar[9][9], oval) - # print("replace end") + + for color in [(20, 20, 20), 10, "green", pygame.Color("blue")]: + sf = pygame.Surface((10, 10)) + ar = pygame.PixelArray(sf) + ar.replace(color, color) def test_extract(self): - # print("extract start") for bpp in (8, 16, 24, 32): sf = pygame.Surface((10, 10), 0, bpp) sf.fill((0, 0, 255)) @@ -1070,7 +1072,11 @@ def test_extract(self): self.assertEqual(newar[3][6], white) self.assertEqual(newar[8][9], black) self.assertEqual(newar[9][9], black) - # print("extract end") + + for color in [(20, 20, 20), 10, "green", pygame.Color("blue")]: + sf = pygame.Surface((10, 10)) + ar = pygame.PixelArray(sf) + ar.extract(color) def test_2dslice_assignment(self): w = 2 * 5 * 8 From e187c66be17e37781957d9239f70d6e08384fbda Mon Sep 17 00:00:00 2001 From: Damiano <97639432+damusss@users.noreply.github.com> Date: Thu, 10 Oct 2024 19:12:30 +0200 Subject: [PATCH 05/44] same thing for mask --- docs/reST/ref/mask.rst | 4 ++-- src_c/mask.c | 4 ++-- test/mask_test.py | 12 +++++++----- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/docs/reST/ref/mask.rst b/docs/reST/ref/mask.rst index 6236dadf34..bfb7acc00c 100644 --- a/docs/reST/ref/mask.rst +++ b/docs/reST/ref/mask.rst @@ -71,10 +71,10 @@ to store which parts collide. :param color: color used to check if the surface's pixels are within the given ``threshold`` range, this parameter is ignored if the optional ``othersurface`` parameter is supplied - :type color: Color or int or tuple(int, int, int, [int]) or list[int, int, int, [int]] + :type color: :data:`pygame.typing.ColorLike` :param threshold: (optional) the threshold range used to check the difference between two colors (default is ``(0, 0, 0, 255)``) - :type threshold: Color or int or tuple(int, int, int, [int]) or list[int, int, int, [int]] + :type threshold: :data:`pygame.typing.ColorLike` :param Surface othersurface: (optional) used to check whether the pixels of the first surface are within the given ``threshold`` range of the pixels from this surface (default is ``None``) diff --git a/src_c/mask.c b/src_c/mask.c index 074ddfd383..df22d24066 100644 --- a/src_c/mask.c +++ b/src_c/mask.c @@ -1130,13 +1130,13 @@ mask_from_threshold(PyObject *self, PyObject *args, PyObject *kwargs) } if (!pg_MappedColorFromObj(rgba_obj_color, surf, &color, - PG_COLOR_HANDLE_INT)) { + PG_COLOR_HANDLE_ALL)) { return NULL; } if (rgba_obj_threshold) { if (!pg_MappedColorFromObj(rgba_obj_threshold, surf, &color_threshold, - PG_COLOR_HANDLE_INT)) { + PG_COLOR_HANDLE_ALL)) { return NULL; } } diff --git a/test/mask_test.py b/test/mask_test.py index 5740bbc2bb..0a46719f0f 100644 --- a/test/mask_test.py +++ b/test/mask_test.py @@ -6325,21 +6325,19 @@ def alternate(func, set_value, unset_value, width, height): def test_from_threshold(self): """Does mask.from_threshold() work correctly?""" - a = [16, 24, 32] + bpp = [16, 24, 32] - for i in a: + for i in bpp: surf = pygame.surface.Surface((70, 70), 0, i) surf.fill((100, 50, 200), (20, 20, 20, 20)) mask = pygame.mask.from_threshold( surf, (100, 50, 200, 255), (10, 10, 10, 255) ) - rects = mask.get_bounding_rects() - self.assertEqual(mask.count(), 400) self.assertEqual(mask.get_bounding_rects(), [pygame.Rect((20, 20, 20, 20))]) - for i in a: + for i in bpp: surf = pygame.surface.Surface((70, 70), 0, i) surf2 = pygame.surface.Surface((70, 70), 0, i) surf.fill((100, 100, 100)) @@ -6356,6 +6354,10 @@ def test_from_threshold(self): self.assertEqual(mask.count(), 100) self.assertEqual(mask.get_bounding_rects(), [pygame.Rect((40, 40, 10, 10))]) + for color in [(20, 20, 20), 10, "green", pygame.Color("blue")]: + surf = pygame.surface.Surface((10, 10)) + pygame.mask.from_threshold(surf, color, color) + def test_zero_size_from_surface(self): """Ensures from_surface can create masks from zero sized surfaces.""" for size in ((100, 0), (0, 100), (0, 0)): From 96c033c048ed1506450119151d2c8300ad7c2a15 Mon Sep 17 00:00:00 2001 From: Ankith Date: Sat, 2 Nov 2024 13:59:09 +0530 Subject: [PATCH 06/44] Port constants.c to SDL3 --- src_c/_pygame.h | 4 ++++ src_c/meson.build | 3 --- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src_c/_pygame.h b/src_c/_pygame.h index 46fe2d966d..07f236149a 100644 --- a/src_c/_pygame.h +++ b/src_c/_pygame.h @@ -284,6 +284,10 @@ typedef enum { SDL_ACTIVEEVENT = SDL_USEREVENT, SDL_VIDEORESIZE, SDL_VIDEOEXPOSE, +#if SDL_VERSION_ATLEAST(3, 0, 0) + /* SDL_SYSWMEVENT removed in SDL3, define it here for compat */ + SDL_SYSWMEVENT, +#endif PGE_MIDIIN, PGE_MIDIOUT, diff --git a/src_c/meson.build b/src_c/meson.build index fb43a584eb..792e699594 100644 --- a/src_c/meson.build +++ b/src_c/meson.build @@ -18,8 +18,6 @@ color = py.extension_module( subdir: pg, ) -# TODO: support SDL3 -if sdl_api != 3 constants = py.extension_module( 'constants', 'constants.c', @@ -28,7 +26,6 @@ constants = py.extension_module( install: true, subdir: pg, ) -endif # TODO: support SDL3 if sdl_api != 3 From 2afed5428b2b7cd821a45f9b8836e0d69a7f4577 Mon Sep 17 00:00:00 2001 From: Ankith Date: Sat, 2 Nov 2024 13:59:56 +0530 Subject: [PATCH 07/44] Port surflock.c to SDL3 --- src_c/meson.build | 2 -- src_c/surflock.c | 4 ++++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src_c/meson.build b/src_c/meson.build index 792e699594..78ae34b06c 100644 --- a/src_c/meson.build +++ b/src_c/meson.build @@ -144,7 +144,6 @@ surface = py.extension_module( endif # TODO: support SDL3 -if sdl_api != 3 surflock = py.extension_module( 'surflock', 'surflock.c', @@ -153,7 +152,6 @@ surflock = py.extension_module( install: true, subdir: pg, ) -endif # TODO: support SDL3 if sdl_api != 3 diff --git a/src_c/surflock.c b/src_c/surflock.c index 62cd3acdbd..60f3d953ec 100644 --- a/src_c/surflock.c +++ b/src_c/surflock.c @@ -99,7 +99,11 @@ pgSurface_LockBy(pgSurfaceObject *surfobj, PyObject *lockobj) if (surf->subsurface != NULL) { pgSurface_Prep(surfobj); } +#if SDL_VERSION_ATLEAST(3, 0, 0) + if (!SDL_LockSurface(surf->surf)) { +#else if (SDL_LockSurface(surf->surf) == -1) { +#endif PyErr_SetString(PyExc_RuntimeError, "error locking surface"); return 0; } From 9ecb01bd04863aa20ee1e169f07269963f6e6cb0 Mon Sep 17 00:00:00 2001 From: Ankith Date: Sat, 2 Nov 2024 14:15:10 +0530 Subject: [PATCH 08/44] Run import pygame test on SDL3 CI --- .github/workflows/build-sdl3.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/build-sdl3.yml b/.github/workflows/build-sdl3.yml index 6f442d58e5..f6107af8e0 100644 --- a/.github/workflows/build-sdl3.yml +++ b/.github/workflows/build-sdl3.yml @@ -91,6 +91,11 @@ jobs: -Csetup-args=-Dmixer=disabled -Csetup-args=-Dfont=disabled + # eventually we need to run all tests, but for now test that importing pygame + # works + - name: Test import works + run: python3 -c 'import pygame' + # - name: Run tests # env: # SDL_VIDEODRIVER: "dummy" From 176649335d3e71739f0529286b215f6223e0ba2f Mon Sep 17 00:00:00 2001 From: Ankith Date: Sat, 2 Nov 2024 15:02:22 +0530 Subject: [PATCH 09/44] Port time.c to SDL3 --- src_c/meson.build | 3 --- src_c/time.c | 17 +++++++++++++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src_c/meson.build b/src_c/meson.build index 78ae34b06c..07189d6180 100644 --- a/src_c/meson.build +++ b/src_c/meson.build @@ -153,8 +153,6 @@ surflock = py.extension_module( subdir: pg, ) -# TODO: support SDL3 -if sdl_api != 3 time = py.extension_module( 'time', 'time.c', @@ -163,7 +161,6 @@ time = py.extension_module( install: true, subdir: pg, ) -endif # TODO: support SDL3 if sdl_api != 3 diff --git a/src_c/time.c b/src_c/time.c index 66dc4fc6f3..a44d859209 100644 --- a/src_c/time.c +++ b/src_c/time.c @@ -276,8 +276,13 @@ _pg_clear_event_timer_type(int ev_type) /* Timer callback function * TODO: This needs better error handling and a way to report to the user */ +#if SDL_VERSION_ATLEAST(3, 0, 0) +static Uint32 +timer_callback(void *param, SDL_TimerID timerID, Uint32 interval) +#else static Uint32 timer_callback(Uint32 interval, void *param) +#endif { pgEventTimer *evtimer; PG_LOCK_TIMER_MUTEX @@ -316,12 +321,14 @@ accurate_delay(Sint64 ticks) if (ticks <= 0) return 0; +#if !SDL_VERSION_ATLEAST(3, 0, 0) if (!SDL_WasInit(SDL_INIT_TIMER)) { if (SDL_InitSubSystem(SDL_INIT_TIMER)) { PyErr_SetString(pgExc_SDLError, SDL_GetError()); return -1; } } +#endif funcstart = PG_GetTicks(); if (ticks >= WORST_CLOCK_ACCURACY) { @@ -342,8 +349,10 @@ accurate_delay(Sint64 ticks) static PyObject * time_get_ticks(PyObject *self, PyObject *_null) { +#if !SDL_VERSION_ATLEAST(3, 0, 0) if (!SDL_WasInit(SDL_INIT_TIMER)) return PyLong_FromLong(0); +#endif return PyLong_FromUnsignedLongLong(PG_GetTicks()); } @@ -371,11 +380,13 @@ time_wait(PyObject *self, PyObject *arg) if (!PyLong_Check(arg)) return RAISE(PyExc_TypeError, "wait requires one integer argument"); +#if !SDL_VERSION_ATLEAST(3, 0, 0) if (!SDL_WasInit(SDL_INIT_TIMER)) { if (SDL_InitSubSystem(SDL_INIT_TIMER)) { return RAISE(pgExc_SDLError, SDL_GetError()); } } +#endif ticks = PyLong_AsLongLong(arg); if (ticks < 0) @@ -455,6 +466,7 @@ time_set_timer(PyObject *self, PyObject *args, PyObject *kwargs) goto end; } +#if !SDL_VERSION_ATLEAST(3, 0, 0) /* just doublecheck that timer is initialized */ if (!SDL_WasInit(SDL_INIT_TIMER)) { if (SDL_InitSubSystem(SDL_INIT_TIMER)) { @@ -462,6 +474,7 @@ time_set_timer(PyObject *self, PyObject *args, PyObject *kwargs) goto end; } } +#endif ecode = _pg_add_event_timer(ev_type, ev_dict, loops); if (ecode != PG_TIMER_NO_ERROR) { @@ -522,12 +535,14 @@ clock_tick_base(pgClockObject *self, PyObject *arg, int use_accurate_delay) self->rawpassed = PG_GetTicks() - self->last_tick; delay = endtime - self->rawpassed; +#if !SDL_VERSION_ATLEAST(3, 0, 0) /*just doublecheck that timer is initialized*/ if (!SDL_WasInit(SDL_INIT_TIMER)) { if (SDL_InitSubSystem(SDL_INIT_TIMER)) { return RAISE(pgExc_SDLError, SDL_GetError()); } } +#endif if (use_accurate_delay) delay = accurate_delay(delay); @@ -639,11 +654,13 @@ clock_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) return NULL; } +#if !SDL_VERSION_ATLEAST(3, 0, 0) if (!SDL_WasInit(SDL_INIT_TIMER)) { if (SDL_InitSubSystem(SDL_INIT_TIMER)) { return RAISE(pgExc_SDLError, SDL_GetError()); } } +#endif pgClockObject *self = (pgClockObject *)(type->tp_alloc(type, 0)); self->fps_tick = 0; From ac4d78579deab4688ee2856f543c899999c0d701 Mon Sep 17 00:00:00 2001 From: Ankith Date: Sun, 3 Nov 2024 15:34:31 +0530 Subject: [PATCH 10/44] Use SequenceLike in geometry stubs --- buildconfig/stubs/pygame/geometry.pyi | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/buildconfig/stubs/pygame/geometry.pyi b/buildconfig/stubs/pygame/geometry.pyi index f7c1edf517..d21842a494 100644 --- a/buildconfig/stubs/pygame/geometry.pyi +++ b/buildconfig/stubs/pygame/geometry.pyi @@ -4,7 +4,6 @@ from typing import ( Callable, Protocol, Tuple, - Sequence, List, ) @@ -120,8 +119,8 @@ class Circle: @overload def colliderect(self, topleft: Point, size: Point, /) -> bool: ... def collideswith(self, other: _CanBeCollided, /) -> bool: ... - def collidelist(self, colliders: Sequence[_CanBeCollided], /) -> int: ... - def collidelistall(self, colliders: Sequence[_CanBeCollided], /) -> List[int]: ... + def collidelist(self, colliders: SequenceLike[_CanBeCollided], /) -> int: ... + def collidelistall(self, colliders: SequenceLike[_CanBeCollided], /) -> List[int]: ... def intersect(self, other: _CanBeIntersected, /) -> List[Tuple[float, float]]: ... def contains(self, shape: _CanBeCollided, /) -> bool: ... @overload From f295ce5c2c602cdb6cfaa8782c4601a5c7bb1636 Mon Sep 17 00:00:00 2001 From: Ankith Date: Tue, 5 Nov 2024 23:55:08 +0530 Subject: [PATCH 11/44] Move brace out of conditional blocks Co-authored-by: gresm <78505251+gresm@users.noreply.github.com> --- src_c/surflock.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src_c/surflock.c b/src_c/surflock.c index 60f3d953ec..0786d0fe66 100644 --- a/src_c/surflock.c +++ b/src_c/surflock.c @@ -100,10 +100,11 @@ pgSurface_LockBy(pgSurfaceObject *surfobj, PyObject *lockobj) pgSurface_Prep(surfobj); } #if SDL_VERSION_ATLEAST(3, 0, 0) - if (!SDL_LockSurface(surf->surf)) { + if (!SDL_LockSurface(surf->surf)) #else - if (SDL_LockSurface(surf->surf) == -1) { + if (SDL_LockSurface(surf->surf) == -1) #endif + { PyErr_SetString(PyExc_RuntimeError, "error locking surface"); return 0; } From 2fdcf73ba5a86febf1073db037f598c8417362a0 Mon Sep 17 00:00:00 2001 From: XORandom <40043238+XORandom@users.noreply.github.com> Date: Tue, 5 Nov 2024 22:14:51 +0300 Subject: [PATCH 12/44] Add Russian readme (#3138) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update README.rst * Create README.ru.rst Added a translation to Russian. * Update README.es.rst Добавлены ссылки на ru.rst * Update README.ru.rst * Update README.ja.rst Added links to ru. rst * Added links to en README * Added links to ru. rst * Added links to ru. rst * Added links to ru. rst * Update README.zh-cn.rst * Update README.fr.rst * Update README.fa.rst * Update README.es.rst * Fixed non-clickable links Fixed non-clickable links to English README and incorrect paths to other README's * Update README.ru.rst * fix incorrect links to other readme's * fix formatting * Corrected the sentence to make it sound better. * Removed extra newline * Update README.ru.rst add `Italiano` * Update README.it.rst * Fix formatting --------- Co-authored-by: Dan Lawrence Co-authored-by: Ankith --- README.rst | 3 +- docs/readmes/README.es.rst | 4 +- docs/readmes/README.fa.rst | 4 +- docs/readmes/README.fr.rst | 4 +- docs/readmes/README.it.rst | 3 +- docs/readmes/README.ja.rst | 13 +- docs/readmes/README.ru.rst | 226 ++++++++++++++++++++++++++++++++++ docs/readmes/README.zh-cn.rst | 4 +- 8 files changed, 250 insertions(+), 11 deletions(-) create mode 100644 docs/readmes/README.ru.rst diff --git a/README.rst b/README.rst index e9c952c6a4..72b6cea133 100644 --- a/README.rst +++ b/README.rst @@ -8,7 +8,7 @@ |PyPiVersion| |PyPiLicense| |Python3| |GithubCommits| |BlackFormatBadge| -**English** `简体中文`_ `繁體中文`_ `Français`_ `فارسی`_ `Español`_ `日本語`_ `Italiano`_ +**English** `简体中文`_ `繁體中文`_ `Français`_ `فارسی`_ `Español`_ `日本語`_ `Italiano`_ `Русский`_ --------------------------------------------------------------------------------------------------- Pygame_ is a free and open-source cross-platform library @@ -221,3 +221,4 @@ See docs/licenses for licenses of dependencies. .. _Español: ./docs/readmes/README.es.rst .. _日本語: ./docs/readmes/README.ja.rst .. _Italiano: ./docs/readmes/README.it.rst +.. _Русский: ./docs/readmes/README.ru.rst diff --git a/docs/readmes/README.es.rst b/docs/readmes/README.es.rst index 9c78006fe2..69d55ea896 100644 --- a/docs/readmes/README.es.rst +++ b/docs/readmes/README.es.rst @@ -7,7 +7,8 @@ |PyPiVersion| |PyPiLicense| |Python3| |GithubCommits| |BlackFormatBadge| -`English`_ `简体中文`_ `繁體中文`_ `Français`_ `فارسی`_ **Español** `日本語`_ `Italiano`_ +`English`_ `简体中文`_ `繁體中文`_ `Français`_ `فارسی`_ **Español** `日本語`_ `Italiano`_ `Русский`_ + --------------------------------------------------------------------------------------------------------------------------------------------------- `Pygame`_ es una biblioteca multiplataforma, gratuita y de código abierto @@ -171,3 +172,4 @@ Consulta docs/licenses para ver las licencias de dependencia. .. _Français: README.fr.rst .. _日本語: README.ja.rst .. _Italiano: README.it.rst +.. _Русский: README.ru.rst diff --git a/docs/readmes/README.fa.rst b/docs/readmes/README.fa.rst index e41ebb3ea8..bb83cd0733 100644 --- a/docs/readmes/README.fa.rst +++ b/docs/readmes/README.fa.rst @@ -7,7 +7,8 @@ |PyPiVersion| |PyPiLicense| |Python3| |GithubCommits| |BlackFormatBadge| -`English`_ `简体中文`_ `繁體中文`_ `Français`_ **فارسی** `Español`_ `日本語`_ `Italiano`_ +`English`_ `简体中文`_ `繁體中文`_ `Français`_ **فارسی** `Español`_ `日本語`_ `Italiano`_ `Русский`_ + --------------------------------------------------------------------------------------------------- کتابخانه Pygame_ @@ -257,3 +258,4 @@ LGPL-2.1-or-later **شناسه مجوز:** .. _Español: README.es.rst .. _日本語: README.ja.rst .. _Italiano: README.it.rst +.. _Русский: README.ru.rst diff --git a/docs/readmes/README.fr.rst b/docs/readmes/README.fr.rst index e546df1afe..72155e294b 100644 --- a/docs/readmes/README.fr.rst +++ b/docs/readmes/README.fr.rst @@ -7,7 +7,8 @@ |PyPiVersion| |PyPiLicense| |Python3| |GithubCommits| |BlackFormatBadge| -`English`_ `简体中文`_ `繁體中文`_ **Français** `فارسی`_ `Español`_ `日本語`_ `Italiano`_ +`English`_ `简体中文`_ `繁體中文`_ **Français** `فارسی`_ `Español`_ `日本語`_ `Italiano`_ `Русский`_ + --------------------------------------------------------------------------------------------------------------------------------------------------- `Pygame`_ est une bibliothèque multi-plateforme, libre et open-source @@ -211,3 +212,4 @@ Voir les docs/licences pour les licences des dépendances. .. _Español: README.es.rst .. _日本語: README.ja.rst .. _Italiano: README.it.rst +.. _Русский: README.ru.rst diff --git a/docs/readmes/README.it.rst b/docs/readmes/README.it.rst index df7dcddb58..0a7f366297 100644 --- a/docs/readmes/README.it.rst +++ b/docs/readmes/README.it.rst @@ -8,7 +8,7 @@ |PyPiVersion| |PyPiLicense| |Python3| |GithubCommits| |BlackFormatBadge| -`English`_ `简体中文`_ `繁體中文`_ `Français`_ `فارسی`_ `Español`_ `日本語`_ **Italiano** +`English`_ `简体中文`_ `繁體中文`_ `Français`_ `فارسی`_ `Español`_ `日本語`_ **Italiano** `Русский`_ --------------------------------------------------------------------------------------------------- Pygame_ è una libreria open source gratuita e multipiattaforma @@ -226,3 +226,4 @@ Controlla docs/licenses per le licenze dei requisiti. .. _Español: README.es.rst .. _日本語: README.ja.rst .. _Italiano: README.it.rst +.. _Русский: README.ru.rst diff --git a/docs/readmes/README.ja.rst b/docs/readmes/README.ja.rst index 7774b97a1d..bc4c0e63ab 100644 --- a/docs/readmes/README.ja.rst +++ b/docs/readmes/README.ja.rst @@ -8,7 +8,8 @@ |PyPiVersion| |PyPiLicense| |Python3| |GithubCommits| |BlackFormatBadge| -`English` `简体中文`_ `繁體中文`_ `Français`_ `فارسی`_ `Español`_ **日本語** `Italiano`_ +`English` `简体中文`_ `繁體中文`_ `Français`_ `فارسی`_ `Español`_ **日本語** `Italiano`_ `Русский`_ + --------------------------------------------------------------------------------------------------- Pygame_ は、Pythonを使ってビデオゲームのようなマルチメディアアプリケーションを @@ -232,9 +233,11 @@ gfxdraw には SDL_gfx の埋め込みバージョンが含まれています。 .. _Pygame Community Discord Server: https://discord.gg/pygame .. _wiki pages: https://github.com/pygame-community/pygame-ce/wiki -.. _简体中文: ./docs/readmes/README.zh-cn.rst +.. _English: ./../../README.rst +.. _简体中文: README.zh-cn.rst .. _繁體中文: README.zh-tw.rst -.. _Français: ./docs/readmes/README.fr.rst -.. _فارسی: ./docs/readmes/README.fa.rst -.. _Español: ./docs/readmes/README.es.rst +.. _Français: README.fr.rst +.. _فارسی: README.fa.rst +.. _Español: README.es.rst .. _Italiano: README.it.rst +.. _Русский: README.ru.rst diff --git a/docs/readmes/README.ru.rst b/docs/readmes/README.ru.rst new file mode 100644 index 0000000000..e6e099775f --- /dev/null +++ b/docs/readmes/README.ru.rst @@ -0,0 +1,226 @@ +.. image:: https://raw.githubusercontent.com/pygame-community/pygame-ce/main/docs/reST/_static/pygame_ce_logo.svg + :width: 800 + :alt: pygame + :target: https://pyga.me/ + + +|DocsStatus| +|PyPiVersion| |PyPiLicense| +|Python3| |GithubCommits| |BlackFormatBadge| + +`English`_ `简体中文`_ `繁體中文`_ `Français`_ `فارسی`_ `Español`_ `日本語`_ `Italiano`_ **Русский** +--------------------------------------------------------------------------------------------------- + +Pygame_ - бесплатная кроссплатформенная библиотека с открытым исходным кодом +для разработки мультимедийных приложений, таких как видеоигры, с использованием Python. +Он использует `Simple DirectMedia Layer library`_ и несколько других популярных библиотек +для абстрагирования наиболее распространенных функций, +что делает написание этих программ более интуитивно понятной задачей. + + +Этот дистрибутив называется **'pygame - Community Edition'** (сокращённо 'pygame-ce'). + +Это ответвление исходного проекта pygame от его бывших главных разработчиков и было создано после того, как непреодолимые +трудности помешали им продолжить разработку исходного проекта. +Новый дистрибутив призван предлагать более частые выпуски, постоянные исправления и усовершенствования, +а также более демократичную модель управления. + +Новые участники приветствуются! + + +Установка +------------ + +:: + + pip install pygame-ce + + +Справка +---- + +Если вы только начинаете работать с pygame, вы сможете приступить к работе довольно быстро. +Pygame поставляется с множеством руководств и введений. +Также имеется полная справочная документация по всей библиотеке. +Просмотрите документацию на страниц `docs page`_. +Вы также можете просмотреть документацию локально, запустив +``python -m pygame.docs`` в Вашем терминале. Если документы не найдены +локально, вместо этого будет запущен онлайн-сайт. + +Интерактивная документация соответствует версии pygame для разработки на github. +Она может быть немного новее, чем версия pygame, которую вы используете. +Чтобы перейти на последнюю выпущенную версию, запустите +``pip install pygame-ce --upgrade`` в Вашем терминале. + +Лучше всего то, что в каталоге examples есть множество воспроизводимых небольших программ, +которые помогут вам сразу начать работу с кодом. + + +Сборка из исходного кода +-------------------- + +Если вы хотите использовать функции, которые в настоящее время находятся в разработке, +или вы хотите внести свой вклад в pygame-ce, +вам нужно будет создать pygame-ce локально из его исходного кода, а не устанавливать его pip. + +Установка из исходного кода довольно автоматизирована. +Основная работа будет включать компиляцию и установку всех зависимостей pygame. +Как только это будет сделано, запустите сценарий ``setup.py``, +который попытается автоматически настроить, собрать и установить pygame. + +Гораздо больше информации об установке и компиляции доступно +на `Compilation wiki page`_. + + +Заслуги +------- + +Спасибо всем, кто помог внести свой вклад в эту библиотеку. +Также уместна особая благодарность. + +* Marcus Von Appen: many changes, and fixes, 1.7.1+ freebsd maintainer +* Lenard Lindstrom: the 1.8+ windows maintainer, many changes, and fixes +* Brian Fisher for svn auto builder, bug tracker and many contributions +* Rene Dudfield: many changes, and fixes, 1.7+ release manager/maintainer +* Phil Hassey for his work on the pygame.org website +* DR0ID for his work on the sprite module +* Richard Goedeken for his smoothscale function +* Ulf Ekström for his pixel perfect collision detection code +* Pete Shinners: original author +* David Clark for filling the right-hand-man position +* Ed Boraas and Francis Irving: Debian packages +* Maxim Sobolev: FreeBSD packaging +* Bob Ippolito: macOS and OS X porting (much work!) +* Jan Ekhol, Ray Kelm, and Peter Nicolai: putting up with early design ideas +* Nat Pryce for starting our unit tests +* Dan Richter for documentation work +* TheCorruptor for his incredible logos and graphics +* Nicholas Dudfield: many test improvements +* Alex Folkner for pygame-ctypes + +Спасибо тем, кто присылает патчи и исправления: Niki Spahiev, Gordon +Tyler, Nathaniel Pryce, Dave Wallace, John Popplewell, Michael Urman, +Andrew Straw, Michael Hudson, Ole Martin Bjoerndalen, Herve Cauwelier, +James Mazer, Lalo Martins, Timothy Stranex, Chad Lester, Matthias +Spiller, Bo Jangeborg, Dmitry Borisov, Campbell Barton, Diego Essaya, +Eyal Lotem, Regis Desgroppes, Emmanuel Hainry, Randy Kaelber, +Matthew L Daniel, Nirav Patel, Forrest Voight, Charlie Nolan, +Frankie Robertson, John Krukoff, Lorenz Quack, Nick Irvine, +Michael George, Saul Spatz, Thomas Ibbotson, Tom Rothamel, Evan Kroske, +Cambell Barton. + +И наши охотники за багами выше всяких похвал: Angus, Guillaume Proux, Frank +Raiser, Austin Henry, Kaweh Kazemi, Arturo Aldama, Mike Mulcheck, +Michael Benfield, David Lau + +Есть еще много людей, которые предоставили полезные идеи, +поддержали этот проект и, по сути, упростили нам жизнь. Спасибо! + +Большое спасибо людям, которые комментируют документацию и добавляют в +`pygame documentation`_ и `pygame-ce documentation`_. + +Также большое спасибо за людей, создающих игры и размещающих их на веб-сайте +pygame.org, чтобы другие могли учиться и получать удовольствие. + +Огромное спасибо James Paige за хостинг pygame bugzilla. + +Также большое спасибо Roger Dingledine и команде SEUL.ORG за наш +отличный хостинг. + + +Зависимости +------------ + +Pygame, очевидно, сильно зависит от SDL и Python. Он также +ссылается на несколько других библиотек меньшего размера и встраивает их. Модуль font +использует SDL_ttf, который зависит от freetype. Модули mixer +(и mixer.music) зависят от SDL_mixer. Модуль image +зависит от SDL_image. Transform.rotozoom имеет встроенную версию +SDL_rotozoom, а gfxdraw имеет встроенную версию SDL_gfx. +Версии зависимостей: + + ++----------+------------------------+ +| CPython | >= 3.8 (Or use PyPy3) | ++----------+------------------------+ +| SDL | >= 2.0.10 | ++----------+------------------------+ +| SDL_mixer| >= 2.0.4 | ++----------+------------------------+ +| SDL_image| >= 2.0.4 | ++----------+------------------------+ +| SDL_ttf | >= 2.0.15 | ++----------+------------------------+ + +Как внести свой вклад +----------------- +Прежде всего, спасибо, что согласились внести свой вклад в pygame-ce! Именно такие люди, как вы, делают pygame-ce отличной библиотекой. Пожалуйста, выполните следующие действия, чтобы начать: + +1. Read the `Contribution Guidelines`_ and the `Many Ways to Contribute`_ wiki pages. +2. Read the documentataion on `Opening A Pull Request`_ and `Opening a Great Pull Request`_. +3. Read how to `label and link reported issues`_. +4. Check the `issue tracker`_ for open issues that interest you or open a new issue to start a discussion about your idea. + +There are many more resources throughout the `wiki pages`_ that can help you get started. + +If you have any questions, please feel free to ask in the `Pygame Community Discord Server`_ or open an issue. + +License +------- +**License Identifier:** LGPL-2.1-or-later + +Эта библиотека распространяется под лицензией `GNU LGPL version 2.1`_, которую можно +найти в файле ``docs/LGPL.txt``. Мы оставляем за собой право размещать +будущие версии этой библиотеки под другой лицензией. + +По сути, это означает, что вы можете использовать pygame в любом проекте, который захотите, +но если вы вносите какие-либо изменения или дополнения в саму pygame, они +должны быть выпущены с совместимой лицензией (preferably submitted +back to the pygame-ce project). Игры с закрытым исходным кодом и коммерческие игры - это нормально. + +Программы в подкаталоге ``examples`` находятся в открытом доступе. + +Смотрите docs/licenses, чтобы узнать лицензии на зависимости. + + +.. |PyPiVersion| image:: https://img.shields.io/pypi/v/pygame-ce.svg?v=1 + :target: https://pypi.python.org/pypi/pygame-ce + +.. |PyPiLicense| image:: https://img.shields.io/pypi/l/pygame-ce.svg?v=1 + :target: https://pypi.python.org/pypi/pygame-ce + +.. |Python3| image:: https://img.shields.io/badge/python-3-blue.svg?v=1 + +.. |GithubCommits| image:: https://img.shields.io/github/commits-since/pygame-community/pygame-ce/2.4.1.svg + :target: https://github.com/pygame-community/pygame-ce/compare/2.4.1...main + +.. |DocsStatus| image:: https://img.shields.io/website?down_message=offline&label=docs&up_message=online&url=https%3A%2F%2Fpyga.me%2Fdocs%2F + :target: https://pyga.me/docs/ + +.. |BlackFormatBadge| image:: https://img.shields.io/badge/code%20style-black-000000.svg + :target: https://github.com/psf/black + +.. _Pygame: https://pyga.me +.. _pygame-ce documentation: https://pyga.me/docs/ +.. _pygame documentation: https://www.pygame.org/docs/ +.. _Simple DirectMedia Layer library: https://www.libsdl.org +.. _Compilation wiki page: https://github.com/pygame-community/pygame-ce/wiki#compiling +.. _docs page: https://pyga.me/docs +.. _GNU LGPL version 2.1: https://www.gnu.org/copyleft/lesser.html +.. _Contribution Guidelines: https://github.com/pygame-community/pygame-ce/wiki/Contribution-guidelines +.. _Many Ways to Contribute: https://github.com/pygame-community/pygame-ce/wiki/Many-ways-to-contribute +.. _Opening A Pull Request: https://github.com/pygame-community/pygame-ce/wiki/Opening-a-pull-request +.. _Opening a Great Pull Request: https://github.com/pygame-community/pygame-ce/wiki/Opening-a-great-pull-request +.. _issue tracker: https://github.com/pygame-community/pygame-ce/issues +.. _label and link reported issues: https://github.com/pygame-community/pygame-ce/wiki/Labelling-&-linking-reported-issues +.. _Pygame Community Discord Server: https://discord.gg/pygame +.. _wiki pages: https://github.com/pygame-community/pygame-ce/wiki + +.. _English: ./../../README.rst +.. _简体中文: README.zh-cn.rst +.. _繁體中文: README.zh-tw.rst +.. _Français: README.fr.rst +.. _فارسی: README.fa.rst +.. _Español: README.es.rst +.. _日本語: README.ja.rst +.. _Italiano: README.it.rst diff --git a/docs/readmes/README.zh-cn.rst b/docs/readmes/README.zh-cn.rst index 7816284e70..6a21668243 100644 --- a/docs/readmes/README.zh-cn.rst +++ b/docs/readmes/README.zh-cn.rst @@ -7,7 +7,8 @@ |PyPiVersion| |PyPiLicense| |Python3| |GithubCommits| |BlackFormatBadge| -`English`_ **简体中文** `繁體中文`_ `Français`_ `فارسی`_ `Español`_ `日本語`_ `Italiano`_ +`English`_ **简体中文** `繁體中文`_ `Français`_ `فارسی`_ `Español`_ `日本語`_ `Italiano`_ `Русский`_ + ---- Pygame_ 是一款自由且开源的跨平台库,用于开发电子游戏等多媒体应用。Pygame基于 `Simple DirectMedia Layer library`_ 以及其他几个广受欢迎的库,汲取其中最常见的函数,让编写游戏成为更加符合直觉的事情。 @@ -161,3 +162,4 @@ pygame显然依赖于SDL和Python。此外pygame还嵌入了几个较小的库 .. _Español: README.es.rst .. _日本語: README.ja.rst .. _Italiano: README.it.rst +.. _Русский: README.ru.rst From fac1c39c973a29c8ebbe95cc503b6ea6aeeb36ef Mon Sep 17 00:00:00 2001 From: Ankith Date: Sun, 3 Nov 2024 19:22:51 +0530 Subject: [PATCH 13/44] Raise minimum supported SDL2 to 2.0.14 --- README.rst | 2 +- docs/reST/ref/event.rst | 2 +- docs/reST/ref/joystick.rst | 2 +- docs/reST/ref/sdl2_controller.rst | 8 ++----- docs/reST/ref/system.rst | 5 +--- docs/readmes/README.es.rst | 2 +- docs/readmes/README.fa.rst | 2 +- docs/readmes/README.fr.rst | 2 +- docs/readmes/README.it.rst | 2 +- docs/readmes/README.ja.rst | 2 +- docs/readmes/README.ru.rst | 2 +- docs/readmes/README.zh-cn.rst | 2 +- src_c/_camera.c | 2 +- src_c/_pygame.h | 40 ------------------------------- src_c/_sdl2/controller.c | 6 ----- src_c/constants.c | 8 ------- src_c/display.c | 19 ++++----------- src_c/event.c | 12 ---------- src_c/font.c | 2 +- src_c/include/pgcompat.h | 18 +------------- src_c/pixelcopy.c | 2 +- src_c/surface.c | 2 +- src_c/system.c | 11 +-------- 23 files changed, 23 insertions(+), 132 deletions(-) diff --git a/README.rst b/README.rst index 72b6cea133..a0347341e7 100644 --- a/README.rst +++ b/README.rst @@ -141,7 +141,7 @@ Dependency versions: +----------+------------------------+ | CPython | >= 3.8 (Or use PyPy3) | +----------+------------------------+ -| SDL | >= 2.0.10 | +| SDL | >= 2.0.14 | +----------+------------------------+ | SDL_mixer| >= 2.0.4 | +----------+------------------------+ diff --git a/docs/reST/ref/event.rst b/docs/reST/ref/event.rst index b6c8349948..186fa37717 100644 --- a/docs/reST/ref/event.rst +++ b/docs/reST/ref/event.rst @@ -154,7 +154,7 @@ pygame 2 also supports controller hot-plugging CLIPBOARDUPDATE RENDER_TARGETS_RESET RENDER_DEVICE_RESET - LOCALECHANGED (SDL backend >= 2.0.14) + LOCALECHANGED Also in this version, ``instance_id`` attributes were added to joystick events, and the ``joy`` attribute was deprecated. diff --git a/docs/reST/ref/joystick.rst b/docs/reST/ref/joystick.rst index 0e89c13dcf..555c549489 100644 --- a/docs/reST/ref/joystick.rst +++ b/docs/reST/ref/joystick.rst @@ -338,7 +338,7 @@ variable. See :ref:`environment variables ` for more deta playing, then it will be overwritten. Returns True if the rumble was played successfully or False if the - joystick does not support it or :meth:`pygame.version.SDL` is below 2.0.9. + joystick does not support it. .. versionaddedold:: 2.0.2 diff --git a/docs/reST/ref/sdl2_controller.rst b/docs/reST/ref/sdl2_controller.rst index c5e61e4d9f..e6ff3ef4bd 100644 --- a/docs/reST/ref/sdl2_controller.rst +++ b/docs/reST/ref/sdl2_controller.rst @@ -19,11 +19,7 @@ always the leftmost button of the 4 buttons on the right. Controllers can generate the following events:: CONTROLLERAXISMOTION, CONTROLLERBUTTONDOWN, CONTROLLERBUTTONUP, - CONTROLLERDEVICEREMAPPED, CONTROLLERDEVICEADDED, CONTROLLERDEVICEREMOVED - -Additionally if pygame is built with SDL 2.0.14 or higher the following events can also be generated -(to get the version of sdl pygame is built with use :meth:`pygame.version.SDL`):: - + CONTROLLERDEVICEREMAPPED, CONTROLLERDEVICEADDED, CONTROLLERDEVICEREMOVED, CONTROLLERTOUCHPADDOWN, CONTROLLERTOUCHPADMOTION, CONTROLLERTOUCHPADUP These events can be enabled/disabled by :meth:`pygame._sdl2.controller.set_eventstate` @@ -274,7 +270,7 @@ events related to controllers. playing, then it will be overwritten. Returns True if the rumble was played successfully or False if the - controller does not support it or :meth:`pygame.version.SDL` is below 2.0.9. + controller does not support it. .. versionaddedold:: 2.0.2 diff --git a/docs/reST/ref/system.rst b/docs/reST/ref/system.rst index eb1450f9e3..de5cb55daf 100644 --- a/docs/reST/ref/system.rst +++ b/docs/reST/ref/system.rst @@ -43,10 +43,7 @@ 'LASX': False } - .. Note:: The value of ``ARMSIMD`` will be always False if - SDL version < 2.0.12. - - The values of ``LSX`` and ``LASX`` will be always False if + .. Note:: The values of ``LSX`` and ``LASX`` will be always False if SDL version < 2.24.0. .. versionadded:: 2.3.1 diff --git a/docs/readmes/README.es.rst b/docs/readmes/README.es.rst index 69d55ea896..d1ca1fd6c2 100644 --- a/docs/readmes/README.es.rst +++ b/docs/readmes/README.es.rst @@ -119,7 +119,7 @@ Versiones de dependencia: +----------+-----------------------------+ | CPython | >= 3.8 (Ou utiliser PyPy3) | +----------+-----------------------------+ -| SDL | >= 2.0.10 | +| SDL | >= 2.0.14 | +----------+-----------------------------+ | SDL_mixer| >= 2.0.4 | +----------+-----------------------------+ diff --git a/docs/readmes/README.fa.rst b/docs/readmes/README.fa.rst index bb83cd0733..b3b7229b33 100644 --- a/docs/readmes/README.fa.rst +++ b/docs/readmes/README.fa.rst @@ -191,7 +191,7 @@ Dependencies (وابستگی ها) +----------+------------------------+ | CPython | >= 3.8 (Or use PyPy3) | +----------+------------------------+ -| SDL | >= 2.0.10 | +| SDL | >= 2.0.14 | +----------+------------------------+ | SDL_mixer| >= 2.0.4 | +----------+------------------------+ diff --git a/docs/readmes/README.fr.rst b/docs/readmes/README.fr.rst index 72155e294b..c17d701fa9 100644 --- a/docs/readmes/README.fr.rst +++ b/docs/readmes/README.fr.rst @@ -148,7 +148,7 @@ Versions des dépendances: +----------+-----------------------------+ | CPython | >= 3.8 (Ou utiliser PyPy3) | +----------+-----------------------------+ -| SDL | >= 2.0.10 | +| SDL | >= 2.0.14 | +----------+-----------------------------+ | SDL_mixer| >= 2.0.4 | +----------+-----------------------------+ diff --git a/docs/readmes/README.it.rst b/docs/readmes/README.it.rst index 0a7f366297..f660b2c3cc 100644 --- a/docs/readmes/README.it.rst +++ b/docs/readmes/README.it.rst @@ -142,7 +142,7 @@ Le versioni dei requisiti: +----------+------------------------+ | CPython | >= 3.8 (Or use PyPy3) | +----------+------------------------+ -| SDL | >= 2.0.10 | +| SDL | >= 2.0.14 | +----------+------------------------+ | SDL_mixer| >= 2.0.4 | +----------+------------------------+ diff --git a/docs/readmes/README.ja.rst b/docs/readmes/README.ja.rst index bc4c0e63ab..502cd98e8e 100644 --- a/docs/readmes/README.ja.rst +++ b/docs/readmes/README.ja.rst @@ -153,7 +153,7 @@ gfxdraw には SDL_gfx の埋め込みバージョンが含まれています。 +----------+------------------------+ | CPython | >= 3.8 (Or use PyPy3) | +----------+------------------------+ -| SDL | >= 2.0.10 | +| SDL | >= 2.0.14 | +----------+------------------------+ | SDL_mixer| >= 2.0.4 | +----------+------------------------+ diff --git a/docs/readmes/README.ru.rst b/docs/readmes/README.ru.rst index e6e099775f..cdcbd37fc7 100644 --- a/docs/readmes/README.ru.rst +++ b/docs/readmes/README.ru.rst @@ -143,7 +143,7 @@ SDL_rotozoom, а gfxdraw имеет встроенную версию SDL_gfx. +----------+------------------------+ | CPython | >= 3.8 (Or use PyPy3) | +----------+------------------------+ -| SDL | >= 2.0.10 | +| SDL | >= 2.0.14 | +----------+------------------------+ | SDL_mixer| >= 2.0.4 | +----------+------------------------+ diff --git a/docs/readmes/README.zh-cn.rst b/docs/readmes/README.zh-cn.rst index 6a21668243..63745b8edb 100644 --- a/docs/readmes/README.zh-cn.rst +++ b/docs/readmes/README.zh-cn.rst @@ -107,7 +107,7 @@ pygame显然依赖于SDL和Python。此外pygame还嵌入了几个较小的库 +----------+------------------------+ | CPython | >= 3.8 (或 PyPy3) | +----------+------------------------+ -| SDL | >= 2.0.10 | +| SDL | >= 2.0.14 | +----------+------------------------+ | SDL_mixer| >= 2.0.4 | +----------+------------------------+ diff --git a/src_c/_camera.c b/src_c/_camera.c index 8bf528b559..3776e9fa68 100644 --- a/src_c/_camera.c +++ b/src_c/_camera.c @@ -425,7 +425,7 @@ camera_get_image(pgCameraObject *self, PyObject *arg) return NULL; if (!surfobj) { - surf = PG_CreateSurface(width, height, PG_PIXELFORMAT_XRGB8888); + surf = PG_CreateSurface(width, height, SDL_PIXELFORMAT_XRGB8888); } else { surf = pgSurface_AsSurface(surfobj); diff --git a/src_c/_pygame.h b/src_c/_pygame.h index 07f236149a..45ac03e341 100644 --- a/src_c/_pygame.h +++ b/src_c/_pygame.h @@ -188,47 +188,7 @@ PG_UnlockMutex(SDL_mutex *mutex) #define PG_INIT_TIMER SDL_INIT_TIMER -#if SDL_VERSION_ATLEAST(2, 0, 14) #define PG_SurfaceHasRLE SDL_HasSurfaceRLE -#else -// vendored in until our lowest SDL version is 2.0.14 -typedef struct { - Uint8 *src; - int src_w, src_h; - int src_pitch; - int src_skip; - Uint8 *dst; - int dst_w, dst_h; - int dst_pitch; - int dst_skip; - SDL_PixelFormat *src_fmt; - SDL_PixelFormat *dst_fmt; - Uint8 *table; - int flags; - Uint32 colorkey; - Uint8 r, g, b, a; -} SDL_InternalBlitInfo; - -struct SDL_BlitMap { - SDL_Surface *dst; - int identity; - SDL_blit blit; - void *data; - SDL_InternalBlitInfo info; - - /* the version count matches the destination; mismatch indicates - an invalid mapping */ - Uint32 dst_palette_version; - Uint32 src_palette_version; -}; -#define SDL_COPY_RLE_DESIRED 0x00001000 - -#define PG_SurfaceHasRLE(surface) \ - (((surface) == NULL) \ - ? 0 \ - : ((surface)->map->info.flags & SDL_COPY_RLE_DESIRED)) - -#endif #endif diff --git a/src_c/_sdl2/controller.c b/src_c/_sdl2/controller.c index 6425aa4f51..331ffd876d 100644 --- a/src_c/_sdl2/controller.c +++ b/src_c/_sdl2/controller.c @@ -367,7 +367,6 @@ controller_rumble(pgControllerObject *self, PyObject *args, PyObject *kwargs) return RAISE(pgExc_SDLError, "Controller is not initalized"); } -#if SDL_VERSION_ATLEAST(2, 0, 9) // rumble takes values in range 0 to 0xFFFF (65535) low_freq = MAX(MIN(low_freq, 1.0f), 0.0f) * 65535; high_freq = MAX(MIN(high_freq, 1.0f), 0.0f) * 65535; @@ -376,9 +375,6 @@ controller_rumble(pgControllerObject *self, PyObject *args, PyObject *kwargs) (Uint16)high_freq, duration); return PyBool_FromLong(success == 0); -#else - Py_RETURN_FALSE; -#endif } static PyObject * @@ -388,9 +384,7 @@ controller_stop_rumble(pgControllerObject *self, PyObject *_null) if (!self->controller) { return RAISE(pgExc_SDLError, "Controller is not initalized"); } -#if SDL_VERSION_ATLEAST(2, 0, 9) SDL_GameControllerRumble(self->controller, 0, 0, 1); -#endif Py_RETURN_NONE; } diff --git a/src_c/constants.c b/src_c/constants.c index f9eb244007..771aefca5a 100644 --- a/src_c/constants.c +++ b/src_c/constants.c @@ -317,19 +317,11 @@ MODINIT_DEFINE(constants) DEC_CONST(CONTROLLERDEVICEADDED); DEC_CONST(CONTROLLERDEVICEREMOVED); DEC_CONST(CONTROLLERDEVICEREMAPPED); -#if SDL_VERSION_ATLEAST(2, 0, 14) DEC_CONST(CONTROLLERTOUCHPADDOWN); DEC_CONST(CONTROLLERTOUCHPADMOTION); DEC_CONST(CONTROLLERTOUCHPADUP); DEC_CONST(CONTROLLERSENSORUPDATE); DEC_CONST(LOCALECHANGED); -#else - DEC_CONSTS(CONTROLLERTOUCHPADDOWN, -1); - DEC_CONSTS(CONTROLLERTOUCHPADMOTION, -1); - DEC_CONSTS(CONTROLLERTOUCHPADUP, -1); - DEC_CONSTS(CONTROLLERSENSORUPDATE, -1); - DEC_CONSTS(LOCALECHANGED, -1); -#endif DEC_CONST(JOYDEVICEADDED); DEC_CONST(JOYDEVICEREMOVED); diff --git a/src_c/display.c b/src_c/display.c index af7e268cbc..3ff35d4fa0 100644 --- a/src_c/display.c +++ b/src_c/display.c @@ -688,7 +688,7 @@ pg_ResizeEventWatch(void *userdata, SDL_Event *event) int h = event->window.data2; pgSurfaceObject *display_surface = pg_GetDefaultWindowSurface(); SDL_Surface *surf = - PG_CreateSurface(w, h, PG_PIXELFORMAT_XRGB8888); + PG_CreateSurface(w, h, SDL_PIXELFORMAT_XRGB8888); SDL_FreeSurface(display_surface->surf); display_surface->surf = surf; @@ -1156,7 +1156,7 @@ pg_set_mode(PyObject *self, PyObject *arg, PyObject *kwds) So we make a fake surface. */ - surf = PG_CreateSurface(w, h, PG_PIXELFORMAT_XRGB8888); + surf = PG_CreateSurface(w, h, SDL_PIXELFORMAT_XRGB8888); newownedsurf = surf; } else { @@ -1265,7 +1265,7 @@ pg_set_mode(PyObject *self, PyObject *arg, PyObject *kwds) pg_renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, w, h); } - surf = PG_CreateSurface(w, h, PG_PIXELFORMAT_XRGB8888); + surf = PG_CreateSurface(w, h, SDL_PIXELFORMAT_XRGB8888); newownedsurf = surf; } else { @@ -1571,7 +1571,7 @@ pg_list_modes(PyObject *self, PyObject *args, PyObject *kwds) } /* use reasonable defaults (cf. SDL_video.c) */ if (!mode.format) - mode.format = PG_PIXELFORMAT_XRGB8888; + mode.format = SDL_PIXELFORMAT_XRGB8888; if (!mode.w) mode.w = 640; if (!mode.h) @@ -2803,9 +2803,7 @@ pg_message_box(PyObject *self, PyObject *arg, PyObject *kwargs) return NULL; } -#if SDL_VERSION_ATLEAST(2, 0, 12) msgbox_data.flags |= SDL_MESSAGEBOX_BUTTONS_LEFT_TO_RIGHT; -#endif if (parent_window == Py_None) { msgbox_data.window = NULL; @@ -2896,12 +2894,7 @@ pg_message_box(PyObject *self, PyObject *arg, PyObject *kwargs) buttons_data = malloc(sizeof(SDL_MessageBoxButtonData) * num_buttons); for (Py_ssize_t i = 0; i < num_buttons; i++) { -#if SDL_VERSION_ATLEAST(2, 0, 12) PyObject *btn_name_obj = PySequence_GetItem(buttons, i); -#else - PyObject *btn_name_obj = - PySequence_GetItem(buttons, num_buttons - i - 1); -#endif if (!btn_name_obj) goto error; @@ -2916,11 +2909,7 @@ pg_message_box(PyObject *self, PyObject *arg, PyObject *kwargs) goto error; buttons_data[i].text = btn_name; -#if SDL_VERSION_ATLEAST(2, 0, 12) buttons_data[i].buttonid = (int)i; -#else - buttons_data[i].buttonid = (int)(num_buttons - i - 1); -#endif buttons_data[i].flags = 0; if (return_button_index == buttons_data[i].buttonid) buttons_data[i].flags |= diff --git a/src_c/event.c b/src_c/event.c index 59132e3330..4af65354f7 100644 --- a/src_c/event.c +++ b/src_c/event.c @@ -342,12 +342,10 @@ _pg_pgevent_proxify_helper(Uint32 type, Uint8 proxify) _PG_HANDLE_PROXIFY(CONTROLLERDEVICEADDED); _PG_HANDLE_PROXIFY(CONTROLLERDEVICEREMOVED); _PG_HANDLE_PROXIFY(CONTROLLERDEVICEREMAPPED); -#if SDL_VERSION_ATLEAST(2, 0, 14) _PG_HANDLE_PROXIFY(CONTROLLERTOUCHPADDOWN); _PG_HANDLE_PROXIFY(CONTROLLERTOUCHPADMOTION); _PG_HANDLE_PROXIFY(CONTROLLERTOUCHPADUP); _PG_HANDLE_PROXIFY(CONTROLLERSENSORUPDATE); -#endif _PG_HANDLE_PROXIFY(DOLLARGESTURE); _PG_HANDLE_PROXIFY(DOLLARRECORD); _PG_HANDLE_PROXIFY(DROPFILE); @@ -367,9 +365,7 @@ _pg_pgevent_proxify_helper(Uint32 type, Uint8 proxify) _PG_HANDLE_PROXIFY(JOYBUTTONUP); _PG_HANDLE_PROXIFY(JOYDEVICEADDED); _PG_HANDLE_PROXIFY(JOYDEVICEREMOVED); -#if SDL_VERSION_ATLEAST(2, 0, 14) _PG_HANDLE_PROXIFY(LOCALECHANGED); -#endif _PG_HANDLE_PROXIFY(MOUSEMOTION); _PG_HANDLE_PROXIFY(MOUSEBUTTONDOWN); _PG_HANDLE_PROXIFY(MOUSEBUTTONUP); @@ -756,10 +752,8 @@ _pg_name_from_eventtype(int type) return "KeyUp"; case SDL_KEYMAPCHANGED: return "KeyMapChanged"; -#if SDL_VERSION_ATLEAST(2, 0, 14) case SDL_LOCALECHANGED: return "LocaleChanged"; -#endif case SDL_MOUSEMOTION: return "MouseMotion"; case SDL_MOUSEBUTTONDOWN: @@ -828,7 +822,6 @@ _pg_name_from_eventtype(int type) return "JoyDeviceAdded"; case SDL_JOYDEVICEREMOVED: return "JoyDeviceRemoved"; -#if SDL_VERSION_ATLEAST(2, 0, 14) case SDL_CONTROLLERTOUCHPADDOWN: return "ControllerTouchpadDown"; case SDL_CONTROLLERTOUCHPADMOTION: @@ -837,7 +830,6 @@ _pg_name_from_eventtype(int type) return "ControllerTouchpadUp"; case SDL_CONTROLLERSENSORUPDATE: return "ControllerSensorUpdate"; -#endif /*SDL_VERSION_ATLEAST(2, 0, 14)*/ case SDL_AUDIODEVICEADDED: return "AudioDeviceAdded"; case SDL_AUDIODEVICEREMOVED: @@ -1215,7 +1207,6 @@ dict_from_event(SDL_Event *event) _pg_insobj(dict, "instance_id", PyLong_FromLong(event->jdevice.which)); break; -#if SDL_VERSION_ATLEAST(2, 0, 14) case SDL_CONTROLLERTOUCHPADDOWN: case SDL_CONTROLLERTOUCHPADMOTION: case SDL_CONTROLLERTOUCHPADUP: @@ -1230,7 +1221,6 @@ dict_from_event(SDL_Event *event) _pg_insobj(dict, "pressure", PyFloat_FromDouble(event->ctouchpad.pressure)); break; -#endif /*SDL_VERSION_ATLEAST(2, 0, 14)*/ #ifdef WIN32 case SDL_SYSWMEVENT: @@ -1318,14 +1308,12 @@ dict_from_event(SDL_Event *event) window = SDL_GetWindowFromID(event->button.windowID); break; } -#if SDL_VERSION_ATLEAST(2, 0, 14) case SDL_FINGERMOTION: case SDL_FINGERDOWN: case SDL_FINGERUP: { window = SDL_GetWindowFromID(event->tfinger.windowID); break; } -#endif default: { return dict; } diff --git a/src_c/font.c b/src_c/font.c index cae985f1cc..8530bcd3e1 100644 --- a/src_c/font.c +++ b/src_c/font.c @@ -612,7 +612,7 @@ font_render(PyObject *self, PyObject *args, PyObject *kwds) if (strlen(astring) == 0) { /* special 0 string case */ int height = TTF_FontHeight(font); - surf = PG_CreateSurface(0, height, PG_PIXELFORMAT_XRGB8888); + surf = PG_CreateSurface(0, height, SDL_PIXELFORMAT_XRGB8888); } else { /* normal case */ if (antialias && bg_rgba_obj == Py_None) { diff --git a/src_c/include/pgcompat.h b/src_c/include/pgcompat.h index 7c89877d78..aa7a2e37e1 100644 --- a/src_c/include/pgcompat.h +++ b/src_c/include/pgcompat.h @@ -27,29 +27,13 @@ typedef uint8_t Uint8; * warning without this check here, which is very weird. */ #ifdef SDL_VERSION_ATLEAST -// SDL_PIXELFORMAT_XRGB8888 and SDL_PIXELFORMAT_XBGR8888 are new names -// in SDL 2.0.14, the macros below let us use the new (less confusing) -// naming while still building on old versions. - -#if SDL_VERSION_ATLEAST(2, 0, 14) -#define PG_PIXELFORMAT_XRGB8888 SDL_PIXELFORMAT_XRGB8888 -#else -#define PG_PIXELFORMAT_XRGB8888 SDL_PIXELFORMAT_RGB888 -#endif - -#if SDL_VERSION_ATLEAST(2, 0, 14) -#define PG_PIXELFORMAT_XBGR8888 SDL_PIXELFORMAT_XBGR8888 -#else -#define PG_PIXELFORMAT_XBGR8888 SDL_PIXELFORMAT_BGR888 -#endif - // SDL does not provide endian independent names for 32 bit formats without // alpha channels the way they do for ones with alpha channels. // E.g. SDL_PIXELFORMAT_RGBA32. This macro allows us the convenience of the // endian independent name. #if SDL_BYTEORDER == SDL_LIL_ENDIAN -#define PG_PIXELFORMAT_RGBX32 PG_PIXELFORMAT_XBGR8888 +#define PG_PIXELFORMAT_RGBX32 SDL_PIXELFORMAT_XBGR8888 #else #define PG_PIXELFORMAT_RGBX32 SDL_PIXELFORMAT_RGBX8888 #endif diff --git a/src_c/pixelcopy.c b/src_c/pixelcopy.c index 751ed25124..a964b9f373 100644 --- a/src_c/pixelcopy.c +++ b/src_c/pixelcopy.c @@ -1160,7 +1160,7 @@ make_surface(PyObject *self, PyObject *arg) pixelformat = SDL_PIXELFORMAT_INDEX8; } else { - pixelformat = PG_PIXELFORMAT_XRGB8888; + pixelformat = SDL_PIXELFORMAT_XRGB8888; } sizex = (int)view_p->shape[0]; sizey = (int)view_p->shape[1]; diff --git a/src_c/surface.c b/src_c/surface.c index d4a8eae2e9..1850ebc19f 100644 --- a/src_c/surface.c +++ b/src_c/surface.c @@ -1612,7 +1612,7 @@ pg_DisplayFormatAlpha(SDL_Surface *surface) #endif case SDL_PIXELFORMAT_ABGR1555: case SDL_PIXELFORMAT_BGR565: - case PG_PIXELFORMAT_XBGR8888: + case SDL_PIXELFORMAT_XBGR8888: case SDL_PIXELFORMAT_ABGR8888: pfe = SDL_PIXELFORMAT_ABGR8888; break; diff --git a/src_c/system.c b/src_c/system.c index 8794a95993..4e7c21162a 100644 --- a/src_c/system.c +++ b/src_c/system.c @@ -35,12 +35,7 @@ pg_system_get_cpu_instruction_sets(PyObject *self, PyObject *_null) INSERT_INSTRUCTIONSET_INFO("AVX2", SDL_HasAVX2); INSERT_INSTRUCTIONSET_INFO("AVX512F", SDL_HasAVX512F); INSERT_INSTRUCTIONSET_INFO("NEON", SDL_HasNEON); -#if SDL_VERSION_ATLEAST(2, 0, 12) INSERT_INSTRUCTIONSET_INFO("ARMSIMD", SDL_HasARMSIMD); -#else - if (PyDict_SetItemString(instruction_sets, "ARMSIMD", Py_False)) - goto error; -#endif #if SDL_VERSION_ATLEAST(2, 24, 0) INSERT_INSTRUCTIONSET_INFO("LSX", SDL_HasLSX); INSERT_INSTRUCTIONSET_INFO("LASX", SDL_HasLASX); @@ -113,7 +108,7 @@ pg_system_get_pref_locales(PyObject *self, PyObject *_null) * information */ return ret_list; } -#elif SDL_VERSION_ATLEAST(2, 0, 14) +#else SDL_Locale *locales = SDL_GetPreferredLocales(); if (!locales) { /* Return an empty list if SDL function does not return any useful @@ -131,7 +126,6 @@ pg_system_get_pref_locales(PyObject *self, PyObject *_null) } #endif -#if SDL_VERSION_ATLEAST(2, 0, 14) for (int i = 0; i < num_locales; i++) { dict = PyDict_New(); if (!dict) { @@ -183,9 +177,6 @@ pg_system_get_pref_locales(PyObject *self, PyObject *_null) SDL_free(locales); Py_DECREF(ret_list); return NULL; -#else - return ret_list; -#endif } static PyObject *PowerState_class = NULL; From 4622f423b1051608f633d342235d307433063967 Mon Sep 17 00:00:00 2001 From: Ankith Date: Sat, 2 Nov 2024 20:21:37 +0530 Subject: [PATCH 14/44] Port event.c to SDL3 --- src_c/_pygame.h | 4 + src_c/event.c | 247 +++++++++++++++++++++++++++++++++++++++++----- src_c/meson.build | 3 - 3 files changed, 229 insertions(+), 25 deletions(-) diff --git a/src_c/_pygame.h b/src_c/_pygame.h index 45ac03e341..05bf8a5228 100644 --- a/src_c/_pygame.h +++ b/src_c/_pygame.h @@ -308,8 +308,10 @@ typedef enum { PGPOST_CONTROLLERTOUCHPADMOTION, PGPOST_CONTROLLERTOUCHPADUP, PGPOST_CONTROLLERSENSORUPDATE, +#if !SDL_VERSION_ATLEAST(3, 0, 0) PGPOST_DOLLARGESTURE, PGPOST_DOLLARRECORD, +#endif PGPOST_DROPFILE, PGPOST_DROPTEXT, PGPOST_DROPBEGIN, @@ -334,7 +336,9 @@ typedef enum { PGPOST_MOUSEBUTTONDOWN, PGPOST_MOUSEBUTTONUP, PGPOST_MOUSEWHEEL, +#if !SDL_VERSION_ATLEAST(3, 0, 0) PGPOST_MULTIGESTURE, +#endif PGPOST_NOEVENT, PGPOST_QUIT, PGPOST_RENDER_TARGETS_RESET, diff --git a/src_c/event.c b/src_c/event.c index 4af65354f7..c7838a0ee8 100644 --- a/src_c/event.c +++ b/src_c/event.c @@ -33,9 +33,11 @@ #include "structmember.h" +#ifndef PG_SDL3 // The system message code is only tested on windows, so only // include it there for now. #include +#endif #define JOYEVENT_INSTANCE_ID "instance_id" #define JOYEVENT_DEVICE_INDEX "device_index" @@ -129,8 +131,13 @@ static char released_mouse_buttons[5] = {0}; } #endif /* not on emscripten */ +#if SDL_VERSION_ATLEAST(3, 0, 0) +static Uint32 +_pg_repeat_callback(void *param, SDL_TimerID timerID, Uint32 interval) +#else static Uint32 _pg_repeat_callback(Uint32 interval, void *param) +#endif { /* This function is called in a SDL Timer thread */ PG_LOCK_EVFILTER_MUTEX @@ -141,8 +148,13 @@ _pg_repeat_callback(Uint32 interval, void *param) PG_UNLOCK_EVFILTER_MUTEX repeat_event_copy.type = PGE_KEYREPEAT; +#if SDL_VERSION_ATLEAST(3, 0, 0) + repeat_event_copy.key.down = true; + repeat_event_copy.key.repeat = true; +#else repeat_event_copy.key.state = SDL_PRESSED; repeat_event_copy.key.repeat = 1; +#endif SDL_PushEvent(&repeat_event_copy); return repeat_interval_copy; } @@ -159,13 +171,22 @@ _pg_repeat_callback(Uint32 interval, void *param) static char _pg_unicode_from_event(SDL_Event *event) { +#if SDL_VERSION_ATLEAST(3, 0, 0) + int capsheld = event->key.mod & KMOD_CAPS; + int shiftheld = event->key.mod & KMOD_SHIFT; + SDL_Keycode key = event->key.key; +#else int capsheld = event->key.keysym.mod & KMOD_CAPS; int shiftheld = event->key.keysym.mod & KMOD_SHIFT; - - int capitalize = (capsheld && !shiftheld) || (shiftheld && !capsheld); SDL_Keycode key = event->key.keysym.sym; +#endif + int capitalize = (capsheld && !shiftheld) || (shiftheld && !capsheld); +#if SDL_VERSION_ATLEAST(3, 0, 0) + if (event->key.mod & KMOD_CTRL) { +#else if (event->key.keysym.mod & KMOD_CTRL) { +#endif /* Control Key held, send control-key related unicode. */ if (key >= SDLK_a && key <= SDLK_z) return key - SDLK_a + 1; @@ -230,7 +251,7 @@ def _pg_strip_utf8(string): return "" */ static void -_pg_strip_utf8(char *str, char *ret) +_pg_strip_utf8(const char *str, char *ret) { Uint8 firstbyte = (Uint8)*str; @@ -261,12 +282,16 @@ _pg_strip_utf8(char *str, char *ret) } static int -_pg_put_event_unicode(SDL_Event *event, char *uni) +_pg_put_event_unicode(SDL_Event *event, const char *uni) { int i; for (i = 0; i < MAX_SCAN_UNICODE; i++) { if (!scanunicode[i].key) { +#if SDL_VERSION_ATLEAST(3, 0, 0) + scanunicode[i].key = event->key.scancode; +#else scanunicode[i].key = event->key.keysym.scancode; +#endif _pg_strip_utf8(uni, scanunicode[i].unicode); return 1; } @@ -282,7 +307,11 @@ _pg_get_event_unicode(SDL_Event *event) char c[4]; int i; for (i = 0; i < MAX_SCAN_UNICODE; i++) { +#if SDL_VERSION_ATLEAST(3, 0, 0) + if (scanunicode[i].key == event->key.scancode) { +#else if (scanunicode[i].key == event->key.keysym.scancode) { +#endif if (event->type == SDL_KEYUP) { /* mark the position as free real estate for other * events to occupy. */ @@ -346,8 +375,10 @@ _pg_pgevent_proxify_helper(Uint32 type, Uint8 proxify) _PG_HANDLE_PROXIFY(CONTROLLERTOUCHPADMOTION); _PG_HANDLE_PROXIFY(CONTROLLERTOUCHPADUP); _PG_HANDLE_PROXIFY(CONTROLLERSENSORUPDATE); +#if !SDL_VERSION_ATLEAST(3, 0, 0) _PG_HANDLE_PROXIFY(DOLLARGESTURE); _PG_HANDLE_PROXIFY(DOLLARRECORD); +#endif _PG_HANDLE_PROXIFY(DROPFILE); _PG_HANDLE_PROXIFY(DROPTEXT); _PG_HANDLE_PROXIFY(DROPBEGIN); @@ -370,7 +401,9 @@ _pg_pgevent_proxify_helper(Uint32 type, Uint8 proxify) _PG_HANDLE_PROXIFY(MOUSEBUTTONDOWN); _PG_HANDLE_PROXIFY(MOUSEBUTTONUP); _PG_HANDLE_PROXIFY(MOUSEWHEEL); +#if !SDL_VERSION_ATLEAST(3, 0, 0) _PG_HANDLE_PROXIFY(MULTIGESTURE); +#endif _PG_HANDLE_PROXIFY(NOEVENT); _PG_HANDLE_PROXIFY(QUIT); _PG_HANDLE_PROXIFY(RENDER_TARGETS_RESET); @@ -417,6 +450,9 @@ _pg_pgevent_deproxify(Uint32 type) return _pg_pgevent_proxify_helper(type, 0); } +#if !SDL_VERSION_ATLEAST(3, 0, 0) +/* We don't need to do window event translation because in SDL3 each window + * event is its own thing anyways */ static int _pg_translate_windowevent(void *_, SDL_Event *event) { @@ -426,8 +462,13 @@ _pg_translate_windowevent(void *_, SDL_Event *event) } return 1; } +#endif +#if SDL_VERSION_ATLEAST(3, 0, 0) +static bool SDLCALL +#else static int SDLCALL +#endif _pg_remove_pending_VIDEORESIZE(void *userdata, SDL_Event *event) { SDL_Event *new_event = (SDL_Event *)userdata; @@ -440,7 +481,11 @@ _pg_remove_pending_VIDEORESIZE(void *userdata, SDL_Event *event) return 1; } +#if SDL_VERSION_ATLEAST(3, 0, 0) +static bool SDLCALL +#else static int SDLCALL +#endif _pg_remove_pending_VIDEOEXPOSE(void *userdata, SDL_Event *event) { SDL_Event *new_event = (SDL_Event *)userdata; @@ -458,16 +503,34 @@ _pg_remove_pending_VIDEOEXPOSE(void *userdata, SDL_Event *event) * This function can be called from multiple threads, so a mutex must be held * when this function tries to modify any global state (the mutex is not needed * on all branches of this function) */ +#if SDL_VERSION_ATLEAST(3, 0, 0) +static bool SDLCALL +#else static int SDLCALL +#endif pg_event_filter(void *_, SDL_Event *event) { SDL_Event newdownevent, newupevent, newevent = *event; +#if SDL_VERSION_ATLEAST(3, 0, 0) + float x, y; + int i; +#else int x, y, i; +#endif +#if SDL_VERSION_ATLEAST(3, 0, 0) + if (event->type >= SDL_EVENT_WINDOW_FIRST && + event->type <= SDL_EVENT_WINDOW_LAST) { +#else if (event->type == SDL_WINDOWEVENT) { +#endif /* DON'T filter SDL_WINDOWEVENTs here. If we delete events, they * won't be available to low-level SDL2 either.*/ +#if SDL_VERSION_ATLEAST(3, 0, 0) + switch (event->type) { +#else switch (event->window.event) { +#endif case SDL_WINDOWEVENT_RESIZED: SDL_FilterEvents(_pg_remove_pending_VIDEORESIZE, &newevent); @@ -487,6 +550,10 @@ pg_event_filter(void *_, SDL_Event *event) case SDL_WINDOWEVENT_MINIMIZED: case SDL_WINDOWEVENT_RESTORED: newevent.type = SDL_ACTIVEEVENT; +#if SDL_VERSION_ATLEAST(3, 0, 0) + /* Backup event->type because it is needed later */ + newevent.window.data2 = event->type; +#endif SDL_PushEvent(&newevent); } } @@ -496,7 +563,11 @@ pg_event_filter(void *_, SDL_Event *event) return 0; PG_LOCK_EVFILTER_MUTEX +#if SDL_VERSION_ATLEAST(3, 0, 0) + pressed_keys[event->key.scancode] = 1; +#else pressed_keys[event->key.keysym.scancode] = 1; +#endif if (pg_key_repeat_delay > 0) { if (_pg_repeat_timer) SDL_RemoveTimer(_pg_repeat_timer); @@ -526,9 +597,15 @@ pg_event_filter(void *_, SDL_Event *event) else if (event->type == SDL_KEYUP) { PG_LOCK_EVFILTER_MUTEX +#if SDL_VERSION_ATLEAST(3, 0, 0) + released_keys[event->key.scancode] = 1; + if (_pg_repeat_timer && + _pg_repeat_event.key.scancode == event->key.scancode) { +#else released_keys[event->key.keysym.scancode] = 1; if (_pg_repeat_timer && _pg_repeat_event.key.keysym.scancode == event->key.keysym.scancode) { +#endif SDL_RemoveTimer(_pg_repeat_timer); _pg_repeat_timer = 0; } @@ -563,20 +640,28 @@ pg_event_filter(void *_, SDL_Event *event) newdownevent.type = SDL_MOUSEBUTTONDOWN; newdownevent.button.x = x; newdownevent.button.y = y; +#if SDL_VERSION_ATLEAST(3, 0, 0) + newdownevent.button.down = true; +#else newdownevent.button.state = SDL_PRESSED; +#endif newdownevent.button.clicks = 1; newdownevent.button.which = event->button.which; newupevent.type = SDL_MOUSEBUTTONUP; newupevent.button.x = x; newupevent.button.y = y; +#if SDL_VERSION_ATLEAST(3, 0, 0) + newupevent.button.down = false; +#else newupevent.button.state = SDL_RELEASED; +#endif newupevent.button.clicks = 1; newupevent.button.which = event->button.which; /* Use a for loop to simulate multiple events, because SDL 1 * works that way */ - for (i = 0; i < abs(event->wheel.y); i++) { + for (i = 0; i < abs((int)event->wheel.y); i++) { /* Do this in the loop because button.button is mutated before it * is posted from this filter */ if (event->wheel.y > 0) { @@ -790,8 +875,10 @@ _pg_name_from_eventtype(int type) return "FingerDown"; case SDL_FINGERUP: return "FingerUp"; +#if !SDL_VERSION_ATLEAST(3, 0, 0) case SDL_MULTIGESTURE: return "MultiGesture"; +#endif case SDL_MOUSEWHEEL: return "MouseWheel"; case SDL_TEXTINPUT: @@ -891,6 +978,17 @@ _pg_insobj(PyObject *dict, char *name, PyObject *v) } } +#if SDL_VERSION_ATLEAST(3, 0, 0) +static PyObject * +get_joy_guid(SDL_JoystickID instance_id) +{ + char strguid[33]; + SDL_GUID guid = SDL_GetJoystickGUIDForID(instance_id); + + SDL_GUIDToString(guid, strguid, 33); + return PyUnicode_FromString(strguid); +} +#else static PyObject * get_joy_guid(int device_index) { @@ -900,6 +998,7 @@ get_joy_guid(int device_index) SDL_JoystickGetGUIDString(guid, strguid, 33); return PyUnicode_FromString(strguid); } +#endif static PyObject * get_joy_device_index(int instance_id) @@ -954,7 +1053,11 @@ dict_from_event(SDL_Event *event) _pg_insobj(dict, "h", PyLong_FromLong(event->window.data2)); break; case SDL_ACTIVEEVENT: +#if SDL_VERSION_ATLEAST(3, 0, 0) + switch (event->window.data2) { +#else switch (event->window.event) { +#endif case SDL_WINDOWEVENT_ENTER: gain = 1; state = SDL_APPMOUSEFOCUS; @@ -989,17 +1092,23 @@ dict_from_event(SDL_Event *event) /* this accesses state also accessed the event filter, so lock */ _pg_insobj(dict, "unicode", _pg_get_event_unicode(event)); PG_UNLOCK_EVFILTER_MUTEX +#if SDL_VERSION_ATLEAST(3, 0, 0) + _pg_insobj(dict, "key", PyLong_FromLong(event->key.key)); + _pg_insobj(dict, "mod", PyLong_FromLong(event->key.mod)); + _pg_insobj(dict, "scancode", PyLong_FromLong(event->key.scancode)); +#else _pg_insobj(dict, "key", PyLong_FromLong(event->key.keysym.sym)); _pg_insobj(dict, "mod", PyLong_FromLong(event->key.keysym.mod)); _pg_insobj(dict, "scancode", PyLong_FromLong(event->key.keysym.scancode)); +#endif break; case SDL_MOUSEMOTION: - obj = pg_tuple_couple_from_values_int(event->motion.x, - event->motion.y); + obj = pg_tuple_couple_from_values_int((int)event->motion.x, + (int)event->motion.y); _pg_insobj(dict, "pos", obj); - obj = pg_tuple_couple_from_values_int(event->motion.xrel, - event->motion.yrel); + obj = pg_tuple_couple_from_values_int((int)event->motion.xrel, + (int)event->motion.yrel); _pg_insobj(dict, "rel", obj); if ((tuple = PyTuple_New(3))) { PyTuple_SET_ITEM(tuple, 0, @@ -1019,8 +1128,8 @@ dict_from_event(SDL_Event *event) break; case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP: - obj = pg_tuple_couple_from_values_int(event->button.x, - event->button.y); + obj = pg_tuple_couple_from_values_int((int)event->button.x, + (int)event->button.y); _pg_insobj(dict, "pos", obj); _pg_insobj(dict, "button", PyLong_FromLong(event->button.button)); _pg_insobj( @@ -1088,17 +1197,29 @@ dict_from_event(SDL_Event *event) // event (valid until next // SDL_GetNumAudioDevices() call), // SDL_AudioDeviceID for the REMOVED event +#if SDL_VERSION_ATLEAST(3, 0, 0) + _pg_insobj(dict, "iscapture", + PyLong_FromLong(event->adevice.recording)); +#else _pg_insobj(dict, "iscapture", PyLong_FromLong(event->adevice.iscapture)); +#endif break; case SDL_FINGERMOTION: case SDL_FINGERDOWN: case SDL_FINGERUP: /* https://wiki.libsdl.org/SDL_TouchFingerEvent */ +#if SDL_VERSION_ATLEAST(3, 0, 0) + _pg_insobj(dict, "touch_id", + PyLong_FromLongLong(event->tfinger.touchID)); + _pg_insobj(dict, "finger_id", + PyLong_FromLongLong(event->tfinger.fingerID)); +#else _pg_insobj(dict, "touch_id", PyLong_FromLongLong(event->tfinger.touchId)); _pg_insobj(dict, "finger_id", PyLong_FromLongLong(event->tfinger.fingerId)); +#endif _pg_insobj(dict, "x", PyFloat_FromDouble(event->tfinger.x)); _pg_insobj(dict, "y", PyFloat_FromDouble(event->tfinger.y)); _pg_insobj(dict, "dx", PyFloat_FromDouble(event->tfinger.dx)); @@ -1106,6 +1227,7 @@ dict_from_event(SDL_Event *event) _pg_insobj(dict, "pressure", PyFloat_FromDouble(event->tfinger.dy)); break; +#if !SDL_VERSION_ATLEAST(3, 0, 0) case SDL_MULTIGESTURE: /* https://wiki.libsdl.org/SDL_MultiGestureEvent */ _pg_insobj(dict, "touch_id", @@ -1119,6 +1241,7 @@ dict_from_event(SDL_Event *event) _pg_insobj(dict, "num_fingers", PyLong_FromLong(event->mgesture.numFingers)); break; +#endif case SDL_MOUSEWHEEL: /* https://wiki.libsdl.org/SDL_MouseWheelEvent */ #ifndef NO_SDL_MOUSEWHEEL_FLIPPED @@ -1128,22 +1251,27 @@ dict_from_event(SDL_Event *event) #else _pg_insobj(dict, "flipped", PyBool_FromLong(0)); #endif - _pg_insobj(dict, "x", PyLong_FromLong(event->wheel.x)); - _pg_insobj(dict, "y", PyLong_FromLong(event->wheel.y)); + _pg_insobj(dict, "x", PyLong_FromLong((long)event->wheel.x)); + _pg_insobj(dict, "y", PyLong_FromLong((long)event->wheel.y)); -#if SDL_VERSION_ATLEAST(2, 0, 18) +#if SDL_VERSION_ATLEAST(3, 0, 0) + _pg_insobj(dict, "precise_x", + PyFloat_FromDouble((double)event->wheel.x)); + _pg_insobj(dict, "precise_y", + PyFloat_FromDouble((double)event->wheel.y)); +#elif SDL_VERSION_ATLEAST(2, 0, 18) _pg_insobj(dict, "precise_x", PyFloat_FromDouble((double)event->wheel.preciseX)); _pg_insobj(dict, "precise_y", PyFloat_FromDouble((double)event->wheel.preciseY)); #else /* ~SDL_VERSION_ATLEAST(2, 0, 18) */ - /* fallback to regular x and y when SDL version used does not - * support precise fields */ - _pg_insobj(dict, "precise_x", - PyFloat_FromDouble((double)event->wheel.x)); - _pg_insobj(dict, "precise_y", - PyFloat_FromDouble((double)event->wheel.y)); + /* fallback to regular x and y when SDL version used does not + * support precise fields */ + _pg_insobj(dict, "precise_x", + PyFloat_FromDouble((double)event->wheel.x)); + _pg_insobj(dict, "precise_y", + PyFloat_FromDouble((double)event->wheel.y)); #endif /* ~SDL_VERSION_ATLEAST(2, 0, 18) */ _pg_insobj( @@ -1163,38 +1291,72 @@ dict_from_event(SDL_Event *event) break; /* https://wiki.libsdl.org/SDL_DropEvent */ case SDL_DROPFILE: +#if SDL_VERSION_ATLEAST(3, 0, 0) + _pg_insobj(dict, "file", PyUnicode_FromString(event->drop.data)); + /* No need to free event->drop.data, SDL3 handles it */ +#else _pg_insobj(dict, "file", PyUnicode_FromString(event->drop.file)); SDL_free(event->drop.file); +#endif break; case SDL_DROPTEXT: +#if SDL_VERSION_ATLEAST(3, 0, 0) + _pg_insobj(dict, "text", PyUnicode_FromString(event->drop.data)); + /* No need to free event->drop.data, SDL3 handles it */ +#else _pg_insobj(dict, "text", PyUnicode_FromString(event->drop.file)); SDL_free(event->drop.file); +#endif break; case SDL_DROPBEGIN: case SDL_DROPCOMPLETE: break; case SDL_CONTROLLERAXISMOTION: /* https://wiki.libsdl.org/SDL_ControllerAxisEvent */ +#if SDL_VERSION_ATLEAST(3, 0, 0) + _pg_insobj(dict, "instance_id", + PyLong_FromLong(event->gaxis.which)); + _pg_insobj(dict, "axis", PyLong_FromLong(event->gaxis.axis)); + _pg_insobj(dict, "value", PyLong_FromLong(event->gaxis.value)); +#else _pg_insobj(dict, "instance_id", PyLong_FromLong(event->caxis.which)); _pg_insobj(dict, "axis", PyLong_FromLong(event->caxis.axis)); _pg_insobj(dict, "value", PyLong_FromLong(event->caxis.value)); +#endif break; case SDL_CONTROLLERBUTTONDOWN: case SDL_CONTROLLERBUTTONUP: +#if SDL_VERSION_ATLEAST(3, 0, 0) + _pg_insobj(dict, "instance_id", + PyLong_FromLong(event->gbutton.which)); + _pg_insobj(dict, "button", PyLong_FromLong(event->gbutton.button)); +#else /* https://wiki.libsdl.org/SDL_ControllerButtonEvent */ _pg_insobj(dict, "instance_id", PyLong_FromLong(event->cbutton.which)); _pg_insobj(dict, "button", PyLong_FromLong(event->cbutton.button)); +#endif break; case SDL_CONTROLLERDEVICEADDED: +#if SDL_VERSION_ATLEAST(3, 0, 0) + _pg_insobj(dict, "device_index", + get_joy_device_index(event->gdevice.which)); + _pg_insobj(dict, "guid", get_joy_guid(event->gdevice.which)); +#else _pg_insobj(dict, "device_index", PyLong_FromLong(event->cdevice.which)); _pg_insobj(dict, "guid", get_joy_guid(event->jdevice.which)); +#endif break; case SDL_JOYDEVICEADDED: +#if SDL_VERSION_ATLEAST(3, 0, 0) + _pg_insobj(dict, "device_index", + get_joy_device_index(event->jdevice.which)); +#else _pg_insobj(dict, "device_index", PyLong_FromLong(event->jdevice.which)); +#endif _pg_insobj(dict, "guid", get_joy_guid(event->jdevice.which)); break; case SDL_CONTROLLERDEVICEREMOVED: @@ -1210,6 +1372,18 @@ dict_from_event(SDL_Event *event) case SDL_CONTROLLERTOUCHPADDOWN: case SDL_CONTROLLERTOUCHPADMOTION: case SDL_CONTROLLERTOUCHPADUP: +#if SDL_VERSION_ATLEAST(3, 0, 0) + _pg_insobj(dict, "instance_id", + PyLong_FromLong(event->gtouchpad.which)); + _pg_insobj(dict, "touch_id", + PyLong_FromLongLong(event->gtouchpad.touchpad)); + _pg_insobj(dict, "finger_id", + PyLong_FromLongLong(event->gtouchpad.finger)); + _pg_insobj(dict, "x", PyFloat_FromDouble(event->gtouchpad.x)); + _pg_insobj(dict, "y", PyFloat_FromDouble(event->gtouchpad.y)); + _pg_insobj(dict, "pressure", + PyFloat_FromDouble(event->gtouchpad.pressure)); +#else _pg_insobj(dict, "instance_id", PyLong_FromLong(event->ctouchpad.which)); _pg_insobj(dict, "touch_id", @@ -1220,8 +1394,10 @@ dict_from_event(SDL_Event *event) _pg_insobj(dict, "y", PyFloat_FromDouble(event->ctouchpad.y)); _pg_insobj(dict, "pressure", PyFloat_FromDouble(event->ctouchpad.pressure)); +#endif break; +#if !SDL_VERSION_ATLEAST(3, 0, 0) #ifdef WIN32 case SDL_SYSWMEVENT: _pg_insobj(dict, "hwnd", @@ -1249,6 +1425,7 @@ dict_from_event(SDL_Event *event) } break; #endif /* (defined(unix) || ... */ +#endif /* !SDL_VERSION_ATLEAST(3, 0, 0) */ } /* switch (event->type) */ /* Events that don't have any attributes are not handled in switch * statement */ @@ -1319,7 +1496,13 @@ dict_from_event(SDL_Event *event) } } PyObject *pgWindow; +#if SDL_VERSION_ATLEAST(3, 0, 0) + if (!window || + !(pgWindow = SDL_GetPointerProperty(SDL_GetWindowProperties(window), + "pg_window", NULL))) { +#else if (!window || !(pgWindow = SDL_GetWindowData(window, "pg_window"))) { +#endif pgWindow = Py_None; } Py_INCREF(pgWindow); @@ -1565,15 +1748,25 @@ set_grab(PyObject *self, PyObject *arg) SDL_Window *win = pg_GetDefaultWindow(); if (win) { if (doit) { +#if SDL_VERSION_ATLEAST(3, 0, 0) + SDL_SetWindowMouseGrab(win, true); + SDL_SetWindowRelativeMouseMode(win, !PG_CursorVisible()); +#else SDL_SetWindowGrab(win, SDL_TRUE); if (PG_CursorVisible() == SDL_DISABLE) SDL_SetRelativeMouseMode(1); else SDL_SetRelativeMouseMode(0); +#endif } else { +#if SDL_VERSION_ATLEAST(3, 0, 0) + SDL_SetWindowMouseGrab(win, false); + SDL_SetWindowRelativeMouseMode(win, false); +#else SDL_SetWindowGrab(win, SDL_FALSE); SDL_SetRelativeMouseMode(0); +#endif } } @@ -1588,8 +1781,13 @@ get_grab(PyObject *self, PyObject *_null) VIDEO_INIT_CHECK(); win = pg_GetDefaultWindow(); - if (win) + if (win) { +#if SDL_VERSION_ATLEAST(3, 0, 0) + mode = SDL_GetWindowMouseGrab(win); +#else mode = SDL_GetWindowGrab(win); +#endif + } return PyBool_FromLong(mode); } @@ -1607,11 +1805,14 @@ _pg_event_pump(int dopump) SDL_PumpEvents(); } + /* WINDOWEVENT translation needed only on SDL2 */ +#if !SDL_VERSION_ATLEAST(3, 0, 0) /* We need to translate WINDOWEVENTS. But if we do that from the * from event filter, internal SDL stuff that rely on WINDOWEVENT * might break. So after every event pump, we translate events from * here */ SDL_FilterEvents(_pg_translate_windowevent, NULL); +#endif } static int @@ -2182,8 +2383,10 @@ pg_event_set_blocked(PyObject *self, PyObject *obj) } Py_DECREF(seq); } - /* Never block SDL_WINDOWEVENT, we need them for translation */ +#if !SDL_VERSION_ATLEAST(3, 0, 0) + /* Never block SDL_WINDOWEVENT on SDL2, we need them for translation */ PG_SetEventEnabled(SDL_WINDOWEVENT, SDL_TRUE); +#endif /* Never block PGE_KEYREPEAT too, its needed for pygame internal use */ PG_SetEventEnabled(PGE_KEYREPEAT, SDL_TRUE); Py_RETURN_NONE; diff --git a/src_c/meson.build b/src_c/meson.build index 07189d6180..bb94eddcb2 100644 --- a/src_c/meson.build +++ b/src_c/meson.build @@ -39,8 +39,6 @@ display = py.extension_module( ) endif -# TODO: support SDL3 -if sdl_api != 3 event = py.extension_module( 'event', 'event.c', @@ -49,7 +47,6 @@ event = py.extension_module( install: true, subdir: pg, ) -endif # TODO: support SDL3 if sdl_api != 3 From b1f0acde1b8acf5d103bf9e62e178cba48b41224 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Nov 2024 06:43:54 +0000 Subject: [PATCH 15/44] Bump actions/attest-build-provenance from 1.4.3 to 1.4.4 Bumps [actions/attest-build-provenance](https://github.com/actions/attest-build-provenance) from 1.4.3 to 1.4.4. - [Release notes](https://github.com/actions/attest-build-provenance/releases) - [Changelog](https://github.com/actions/attest-build-provenance/blob/main/RELEASE.md) - [Commits](https://github.com/actions/attest-build-provenance/compare/v1.4.3...v1.4.4) --- updated-dependencies: - dependency-name: actions/attest-build-provenance dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/release-gh-draft.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-gh-draft.yml b/.github/workflows/release-gh-draft.yml index 32917cf703..c56e9d3bfd 100644 --- a/.github/workflows/release-gh-draft.yml +++ b/.github/workflows/release-gh-draft.yml @@ -61,7 +61,7 @@ jobs: run: echo "VER=${GITHUB_REF_NAME#'release/'}" >> $GITHUB_OUTPUT - name: Generate release attestation - uses: actions/attest-build-provenance@v1.4.3 + uses: actions/attest-build-provenance@v1.4.4 with: subject-path: "pygame-wheels/*" From 41f8924e34ade9fcbe0841b29be0c633550e01c6 Mon Sep 17 00:00:00 2001 From: damusss Date: Sat, 16 Nov 2024 11:37:04 +0100 Subject: [PATCH 16/44] Address requested changes --- buildconfig/stubs/pygame/pixelarray.pyi | 10 ++++++---- src_c/pixelarray_methods.c | 16 +++------------- test/pixelarray_test.py | 10 ---------- 3 files changed, 9 insertions(+), 27 deletions(-) diff --git a/buildconfig/stubs/pygame/pixelarray.pyi b/buildconfig/stubs/pygame/pixelarray.pyi index a10bb66e42..128748fe9b 100644 --- a/buildconfig/stubs/pygame/pixelarray.pyi +++ b/buildconfig/stubs/pygame/pixelarray.pyi @@ -1,8 +1,10 @@ from typing import Any, Dict, Tuple, Union, overload from pygame.surface import Surface +from pygame.color import Color +from pygame.typing import SequenceLike -from pygame.typing import ColorLike, SequenceLike +_ColorLike = int | Color | tuple[int, int, int] | tuple[int, int, int, int] class PixelArray: surface: Surface @@ -34,14 +36,14 @@ class PixelArray: def make_surface(self) -> Surface: ... def replace( self, - color: ColorLike, - repcolor: ColorLike, + color: _ColorLike, + repcolor: _ColorLike, distance: float = 0, weights: SequenceLike[float] = (0.299, 0.587, 0.114), ) -> None: ... def extract( self, - color: ColorLike, + color: _ColorLike, distance: float = 0, weights: SequenceLike[float] = (0.299, 0.587, 0.114), ) -> PixelArray: ... diff --git a/src_c/pixelarray_methods.c b/src_c/pixelarray_methods.c index 62f33a796a..8ecbebdb91 100644 --- a/src_c/pixelarray_methods.c +++ b/src_c/pixelarray_methods.c @@ -46,16 +46,6 @@ _get_color_from_object(PyObject *val, SDL_Surface *surf, Uint32 *color) val, surf, color, PG_COLOR_HANDLE_INT | PG_COLOR_HANDLE_RESTRICT_SEQ); } -static int -_get_color_from_object_all(PyObject *val, SDL_Surface *surf, Uint32 *color) -{ - if (!val) { - return 0; - } - - return pg_MappedColorFromObj(val, surf, color, PG_COLOR_HANDLE_ALL); -} - /** * Retrieves a single pixel located at index from the surface pixel * array. @@ -385,8 +375,8 @@ _replace_color(pgPixelArrayObject *array, PyObject *args, PyObject *kwds) format = surf->format; bpp = PG_SURF_BytesPerPixel(surf); - if (!_get_color_from_object_all(delcolor, surf, &dcolor) || - !_get_color_from_object_all(replcolor, surf, &rcolor)) { + if (!_get_color_from_object(delcolor, surf, &dcolor) || + !_get_color_from_object(replcolor, surf, &rcolor)) { return 0; } @@ -591,7 +581,7 @@ _extract_color(pgPixelArrayObject *array, PyObject *args, PyObject *kwds) black = SDL_MapRGBA(format, 0, 0, 0, 255); white = SDL_MapRGBA(format, 255, 255, 255, 255); - if (!_get_color_from_object_all(excolor, surf, &color)) { + if (!_get_color_from_object(excolor, surf, &color)) { Py_DECREF(new_array); return 0; } diff --git a/test/pixelarray_test.py b/test/pixelarray_test.py index e56f11ed0e..af8117ceeb 100644 --- a/test/pixelarray_test.py +++ b/test/pixelarray_test.py @@ -1041,11 +1041,6 @@ def test_replace(self): self.assertEqual(ar[8][9], oval) self.assertEqual(ar[9][9], oval) - for color in [(20, 20, 20), 10, "green", pygame.Color("blue")]: - sf = pygame.Surface((10, 10)) - ar = pygame.PixelArray(sf) - ar.replace(color, color) - def test_extract(self): for bpp in (8, 16, 24, 32): sf = pygame.Surface((10, 10), 0, bpp) @@ -1073,11 +1068,6 @@ def test_extract(self): self.assertEqual(newar[8][9], black) self.assertEqual(newar[9][9], black) - for color in [(20, 20, 20), 10, "green", pygame.Color("blue")]: - sf = pygame.Surface((10, 10)) - ar = pygame.PixelArray(sf) - ar.extract(color) - def test_2dslice_assignment(self): w = 2 * 5 * 8 h = 3 * 5 * 9 From ab5016e5a8a74f4dfec2380ec3144e3a8e3d5e87 Mon Sep 17 00:00:00 2001 From: Ankith Date: Sat, 5 Oct 2024 21:56:59 +0530 Subject: [PATCH 17/44] Drop python 3.8 --- README.rst | 2 +- docs/readmes/README.es.rst | 2 +- docs/readmes/README.fa.rst | 2 +- docs/readmes/README.fr.rst | 2 +- docs/readmes/README.it.rst | 2 +- docs/readmes/README.ja.rst | 2 +- docs/readmes/README.ru.rst | 2 +- docs/readmes/README.zh-cn.rst | 2 +- pyproject.toml | 5 ++--- setup.cfg | 2 +- setup.py | 9 ++++----- 11 files changed, 15 insertions(+), 17 deletions(-) diff --git a/README.rst b/README.rst index a0347341e7..f0fcc4fac0 100644 --- a/README.rst +++ b/README.rst @@ -139,7 +139,7 @@ Dependency versions: +----------+------------------------+ -| CPython | >= 3.8 (Or use PyPy3) | +| CPython | >= 3.9 (Or use PyPy3) | +----------+------------------------+ | SDL | >= 2.0.14 | +----------+------------------------+ diff --git a/docs/readmes/README.es.rst b/docs/readmes/README.es.rst index d1ca1fd6c2..205ea5b14c 100644 --- a/docs/readmes/README.es.rst +++ b/docs/readmes/README.es.rst @@ -117,7 +117,7 @@ El módulo surfarray necesita el paquete python numpy, para sus matrices numéri Versiones de dependencia: +----------+-----------------------------+ -| CPython | >= 3.8 (Ou utiliser PyPy3) | +| CPython | >= 3.9 (Ou utiliser PyPy3) | +----------+-----------------------------+ | SDL | >= 2.0.14 | +----------+-----------------------------+ diff --git a/docs/readmes/README.fa.rst b/docs/readmes/README.fa.rst index b3b7229b33..99c70fdcba 100644 --- a/docs/readmes/README.fa.rst +++ b/docs/readmes/README.fa.rst @@ -189,7 +189,7 @@ Dependencies (وابستگی ها) مشاهده کنید. +----------+------------------------+ -| CPython | >= 3.8 (Or use PyPy3) | +| CPython | >= 3.9 (Or use PyPy3) | +----------+------------------------+ | SDL | >= 2.0.14 | +----------+------------------------+ diff --git a/docs/readmes/README.fr.rst b/docs/readmes/README.fr.rst index c17d701fa9..e77a2376c6 100644 --- a/docs/readmes/README.fr.rst +++ b/docs/readmes/README.fr.rst @@ -146,7 +146,7 @@ multidimensionnels. Versions des dépendances: +----------+-----------------------------+ -| CPython | >= 3.8 (Ou utiliser PyPy3) | +| CPython | >= 3.9 (Ou utiliser PyPy3) | +----------+-----------------------------+ | SDL | >= 2.0.14 | +----------+-----------------------------+ diff --git a/docs/readmes/README.it.rst b/docs/readmes/README.it.rst index f660b2c3cc..496eeb8b11 100644 --- a/docs/readmes/README.it.rst +++ b/docs/readmes/README.it.rst @@ -140,7 +140,7 @@ Le versioni dei requisiti: +----------+------------------------+ -| CPython | >= 3.8 (Or use PyPy3) | +| CPython | >= 3.9 (Or use PyPy3) | +----------+------------------------+ | SDL | >= 2.0.14 | +----------+------------------------+ diff --git a/docs/readmes/README.ja.rst b/docs/readmes/README.ja.rst index 502cd98e8e..be55955dcc 100644 --- a/docs/readmes/README.ja.rst +++ b/docs/readmes/README.ja.rst @@ -151,7 +151,7 @@ gfxdraw には SDL_gfx の埋め込みバージョンが含まれています。 依存バージョン: +----------+------------------------+ -| CPython | >= 3.8 (Or use PyPy3) | +| CPython | >= 3.9 (Or use PyPy3) | +----------+------------------------+ | SDL | >= 2.0.14 | +----------+------------------------+ diff --git a/docs/readmes/README.ru.rst b/docs/readmes/README.ru.rst index cdcbd37fc7..57eea35501 100644 --- a/docs/readmes/README.ru.rst +++ b/docs/readmes/README.ru.rst @@ -141,7 +141,7 @@ SDL_rotozoom, а gfxdraw имеет встроенную версию SDL_gfx. +----------+------------------------+ -| CPython | >= 3.8 (Or use PyPy3) | +| CPython | >= 3.9 (Or use PyPy3) | +----------+------------------------+ | SDL | >= 2.0.14 | +----------+------------------------+ diff --git a/docs/readmes/README.zh-cn.rst b/docs/readmes/README.zh-cn.rst index 63745b8edb..98fec8dadd 100644 --- a/docs/readmes/README.zh-cn.rst +++ b/docs/readmes/README.zh-cn.rst @@ -105,7 +105,7 @@ pygame显然依赖于SDL和Python。此外pygame还嵌入了几个较小的库 +----------+------------------------+ -| CPython | >= 3.8 (或 PyPy3) | +| CPython | >= 3.9 (或 PyPy3) | +----------+------------------------+ | SDL | >= 2.0.14 | +----------+------------------------+ diff --git a/pyproject.toml b/pyproject.toml index 476a08242e..d2d3ea2f4a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ name = "pygame-ce" version = "2.5.3.dev1" description = "Python Game Development" readme = "README.rst" # for long description -requires-python = ">=3.8" +requires-python = ">=3.9" license = {text = "LGPL v2.1"} authors = [{name = "A community project"}] classifiers = [ @@ -14,7 +14,6 @@ classifiers = [ "Programming Language :: Cython", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", @@ -74,7 +73,7 @@ install = ['--tags=runtime,python-runtime,pg-tag'] # dependencies. Here is where uv comes into the picture. It is an "installer" like pip, # but faster. It has been observed to save a couple of minutes of CI time. build-frontend = "build[uv]" -build = "cp3{8,9,10,11,12,13}-* pp3{8,9,10}-*" +build = "cp3{9,10,11,12,13}-* pp3{9,10}-*" skip = "*-musllinux_*" # build[uv] is verbose by default, so below flag is not needed here # build-verbosity = 3 diff --git a/setup.cfg b/setup.cfg index 1c71cfb797..c3fdd9f9d5 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,5 +1,5 @@ [tox:tox] -envlist = py{38,39,310,311,312,313} +envlist = py{39,310,311,312,313} skip_missing_interpreters = True skipsdist = True diff --git a/setup.py b/setup.py index cbad740727..001edc3e2c 100644 --- a/setup.py +++ b/setup.py @@ -39,7 +39,6 @@ "Programming Language :: Cython", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", @@ -63,7 +62,7 @@ "Operating System :: MacOS", "Typing :: Typed" ], - "python_requires": '>=3.8', + "python_requires": '>=3.9', } import re @@ -156,11 +155,11 @@ def compilation_help(): print('---\n') -if not hasattr(sys, 'version_info') or sys.version_info < (3, 8): +if not hasattr(sys, 'version_info') or sys.version_info < (3, 9): compilation_help() - raise SystemExit("Pygame-ce requires Python3 version 3.8 or above.") + raise SystemExit("Pygame-ce requires Python3 version 3.9 or above.") if IS_PYPY and sys.pypy_version_info < (7,): - raise SystemExit("Pygame-ce requires PyPy version 7.0.0 above, compatible with CPython >= 3.8") + raise SystemExit("Pygame-ce requires PyPy version 7.0.0 above, compatible with CPython >= 3.9") def consume_arg(name): From 71ab2e2197dbdf2b4ad33e0db6b10e2b6c74a018 Mon Sep 17 00:00:00 2001 From: Ankith Date: Sat, 5 Oct 2024 21:57:06 +0530 Subject: [PATCH 18/44] Use python 3.9isms in code, examples and docs --- docs/reST/ref/sprite.rst | 2 +- examples/stars.py | 9 ++++----- examples/textinput.py | 7 +++---- src_c/cython/pygame/_sdl2/audio.pyx | 2 +- src_c/doc/sprite_doc.h | 2 +- src_py/_debug.py | 5 +++-- src_py/pkgdata.py | 31 ++++++++++------------------- 7 files changed, 23 insertions(+), 35 deletions(-) diff --git a/docs/reST/ref/sprite.rst b/docs/reST/ref/sprite.rst index 268727a1d0..a1e96a71c9 100644 --- a/docs/reST/ref/sprite.rst +++ b/docs/reST/ref/sprite.rst @@ -291,7 +291,7 @@ Sprites are not thread safe. So lock them yourself if using threads. .. method:: draw | :sl:`blit the Sprite images` - | :sg:`draw(Surface) -> List[Rect]` + | :sg:`draw(Surface) -> list[Rect]` Draws the contained Sprites to the Surface argument. This uses the ``Sprite.image`` attribute for the source surface, and ``Sprite.rect`` diff --git a/examples/stars.py b/examples/stars.py index 0b7bd32942..0b63d922f4 100644 --- a/examples/stars.py +++ b/examples/stars.py @@ -11,7 +11,6 @@ """ import random -from typing import List import pygame @@ -19,7 +18,7 @@ class Particle: def __init__( self, - pos: List[int], + pos: list[int], vel: pygame.Vector2, ): """ @@ -55,7 +54,7 @@ def update(self): self.pos += self.vel -def create_particle(particle_list: List[Particle], pos: pygame.Vector2): +def create_particle(particle_list: list[Particle], pos: pygame.Vector2): """ Creates a new particle Parameters: @@ -71,7 +70,7 @@ def create_particle(particle_list: List[Particle], pos: pygame.Vector2): ) -def update_particles(particle_list: List[Particle], screen_rect: pygame.Rect): +def update_particles(particle_list: list[Particle], screen_rect: pygame.Rect): """ Updates the particles Parameters: @@ -87,7 +86,7 @@ def update_particles(particle_list: List[Particle], screen_rect: pygame.Rect): particle.update() -def draw_particles(particle_list: List[Particle], display: pygame.Surface): +def draw_particles(particle_list: list[Particle], display: pygame.Surface): """ Draws the particles Parameters: diff --git a/examples/textinput.py b/examples/textinput.py index 76cfb38902..c783de8bd8 100644 --- a/examples/textinput.py +++ b/examples/textinput.py @@ -6,7 +6,6 @@ Shows how to use the TEXTEDITING and TEXTINPUT events. """ -from typing import Tuple, List import sys import os @@ -39,8 +38,8 @@ class TextInput: def __init__( self, prompt: str, - pos: Tuple[int, int], - screen_dimensions: Tuple[int, int], + pos: tuple[int, int], + screen_dimensions: tuple[int, int], print_event: bool, text_color="white", fps: int = 50, @@ -77,7 +76,7 @@ def __init__( print("Using font: " + self.font.name) - def update(self, events: List[pygame.Event]) -> None: + def update(self, events: list[pygame.Event]) -> None: """ Updates the text input widget """ diff --git a/src_c/cython/pygame/_sdl2/audio.pyx b/src_c/cython/pygame/_sdl2/audio.pyx index c3667d5e32..97c6504a08 100644 --- a/src_c/cython/pygame/_sdl2/audio.pyx +++ b/src_c/cython/pygame/_sdl2/audio.pyx @@ -51,7 +51,7 @@ def get_audio_device_names(iscapture = False): If True return devices available for capture. :return: list of devicenames. - :rtype: List[string] + :rtype: list[string] """ cdef int count = SDL_GetNumAudioDevices(iscapture) diff --git a/src_c/doc/sprite_doc.h b/src_c/doc/sprite_doc.h index 86e61f3565..857f1c6d70 100644 --- a/src_c/doc/sprite_doc.h +++ b/src_c/doc/sprite_doc.h @@ -15,7 +15,7 @@ #define DOC_SPRITE_GROUP_REMOVE "remove(*sprites) -> None\nremove Sprites from the Group" #define DOC_SPRITE_GROUP_HAS "has(*sprites) -> bool\ntest if a Group contains Sprites" #define DOC_SPRITE_GROUP_UPDATE "update(*args, **kwargs) -> None\ncall the update method on contained Sprites" -#define DOC_SPRITE_GROUP_DRAW "draw(Surface) -> List[Rect]\nblit the Sprite images" +#define DOC_SPRITE_GROUP_DRAW "draw(Surface) -> list[Rect]\nblit the Sprite images" #define DOC_SPRITE_GROUP_CLEAR "clear(Surface_dest, background) -> None\ndraw a background over the Sprites" #define DOC_SPRITE_GROUP_EMPTY "empty() -> None\nremove all Sprites" #define DOC_SPRITE_RENDERUPDATES "RenderUpdates(*sprites) -> RenderUpdates\nGroup sub-class that tracks dirty updates." diff --git a/src_py/_debug.py b/src_py/_debug.py index 3d39850a60..c8d73fa512 100644 --- a/src_py/_debug.py +++ b/src_py/_debug.py @@ -4,13 +4,14 @@ import sys import traceback import importlib -from typing import Tuple, Optional, Callable +from collections.abc import Callable +from typing import Optional from os import environ from pygame.version import ver from pygame.system import get_cpu_instruction_sets -ImportResult = Tuple[str, bool, Optional[Callable]] +ImportResult = tuple[str, bool, Optional[Callable]] def str_from_tuple(version_tuple): diff --git a/src_py/pkgdata.py b/src_py/pkgdata.py index 8076900e3e..7cff0c383f 100644 --- a/src_py/pkgdata.py +++ b/src_py/pkgdata.py @@ -22,27 +22,16 @@ def getResource(identifier, pkgname=__name__): import os try: - if sys.version_info[:2] > (3, 8): - from importlib.resources import files - - def resource_exists(_package_or_requirement, _resource_name): - _package_or_requirement = _package_or_requirement.split(".")[0] - return files(_package_or_requirement).joinpath(_resource_name).is_file() - - def resource_stream(_package_or_requirement, _resource_name): - _package_or_requirement = _package_or_requirement.split(".")[0] - ref = files(_package_or_requirement).joinpath(_resource_name) - return ref.open('rb') - else: - from importlib import resources - - def resource_exists(_package_or_requirement, _resource_name): - _package_or_requirement = _package_or_requirement.split(".")[0] - return resources.is_resource(_package_or_requirement, _resource_name) # pylint: disable=deprecated-method - - def resource_stream(_package_or_requirement, _resource_name): - _package_or_requirement = _package_or_requirement.split(".")[0] - return resources.open_binary(_package_or_requirement, _resource_name) # pylint: disable=deprecated-method + from importlib.resources import files + + def resource_exists(_package_or_requirement, _resource_name): + _package_or_requirement = _package_or_requirement.split(".")[0] + return files(_package_or_requirement).joinpath(_resource_name).is_file() + + def resource_stream(_package_or_requirement, _resource_name): + _package_or_requirement = _package_or_requirement.split(".")[0] + ref = files(_package_or_requirement).joinpath(_resource_name) + return ref.open("rb") except ImportError: From 81fc491e7cb4b64df7cb3f445a82ac282deee9e7 Mon Sep 17 00:00:00 2001 From: Ankith Date: Wed, 6 Nov 2024 00:56:26 +0530 Subject: [PATCH 19/44] Use python 3.9isms in typing --- buildconfig/stubs/pygame/_debug.pyi | 7 ++- buildconfig/stubs/pygame/_sdl2/audio.pyi | 4 +- .../stubs/pygame/_sdl2/controller_old.pyi | 5 +- buildconfig/stubs/pygame/_sdl2/touch.pyi | 4 +- buildconfig/stubs/pygame/_sdl2/video.pyi | 10 ++-- buildconfig/stubs/pygame/base.pyi | 7 ++- buildconfig/stubs/pygame/bufferproxy.pyi | 4 +- buildconfig/stubs/pygame/camera.pyi | 14 ++--- buildconfig/stubs/pygame/color.pyi | 37 +++++------- buildconfig/stubs/pygame/cursors.pyi | 17 +++--- buildconfig/stubs/pygame/display.pyi | 23 ++++---- buildconfig/stubs/pygame/event.pyi | 20 +++---- buildconfig/stubs/pygame/font.pyi | 11 ++-- buildconfig/stubs/pygame/freetype.pyi | 19 +++--- buildconfig/stubs/pygame/geometry.pyi | 32 +++++----- buildconfig/stubs/pygame/image.pyi | 4 +- buildconfig/stubs/pygame/joystick.pyi | 8 +-- buildconfig/stubs/pygame/key.pyi | 6 +- buildconfig/stubs/pygame/mask.pyi | 14 ++--- buildconfig/stubs/pygame/math.pyi | 23 +++----- buildconfig/stubs/pygame/midi.pyi | 12 ++-- buildconfig/stubs/pygame/mixer.pyi | 8 +-- buildconfig/stubs/pygame/mixer_music.pyi | 4 +- buildconfig/stubs/pygame/mouse.pyi | 14 ++--- buildconfig/stubs/pygame/pixelarray.pyi | 10 ++-- buildconfig/stubs/pygame/rect.pyi | 58 ++++++++----------- buildconfig/stubs/pygame/rwobject.pyi | 8 +-- buildconfig/stubs/pygame/scrap.pyi | 4 +- buildconfig/stubs/pygame/sndarray.pyi | 3 +- buildconfig/stubs/pygame/sprite.pyi | 35 +++++------ buildconfig/stubs/pygame/surface.pyi | 35 +++++------ buildconfig/stubs/pygame/surfarray.pyi | 3 +- buildconfig/stubs/pygame/system.pyi | 4 +- buildconfig/stubs/pygame/transform.pyi | 4 +- buildconfig/stubs/pygame/typing.pyi | 17 +----- buildconfig/stubs/pygame/version.pyi | 6 +- buildconfig/stubs/pygame/window.pyi | 10 ++-- src_py/typing.py | 17 +----- 38 files changed, 234 insertions(+), 287 deletions(-) diff --git a/buildconfig/stubs/pygame/_debug.pyi b/buildconfig/stubs/pygame/_debug.pyi index c325c808f5..a7c8cb1994 100644 --- a/buildconfig/stubs/pygame/_debug.pyi +++ b/buildconfig/stubs/pygame/_debug.pyi @@ -1,7 +1,8 @@ -from typing import Tuple, Union, Optional, Callable +from collections.abc import Callable +from typing import Union, Optional -ImportResult = Tuple[str, bool, Optional[Callable]] +ImportResult = tuple[str, bool, Optional[Callable]] -def str_from_tuple(version_tuple: Union[Tuple[int, int, int], None]) -> str: ... +def str_from_tuple(version_tuple: Union[tuple[int, int, int], None]) -> str: ... def attempt_import(module: str, function_name: str, output_str: str = "") -> ImportResult: ... def print_debug_info(filename: Optional[str] = None) -> None: ... diff --git a/buildconfig/stubs/pygame/_sdl2/audio.pyi b/buildconfig/stubs/pygame/_sdl2/audio.pyi index 332f645ded..fffb94e55f 100644 --- a/buildconfig/stubs/pygame/_sdl2/audio.pyi +++ b/buildconfig/stubs/pygame/_sdl2/audio.pyi @@ -1,4 +1,4 @@ -from typing import Callable, List +from collections.abc import Callable AUDIO_U8: int AUDIO_S8: int @@ -20,7 +20,7 @@ AUDIO_ALLOW_FORMAT_CHANGE: int AUDIO_ALLOW_CHANNELS_CHANGE: int AUDIO_ALLOW_ANY_CHANGE: int -def get_audio_device_names(iscapture: bool = False) -> List[str]: ... +def get_audio_device_names(iscapture: bool = False) -> list[str]: ... class AudioDevice: def __init__( diff --git a/buildconfig/stubs/pygame/_sdl2/controller_old.pyi b/buildconfig/stubs/pygame/_sdl2/controller_old.pyi index 3810fbba0a..e1ae7a54ea 100644 --- a/buildconfig/stubs/pygame/_sdl2/controller_old.pyi +++ b/buildconfig/stubs/pygame/_sdl2/controller_old.pyi @@ -1,4 +1,5 @@ -from typing import Dict, Mapping, Optional +from collections.abc import Mapping +from typing import Optional from pygame.joystick import JoystickType @@ -27,7 +28,7 @@ class Controller: def as_joystick(self) -> JoystickType: ... def get_axis(self, axis: int) -> int: ... def get_button(self, button: int) -> bool: ... - def get_mapping(self) -> Dict[str, str]: ... + def get_mapping(self) -> dict[str, str]: ... def set_mapping(self, mapping: Mapping[str, str]) -> int: ... def rumble( self, low_frequency: float, high_frequency: float, duration: int diff --git a/buildconfig/stubs/pygame/_sdl2/touch.pyi b/buildconfig/stubs/pygame/_sdl2/touch.pyi index 93e2745767..2febfad900 100644 --- a/buildconfig/stubs/pygame/_sdl2/touch.pyi +++ b/buildconfig/stubs/pygame/_sdl2/touch.pyi @@ -1,6 +1,6 @@ -from typing import Dict, Union +from typing import Union def get_num_devices() -> int: ... def get_device(index: int) -> int: ... def get_num_fingers(device_id: int) -> int: ... -def get_finger(touchid: int, index: int) -> Dict[str, Union[int, float]]: ... +def get_finger(touchid: int, index: int) -> dict[str, Union[int, float]]: ... diff --git a/buildconfig/stubs/pygame/_sdl2/video.pyi b/buildconfig/stubs/pygame/_sdl2/video.pyi index 905431df28..8e741e8ab4 100644 --- a/buildconfig/stubs/pygame/_sdl2/video.pyi +++ b/buildconfig/stubs/pygame/_sdl2/video.pyi @@ -1,4 +1,5 @@ -from typing import Any, Generator, Iterable, Optional, Tuple, Union +from collections.abc import Generator, Iterable +from typing import Any, Optional, Union from pygame.color import Color from pygame.rect import Rect @@ -34,7 +35,7 @@ def messagebox( info: bool = False, warn: bool = False, error: bool = False, - buttons: Tuple[str, ...] = ("OK",), + buttons: tuple[str, ...] = ("OK",), return_button: int = 0, escape_button: int = 0, ) -> int: ... @@ -47,7 +48,7 @@ class Texture: static: bool = False, streaming: bool = False, target: bool = False, - scale_quality: Optional[int] =None + scale_quality: Optional[int] = None, ) -> None: ... @staticmethod def from_surface(renderer: Renderer, surface: Surface) -> Texture: ... @@ -61,7 +62,6 @@ class Texture: def color(self) -> Color: ... @color.setter def color(self, value: ColorLike) -> None: ... - def get_rect(self, **kwargs: Any) -> Rect: ... def draw( self, @@ -176,5 +176,5 @@ class Renderer: ) -> Surface: ... @staticmethod def compose_custom_blend_mode( - color_mode: Tuple[int, int, int], alpha_mode: Tuple[int, int, int] + color_mode: tuple[int, int, int], alpha_mode: tuple[int, int, int] ) -> int: ... diff --git a/buildconfig/stubs/pygame/base.pyi b/buildconfig/stubs/pygame/base.pyi index 4aa5d42149..b974235d18 100644 --- a/buildconfig/stubs/pygame/base.pyi +++ b/buildconfig/stubs/pygame/base.pyi @@ -1,4 +1,5 @@ -from typing import Any, Tuple, Callable +from collections.abc import Callable +from typing import Any __version__: str @@ -8,12 +9,12 @@ class BufferError(Exception): ... # Always defined HAVE_NEWBUF: int = 1 -def init() -> Tuple[int, int]: ... +def init() -> tuple[int, int]: ... def quit() -> None: ... def get_init() -> bool: ... def get_error() -> str: ... def set_error(error_msg: str, /) -> None: ... -def get_sdl_version(linked: bool = True) -> Tuple[int, int, int]: ... +def get_sdl_version(linked: bool = True) -> tuple[int, int, int]: ... def get_sdl_byteorder() -> int: ... def register_quit(callable: Callable[[], Any], /) -> None: ... diff --git a/buildconfig/stubs/pygame/bufferproxy.pyi b/buildconfig/stubs/pygame/bufferproxy.pyi index b77eb46c43..6eb21c5f4b 100644 --- a/buildconfig/stubs/pygame/bufferproxy.pyi +++ b/buildconfig/stubs/pygame/bufferproxy.pyi @@ -1,4 +1,4 @@ -from typing import Any, Dict, overload +from typing import Any, overload class BufferProxy: parent: Any @@ -6,7 +6,7 @@ class BufferProxy: raw: bytes # possibly going to be deprecated/removed soon, in which case these # typestubs must be removed too - __array_interface__: Dict[str, Any] + __array_interface__: dict[str, Any] __array_struct__: Any @overload def __init__(self) -> None: ... diff --git a/buildconfig/stubs/pygame/camera.pyi b/buildconfig/stubs/pygame/camera.pyi index 09dd9f8564..2609bd640f 100644 --- a/buildconfig/stubs/pygame/camera.pyi +++ b/buildconfig/stubs/pygame/camera.pyi @@ -1,14 +1,14 @@ from abc import ABC, abstractmethod -from typing import List, Optional, Tuple, Union, Literal +from typing import Optional, Union, Literal from pygame.typing import IntPoint from pygame.surface import Surface -def get_backends() -> List[str]: ... +def get_backends() -> list[str]: ... def init(backend: Optional[str] = None) -> None: ... def quit() -> None: ... -def list_cameras() -> List[str]: ... +def list_cameras() -> list[str]: ... def colorspace( surface: Surface, color: Literal["YUV", "HSV"], dest_surface: Surface = ..., / ) -> Surface: ... @@ -21,7 +21,7 @@ class AbstractCamera(ABC): @abstractmethod def stop(self) -> None: ... @abstractmethod - def get_size(self) -> Tuple[int, int]: ... + def get_size(self) -> tuple[int, int]: ... @abstractmethod def query_image(self) -> bool: ... @abstractmethod @@ -41,14 +41,14 @@ class Camera(AbstractCamera): ) -> None: ... def start(self) -> None: ... def stop(self) -> None: ... - def get_controls(self) -> Tuple[bool, bool, int]: ... + def get_controls(self) -> tuple[bool, bool, int]: ... def set_controls( self, hflip: bool = ..., vflip: bool = ..., brightness: int = ..., - ) -> Tuple[bool, bool, int]: ... - def get_size(self) -> Tuple[int, int]: ... + ) -> tuple[bool, bool, int]: ... + def get_size(self) -> tuple[int, int]: ... def query_image(self) -> bool: ... def get_image(self, surface: Optional[Surface] = None) -> Surface: ... def get_raw(self) -> bytes: ... diff --git a/buildconfig/stubs/pygame/color.pyi b/buildconfig/stubs/pygame/color.pyi index 635b05d4ea..217e6cab1b 100644 --- a/buildconfig/stubs/pygame/color.pyi +++ b/buildconfig/stubs/pygame/color.pyi @@ -1,15 +1,10 @@ -import sys -from typing import Any, Dict, Iterator, SupportsIndex, Tuple, Union, overload -from typing_extensions import deprecated # added in 3.13 +from collections.abc import Collection, Iterator +from typing import Any, SupportsIndex, Union, overload +from typing_extensions import deprecated # added in 3.13 from pygame.typing import ColorLike -if sys.version_info >= (3, 9): - from collections.abc import Collection -else: - from typing import Collection - -THECOLORS: Dict[str, Tuple[int, int, int, int]] +THECOLORS: dict[str, tuple[int, int, int, int]] # Color confirms to the Collection ABC, since it also confirms to # Sized, Iterable and Container ABCs @@ -18,11 +13,11 @@ class Color(Collection[int]): g: int b: int a: int - cmy: Tuple[float, float, float] - hsva: Tuple[float, float, float, float] - hsla: Tuple[float, float, float, float] - i1i2i3: Tuple[float, float, float] - normalized: Tuple[float, float, float, float] + cmy: tuple[float, float, float] + hsva: tuple[float, float, float, float] + hsla: tuple[float, float, float, float] + i1i2i3: tuple[float, float, float] + normalized: tuple[float, float, float, float] __hash__: None # type: ignore __array_struct__: Any @overload @@ -32,7 +27,7 @@ class Color(Collection[int]): @overload def __getitem__(self, i: SupportsIndex) -> int: ... @overload - def __getitem__(self, s: slice) -> Tuple[int, ...]: ... + def __getitem__(self, s: slice) -> tuple[int, ...]: ... def __setitem__(self, key: int, value: int) -> None: ... def __iter__(self) -> Iterator[int]: ... def __add__(self, other: Color) -> Color: ... @@ -50,35 +45,35 @@ class Color(Collection[int]): def __setattr__(self, attr: str, value: Union[Color, tuple]) -> None: ... @overload @classmethod - def from_cmy(cls, object: Tuple[float, float, float], /) -> Color: ... + def from_cmy(cls, object: tuple[float, float, float], /) -> Color: ... @overload @classmethod def from_cmy(cls, c: float, m: float, y: float, /) -> Color: ... @overload @classmethod - def from_hsva(cls, object: Tuple[float, float, float, float], /) -> Color: ... + def from_hsva(cls, object: tuple[float, float, float, float], /) -> Color: ... @overload @classmethod def from_hsva(cls, h: float, s: float, v: float, a: float, /) -> Color: ... @overload @classmethod - def from_hsla(cls, object: Tuple[float, float, float, float], /) -> Color: ... + def from_hsla(cls, object: tuple[float, float, float, float], /) -> Color: ... @overload @classmethod def from_hsla(cls, h: float, s: float, l: float, a: float, /) -> Color: ... @overload @classmethod - def from_i1i2i3(cls, object: Tuple[float, float, float], /) -> Color: ... + def from_i1i2i3(cls, object: tuple[float, float, float], /) -> Color: ... @overload @classmethod def from_i1i2i3(cls, i1: float, i2: float, i3: float, /) -> Color: ... @overload @classmethod - def from_normalized(cls, object: Tuple[float, float, float, float], /) -> Color: ... + def from_normalized(cls, object: tuple[float, float, float, float], /) -> Color: ... @overload @classmethod def from_normalized(cls, r: float, g: float, b: float, a: float, /) -> Color: ... - def normalize(self) -> Tuple[float, float, float, float]: ... + def normalize(self) -> tuple[float, float, float, float]: ... def correct_gamma(self, gamma: float, /) -> Color: ... @deprecated("since 2.1.3. Use unpacking instead") def set_length(self, length: int, /) -> None: ... diff --git a/buildconfig/stubs/pygame/cursors.pyi b/buildconfig/stubs/pygame/cursors.pyi index d78b797316..ae22d0dcb8 100644 --- a/buildconfig/stubs/pygame/cursors.pyi +++ b/buildconfig/stubs/pygame/cursors.pyi @@ -1,13 +1,14 @@ -from typing import Any, Iterator, Literal, Tuple, Union, overload +from collections.abc import Iterator +from typing import Any, Literal, Union, overload from pygame.surface import Surface from pygame.typing import FileLike, IntPoint, SequenceLike -_Small_string = Tuple[ +_Small_string = tuple[ str, str, str, str, str, str, str, str, str, str, str, str, str, str, str, str ] -_Big_string = Tuple[ +_Big_string = tuple[ str, str, str, @@ -51,10 +52,10 @@ def compile( black: str = "X", white: str = ".", xor: str = "o", -) -> Tuple[Tuple[int, ...], Tuple[int, ...]]: ... +) -> tuple[tuple[int, ...], tuple[int, ...]]: ... def load_xbm( curs: FileLike, mask: FileLike -) -> Tuple[Tuple[int, int], Tuple[int, int], Tuple[int, ...], Tuple[int, ...]]: ... +) -> tuple[tuple[int, int], tuple[int, int], tuple[int, ...], tuple[int, ...]]: ... class Cursor: @overload @@ -85,7 +86,7 @@ class Cursor: def copy(self) -> Cursor: ... type: Literal["system", "color", "bitmap"] data: Union[ - Tuple[int], - Tuple[Tuple[int, int], Tuple[int, int], Tuple[int, ...], Tuple[int, ...]], - Tuple[IntPoint, Surface], + tuple[int], + tuple[tuple[int, int], tuple[int, int], tuple[int, ...], tuple[int, ...]], + tuple[IntPoint, Surface], ] diff --git a/buildconfig/stubs/pygame/display.pyi b/buildconfig/stubs/pygame/display.pyi index de106bfb19..5124e92b47 100644 --- a/buildconfig/stubs/pygame/display.pyi +++ b/buildconfig/stubs/pygame/display.pyi @@ -1,4 +1,5 @@ -from typing import Dict, List, Optional, Tuple, Union, overload, Literal, Iterable +from collections.abc import Iterable +from typing import Optional, Union, overload, Literal from typing_extensions import deprecated # added in 3.13 from pygame.constants import FULLSCREEN @@ -20,9 +21,9 @@ class _VidInfo: video_mem: int bitsize: int bytesize: int - masks: Tuple[int, int, int, int] - shifts: Tuple[int, int, int, int] - losses: Tuple[int, int, int, int] + masks: tuple[int, int, int, int] + shifts: tuple[int, int, int, int] + losses: tuple[int, int, int, int] blit_hw: int blit_hw_CC: int blit_hw_A: int @@ -55,12 +56,12 @@ def update(x: int, y: int, w: int, h: int, /) -> None: ... def update(xy: Point, wh: Point, /) -> None: ... def get_driver() -> str: ... def Info() -> _VidInfo: ... -def get_wm_info() -> Dict[str, int]: ... +def get_wm_info() -> dict[str, int]: ... def list_modes( depth: int = 0, flags: int = FULLSCREEN, display: int = 0, -) -> List[Tuple[int, int]]: ... +) -> list[tuple[int, int]]: ... def mode_ok( size: IntPoint, flags: int = 0, @@ -80,19 +81,19 @@ def set_gamma_ramp( ) -> int: ... def set_icon(surface: Surface, /) -> None: ... def set_caption(title: str, icontitle: Optional[str] = None, /) -> None: ... -def get_caption() -> Tuple[str, str]: ... +def get_caption() -> tuple[str, str]: ... 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 get_window_size() -> tuple[int, int]: ... +def get_window_position() -> tuple[int, int]:... def set_window_position(position: Point) -> None:... def get_allow_screensaver() -> bool: ... def set_allow_screensaver(value: bool = True) -> None: ... -def get_desktop_sizes() -> List[Tuple[int, int]]: ... +def get_desktop_sizes() -> list[tuple[int, int]]: ... def is_fullscreen() -> bool: ... def is_vsync() -> bool: ... def get_current_refresh_rate() -> int: ... -def get_desktop_refresh_rates() -> List[int]: ... +def get_desktop_refresh_rates() -> list[int]: ... def message_box( title: str, message: Optional[str] = None, diff --git a/buildconfig/stubs/pygame/event.pyi b/buildconfig/stubs/pygame/event.pyi index 1987f96de9..7f8ed1a6b7 100644 --- a/buildconfig/stubs/pygame/event.pyi +++ b/buildconfig/stubs/pygame/event.pyi @@ -1,28 +1,24 @@ -from typing import ( - Any, - Dict, - List, - Optional, - Union, - final, -) +from typing import Any, Optional, Union, final from pygame.typing import SequenceLike @final class Event: type: int - dict: Dict[str, Any] - __dict__: Dict[str, Any] + __dict__: dict[str, Any] __hash__: None # type: ignore def __init__( - self, type: int, dict: Dict[str, Any] = ..., **kwargs: Any + self, type: int, dict: dict[str, Any] = ..., **kwargs: Any ) -> None: ... def __getattribute__(self, name: str) -> Any: ... def __setattr__(self, name: str, value: Any) -> None: ... def __delattr__(self, name: str) -> None: ... def __bool__(self) -> bool: ... + # this is at the bottom because mypy complains if this declaration comes + # before any uses of the dict[] typehinting because of the same naming + dict: dict[str, Any] + _EventTypes = Union[int, SequenceLike[int]] def pump() -> None: ... @@ -30,7 +26,7 @@ def get( eventtype: Optional[_EventTypes] = None, pump: Any = True, exclude: Optional[_EventTypes] = None, -) -> List[Event]: ... +) -> list[Event]: ... def poll() -> Event: ... def wait(timeout: int = 0) -> Event: ... def peek(eventtype: Optional[_EventTypes] = None, pump: Any = True) -> bool: ... diff --git a/buildconfig/stubs/pygame/font.pyi b/buildconfig/stubs/pygame/font.pyi index ea1074cee7..931d8ceeba 100644 --- a/buildconfig/stubs/pygame/font.pyi +++ b/buildconfig/stubs/pygame/font.pyi @@ -1,4 +1,5 @@ -from typing import Callable, Hashable, Iterable, List, Literal, Optional, Tuple, Union +from collections.abc import Callable, Hashable, Iterable +from typing import Literal, Optional, Union from pygame.surface import Surface @@ -11,9 +12,9 @@ UCS4: Literal[1] def init() -> None: ... def quit() -> None: ... def get_init() -> bool: ... -def get_sdl_ttf_version(linked: bool = True) -> Tuple[int, int, int]: ... +def get_sdl_ttf_version(linked: bool = True) -> tuple[int, int, int]: ... def get_default_font() -> str: ... -def get_fonts() -> List[str]: ... +def get_fonts() -> list[str]: ... def match_font( name: Union[str, bytes, Iterable[Union[str, bytes]]], bold: Hashable = False, @@ -65,7 +66,7 @@ class Font: bgcolor: Optional[ColorLike] = None, wraplength: int = 0, ) -> Surface: ... - def size(self, text: Union[str, bytes], /) -> Tuple[int, int]: ... + def size(self, text: Union[str, bytes], /) -> tuple[int, int]: ... def set_underline(self, value: bool, /) -> None: ... def get_underline(self) -> bool: ... def set_strikethrough(self, value: bool, /) -> None: ... @@ -75,7 +76,7 @@ class Font: def set_italic(self, value: bool, /) -> None: ... def metrics( self, text: Union[str, bytes], / - ) -> List[Tuple[int, int, int, int, int]]: ... + ) -> list[tuple[int, int, int, int, int]]: ... def get_italic(self) -> bool: ... def get_linesize(self) -> int: ... def get_height(self) -> int: ... diff --git a/buildconfig/stubs/pygame/freetype.pyi b/buildconfig/stubs/pygame/freetype.pyi index 8ce24499b8..1953766aef 100644 --- a/buildconfig/stubs/pygame/freetype.pyi +++ b/buildconfig/stubs/pygame/freetype.pyi @@ -1,4 +1,5 @@ -from typing import Any, Callable, Iterable, List, Optional, Tuple, Union +from collections.abc import Callable, Iterable +from typing import Any, Optional, Union from typing_extensions import deprecated # added in 3.13 from pygame.color import Color @@ -8,7 +9,7 @@ from pygame.surface import Surface from pygame.typing import ColorLike, FileLike, RectLike def get_error() -> str: ... -def get_version(linked: bool = True) -> Tuple[int, int, int]: ... +def get_version(linked: bool = True) -> tuple[int, int, int]: ... def init(cache_size: int = 64, resolution: int = 72) -> None: ... def quit() -> None: ... def get_init() -> bool: ... @@ -25,7 +26,7 @@ def SysFont( constructor: Optional[Callable[[Optional[str], int, bool, bool], Font]] = None, ) -> Font: ... def get_default_font() -> str: ... -def get_fonts() -> List[str]: ... +def get_fonts() -> list[str]: ... def match_font( name: Union[str, bytes, Iterable[Union[str, bytes]]], bold: Any = False, @@ -41,9 +42,9 @@ STYLE_DEFAULT: int class Font: @property - def size(self) -> Union[float, Tuple[float, float]]: ... + def size(self) -> Union[float, tuple[float, float]]: ... @size.setter - def size(self, value: Union[float, Tuple[float, float]]) -> None: ... + def size(self, value: Union[float, tuple[float, float]]) -> None: ... @property def style(self) -> int: ... @style.setter @@ -149,12 +150,12 @@ class Font: ) -> Rect: ... def get_metrics( self, text: str, size: float = 0 - ) -> List[Tuple[int, int, int, int, float, float]]: ... + ) -> list[tuple[int, int, int, int, float, float]]: ... def get_sized_ascender(self, size: float, /) -> int: ... def get_sized_descender(self, size: float, /) -> int: ... def get_sized_height(self, size: float, /) -> int: ... def get_sized_glyph_height(self, size: float, /) -> int: ... - def get_sizes(self) -> List[Tuple[int, int, int, float, float]]: ... + def get_sizes(self) -> list[tuple[int, int, int, float, float]]: ... def render( self, text: str, @@ -163,7 +164,7 @@ class Font: style: int = STYLE_DEFAULT, rotation: int = 0, size: float = 0, - ) -> Tuple[Surface, Rect]: ... + ) -> tuple[Surface, Rect]: ... def render_to( self, surf: Surface, @@ -182,7 +183,7 @@ class Font: rotation: int = 0, size: float = 0, invert: bool = False, - ) -> Tuple[bytes, Tuple[int, int]]: ... + ) -> tuple[bytes, tuple[int, int]]: ... def render_raw_to( self, array: Any, diff --git a/buildconfig/stubs/pygame/geometry.pyi b/buildconfig/stubs/pygame/geometry.pyi index d21842a494..efbf54a23a 100644 --- a/buildconfig/stubs/pygame/geometry.pyi +++ b/buildconfig/stubs/pygame/geometry.pyi @@ -1,11 +1,5 @@ -from typing import ( - overload, - Union, - Callable, - Protocol, - Tuple, - List, -) +from collections.abc import Callable +from typing import overload, Union, Protocol from pygame import Rect, FRect from pygame.typing import Point, RectLike, SequenceLike @@ -17,7 +11,7 @@ class _HasCircleAttribute(Protocol): def circle(self) -> Union[_CircleLike, Callable[[], _CircleLike]]: ... _CircleLike = Union[ - Circle, Tuple[Point, float], SequenceLike[float], _HasCircleAttribute + Circle, tuple[Point, float], SequenceLike[float], _HasCircleAttribute ] class _HasLineAttribute(Protocol): @@ -69,23 +63,23 @@ class Circle: @circumference.setter def circumference(self, value: float) -> None: ... @property - def center(self) -> Tuple[float, float]: ... + def center(self) -> tuple[float, float]: ... @center.setter def center(self, value: Point) -> None: ... @property - def top(self) -> Tuple[float, float]: ... + def top(self) -> tuple[float, float]: ... @top.setter def top(self, value: Point) -> None: ... @property - def left(self) -> Tuple[float, float]: ... + def left(self) -> tuple[float, float]: ... @left.setter def left(self, value: Point) -> None: ... @property - def bottom(self) -> Tuple[float, float]: ... + def bottom(self) -> tuple[float, float]: ... @bottom.setter def bottom(self, value: Point) -> None: ... @property - def right(self) -> Tuple[float, float]: ... + def right(self) -> tuple[float, float]: ... @right.setter def right(self, value: Point) -> None: ... @overload @@ -120,8 +114,10 @@ class Circle: def colliderect(self, topleft: Point, size: Point, /) -> bool: ... def collideswith(self, other: _CanBeCollided, /) -> bool: ... def collidelist(self, colliders: SequenceLike[_CanBeCollided], /) -> int: ... - def collidelistall(self, colliders: SequenceLike[_CanBeCollided], /) -> List[int]: ... - def intersect(self, other: _CanBeIntersected, /) -> List[Tuple[float, float]]: ... + def collidelistall( + self, colliders: SequenceLike[_CanBeCollided], / + ) -> list[int]: ... + def intersect(self, other: _CanBeIntersected, /) -> list[tuple[float, float]]: ... def contains(self, shape: _CanBeCollided, /) -> bool: ... @overload def update(self, circle: _CircleLike, /) -> None: ... @@ -160,11 +156,11 @@ class Line: @by.setter def by(self, value: float) -> None: ... @property - def a(self) -> Tuple[float, float]: ... + def a(self) -> tuple[float, float]: ... @a.setter def a(self, value: Point) -> None: ... @property - def b(self) -> Tuple[float, float]: ... + def b(self) -> tuple[float, float]: ... @b.setter def b(self, value: Point) -> None: ... @overload diff --git a/buildconfig/stubs/pygame/image.pyi b/buildconfig/stubs/pygame/image.pyi index a85af02e09..7a11a55cc5 100644 --- a/buildconfig/stubs/pygame/image.pyi +++ b/buildconfig/stubs/pygame/image.pyi @@ -1,4 +1,4 @@ -from typing import Literal, Optional, Tuple, Union +from typing import Literal, Optional, Union from typing_extensions import deprecated # added in 3.13 from pygame.bufferproxy import BufferProxy @@ -16,7 +16,7 @@ _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: Point) -> 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_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") def tostring( diff --git a/buildconfig/stubs/pygame/joystick.pyi b/buildconfig/stubs/pygame/joystick.pyi index 2936e5a2b3..517829bf2c 100644 --- a/buildconfig/stubs/pygame/joystick.pyi +++ b/buildconfig/stubs/pygame/joystick.pyi @@ -1,5 +1,5 @@ -from typing import Tuple, final -from typing_extensions import deprecated # added in 3.13 +from typing import final +from typing_extensions import deprecated # added in 3.13 def init() -> None: ... def quit() -> None: ... @@ -21,11 +21,11 @@ class JoystickType: def get_numaxes(self) -> int: ... def get_axis(self, axis_number: int, /) -> float: ... def get_numballs(self) -> int: ... - def get_ball(self, ball_number: int, /) -> Tuple[float, float]: ... + def get_ball(self, ball_number: int, /) -> tuple[float, float]: ... def get_numbuttons(self) -> int: ... def get_button(self, button: int, /) -> bool: ... def get_numhats(self) -> int: ... - def get_hat(self, hat_number: int, /) -> Tuple[float, float]: ... + def get_hat(self, hat_number: int, /) -> tuple[float, float]: ... def rumble( self, low_frequency: float, high_frequency: float, duration: int ) -> bool: ... diff --git a/buildconfig/stubs/pygame/key.pyi b/buildconfig/stubs/pygame/key.pyi index 09aa380b35..24a61739bb 100644 --- a/buildconfig/stubs/pygame/key.pyi +++ b/buildconfig/stubs/pygame/key.pyi @@ -1,8 +1,6 @@ -from typing import Tuple - from pygame.typing import RectLike -class ScancodeWrapper(Tuple[bool, ...]): ... +class ScancodeWrapper(tuple[bool, ...]): ... def get_focused() -> bool: ... def get_pressed() -> ScancodeWrapper: ... @@ -11,7 +9,7 @@ def get_just_released() -> ScancodeWrapper: ... def get_mods() -> int: ... def set_mods(mods: int, /) -> None: ... def set_repeat(delay: int = 0, interval: int = 0, /) -> None: ... -def get_repeat() -> Tuple[int, int]: ... +def get_repeat() -> tuple[int, int]: ... def name(key: int, use_compat: bool = True) -> str: ... def key_code(name: str) -> int: ... def start_text_input() -> None: ... diff --git a/buildconfig/stubs/pygame/mask.pyi b/buildconfig/stubs/pygame/mask.pyi index a866c469d4..18d6e4e69d 100644 --- a/buildconfig/stubs/pygame/mask.pyi +++ b/buildconfig/stubs/pygame/mask.pyi @@ -1,4 +1,4 @@ -from typing import Any, List, Optional, Tuple, Union +from typing import Any, Optional, Union from pygame.rect import Rect from pygame.surface import Surface @@ -18,11 +18,11 @@ class Mask: def __init__(self, size: Point, fill: bool = False) -> None: ... def __copy__(self) -> Mask: ... def copy(self) -> Mask: ... - def get_size(self) -> Tuple[int, int]: ... + 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: Point) -> int: ... def set_at(self, pos: Point, value: int = 1) -> None: ... - def overlap(self, other: Mask, offset: Point) -> Optional[Tuple[int, int]]: ... + def overlap(self, other: Mask, offset: Point) -> Optional[tuple[int, int]]: ... def overlap_area(self, other: Mask, offset: Point) -> int: ... def overlap_mask(self, other: Mask, offset: Point) -> Mask: ... def fill(self) -> None: ... @@ -32,9 +32,9 @@ class Mask: def draw(self, other: Mask, offset: Point) -> None: ... def erase(self, other: Mask, offset: Point) -> None: ... def count(self) -> int: ... - def centroid(self) -> Tuple[int, int]: ... + def centroid(self) -> tuple[int, int]: ... def angle(self) -> float: ... - def outline(self, every: int = 1) -> List[Tuple[int, int]]: ... + def outline(self, every: int = 1) -> list[tuple[int, int]]: ... def convolve( self, other: Mask, @@ -42,8 +42,8 @@ class Mask: offset: Point = (0, 0), ) -> Mask: ... def connected_component(self, pos: Point = ...) -> Mask: ... - def connected_components(self, minimum: int = 0) -> List[Mask]: ... - def get_bounding_rects(self) -> List[Rect]: ... + def connected_components(self, minimum: int = 0) -> list[Mask]: ... + def get_bounding_rects(self) -> list[Rect]: ... def to_surface( self, surface: Optional[Surface] = None, diff --git a/buildconfig/stubs/pygame/math.pyi b/buildconfig/stubs/pygame/math.pyi index 4526960b5a..5387d31a72 100644 --- a/buildconfig/stubs/pygame/math.pyi +++ b/buildconfig/stubs/pygame/math.pyi @@ -1,13 +1,9 @@ -import sys +from collections.abc import Collection, Iterator from typing import ( Any, Generic, - Iterator, - List, Literal, SupportsIndex, - Tuple, - Type, TypeVar, Union, final, @@ -16,11 +12,6 @@ from typing import ( ) from typing_extensions import deprecated # added in 3.13 -if sys.version_info >= (3, 9): - from collections.abc import Collection -else: - from typing import Collection - from pygame.typing import SequenceLike def clamp(value: float, min: float, max: float, /) -> float: ... @@ -41,7 +32,7 @@ class _GenericVector(Collection[float]): @overload def __getitem__(self, i: SupportsIndex) -> float: ... @overload - def __getitem__(self, s: slice) -> List[float]: ... + def __getitem__(self, s: slice) -> list[float]: ... def __iter__(self) -> VectorIterator: ... def __add__(self: _TVec, other: Union[SequenceLike[float], _TVec]) -> _TVec: ... def __radd__(self: _TVec, other: Union[SequenceLike[float], _TVec]) -> _TVec: ... @@ -228,7 +219,7 @@ class Vector2(_GenericVector): ) -> None: ... @overload def __init__(self, x: float, y: float) -> None: ... - def __reduce__(self: _TVec) -> Tuple[Type[_TVec], Tuple[float, float]]: ... + def __reduce__(self: _TVec) -> tuple[type[_TVec], tuple[float, float]]: ... def rotate(self: _TVec, angle: float, /) -> _TVec: ... def rotate_rad(self: _TVec, angle: float, /) -> _TVec: ... def rotate_ip(self, angle: float, /) -> None: ... @@ -236,7 +227,7 @@ class Vector2(_GenericVector): @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[SequenceLike[float], _TVec], /) -> float: ... - def as_polar(self) -> Tuple[float, float]: ... + def as_polar(self) -> tuple[float, float]: ... def from_polar(self, polar_value: SequenceLike[float], /) -> None: ... @overload def update( @@ -293,7 +284,7 @@ class Vector3(_GenericVector): ) -> None: ... @overload def __init__(self, x: float, y: float, z: float) -> None: ... - def __reduce__(self: _TVec) -> Tuple[Type[_TVec], Tuple[float, float, float]]: ... + def __reduce__(self: _TVec) -> tuple[type[_TVec], tuple[float, float, float]]: ... def cross(self: _TVec, other: Union[SequenceLike[float], _TVec], /) -> _TVec: ... def rotate( self: _TVec, angle: float, axis: Union[SequenceLike[float], _TVec], / @@ -329,8 +320,8 @@ class Vector3(_GenericVector): def rotate_z_rad_ip(self, angle: float, /) -> None: ... @deprecated("since 2.1.1. Use `pygame.Vector3.rotate_z_rad_ip` instead") def rotate_z_ip_rad(self, angle: float, /) -> None: ... - def as_spherical(self) -> Tuple[float, float, float]: ... - def from_spherical(self, spherical: Tuple[float, float, float], /) -> None: ... + def as_spherical(self) -> tuple[float, float, float]: ... + def from_spherical(self, spherical: tuple[float, float, float], /) -> None: ... @overload def update( self: _TVec, diff --git a/buildconfig/stubs/pygame/midi.pyi b/buildconfig/stubs/pygame/midi.pyi index 22fc749f80..4cce264e26 100644 --- a/buildconfig/stubs/pygame/midi.pyi +++ b/buildconfig/stubs/pygame/midi.pyi @@ -1,4 +1,4 @@ -from typing import List, Tuple, Union +from typing import Union from pygame.event import Event from pygame.typing import SequenceLike @@ -15,10 +15,10 @@ def get_init() -> bool: ... def get_count() -> int: ... 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 get_device_info(an_id: int) -> tuple[str, str, int, int, int]: ... def midis2events( midis: SequenceLike[SequenceLike[Union[SequenceLike[int], int]]], device_id: int -) -> List[Event]: ... +) -> list[Event]: ... def time() -> int: ... def frequency_to_midi(frequency: float) -> int: ... def midi_to_frequency(midi_note: int) -> float: ... @@ -29,7 +29,7 @@ class Input: def __init__(self, device_id: int, buffer_size: int = 4096) -> None: ... def close(self) -> None: ... def poll(self) -> bool: ... - def read(self, num_events: int) -> List[List[Union[List[int], int]]]: ... + def read(self, num_events: int) -> list[list[Union[list[int], int]]]: ... class Output: device_id: int @@ -45,6 +45,6 @@ class Output: def note_on(self, note: int, velocity: int, channel: int = 0) -> None: ... def set_instrument(self, instrument_id: int, channel: int = 0) -> None: ... def pitch_bend(self, value: int = 0, channel: int = 0) -> None: ... - def write(self, data: List[List[Union[List[int], int]]]) -> None: ... + def write(self, data: list[list[Union[list[int], int]]]) -> None: ... def write_short(self, status: int, data1: int = 0, data2: int = 0) -> None: ... - def write_sys_ex(self, when: int, msg: Union[List[int], str]) -> None: ... + def write_sys_ex(self, when: int, msg: Union[list[int], str]) -> None: ... diff --git a/buildconfig/stubs/pygame/mixer.pyi b/buildconfig/stubs/pygame/mixer.pyi index 84646b419b..205679768c 100644 --- a/buildconfig/stubs/pygame/mixer.pyi +++ b/buildconfig/stubs/pygame/mixer.pyi @@ -1,4 +1,4 @@ -from typing import Any, Dict, Optional, Tuple, Union, overload +from typing import Any, Optional, Union, overload import numpy @@ -27,7 +27,7 @@ def pre_init( allowedchanges: int = 5, ) -> None: ... def quit() -> None: ... -def get_init() -> Tuple[int, int, int]: ... +def get_init() -> tuple[int, int, int]: ... def get_driver() -> str: ... def stop() -> None: ... def pause() -> None: ... @@ -40,7 +40,7 @@ def find_channel(force: bool = False) -> Channel: ... def set_soundfont(paths: Optional[str] = None, /) -> None: ... def get_soundfont() -> Optional[str]: ... def get_busy() -> bool: ... -def get_sdl_mixer_version(linked: bool = True) -> Tuple[int, int, int]: ... +def get_sdl_mixer_version(linked: bool = True) -> tuple[int, int, int]: ... class Sound: @overload @@ -61,7 +61,7 @@ class Sound: ) -> Channel: ... # possibly going to be deprecated/removed soon, in which case these # typestubs must be removed too - __array_interface__: Dict[str, Any] + __array_interface__: dict[str, Any] __array_struct__: Any def stop(self) -> None: ... def fadeout(self, time: int, /) -> None: ... diff --git a/buildconfig/stubs/pygame/mixer_music.pyi b/buildconfig/stubs/pygame/mixer_music.pyi index 40cf46e2a9..a7000be125 100644 --- a/buildconfig/stubs/pygame/mixer_music.pyi +++ b/buildconfig/stubs/pygame/mixer_music.pyi @@ -1,4 +1,4 @@ -from typing import Optional, Dict +from typing import Optional from pygame.typing import FileLike @@ -18,4 +18,4 @@ def get_pos() -> int: ... 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[FileLike] = 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 d10fc742de..805862812d 100644 --- a/buildconfig/stubs/pygame/mouse.pyi +++ b/buildconfig/stubs/pygame/mouse.pyi @@ -1,4 +1,4 @@ -from typing import Literal, Tuple, overload +from typing import Literal, overload from typing_extensions import deprecated # added in 3.13 from pygame.cursors import Cursor @@ -9,15 +9,15 @@ from pygame.typing import Point, SequenceLike, IntPoint @overload def get_pressed( num_buttons: Literal[3] = 3, - desktop: bool = False) -> Tuple[bool, bool, bool]: ... + desktop: bool = False) -> tuple[bool, bool, bool]: ... @overload def get_pressed( num_buttons: Literal[5], - desktop: bool = False) -> Tuple[bool, bool, bool, bool, bool]: ... -def get_just_pressed() -> Tuple[bool, bool, bool, bool, bool]: ... -def get_just_released() -> Tuple[bool, bool, bool, bool, bool]: ... -def get_pos(desktop: bool = False) -> Tuple[int, int]: ... -def get_rel() -> Tuple[int, int]: ... + desktop: bool = False) -> tuple[bool, bool, bool, bool, bool]: ... +def get_just_pressed() -> tuple[bool, bool, bool, bool, bool]: ... +def get_just_released() -> tuple[bool, bool, bool, bool, bool]: ... +def get_pos(desktop: bool = False) -> tuple[int, int]: ... +def get_rel() -> tuple[int, int]: ... @overload def set_pos(pos: Point, /) -> None: ... @overload diff --git a/buildconfig/stubs/pygame/pixelarray.pyi b/buildconfig/stubs/pygame/pixelarray.pyi index a10bb66e42..fe7a176fe0 100644 --- a/buildconfig/stubs/pygame/pixelarray.pyi +++ b/buildconfig/stubs/pygame/pixelarray.pyi @@ -1,4 +1,4 @@ -from typing import Any, Dict, Tuple, Union, overload +from typing import Any, Union, overload from pygame.surface import Surface @@ -8,11 +8,11 @@ class PixelArray: surface: Surface itemsize: int ndim: int - shape: Tuple[int, ...] - strides: Tuple[int, ...] + shape: tuple[int, ...] + strides: tuple[int, ...] # possibly going to be deprecated/removed soon, in which case these # typestubs must be removed too - __array_interface__: Dict[str, Any] + __array_interface__: dict[str, Any] __array_struct__: Any def __init__(self, surface: Surface) -> None: ... def __enter__(self) -> PixelArray: ... @@ -27,7 +27,7 @@ class PixelArray: def __getitem__(self, index_range: slice) -> Union[PixelArray, None]: ... # only valid for a 2D PixelArray @overload - def __getitem__(self, indices: Tuple[int, int]) -> int: ... + def __getitem__(self, indices: tuple[int, int]) -> int: ... # returns self @overload def __getitem__(self, ell: ellipsis) -> PixelArray: ... diff --git a/buildconfig/stubs/pygame/rect.pyi b/buildconfig/stubs/pygame/rect.pyi index d18ea3cdf4..72bf30b73f 100644 --- a/buildconfig/stubs/pygame/rect.pyi +++ b/buildconfig/stubs/pygame/rect.pyi @@ -1,14 +1,11 @@ import sys +from collections.abc import Callable, Collection, Iterator from typing import ( - Dict, - List, Literal, SupportsIndex, - Tuple, TypeVar, Union, overload, - Callable, Optional, ) @@ -19,11 +16,6 @@ if sys.version_info >= (3, 11): else: from typing_extensions import Self -if sys.version_info >= (3, 9): - from collections.abc import Collection, Iterator -else: - from typing import Collection, Iterator - _N = TypeVar("_N", int, float) _K = TypeVar("_K") _V = TypeVar("_V") @@ -57,39 +49,39 @@ class _GenericRect(Collection[_N]): @right.setter def right(self, value: float) -> None: ... @property - def topleft(self) -> Tuple[_N, _N]: ... + def topleft(self) -> tuple[_N, _N]: ... @topleft.setter def topleft(self, value: Point) -> None: ... @property - def bottomleft(self) -> Tuple[_N, _N]: ... + def bottomleft(self) -> tuple[_N, _N]: ... @bottomleft.setter def bottomleft(self, value: Point) -> None: ... @property - def topright(self) -> Tuple[_N, _N]: ... + def topright(self) -> tuple[_N, _N]: ... @topright.setter def topright(self, value: Point) -> None: ... @property - def bottomright(self) -> Tuple[_N, _N]: ... + def bottomright(self) -> tuple[_N, _N]: ... @bottomright.setter def bottomright(self, value: Point) -> None: ... @property - def midtop(self) -> Tuple[_N, _N]: ... + def midtop(self) -> tuple[_N, _N]: ... @midtop.setter def midtop(self, value: Point) -> None: ... @property - def midleft(self) -> Tuple[_N, _N]: ... + def midleft(self) -> tuple[_N, _N]: ... @midleft.setter def midleft(self, value: Point) -> None: ... @property - def midbottom(self) -> Tuple[_N, _N]: ... + def midbottom(self) -> tuple[_N, _N]: ... @midbottom.setter def midbottom(self, value: Point) -> None: ... @property - def midright(self) -> Tuple[_N, _N]: ... + def midright(self) -> tuple[_N, _N]: ... @midright.setter def midright(self, value: Point) -> None: ... @property - def center(self) -> Tuple[_N, _N]: ... + def center(self) -> tuple[_N, _N]: ... @center.setter def center(self, value: Point) -> None: ... @property @@ -101,7 +93,7 @@ class _GenericRect(Collection[_N]): @centery.setter def centery(self, value: float) -> None: ... @property - def size(self) -> Tuple[_N, _N]: ... + def size(self) -> tuple[_N, _N]: ... @size.setter def size(self, value: Point) -> None: ... @property @@ -137,7 +129,7 @@ class _GenericRect(Collection[_N]): @overload def __getitem__(self, i: SupportsIndex) -> _N: ... @overload - def __getitem__(self, s: slice) -> List[_N]: ... + def __getitem__(self, s: slice) -> list[_N]: ... @overload def __setitem__(self, key: int, value: float) -> None: ... @overload @@ -198,15 +190,15 @@ class _GenericRect(Collection[_N]): @overload def clipline( self, x1: float, x2: float, x3: float, x4: float, / - ) -> Union[Tuple[Tuple[_N, _N], Tuple[_N, _N]], Tuple[()]]: ... + ) -> Union[tuple[tuple[_N, _N], tuple[_N, _N]], tuple[()]]: ... @overload def clipline( self, first_point: Point, second_point: Point, / - ) -> Union[Tuple[Tuple[_N, _N], Tuple[_N, _N]], Tuple[()]]: ... + ) -> Union[tuple[tuple[_N, _N], tuple[_N, _N]], tuple[()]]: ... @overload def clipline( self, rect_arg: RectLike, / - ) -> Union[Tuple[Tuple[_N, _N], Tuple[_N, _N]], Tuple[()]]: ... + ) -> Union[tuple[tuple[_N, _N], tuple[_N, _N]], tuple[()]]: ... @overload def union(self, rect: RectLike, /) -> Self: ... @overload @@ -252,29 +244,29 @@ class _GenericRect(Collection[_N]): self, left: float, top: float, width: float, height: float, / ) -> bool: ... def collidelist(self, rect_list: SequenceLike[_RectTypeCompatible_co], /) -> int: ... - def collidelistall(self, rect_list: SequenceLike[_RectTypeCompatible_co], /) -> List[int]: ... + def collidelistall(self, rect_list: SequenceLike[_RectTypeCompatible_co], /) -> list[int]: ... def collideobjectsall( self, objects: SequenceLike[_T], key: Optional[Callable[[_T], RectLike]] = None - ) -> List[_T]: ... + ) -> list[_T]: ... def collideobjects( self, objects: SequenceLike[_T], key: Optional[Callable[[_T], RectLike]] = None ) -> Optional[_T]: ... @overload def collidedict( - self, rect_dict: Dict[_RectTypeCompatible_co, _V], values: Literal[False] = False - ) -> Optional[Tuple[_RectTypeCompatible_co, _V]]: ... + self, rect_dict: dict[_RectTypeCompatible_co, _V], values: Literal[False] = False + ) -> Optional[tuple[_RectTypeCompatible_co, _V]]: ... @overload def collidedict( - self, rect_dict: Dict[_K, _RectTypeCompatible_co], values: Literal[True] - ) -> Optional[Tuple[_K, _RectTypeCompatible_co]]: ... + self, rect_dict: dict[_K, _RectTypeCompatible_co], values: Literal[True] + ) -> Optional[tuple[_K, _RectTypeCompatible_co]]: ... @overload def collidedictall( - self, rect_dict: Dict[_RectTypeCompatible_co, _V], values: Literal[False] = False - ) -> List[Tuple[_RectTypeCompatible_co, _V]]: ... + self, rect_dict: dict[_RectTypeCompatible_co, _V], values: Literal[False] = False + ) -> list[tuple[_RectTypeCompatible_co, _V]]: ... @overload def collidedictall( - self, rect_dict: Dict[_K, _RectTypeCompatible_co], values: Literal[True] - ) -> List[Tuple[_K, _RectTypeCompatible_co]]: ... + self, rect_dict: dict[_K, _RectTypeCompatible_co], values: Literal[True] + ) -> list[tuple[_K, _RectTypeCompatible_co]]: ... # Rect confirms to the Collection ABC, since it also confirms to # Sized, Iterable and Container ABCs diff --git a/buildconfig/stubs/pygame/rwobject.pyi b/buildconfig/stubs/pygame/rwobject.pyi index d14c62a804..11eb417a5b 100644 --- a/buildconfig/stubs/pygame/rwobject.pyi +++ b/buildconfig/stubs/pygame/rwobject.pyi @@ -1,4 +1,4 @@ -from typing import Any, Optional, overload, Type +from typing import Any, Optional, overload from pygame.typing import _PathLike @@ -6,13 +6,13 @@ def encode_string( obj: Optional[_PathLike], encoding: Optional[str] = "unicode_escape", errors: Optional[str] = "backslashreplace", - etype: Optional[Type[Exception]] = UnicodeEncodeError, + etype: Optional[type[Exception]] = UnicodeEncodeError, ) -> bytes: ... @overload def encode_file_path( - obj: Optional[_PathLike], etype: Optional[Type[Exception]] = UnicodeEncodeError + obj: Optional[_PathLike], etype: Optional[type[Exception]] = UnicodeEncodeError ) -> bytes: ... @overload def encode_file_path( - obj: Any, etype: Optional[Type[Exception]] = UnicodeEncodeError + obj: Any, etype: Optional[type[Exception]] = UnicodeEncodeError ) -> bytes: ... diff --git a/buildconfig/stubs/pygame/scrap.pyi b/buildconfig/stubs/pygame/scrap.pyi index edb98e8801..54e8044bd2 100644 --- a/buildconfig/stubs/pygame/scrap.pyi +++ b/buildconfig/stubs/pygame/scrap.pyi @@ -1,4 +1,4 @@ -from typing import List, Optional +from typing import Optional from typing_extensions import deprecated # added in 3.13 from collections.abc import ByteString @@ -9,7 +9,7 @@ def get_init() -> bool: ... @deprecated("since 2.2.0. Use the new API instead: `pygame.scrap.get_text`") def get(data_type: str, /) -> Optional[bytes]: ... @deprecated("since 2.2.0. Use the new API instead, which only supports strings") -def get_types() -> List[str]: ... +def get_types() -> list[str]: ... @deprecated("since 2.2.0. Use the new API instead: `pygame.scrap.put_text`") def put(data_type: str, data: ByteString, /) -> None: ... @deprecated("since 2.2.0. Use the new API instead: `pygame.scrap.has_text`") diff --git a/buildconfig/stubs/pygame/sndarray.pyi b/buildconfig/stubs/pygame/sndarray.pyi index bf03698feb..0f0342a92a 100644 --- a/buildconfig/stubs/pygame/sndarray.pyi +++ b/buildconfig/stubs/pygame/sndarray.pyi @@ -1,4 +1,3 @@ -from typing import Tuple from typing_extensions import deprecated # added in 3.13 import numpy @@ -13,4 +12,4 @@ def use_arraytype(arraytype: str) -> Sound: ... @deprecated("Only numpy is supported") def get_arraytype() -> str: ... @deprecated("Only numpy is supported") -def get_arraytypes() -> Tuple[str]: ... +def get_arraytypes() -> tuple[str]: ... diff --git a/buildconfig/stubs/pygame/sprite.pyi b/buildconfig/stubs/pygame/sprite.pyi index 8220c36ba9..e29ebfc183 100644 --- a/buildconfig/stubs/pygame/sprite.pyi +++ b/buildconfig/stubs/pygame/sprite.pyi @@ -1,15 +1,10 @@ +from collections.abc import Callable, Iterable, Iterator from typing import ( Any, - Callable, - Dict, Generic, - Iterable, - Iterator, - List, Optional, Protocol, SupportsFloat, - Tuple, TypeVar, Union, ) @@ -46,7 +41,7 @@ class _SupportsSprite(Protocol): def remove(self, *groups: _Group) -> None: ... def kill(self) -> None: ... def alive(self) -> bool: ... - def groups(self) -> List[_Group]: ... + def groups(self) -> list[_Group]: ... # also a protocol class _SupportsDirtySprite(_SupportsSprite, Protocol): @@ -80,7 +75,7 @@ class Sprite(_SupportsSprite): def remove(self, *groups: _Group) -> None: ... def kill(self) -> None: ... def alive(self) -> bool: ... - def groups(self) -> List[_Group]: ... + def groups(self) -> list[_Group]: ... # concrete dirty sprite implementation class class DirtySprite(_SupportsDirtySprite): @@ -147,8 +142,8 @@ _TDirtySprite = TypeVar("_TDirtySprite", bound=_DirtySpriteSupportsGroup) # b = Group(MySprite()) class AbstractGroup(Generic[_TSprite]): - spritedict: Dict[_TSprite, Optional[Union[FRect, Rect]]] - lostsprites: List[Union[FRect, Rect]] + spritedict: dict[_TSprite, Optional[Union[FRect, Rect]]] + lostsprites: list[Union[FRect, Rect]] def __init__(self) -> None: ... def __len__(self) -> int: ... def __iter__(self) -> Iterator[_TSprite]: ... @@ -158,7 +153,7 @@ class AbstractGroup(Generic[_TSprite]): def remove_internal(self, sprite: _TSprite) -> None: ... def has_internal(self, sprite: _TSprite) -> bool: ... def copy(self: _TGroup) -> _TGroup: ... # typing.Self is py3.11+ - def sprites(self) -> List[_TSprite]: ... + def sprites(self) -> list[_TSprite]: ... def add( self, *sprites: Union[_TSprite, AbstractGroup[_TSprite], Iterable[_TSprite]] ) -> None: ... @@ -169,7 +164,7 @@ class AbstractGroup(Generic[_TSprite]): self, *sprites: Union[_TSprite, AbstractGroup[_TSprite], Iterable[_TSprite]] ) -> bool: ... def update(self, *args: Any, **kwargs: Any) -> None: ... - def draw(self, surface: Surface) -> List[Union[FRect, Rect]]: ... + def draw(self, surface: Surface) -> list[Union[FRect, Rect]]: ... def clear( self, surface: Surface, @@ -211,10 +206,10 @@ class LayeredUpdates(AbstractGroup[_TSprite]): ], **kwargs: Any ) -> None: ... - def get_sprites_at(self, pos: Point) -> List[_TSprite]: ... + def get_sprites_at(self, pos: Point) -> 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]: ... + def remove_sprites_of_layer(self, layer_nr: int) -> list[_TSprite]: ... + def layers(self) -> list[int]: ... def change_layer(self, sprite: _TSprite, new_layer: int) -> None: ... def get_layer_of_sprite(self, sprite: _TSprite) -> int: ... def get_top_layer(self) -> int: ... @@ -222,14 +217,14 @@ class LayeredUpdates(AbstractGroup[_TSprite]): def move_to_front(self, sprite: _TSprite) -> None: ... def move_to_back(self, sprite: _TSprite) -> None: ... def get_top_sprite(self) -> _TSprite: ... - def get_sprites_from_layer(self, layer: int) -> List[_TSprite]: ... + def get_sprites_from_layer(self, layer: int) -> list[_TSprite]: ... def switch_layer(self, layer1_nr: int, layer2_nr: int) -> None: ... class LayeredDirty(LayeredUpdates[_TDirtySprite]): def __init__(self, *sprites: _TDirtySprite, **kwargs: Any) -> None: ... def draw( self, surface: Surface, bgd: Optional[Surface] = None - ) -> List[Union[FRect, Rect]]: ... + ) -> 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: RectLike) -> None: ... @@ -275,20 +270,20 @@ _SupportsCollideMask = Union[_HasImageAndRect, _HasMaskAndRect] def collide_mask( left: _SupportsCollideMask, right: _SupportsCollideMask -) -> Optional[Tuple[int, int]]: ... +) -> Optional[tuple[int, int]]: ... def spritecollide( sprite: _HasRect, group: AbstractGroup[_TSprite], dokill: bool, collided: Optional[Callable[[_TSprite, _TSprite2], Any]] = None, -) -> List[_TSprite]: ... +) -> list[_TSprite]: ... def groupcollide( groupa: AbstractGroup[_TSprite], groupb: AbstractGroup[_TSprite2], dokilla: bool, dokillb: bool, collided: Optional[Callable[[_TSprite, _TSprite2], Any]] = None, -) -> Dict[_TSprite, List[_TSprite2]]: ... +) -> dict[_TSprite, list[_TSprite2]]: ... def spritecollideany( sprite: _HasRect, group: AbstractGroup[_TSprite], diff --git a/buildconfig/stubs/pygame/surface.pyi b/buildconfig/stubs/pygame/surface.pyi index a32c840eba..98425b8adf 100644 --- a/buildconfig/stubs/pygame/surface.pyi +++ b/buildconfig/stubs/pygame/surface.pyi @@ -1,5 +1,6 @@ -from typing import Any, Iterable, List, Literal, Optional, Tuple, Union, overload -from typing_extensions import deprecated # added in 3.13 +from collections.abc import Iterable +from typing import Any, Literal, Optional, Union, overload +from typing_extensions import deprecated # added in 3.13 from pygame.bufferproxy import BufferProxy from pygame.color import Color @@ -46,7 +47,7 @@ class Surface: @property def height(self) -> int: ... @property - def size(self) -> Tuple[int, int]: ... + def size(self) -> tuple[int, int]: ... @overload def __init__( self, @@ -76,16 +77,16 @@ class Surface: self, blit_SequenceLike: Iterable[ Union[ - Tuple[Surface, Union[Point, RectLike]], - Tuple[Surface, Union[Point, RectLike], Union[RectLike, int]], - Tuple[Surface, Union[Point, RectLike], RectLike, int], + tuple[Surface, Union[Point, RectLike]], + tuple[Surface, Union[Point, RectLike], Union[RectLike, int]], + tuple[Surface, Union[Point, RectLike], RectLike, int], ] ], doreturn: Union[int, bool] = 1, - ) -> Union[List[Rect], None]: ... + ) -> Union[list[Rect], None]: ... def fblits( self, - blit_SequenceLike: Iterable[Tuple[Surface, Union[Point, RectLike]]], + blit_SequenceLike: Iterable[tuple[Surface, Union[Point, RectLike]]], special_flags: int = 0, / ) -> None: ... @overload @@ -110,7 +111,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[Tuple[int, int, int, int]]: ... + def get_colorkey(self) -> Optional[tuple[int, int, int, int]]: ... @overload def set_alpha(self, value: int, flags: int = 0, /) -> None: ... @overload @@ -120,11 +121,11 @@ class Surface: def unlock(self) -> None: ... def mustlock(self) -> bool: ... def get_locked(self) -> bool: ... - def get_locks(self) -> Tuple[Any, ...]: ... + def get_locks(self) -> tuple[Any, ...]: ... def get_at(self, x_y: Point, /) -> Color: ... def set_at(self, x_y: Point, color: ColorLike, /) -> None: ... def get_at_mapped(self, x_y: Point, /) -> int: ... - def get_palette(self) -> List[Color]: ... + def get_palette(self) -> list[Color]: ... def get_palette_at(self, index: int, /) -> Color: ... def set_palette(self, palette: SequenceLike[ColorLike], /) -> None: ... def set_palette_at(self, index: int, color: ColorLike, /) -> None: ... @@ -142,9 +143,9 @@ class Surface: ) -> Surface: ... def get_parent(self) -> Surface: ... def get_abs_parent(self) -> Surface: ... - def get_offset(self) -> Tuple[int, int]: ... - def get_abs_offset(self) -> Tuple[int, int]: ... - def get_size(self) -> Tuple[int, int]: ... + def get_offset(self) -> tuple[int, int]: ... + def get_abs_offset(self) -> tuple[int, int]: ... + def get_size(self) -> tuple[int, int]: ... def get_width(self) -> int: ... def get_height(self) -> int: ... def get_rect(self, **kwargs: Any) -> Rect: ... @@ -153,13 +154,13 @@ class Surface: def get_bytesize(self) -> int: ... def get_flags(self) -> int: ... def get_pitch(self) -> int: ... - def get_masks(self) -> Tuple[int, int, int, int]: ... + def get_masks(self) -> tuple[int, int, int, int]: ... @deprecated("since 2.0.0. Immutable in SDL2") def set_masks(self, color: ColorLike, /) -> None: ... - def get_shifts(self) -> Tuple[int, int, int, int]: ... + def get_shifts(self) -> tuple[int, int, int, int]: ... @deprecated("since 2.0.0. Immutable in SDL2") def set_shifts(self, color: ColorLike, /) -> None: ... - def get_losses(self) -> Tuple[int, int, int, int]: ... + def get_losses(self) -> tuple[int, int, int, int]: ... 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/surfarray.pyi b/buildconfig/stubs/pygame/surfarray.pyi index c15f089518..bafe709376 100644 --- a/buildconfig/stubs/pygame/surfarray.pyi +++ b/buildconfig/stubs/pygame/surfarray.pyi @@ -1,4 +1,3 @@ -from typing import Tuple from typing_extensions import deprecated # added in 3.13 import numpy @@ -32,4 +31,4 @@ def use_arraytype(arraytype: str) -> None: ... @deprecated("Only numpy is supported") def get_arraytype() -> str: ... @deprecated("Only numpy is supported") -def get_arraytypes() -> Tuple[str]: ... +def get_arraytypes() -> tuple[str]: ... diff --git a/buildconfig/stubs/pygame/system.pyi b/buildconfig/stubs/pygame/system.pyi index f2e367473f..514af9a134 100644 --- a/buildconfig/stubs/pygame/system.pyi +++ b/buildconfig/stubs/pygame/system.pyi @@ -1,4 +1,4 @@ -from typing import List, Optional, TypedDict +from typing import Optional, TypedDict from pygame._data_classes import PowerState @@ -26,5 +26,5 @@ class _Locale(TypedDict): def get_cpu_instruction_sets() -> _InstructionSets: ... def get_total_ram() -> int: ... def get_pref_path(org: str, app: str) -> str: ... -def get_pref_locales() -> List[_Locale]: ... +def get_pref_locales() -> list[_Locale]: ... def get_power_state() -> Optional[PowerState]: ... diff --git a/buildconfig/stubs/pygame/transform.pyi b/buildconfig/stubs/pygame/transform.pyi index f1a5f27918..384b41d3ac 100644 --- a/buildconfig/stubs/pygame/transform.pyi +++ b/buildconfig/stubs/pygame/transform.pyi @@ -1,4 +1,4 @@ -from typing import Optional, Union, Literal, Tuple +from typing import Optional, Union, Literal from pygame.surface import Surface @@ -47,7 +47,7 @@ def average_surfaces( ) -> Surface: ... def average_color( surface: Surface, rect: Optional[RectLike] = None, consider_alpha: bool = False -) -> Tuple[int, int, int, int]: ... +) -> tuple[int, int, int, int]: ... def threshold( dest_surface: Optional[Surface], surface: Surface, diff --git a/buildconfig/stubs/pygame/typing.pyi b/buildconfig/stubs/pygame/typing.pyi index ca88863a59..2897a338fe 100644 --- a/buildconfig/stubs/pygame/typing.pyi +++ b/buildconfig/stubs/pygame/typing.pyi @@ -12,24 +12,15 @@ __all__ = [ "IntPoint", ] -import sys from abc import abstractmethod -from typing import IO, Callable, Tuple, Union, TypeVar, Protocol +from collections.abc import Callable +from os import PathLike as _PathProtocol +from typing import IO, Union, TypeVar, Protocol from pygame.color import Color from pygame.rect import Rect, FRect -if sys.version_info >= (3, 9): - from os import PathLike as _PathProtocol -else: - _AnyStr_co = TypeVar("_AnyStr_co", str, bytes, covariant=True) - - class _PathProtocol(Protocol[_AnyStr_co]): - @abstractmethod - def __fspath__(self) -> _AnyStr_co: ... - - # 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 @@ -74,14 +65,12 @@ RectLike = Union[ # cleanup namespace del ( - sys, abstractmethod, Color, Rect, FRect, IO, Callable, - Tuple, Union, TypeVar, Protocol, diff --git a/buildconfig/stubs/pygame/version.pyi b/buildconfig/stubs/pygame/version.pyi index 3838d68274..4de5eb29e3 100644 --- a/buildconfig/stubs/pygame/version.pyi +++ b/buildconfig/stubs/pygame/version.pyi @@ -1,6 +1,6 @@ -from typing import Literal, Tuple +from typing import Literal -class SoftwareVersion(Tuple[int, int, int]): +class SoftwareVersion(tuple[int, int, int]): def __new__(cls, major: int, minor: int, patch: int) -> SoftwareVersion: ... def __repr__(self) -> str: ... def __str__(self) -> str: ... @@ -10,7 +10,7 @@ class SoftwareVersion(Tuple[int, int, int]): def minor(self) -> int: ... @property def patch(self) -> int: ... - fields: Tuple[Literal["major"], Literal["minor"], Literal["patch"]] + fields: tuple[Literal["major"], Literal["minor"], Literal["patch"]] class PygameVersion(SoftwareVersion): ... class SDLVersion(SoftwareVersion): ... diff --git a/buildconfig/stubs/pygame/window.pyi b/buildconfig/stubs/pygame/window.pyi index 69d04b3b36..338129bb70 100644 --- a/buildconfig/stubs/pygame/window.pyi +++ b/buildconfig/stubs/pygame/window.pyi @@ -1,4 +1,4 @@ -from typing import Optional, Tuple, Union +from typing import Optional, Union from typing_extensions import deprecated # added in 3.13 from pygame.typing import Point, RectLike @@ -53,19 +53,19 @@ class Window: @mouse_rect.setter def mouse_rect(self, value: Optional[RectLike]) -> None: ... @property - def size(self) -> Tuple[int, int]: ... + def size(self) -> tuple[int, int]: ... @size.setter def size(self, value: Point) -> None: ... @property - def minimum_size(self) -> Tuple[int, int]: ... + def minimum_size(self) -> tuple[int, int]: ... @minimum_size.setter def minimum_size(self, value: Point) -> None: ... @property - def maximum_size(self) -> Tuple[int, int]: ... + def maximum_size(self) -> tuple[int, int]: ... @maximum_size.setter def maximum_size(self, value: Point) -> None: ... @property - def position(self) -> Tuple[int, int]: ... + def position(self) -> tuple[int, int]: ... @position.setter def position(self, value: Union[int, Point]) -> None: ... @property diff --git a/src_py/typing.py b/src_py/typing.py index ca88863a59..2897a338fe 100644 --- a/src_py/typing.py +++ b/src_py/typing.py @@ -12,24 +12,15 @@ "IntPoint", ] -import sys from abc import abstractmethod -from typing import IO, Callable, Tuple, Union, TypeVar, Protocol +from collections.abc import Callable +from os import PathLike as _PathProtocol +from typing import IO, Union, TypeVar, Protocol from pygame.color import Color from pygame.rect import Rect, FRect -if sys.version_info >= (3, 9): - from os import PathLike as _PathProtocol -else: - _AnyStr_co = TypeVar("_AnyStr_co", str, bytes, covariant=True) - - class _PathProtocol(Protocol[_AnyStr_co]): - @abstractmethod - def __fspath__(self) -> _AnyStr_co: ... - - # 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 @@ -74,14 +65,12 @@ def rect(self) -> Union["RectLike", Callable[[], "RectLike"]]: ... # cleanup namespace del ( - sys, abstractmethod, Color, Rect, FRect, IO, Callable, - Tuple, Union, TypeVar, Protocol, From 11773ae1f4bbb55e17bac95552d19f289e097350 Mon Sep 17 00:00:00 2001 From: polastyn <78505251+gresm@users.noreply.github.com> Date: Tue, 19 Nov 2024 12:41:33 +0100 Subject: [PATCH 20/44] Utility Window implementation. --- buildconfig/stubs/pygame/window.pyi | 2 ++ docs/reST/ref/window.rst | 10 ++++++++++ src_c/doc/window_doc.h | 1 + src_c/window.c | 16 ++++++++++++++++ test/window_test.py | 7 +++++++ 5 files changed, 36 insertions(+) diff --git a/buildconfig/stubs/pygame/window.pyi b/buildconfig/stubs/pygame/window.pyi index 69d04b3b36..3babd3846c 100644 --- a/buildconfig/stubs/pygame/window.pyi +++ b/buildconfig/stubs/pygame/window.pyi @@ -70,6 +70,8 @@ class Window: def position(self, value: Union[int, Point]) -> None: ... @property def opengl(self) -> bool: ... + @property + def utility(self) -> bool: ... @classmethod @deprecated("since 2.4.0. Use either the display module or the Window class with get_surface and flip. Try not to mix display and Window") def from_display_module(cls) -> Window: ... diff --git a/docs/reST/ref/window.rst b/docs/reST/ref/window.rst index 7c78de9dc0..c6ea5c337c 100644 --- a/docs/reST/ref/window.rst +++ b/docs/reST/ref/window.rst @@ -43,6 +43,7 @@ (unrelated to INPUT_GRABBED). :param bool always_on_top: Create a window that is always presented above others. + :param bool utility: Create a window that doesn't appear in the task-bar . Event behavior if one Window is created: When the close button is pressed, the ``QUIT`` event will be sent to the event queue. @@ -289,6 +290,15 @@ .. versionadded:: 2.5.0 + .. attribute:: utility + + | :sl:`Get if the windos is an utility window` + | :sg:`utility -> bool` + + ``True`` if the window doesn't appear in the task bar, ``False`` otherwise + + .. versionadded:: TBD + .. classmethod:: from_display_module | :sl:`Create a Window object using window data from display module` diff --git a/src_c/doc/window_doc.h b/src_c/doc/window_doc.h index b7fd796810..42850a2cda 100644 --- a/src_c/doc/window_doc.h +++ b/src_c/doc/window_doc.h @@ -17,6 +17,7 @@ #define DOC_WINDOW_POSITION "position -> (int, int) or WINDOWPOS_CENTERED or WINDOWPOS_UNDEFINED\nGet or set the window position in screen coordinates" #define DOC_WINDOW_OPACITY "opacity -> float\nGet or set the window opacity, between 0.0 (fully transparent) and 1.0 (fully opaque)" #define DOC_WINDOW_OPENGL "opengl -> bool\nGet if the window supports OpenGL" +#define DOC_WINDOW_UTILITY "utility -> bool\nGet if the windos is an utility window" #define DOC_WINDOW_FROMDISPLAYMODULE "from_display_module() -> Window\nCreate a Window object using window data from display module" #define DOC_WINDOW_GETSURFACE "get_surface() -> Surface\nGet the window surface" #define DOC_WINDOW_FLIP "flip() -> None\nUpdate the display surface to the window." diff --git a/src_c/window.c b/src_c/window.c index 63b7270d06..1093c58f17 100644 --- a/src_c/window.c +++ b/src_c/window.c @@ -779,6 +779,13 @@ window_get_opengl(pgWindowObject *self, void *v) return PyBool_FromLong(hasGL); } +static PyObject * +window_get_utility(pgWindowObject *self, void *v) +{ + return PyBool_FromLong(SDL_GetWindowFlags(self->_win) & + SDL_WINDOW_UTILITY); +} + static void window_dealloc(pgWindowObject *self, PyObject *_null) { @@ -944,6 +951,14 @@ window_init(pgWindowObject *self, PyObject *args, PyObject *kwargs) if (_value_bool) flags |= SDL_WINDOW_VULKAN; } + else if (!strcmp(_key_str, "utility")) { + if (_value_bool) { + flags |= SDL_WINDOW_UTILITY; +#if !SDL_VERSION_ATLEAST(3, 0, 0) + flags |= SDL_WINDOW_SKIP_TASKBAR; +#endif + } + } else { PyErr_Format(PyExc_TypeError, "__init__ got an unexpected flag \'%s\'", @@ -1195,6 +1210,7 @@ static PyGetSetDef _window_getset[] = { DOC_WINDOW_OPACITY, NULL}, {"id", (getter)window_get_window_id, NULL, DOC_WINDOW_ID, NULL}, {"opengl", (getter)window_get_opengl, NULL, DOC_WINDOW_OPENGL, NULL}, + {"utility", (getter)window_get_utility, NULL, DOC_WINDOW_UTILITY, NULL}, {NULL, 0, NULL, NULL, NULL} /* Sentinel */ }; diff --git a/test/window_test.py b/test/window_test.py index fd7828393f..334753d44c 100644 --- a/test/window_test.py +++ b/test/window_test.py @@ -1,3 +1,5 @@ +from math import trunc +from re import S import unittest import pygame import os @@ -290,6 +292,11 @@ def test_init_flags(self): self.assertTrue(win.resizable) win.destroy() + # test utility + win = Window(utility=True) + self.assertTrue(win.utility) + win.destroy() + # should raise a TypeError if keyword is random self.assertRaises(TypeError, lambda: Window(aaa=True)) self.assertRaises(TypeError, lambda: Window(aaa=False)) From 9da90463224528364069a1b0a94aa958cac704d3 Mon Sep 17 00:00:00 2001 From: polastyn <78505251+gresm@users.noreply.github.com> Date: Tue, 19 Nov 2024 16:06:29 +0100 Subject: [PATCH 21/44] Add a note in docs. --- docs/reST/ref/window.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/reST/ref/window.rst b/docs/reST/ref/window.rst index c6ea5c337c..7fc9b3be46 100644 --- a/docs/reST/ref/window.rst +++ b/docs/reST/ref/window.rst @@ -43,7 +43,7 @@ (unrelated to INPUT_GRABBED). :param bool always_on_top: Create a window that is always presented above others. - :param bool utility: Create a window that doesn't appear in the task-bar . + :param bool utility: Create a window that doesn't appear in the task-bar. Event behavior if one Window is created: When the close button is pressed, the ``QUIT`` event will be sent to the event queue. @@ -295,7 +295,8 @@ | :sl:`Get if the windos is an utility window` | :sg:`utility -> bool` - ``True`` if the window doesn't appear in the task bar, ``False`` otherwise + ``True`` if the window doesn't appear in the task bar, ``False`` otherwise. + This only works for X11 and Windows, for other platforms, creating ``Window(utility=True)`` won't do anything. .. versionadded:: TBD From 27336859e1ccd5c4308fcd656aaafabd55b2ce51 Mon Sep 17 00:00:00 2001 From: polastyn <78505251+gresm@users.noreply.github.com> Date: Tue, 19 Nov 2024 16:20:22 +0100 Subject: [PATCH 22/44] Nitpicks. --- docs/reST/ref/window.rst | 6 +++--- test/window_test.py | 2 -- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/docs/reST/ref/window.rst b/docs/reST/ref/window.rst index 7fc9b3be46..215072421f 100644 --- a/docs/reST/ref/window.rst +++ b/docs/reST/ref/window.rst @@ -43,7 +43,7 @@ (unrelated to INPUT_GRABBED). :param bool always_on_top: Create a window that is always presented above others. - :param bool utility: Create a window that doesn't appear in the task-bar. + :param bool utility: Create a window that doesn't appear in the task bar. Event behavior if one Window is created: When the close button is pressed, the ``QUIT`` event will be sent to the event queue. @@ -292,11 +292,11 @@ .. attribute:: utility - | :sl:`Get if the windos is an utility window` + | :sl:`Get if the windos is an utility window (**read-only**)` | :sg:`utility -> bool` ``True`` if the window doesn't appear in the task bar, ``False`` otherwise. - This only works for X11 and Windows, for other platforms, creating ``Window(utility=True)`` won't do anything. + This only works for X11 and Windows, for other platforms, creating ``Window(utility=True)`` won't change anything. .. versionadded:: TBD diff --git a/test/window_test.py b/test/window_test.py index 334753d44c..f30ab08bc5 100644 --- a/test/window_test.py +++ b/test/window_test.py @@ -1,5 +1,3 @@ -from math import trunc -from re import S import unittest import pygame import os From 816bd7746fa722ab3e9c6db79130d7a6d9da3cb8 Mon Sep 17 00:00:00 2001 From: Charlie Hayden <46412508+Starbuck5@users.noreply.github.com> Date: Tue, 19 Nov 2024 14:19:35 -0800 Subject: [PATCH 23/44] Batch and error check allocations (#3224) * Batch PyMem_New-s in draw routines * Batch and error check mallocs in blur routines * Move PyErr_NoMemory out of GIL-less block * Remove misplaced PyMem_Free --- src_c/draw.c | 48 ++++++++++++++---------------------------- src_c/transform.c | 53 +++++++++++++++++++++++++++++++++-------------- 2 files changed, 53 insertions(+), 48 deletions(-) diff --git a/src_c/draw.c b/src_c/draw.c index 0d6b9fc8a8..ab5e30c76b 100644 --- a/src_c/draw.c +++ b/src_c/draw.c @@ -279,7 +279,6 @@ aalines(PyObject *self, PyObject *arg, PyObject *kwargs) Uint32 color; float pts[4]; float pts_prev[4]; - float *xlist, *ylist; float x, y; int l, t; int extra_px; @@ -333,16 +332,12 @@ aalines(PyObject *self, PyObject *arg, PyObject *kwargs) "points argument must contain 2 or more points"); } - xlist = PyMem_New(float, length); - ylist = PyMem_New(float, length); + // Allocate bytes for the xlist and ylist at once to reduce allocations. + float *points_buf = PyMem_New(float, length * 2); + float *xlist = points_buf; + float *ylist = points_buf + length; - if (NULL == xlist || NULL == ylist) { - if (xlist) { - PyMem_Free(xlist); - } - if (ylist) { - PyMem_Free(ylist); - } + if (points_buf == NULL) { return RAISE(PyExc_MemoryError, "cannot allocate memory to draw aalines"); } @@ -357,8 +352,7 @@ aalines(PyObject *self, PyObject *arg, PyObject *kwargs) Py_DECREF(item); if (!result) { - PyMem_Free(xlist); - PyMem_Free(ylist); + PyMem_Free(points_buf); return RAISE(PyExc_TypeError, "points must be number pairs"); } @@ -367,8 +361,7 @@ aalines(PyObject *self, PyObject *arg, PyObject *kwargs) } if (!pgSurface_Lock(surfobj)) { - PyMem_Free(xlist); - PyMem_Free(ylist); + PyMem_Free(points_buf); return RAISE(PyExc_RuntimeError, "error locking surface"); } @@ -460,8 +453,7 @@ aalines(PyObject *self, PyObject *arg, PyObject *kwargs) disable_endpoints, disable_endpoints, extra_px); } - PyMem_Free(xlist); - PyMem_Free(ylist); + PyMem_Free(points_buf); if (!pgSurface_Unlock(surfobj)) { return RAISE(PyExc_RuntimeError, "error unlocking surface"); @@ -970,7 +962,6 @@ polygon(PyObject *self, PyObject *arg, PyObject *kwargs) PyObject *colorobj, *points, *item = NULL; SDL_Surface *surf = NULL; Uint32 color; - int *xlist = NULL, *ylist = NULL; int width = 0; /* Default width. */ int x, y, result, l, t; int drawn_area[4] = {INT_MAX, INT_MAX, INT_MIN, @@ -1021,16 +1012,12 @@ polygon(PyObject *self, PyObject *arg, PyObject *kwargs) "points argument must contain more than 2 points"); } - xlist = PyMem_New(int, length); - ylist = PyMem_New(int, length); + // Allocate bytes for the xlist and ylist at once to reduce allocations. + int *points_buf = PyMem_New(int, length * 2); + int *xlist = points_buf; + int *ylist = points_buf + length; - if (NULL == xlist || NULL == ylist) { - if (xlist) { - PyMem_Free(xlist); - } - if (ylist) { - PyMem_Free(ylist); - } + if (points_buf == NULL) { return RAISE(PyExc_MemoryError, "cannot allocate memory to draw polygon"); } @@ -1045,8 +1032,7 @@ polygon(PyObject *self, PyObject *arg, PyObject *kwargs) Py_DECREF(item); if (!result) { - PyMem_Free(xlist); - PyMem_Free(ylist); + PyMem_Free(points_buf); return RAISE(PyExc_TypeError, "points must be number pairs"); } @@ -1055,8 +1041,7 @@ polygon(PyObject *self, PyObject *arg, PyObject *kwargs) } if (!pgSurface_Lock(surfobj)) { - PyMem_Free(xlist); - PyMem_Free(ylist); + PyMem_Free(points_buf); return RAISE(PyExc_RuntimeError, "error locking surface"); } @@ -1066,8 +1051,7 @@ polygon(PyObject *self, PyObject *arg, PyObject *kwargs) else { draw_filltri(surf, xlist, ylist, color, drawn_area); } - PyMem_Free(xlist); - PyMem_Free(ylist); + PyMem_Free(points_buf); if (!pgSurface_Unlock(surfobj)) { return RAISE(PyExc_RuntimeError, "error unlocking surface"); diff --git a/src_c/transform.c b/src_c/transform.c index 00f72efb19..e4107f07cd 100644 --- a/src_c/transform.c +++ b/src_c/transform.c @@ -3562,7 +3562,7 @@ surf_average_color(PyObject *self, PyObject *args, PyObject *kwargs) return Py_BuildValue("(bbbb)", r, g, b, a); } -static void +static int box_blur(SDL_Surface *src, SDL_Surface *dst, int radius, SDL_bool repeat) { // Reference : https://blog.csdn.net/blogshinelee/article/details/80997324 @@ -3574,9 +3574,16 @@ box_blur(SDL_Surface *src, SDL_Surface *dst, int radius, SDL_bool repeat) int dst_pitch = dst->pitch; int src_pitch = src->pitch; int i, x, y, color; - Uint32 *buf = malloc(dst_pitch * sizeof(Uint32)); - Uint32 *sum_v = malloc(dst_pitch * sizeof(Uint32)); - Uint32 *sum_h = malloc(nb * sizeof(Uint32)); + + // Allocate bytes for buf, sum_v, and sum_h at once to reduce allocations. + Uint32 *overall_buf = malloc(sizeof(Uint32) * (dst_pitch * 2 + nb)); + Uint32 *buf = overall_buf; + Uint32 *sum_v = overall_buf + dst_pitch; + Uint32 *sum_h = overall_buf + dst_pitch * 2; + + if (overall_buf == NULL) { + return -1; + } memset(sum_v, 0, dst_pitch * sizeof(Uint32)); for (y = 0; y <= radius; y++) { // y-pre @@ -3641,12 +3648,11 @@ box_blur(SDL_Surface *src, SDL_Surface *dst, int radius, SDL_bool repeat) } } - free(buf); - free(sum_v); - free(sum_h); + free(overall_buf); + return 0; } -static void +static int gaussian_blur(SDL_Surface *src, SDL_Surface *dst, int sigma, SDL_bool repeat) { Uint8 *srcpx = (Uint8 *)src->pixels; @@ -3657,11 +3663,19 @@ gaussian_blur(SDL_Surface *src, SDL_Surface *dst, int sigma, SDL_bool repeat) int src_pitch = src->pitch; int i, j, x, y, color; int kernel_radius = sigma * 2; - float *buf = malloc(dst_pitch * sizeof(float)); - float *buf2 = malloc(dst_pitch * sizeof(float)); - float *lut = malloc((kernel_radius + 1) * sizeof(float)); float lut_sum = 0.0; + // Allocate bytes for buf, buf2, and lut at once to reduce allocations. + float *overall_buf = + malloc(sizeof(float) * (dst_pitch * 2 + kernel_radius + 1)); + float *buf = overall_buf; + float *buf2 = overall_buf + dst_pitch; + float *lut = overall_buf + dst_pitch * 2; + + if (overall_buf == NULL) { + return -1; + } + for (i = 0; i <= kernel_radius; i++) { // init gaussian lut // Gaussian function lut[i] = @@ -3723,9 +3737,8 @@ gaussian_blur(SDL_Surface *src, SDL_Surface *dst, int sigma, SDL_bool repeat) } } - free(buf); - free(buf2); - free(lut); + free(overall_buf); + return 0; } static SDL_Surface * @@ -3734,6 +3747,7 @@ blur(pgSurfaceObject *srcobj, pgSurfaceObject *dstobj, int radius, { SDL_Surface *src = NULL; SDL_Surface *retsurf = NULL; + int result = 0; if (radius < 0) { return RAISE(PyExc_ValueError, @@ -3793,10 +3807,10 @@ blur(pgSurfaceObject *srcobj, pgSurfaceObject *dstobj, int radius, Py_BEGIN_ALLOW_THREADS; if (algorithm == 'b') { - box_blur(src, retsurf, radius, repeat); + result = box_blur(src, retsurf, radius, repeat); } else if (algorithm == 'g') { - gaussian_blur(src, retsurf, radius, repeat); + result = gaussian_blur(src, retsurf, radius, repeat); } Py_END_ALLOW_THREADS; @@ -3804,6 +3818,13 @@ blur(pgSurfaceObject *srcobj, pgSurfaceObject *dstobj, int radius, pgSurface_Unlock(srcobj); SDL_UnlockSurface(retsurf); + // Routines only set error flag if memory allocation failed + // Setting Python exception here outside of Py_ THREADS block to be safe + if (result) { + PyErr_NoMemory(); + return NULL; + } + return retsurf; } From 9c90cd71619ead4f608a48d2f03e22a40f5c5887 Mon Sep 17 00:00:00 2001 From: Alexia Date: Wed, 20 Nov 2024 11:26:47 +0100 Subject: [PATCH 24/44] enhancing test for pygame.draw.arc --- test/draw_test.py | 65 +++++++++++++++++++++++++++++++---------------- 1 file changed, 43 insertions(+), 22 deletions(-) diff --git a/test/draw_test.py b/test/draw_test.py index 8c57834de9..478191d854 100644 --- a/test/draw_test.py +++ b/test/draw_test.py @@ -6204,39 +6204,60 @@ def test_arc__correct_drawing(self): rectangles = [ pygame.Rect((200, 200), (300 + i, 200 + i)) for i in range(-100, 50, 30) ] # Test on different bounding rectangles - start = 0 - stop = 2 + angle_pairs = [ + (0, 2), + (0, 3.14), + (1, 4), + (2, 5.5), + (0, 6.28), + ] # Test a variety of start and stop angles + widths = [ + -10, + -5, + -1, + 0, + 1, + 2, + 5, + 10, + 20, + 50, + 100, + ] # Test a wider range of stroke width for rect in rectangles: - kwargs = { - "surface": surface, - "color": arc_color, - "rect": rect, - "start_angle": start, - "stop_angle": stop, - "width": 1, - } - - pygame.draw.arc(**kwargs) - - a, b = rect.width / 2, rect.height / 2 - number_of_valid_arc_points = 0 - number_of_invalid_arc_points = 0 - # Define a threshold for comparison - eps = 0.1 - center_x = rect.centerx - center_y = rect.centery + for start, stop in angle_pairs: + for width in widths: + # A tolerance value that adapt to the width + tolerance_radius = min(max(0, width // 10), 1) + kwargs = { + "surface": surface, + "color": arc_color, + "rect": rect, + "start_angle": start, + "stop_angle": stop, + "width": width, + } + + pygame.draw.arc(**kwargs) + + a, b = rect.width / 2, rect.height / 2 + number_of_valid_arc_points = 0 + number_of_invalid_arc_points = 0 + # Define a threshold for comparison + eps = 0.01 + center_x = rect.centerx + center_y = rect.centery for x in range(surfw): for y in range(surfh): # Check whether the point on the arc belongs to the ellipse defined by the bounding rectangle if (surface.get_at((x, y)) == arc_color) and abs( ((x - center_x) / a) ** 2 + ((y - center_y) / b) ** 2 - 1 - ) <= eps: + ) <= eps + tolerance_radius: number_of_valid_arc_points += 1 elif surface.get_at((x, y)) == arc_color: number_of_invalid_arc_points += 1 - surface.fill(surface_color) # Clear for the next test self.assertEqual(number_of_invalid_arc_points, 0) From 3b850e7488de8e71d0f399acdfe1beff80fa179c Mon Sep 17 00:00:00 2001 From: GabrieleLS Date: Wed, 20 Nov 2024 17:19:56 +0100 Subject: [PATCH 25/44] Update mixer documentation to clarify channel confusion (#3228) Co-authored-by: Gabriele Co-authored-by: AntoineM <160046187+AntoineMamou@users.noreply.github.com> --- docs/reST/ref/mixer.rst | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/reST/ref/mixer.rst b/docs/reST/ref/mixer.rst index 5a441c7f81..76d1122772 100644 --- a/docs/reST/ref/mixer.rst +++ b/docs/reST/ref/mixer.rst @@ -79,6 +79,9 @@ The following file formats are supported The channels argument is used to specify whether to use mono or stereo. 1 for mono and 2 for stereo. + ``NOTE``: The channels argument is not related to the number + of channels for playback of sounds, that you can get with the function + "get_num_channels" or set with the function "set_num_channels" (see below). The buffer argument controls the number of internal samples used in the sound mixer. The default value should work for most cases. It can be lowered @@ -220,7 +223,7 @@ The following file formats are supported | :sl:`set the total number of playback channels` | :sg:`set_num_channels(count, /) -> None` - Sets the number of available channels for the mixer. The default value is 8. + Sets the number of available playback channels for the mixer. The default value is 8. The value can be increased or decreased. If the value is decreased, sounds playing on the truncated channels are stopped. From e7167e0df56315136ac8453b6e5442fc45fd49e4 Mon Sep 17 00:00:00 2001 From: polastyn <78505251+gresm@users.noreply.github.com> Date: Wed, 20 Nov 2024 18:23:28 +0100 Subject: [PATCH 26/44] Regen docs without renaming. --- src_c/doc/window_doc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src_c/doc/window_doc.h b/src_c/doc/window_doc.h index 42850a2cda..bed2a7cd27 100644 --- a/src_c/doc/window_doc.h +++ b/src_c/doc/window_doc.h @@ -17,7 +17,7 @@ #define DOC_WINDOW_POSITION "position -> (int, int) or WINDOWPOS_CENTERED or WINDOWPOS_UNDEFINED\nGet or set the window position in screen coordinates" #define DOC_WINDOW_OPACITY "opacity -> float\nGet or set the window opacity, between 0.0 (fully transparent) and 1.0 (fully opaque)" #define DOC_WINDOW_OPENGL "opengl -> bool\nGet if the window supports OpenGL" -#define DOC_WINDOW_UTILITY "utility -> bool\nGet if the windos is an utility window" +#define DOC_WINDOW_UTILITY "utility -> bool\nGet if the windos is an utility window (**read-only**)" #define DOC_WINDOW_FROMDISPLAYMODULE "from_display_module() -> Window\nCreate a Window object using window data from display module" #define DOC_WINDOW_GETSURFACE "get_surface() -> Surface\nGet the window surface" #define DOC_WINDOW_FLIP "flip() -> None\nUpdate the display surface to the window." From a888e5e61430853ab437dfd494a2cec704fb96da Mon Sep 17 00:00:00 2001 From: Brett Kaplan Date: Wed, 20 Nov 2024 17:33:48 -0500 Subject: [PATCH 27/44] fixing grammar --- docs/reST/ref/surface.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/reST/ref/surface.rst b/docs/reST/ref/surface.rst index dbaac65828..7153dc7fd3 100644 --- a/docs/reST/ref/surface.rst +++ b/docs/reST/ref/surface.rst @@ -32,7 +32,7 @@ Both flags are only a request, and may not be possible for all displays and formats. - Advance users can combine a set of bitmasks with a depth value. The masks + Advanced users can combine a set of bitmasks with a depth value. The masks are a set of 4 integers representing which bits in a pixel will represent each color. Normal Surfaces should not require the masks argument. From acd00e9ccc21e1c0bd36fb60212c0cd2c3d01722 Mon Sep 17 00:00:00 2001 From: Ankith Date: Sun, 3 Nov 2024 17:50:44 +0530 Subject: [PATCH 28/44] Bump build dependencies --- .github/workflows/build-macos.yml | 2 +- .github/workflows/build-windows.yml | 2 +- dev.py | 6 +++--- pyproject.toml | 8 ++++---- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build-macos.yml b/.github/workflows/build-macos.yml index 23e304285f..8c269d9cb3 100644 --- a/.github/workflows/build-macos.yml +++ b/.github/workflows/build-macos.yml @@ -135,7 +135,7 @@ jobs: - name: Install uv for speed uses: yezz123/setup-uv@v4 with: - uv-version: "0.4.10" + uv-version: "0.5.4" - name: Build and test wheels uses: pypa/cibuildwheel@v2.21.3 diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml index d868bfabce..99b30d9d69 100644 --- a/.github/workflows/build-windows.yml +++ b/.github/workflows/build-windows.yml @@ -59,7 +59,7 @@ jobs: - name: Install uv for speed uses: yezz123/setup-uv@v4 with: - uv-version: "0.4.10" + uv-version: "0.5.4" - name: Build and test wheels uses: pypa/cibuildwheel@v2.21.3 diff --git a/dev.py b/dev.py index c3f27a00b8..c7a5dfb29e 100644 --- a/dev.py +++ b/dev.py @@ -196,9 +196,9 @@ def __init__(self) -> None: "build": get_build_deps(), "docs": get_build_deps(), "test": {"numpy"}, - "lint": {"pylint==3.3.0", "numpy"}, - "stubs": {"mypy==1.11.2", "numpy"}, - "format": {"pre-commit==3.8.0"}, + "lint": {"pylint==3.3.1", "numpy"}, + "stubs": {"mypy==1.13.0", "numpy"}, + "format": {"pre-commit==4.0.1"}, } self.deps["all"] = set() for k in self.deps.values(): diff --git a/pyproject.toml b/pyproject.toml index 476a08242e..acf6eb483d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -54,11 +54,11 @@ pygame_ce = 'pygame.__briefcase.pygame_ce:PygameCEGuiBootstrap' [build-system] requires = [ - "meson-python<=0.16.0", - "meson<=1.5.1", - "ninja<=1.11.1.1", + "meson-python<=0.17.1", + "meson<=1.6.0", + "ninja<=1.12.1", "cython<=3.0.11", - "sphinx<=7.2.6", + "sphinx<=8.1.3", ] build-backend = 'mesonpy' From a6e26474f350e00194f2ef2faa3726d817bab740 Mon Sep 17 00:00:00 2001 From: Ankith Date: Sun, 3 Nov 2024 17:51:53 +0530 Subject: [PATCH 29/44] Update msys2/multiarch CI to use `dev.py` --- .github/workflows/build-debian-multiarch.yml | 10 ++++------ .github/workflows/build-on-msys2.yml | 10 ++++------ 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/.github/workflows/build-debian-multiarch.yml b/.github/workflows/build-debian-multiarch.yml index 543486b8e7..8fe0937bba 100644 --- a/.github/workflows/build-debian-multiarch.yml +++ b/.github/workflows/build-debian-multiarch.yml @@ -96,13 +96,11 @@ jobs: install: ${{ env.INSTALL_CMD }} # Build a wheel, install it for running unit tests. - # --no-build-isolation is passed so that preinstalled meson-python can be used - # (done for optimization reasons) + # pip does not know that ninja is installed, and tries to install it again. + # so pass --ignore-dep ninja explicitly run: | - echo "\nBuilding pygame wheel\n" - pip3 wheel . --no-build-isolation --wheel-dir /artifacts -vvv - echo "\nInstalling wheel\n" - pip3 install --no-index --pre --break-system-packages --find-links /artifacts pygame-ce + echo "\nBuilding and installing pygame wheel\n" + PIP_BREAK_SYSTEM_PACKAGES=1 python3 dev.py --ignore-dep ninja build --wheel /artifacts --lax echo "\nRunning tests\n" export SDL_VIDEODRIVER=dummy export SDL_AUDIODRIVER=disk diff --git a/.github/workflows/build-on-msys2.yml b/.github/workflows/build-on-msys2.yml index 6ac74c15f4..0845aefce2 100644 --- a/.github/workflows/build-on-msys2.yml +++ b/.github/workflows/build-on-msys2.yml @@ -68,12 +68,10 @@ jobs: # mingw-w64-${{ matrix.env }}-freetype # mingw-w64-${{ matrix.env }}-portmidi - - name: Building pygame wheel - run: | - pip3 wheel . --wheel-dir /artifacts -vvv --no-build-isolation - - - name: Installing wheel - run: pip3 install --no-index --pre --find-links /artifacts pygame-ce + # pip does not know that ninja is installed, and tries to install it again. + # so pass --ignore-dep ninja explicitly + - name: Build and install pygame wheel + run: python3 dev.py --ignore-dep ninja build --wheel /artifacts --lax - name: Run tests env: From eba1fe85f5db60fc7f257ffa8799a9ef06049071 Mon Sep 17 00:00:00 2001 From: Ankith Date: Thu, 21 Nov 2024 12:15:22 +0530 Subject: [PATCH 30/44] Fix SDL3 CI apt issues --- .github/workflows/build-sdl3.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-sdl3.yml b/.github/workflows/build-sdl3.yml index 058ca74ab7..066439e04e 100644 --- a/.github/workflows/build-sdl3.yml +++ b/.github/workflows/build-sdl3.yml @@ -56,7 +56,9 @@ jobs: - name: Install pygame deps (linux) if: matrix.os == 'ubuntu-24.04' - run: sudo apt-get install libfreetype6-dev libportmidi-dev python3-dev + run: | + sudo apt-get update --fix-missing + sudo apt-get install libfreetype6-dev libportmidi-dev python3-dev - name: Install pygame deps (mac) if: matrix.os == 'macos-14' From 731db170f06b8fca60801854dff1581b27b03eb7 Mon Sep 17 00:00:00 2001 From: gresm <78505251+gresm@users.noreply.github.com> Date: Thu, 21 Nov 2024 14:38:23 +0100 Subject: [PATCH 31/44] Update docs/reST/ref/window.rst MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 云line <31395137+yunline@users.noreply.github.com> --- docs/reST/ref/window.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/reST/ref/window.rst b/docs/reST/ref/window.rst index 215072421f..1b9196c52a 100644 --- a/docs/reST/ref/window.rst +++ b/docs/reST/ref/window.rst @@ -298,7 +298,7 @@ ``True`` if the window doesn't appear in the task bar, ``False`` otherwise. This only works for X11 and Windows, for other platforms, creating ``Window(utility=True)`` won't change anything. - .. versionadded:: TBD + .. versionadded:: 2.5.3 .. classmethod:: from_display_module From c00ff2924ea3d2c558e3528d0fceab651befbfcf Mon Sep 17 00:00:00 2001 From: Ankith Date: Fri, 22 Nov 2024 22:22:22 +0530 Subject: [PATCH 32/44] Deprecate Window foreign kwarg --- docs/reST/ref/window.rst | 1 - src_c/window.c | 6 ++++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/reST/ref/window.rst b/docs/reST/ref/window.rst index 7c78de9dc0..9b18406a80 100644 --- a/docs/reST/ref/window.rst +++ b/docs/reST/ref/window.rst @@ -37,7 +37,6 @@ :param bool keyboard_grabbed: Create a window with grabbed keyboard input. :param bool input_focus: Create a window with input focus. :param bool mouse_focus: Create a window with mouse focus. - :param bool foreign: Marks a window not created by SDL. :param bool allow_high_dpi: Create a window in high-DPI mode if supported. :param bool mouse_capture: Create a window that has the mouse captured (unrelated to INPUT_GRABBED). diff --git a/src_c/window.c b/src_c/window.c index 63b7270d06..727aa06d3b 100644 --- a/src_c/window.c +++ b/src_c/window.c @@ -923,6 +923,12 @@ window_init(pgWindowObject *self, PyObject *args, PyObject *kwargs) } } else if (!strcmp(_key_str, "foreign")) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "The foreign kwarg has been deprecated " + "and may be removed in a future version", + 1) == -1) { + return -1; + } if (_value_bool) { flags |= SDL_WINDOW_FOREIGN; } From fae899bd0cfaba14785550a1f855e9961cbfaad8 Mon Sep 17 00:00:00 2001 From: Ankith Date: Fri, 22 Nov 2024 22:56:17 +0530 Subject: [PATCH 33/44] Deprecate input_only argument --- docs/reST/ref/window.rst | 5 ++++- src_c/window.c | 6 ++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/docs/reST/ref/window.rst b/docs/reST/ref/window.rst index 9b18406a80..81352fee3c 100644 --- a/docs/reST/ref/window.rst +++ b/docs/reST/ref/window.rst @@ -403,7 +403,10 @@ :param bool input_only: if ``True``, the window will be given input focus but may be completely obscured by other windows. - Only supported on X11. + Only supported on X11. This has been deprecated and + may be removed in a future version. + + .. deprecated:: 2.5.3 ``input_only`` argument .. method:: restore diff --git a/src_c/window.c b/src_c/window.c index 727aa06d3b..5fe7ca90d2 100644 --- a/src_c/window.c +++ b/src_c/window.c @@ -289,6 +289,12 @@ window_focus(pgWindowObject *self, PyObject *args, PyObject *kwargs) return NULL; } if (input_only) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "The input_only kwarg has been deprecated and may be " + "removed in a future version", + 1) == -1) { + return NULL; + } if (SDL_SetWindowInputFocus(self->_win)) { return RAISE(pgExc_SDLError, SDL_GetError()); } From 6ba909ba3bafc7178aba92b461f5ebd351d0df94 Mon Sep 17 00:00:00 2001 From: Starbuck5 <46412508+Starbuck5@users.noreply.github.com> Date: Sun, 24 Nov 2024 22:52:06 -0800 Subject: [PATCH 34/44] Remove unnecessary calls to PyNumber_Index, PyLong_Checks --- src_c/pixelarray.c | 20 ++++---------------- src_c/rect_impl.h | 19 ++----------------- 2 files changed, 6 insertions(+), 33 deletions(-) diff --git a/src_c/pixelarray.c b/src_c/pixelarray.c index 53c32a41f5..f13c604553 100644 --- a/src_c/pixelarray.c +++ b/src_c/pixelarray.c @@ -1666,15 +1666,9 @@ _pxarray_subscript(pgPixelArrayObject *array, PyObject *op) return _pxarray_subscript_internal(array, start, stop, step, 0, dim1, 1); } - else if (PyIndex_Check(op) || PyLong_Check(op)) { - Py_ssize_t i; - PyObject *val = PyNumber_Index(op); - if (!val) { - return 0; - } + else if (PyIndex_Check(op)) { /* A simple index. */ - i = PyNumber_AsSsize_t(val, PyExc_IndexError); - Py_DECREF(val); + Py_ssize_t i = PyNumber_AsSsize_t(op, PyExc_IndexError); if (i == -1 && PyErr_Occurred()) { return 0; } @@ -1828,15 +1822,9 @@ _pxarray_ass_subscript(pgPixelArrayObject *array, PyObject *op, Py_DECREF(tmparray); return retval; } - else if (PyIndex_Check(op) || PyLong_Check(op)) { - Py_ssize_t i; - PyObject *val = PyNumber_Index(op); - if (!val) { - return -1; - } + else if (PyIndex_Check(op)) { /* A simple index. */ - i = PyNumber_AsSsize_t(val, PyExc_IndexError); - Py_DECREF(val); + Py_ssize_t i = PyNumber_AsSsize_t(op, PyExc_IndexError); if (i == -1 && PyErr_Occurred()) { return -1; } diff --git a/src_c/rect_impl.h b/src_c/rect_impl.h index 3f4084ff9c..0deafbcef4 100644 --- a/src_c/rect_impl.h +++ b/src_c/rect_impl.h @@ -2160,14 +2160,7 @@ RectExport_subscript(RectObject *self, PyObject *op) PrimitiveType *data = (PrimitiveType *)&self->r; if (PyIndex_Check(op)) { - PyObject *index = PyNumber_Index(op); - Py_ssize_t i; - - if (index == NULL) { - return NULL; - } - i = PyNumber_AsSsize_t(index, NULL); - Py_DECREF(index); + Py_ssize_t i = PyNumber_AsSsize_t(op, NULL); return RectExport_item(self, i); } else if (op == Py_Ellipsis) { @@ -2213,15 +2206,7 @@ RectExport_assSubscript(RectObject *self, PyObject *op, PyObject *value) return -1; } if (PyIndex_Check(op)) { - PyObject *index; - Py_ssize_t i; - - index = PyNumber_Index(op); - if (index == NULL) { - return -1; - } - i = PyNumber_AsSsize_t(index, NULL); - Py_DECREF(index); + Py_ssize_t i = PyNumber_AsSsize_t(op, NULL); return RectExport_assItem(self, i, value); } else if (op == Py_Ellipsis) { From e21bcc131191016e702375c35e364802f39b6381 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Nov 2024 06:54:20 +0000 Subject: [PATCH 35/44] Bump docker/metadata-action from 5.5.1 to 5.6.1 Bumps [docker/metadata-action](https://github.com/docker/metadata-action) from 5.5.1 to 5.6.1. - [Release notes](https://github.com/docker/metadata-action/releases) - [Commits](https://github.com/docker/metadata-action/compare/8e5442c4ef9f78752691e2d8f8d19755c6f78e81...369eb591f429131d6889c46b94e711f089e6ca96) --- updated-dependencies: - dependency-name: docker/metadata-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/build-manylinux.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-manylinux.yml b/.github/workflows/build-manylinux.yml index b3bda630ad..964569e0e7 100644 --- a/.github/workflows/build-manylinux.yml +++ b/.github/workflows/build-manylinux.yml @@ -68,7 +68,7 @@ jobs: - name: Extract metadata (tags, labels) for Docker id: meta - uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81 + uses: docker/metadata-action@369eb591f429131d6889c46b94e711f089e6ca96 with: images: ghcr.io/${{ github.repository }}_${{ matrix.arch }} tags: type=raw,value=${{ hashFiles('buildconfig/manylinux-build/**') }} From 7fe97ddded9cb825bd96fe36c1255488d0d8f627 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Nov 2024 06:54:17 +0000 Subject: [PATCH 36/44] Bump pypa/cibuildwheel from 2.21.3 to 2.22.0 Bumps [pypa/cibuildwheel](https://github.com/pypa/cibuildwheel) from 2.21.3 to 2.22.0. - [Release notes](https://github.com/pypa/cibuildwheel/releases) - [Changelog](https://github.com/pypa/cibuildwheel/blob/main/docs/changelog.md) - [Commits](https://github.com/pypa/cibuildwheel/compare/v2.21.3...v2.22.0) --- updated-dependencies: - dependency-name: pypa/cibuildwheel dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/build-macos.yml | 2 +- .github/workflows/build-manylinux.yml | 2 +- .github/workflows/build-windows.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-macos.yml b/.github/workflows/build-macos.yml index 23e304285f..769f92499a 100644 --- a/.github/workflows/build-macos.yml +++ b/.github/workflows/build-macos.yml @@ -138,7 +138,7 @@ jobs: uv-version: "0.4.10" - name: Build and test wheels - uses: pypa/cibuildwheel@v2.21.3 + uses: pypa/cibuildwheel@v2.22.0 - uses: actions/upload-artifact@v4 with: diff --git a/.github/workflows/build-manylinux.yml b/.github/workflows/build-manylinux.yml index 964569e0e7..a61fa3dfec 100644 --- a/.github/workflows/build-manylinux.yml +++ b/.github/workflows/build-manylinux.yml @@ -91,7 +91,7 @@ jobs: CIBW_MANYLINUX_I686_IMAGE: ghcr.io/${{ github.repository }}_i686:${{ steps.meta.outputs.version }} CIBW_MANYLINUX_PYPY_I686_IMAGE: ghcr.io/${{ github.repository }}_i686:${{ steps.meta.outputs.version }} - uses: pypa/cibuildwheel@v2.21.3 + uses: pypa/cibuildwheel@v2.22.0 # We upload the generated files under github actions assets - name: Upload dist diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml index d868bfabce..f7f72ac9b7 100644 --- a/.github/workflows/build-windows.yml +++ b/.github/workflows/build-windows.yml @@ -62,7 +62,7 @@ jobs: uv-version: "0.4.10" - name: Build and test wheels - uses: pypa/cibuildwheel@v2.21.3 + uses: pypa/cibuildwheel@v2.22.0 - uses: actions/upload-artifact@v4 with: From 1234c84bfe7ae2d080e3a80fa55b5cdde356d5ca Mon Sep 17 00:00:00 2001 From: Ankith Date: Tue, 26 Nov 2024 00:56:05 +0530 Subject: [PATCH 37/44] Sync docker base images to cibuildwheel --- buildconfig/manylinux-build/docker_base/Dockerfile-aarch64 | 2 +- buildconfig/manylinux-build/docker_base/Dockerfile-i686 | 2 +- buildconfig/manylinux-build/docker_base/Dockerfile-x86_64 | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/buildconfig/manylinux-build/docker_base/Dockerfile-aarch64 b/buildconfig/manylinux-build/docker_base/Dockerfile-aarch64 index 061bd1da33..8092c9d070 100644 --- a/buildconfig/manylinux-build/docker_base/Dockerfile-aarch64 +++ b/buildconfig/manylinux-build/docker_base/Dockerfile-aarch64 @@ -1,5 +1,5 @@ # pin version on image for CI stability -FROM quay.io/pypa/manylinux2014_aarch64:2024.10.07-1 +FROM quay.io/pypa/manylinux2014_aarch64:2024.11.16-1 ENV MAKEFLAGS="-j 2" ENV PG_DEP_PREFIX="/usr/local" diff --git a/buildconfig/manylinux-build/docker_base/Dockerfile-i686 b/buildconfig/manylinux-build/docker_base/Dockerfile-i686 index 86d901c9c8..46541c63de 100644 --- a/buildconfig/manylinux-build/docker_base/Dockerfile-i686 +++ b/buildconfig/manylinux-build/docker_base/Dockerfile-i686 @@ -1,5 +1,5 @@ # pin version on image for CI stability -FROM quay.io/pypa/manylinux2014_i686:2024.10.07-1 +FROM quay.io/pypa/manylinux2014_i686:2024.11.16-1 ENV MAKEFLAGS="-j 2" ENV PG_DEP_PREFIX="/usr/local" diff --git a/buildconfig/manylinux-build/docker_base/Dockerfile-x86_64 b/buildconfig/manylinux-build/docker_base/Dockerfile-x86_64 index 1ffe460e8d..78090eed02 100644 --- a/buildconfig/manylinux-build/docker_base/Dockerfile-x86_64 +++ b/buildconfig/manylinux-build/docker_base/Dockerfile-x86_64 @@ -1,5 +1,5 @@ # pin version on image for CI stability -FROM quay.io/pypa/manylinux2014_x86_64:2024.10.07-1 +FROM quay.io/pypa/manylinux2014_x86_64:2024.11.16-1 ENV MAKEFLAGS="-j 2" ENV PG_DEP_PREFIX="/usr/local" From f35dc0c693855ca0d6207f23f636f5fd7e80c3e8 Mon Sep 17 00:00:00 2001 From: Ankith Date: Tue, 26 Nov 2024 00:56:45 +0530 Subject: [PATCH 38/44] Bump cibw on circleci --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index d8212fbe8b..3777927445 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -42,7 +42,7 @@ jobs: - run: name: Build the Linux wheels. command: | - pip3 install --user cibuildwheel==2.21.3 + pip3 install --user cibuildwheel==2.22.0 PATH="$HOME/.local/bin:$PATH" cibuildwheel --output-dir wheelhouse - store_artifacts: From 4f34cafeb31a81a5ea50b7dc98eea312a4543633 Mon Sep 17 00:00:00 2001 From: Ankith Date: Tue, 26 Nov 2024 14:34:31 +0530 Subject: [PATCH 39/44] Remove unneeded pkgconfig install to fix fail --- .github/workflows/build-macos.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/build-macos.yml b/.github/workflows/build-macos.yml index 769f92499a..b5dabf38b7 100644 --- a/.github/workflows/build-macos.yml +++ b/.github/workflows/build-macos.yml @@ -64,7 +64,7 @@ jobs: if: steps.macdep-cache.outputs.cache-hit != 'true' run: | export MAC_ARCH="${{ matrix.macarch }}" - brew install coreutils pkg-config + brew install coreutils cd buildconfig/macdependencies bash ./build_mac_deps.sh @@ -104,7 +104,6 @@ jobs: # Setup macOS dependencies CIBW_BEFORE_ALL: | - brew install pkg-config cd buildconfig/macdependencies cp -r ${{ github.workspace }}/pygame_mac_deps_${{ matrix.macarch }} ${{ github.workspace }}/pygame_mac_deps bash ./install_mac_deps.sh From b7eed5f40eb1b371a93ab907c6ed1cd8295ea7b2 Mon Sep 17 00:00:00 2001 From: Starbuck5 <46412508+Starbuck5@users.noreply.github.com> Date: Tue, 26 Nov 2024 23:07:50 -0800 Subject: [PATCH 40/44] Error check PyNumber_AsSsize_t in rect_impl.h --- src_c/rect_impl.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src_c/rect_impl.h b/src_c/rect_impl.h index 0deafbcef4..27df1bc315 100644 --- a/src_c/rect_impl.h +++ b/src_c/rect_impl.h @@ -2161,6 +2161,9 @@ RectExport_subscript(RectObject *self, PyObject *op) if (PyIndex_Check(op)) { Py_ssize_t i = PyNumber_AsSsize_t(op, NULL); + if (i == -1 && PyErr_Occurred()) { + return NULL; + } return RectExport_item(self, i); } else if (op == Py_Ellipsis) { @@ -2207,6 +2210,9 @@ RectExport_assSubscript(RectObject *self, PyObject *op, PyObject *value) } if (PyIndex_Check(op)) { Py_ssize_t i = PyNumber_AsSsize_t(op, NULL); + if (i == -1 && PyErr_Occurred()) { + return -1; + } return RectExport_assItem(self, i, value); } else if (op == Py_Ellipsis) { From 1618b9573ed0479b038a2ff1e5b25ef4c585540d Mon Sep 17 00:00:00 2001 From: sonotopes <105621535+sonotopes@users.noreply.github.com> Date: Thu, 28 Nov 2024 20:54:22 -0500 Subject: [PATCH 41/44] updated sys.platform check for linux since 'in' operator is no longer needed. --- src_py/camera.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src_py/camera.py b/src_py/camera.py index 2a5db6c4f2..5aa8eb7374 100644 --- a/src_py/camera.py +++ b/src_py/camera.py @@ -114,7 +114,7 @@ def get_backends(): if sys.platform == "win32" and int(platform.win32_ver()[0].split(".")[0]) >= 8: possible_backends.append("_camera (MSMF)") - if "linux" in sys.platform: + if sys.platform == "linux": possible_backends.append("_camera (V4L2)") if "darwin" in sys.platform: From b77bf55fee5f01415135f0b4e003510ade8cbbf8 Mon Sep 17 00:00:00 2001 From: Axlor <91232098+MrRedstone058@users.noreply.github.com> Date: Mon, 2 Dec 2024 03:35:36 +0800 Subject: [PATCH 42/44] Added ```Line``` methods and ```length``` attribute (#3179) * Added Line methods and 'length: attribute * fixed minor checks * Update geometry.pyi * commit geometry.Line changes * changed geometry docs * changed docs, if_else statements and decluttered * Compacted geometry_common.c * Update geometry_common.c * Update line.c --------- Co-authored-by: Emc2356 <63981925+emc2356@users.noreply.github.com> Co-authored-by: NovialRiptide <35881688+novialriptide@users.noreply.github.com> Co-authored-by: ScriptLineStudios Co-authored-by: Avaxar <44055981+avaxar@users.noreply.github.com> Co-authored-by: maqa41 Co-authored-by: itzpr3d4t0r <103119829+itzpr3d4t0r@users.noreply.github.com> --- buildconfig/stubs/pygame/geometry.pyi | 26 +++ docs/reST/ref/geometry.rst | 143 ++++++++++++++++- src_c/doc/geometry_doc.h | 8 + src_c/geometry_common.c | 58 ++++--- src_c/geometry_common.h | 4 + src_c/line.c | 180 ++++++++++++++++++++- test/geometry_test.py | 220 ++++++++++++++++++++++++++ 7 files changed, 609 insertions(+), 30 deletions(-) diff --git a/buildconfig/stubs/pygame/geometry.pyi b/buildconfig/stubs/pygame/geometry.pyi index efbf54a23a..7e3884f228 100644 --- a/buildconfig/stubs/pygame/geometry.pyi +++ b/buildconfig/stubs/pygame/geometry.pyi @@ -163,6 +163,8 @@ class Line: def b(self) -> tuple[float, float]: ... @b.setter def b(self, value: Point) -> None: ... + @property + def length(self) -> float: ... @overload def __init__(self, ax: float, ay: float, bx: float, by: float) -> None: ... @overload @@ -171,3 +173,27 @@ class Line: def __init__(self, line: _LineLike) -> None: ... def __copy__(self) -> Line: ... def copy(self) -> Line: ... + @overload + def update(self, ax: float, ay: float, bx: float, by: float, /) -> None: ... + @overload + def update(self, a: Point, b: Point, /) -> None: ... + @overload + def update(self, line: _LineLike, /) -> None: ... + @overload + def move(self, x: float, y: float, /) -> Line: ... + @overload + def move(self, move_by: Point, /) -> Line: ... + @overload + def move_ip(self, x: float, y: float, /) -> None: ... + @overload + def move_ip(self, move_by: Point, /) -> None: ... + @overload + def scale(self, factor: float, origin: float, /) -> Line: ... + @overload + def scale(self, factor_and_origin: Tuple[float, float], /) -> Line: ... + @overload + def scale_ip(self, factor: float, origin: float, /) -> None: ... + @overload + def scale_ip(self, factor_and_origin: Tuple[float, float], /) -> None: ... + def flip_ab(self) -> Line: ... + def flip_ab_ip(self) -> None: ... diff --git a/docs/reST/ref/geometry.rst b/docs/reST/ref/geometry.rst index c6b3b99021..12ffc5ec9f 100644 --- a/docs/reST/ref/geometry.rst +++ b/docs/reST/ref/geometry.rst @@ -98,7 +98,7 @@ | :sl:`x and y coordinates of the center of the circle` | :sg:`center -> (float, float)` - It's a tuple containing the circle's `x` and `y` coordinates representing its center. + A tuple containing the circle's `x` and `y` coordinates representing its center. Reassigning it moves the circle to the new position. .. versionadded:: 2.4.0 @@ -147,7 +147,7 @@ | :sl:`top coordinate of the circle` | :sg:`top -> (float, float)` - It's a tuple containing the `x` and `y` coordinates that represent the top + A tuple containing the `x` and `y` coordinates that represent the top of the circle. Reassigning it moves the circle to the new position. The radius will not be affected. @@ -160,7 +160,7 @@ | :sl:`bottom coordinate of the circle` | :sg:`bottom -> (float, float)` - It's a tuple containing the `x` and `y` coordinates that represent the bottom + A tuple containing the `x` and `y` coordinates that represent the bottom of the circle. Reassigning it moves the circle to the new position. The radius will not be affected. @@ -173,7 +173,7 @@ | :sl:`left coordinate of the circle` | :sg:`left -> (float, float)` - It's a tuple containing the `x` and `y` coordinates that represent the left + A tuple containing the `x` and `y` coordinates that represent the left of the circle. Reassigning it moves the circle to the new position. The radius will not be affected. @@ -186,7 +186,7 @@ | :sl:`right coordinate of the circle` | :sg:`right -> (float, float)` - It's a tuple containing the `x` and `y` coordinates that represent the right + A tuple containing the `x` and `y` coordinates that represent the right of the circle. Reassigning it moves the circle to the new position. The radius will not be affected. @@ -574,7 +574,7 @@ | :sl:`the first point of the line` | :sg:`a -> (float, float)` - It's a tuple containing the `ax` and `ay` attributes representing the line's first point. + A tuple containing the `ax` and `ay` attributes representing the line's first point. It can be reassigned to move the `Line`. If reassigned the `ax` and `ay` attributes will be changed to produce a `Line` with matching first point position. The `bx` and `by` attributes will not be affected. @@ -588,7 +588,7 @@ | :sl:`the second point of the line` | :sg:`b -> (float, float)` - It's a tuple containing `bx` and `by` attributes representing the line's second point. + A tuple containing `bx` and `by` attributes representing the line's second point. It can be reassigned to move the `Line`. If reassigned the `bx` and `by` attributes will be changed to produce a `Line` with matching second point position. The `ax` and `ay` attributes will not be affected. @@ -597,6 +597,19 @@ .. ## Line.b ## + .. attribute:: length + + | :sl:`the length of the line` + | :sg:`length -> float` + + The length of the line. Calculated using the `sqrt((bx-ax)**2 + (by-ay)**2)` formula. + This attribute is read-only, it cannot be reassigned. To change the line's length + use the `scale` method or change its `a` or `b` attributes. + + .. versionadded:: 2.5.3 + + .. ## Line.length ## + **Line Methods** ---- @@ -611,3 +624,119 @@ .. versionadded:: 2.5.2 .. ## Line.copy ## + + .. method:: move + + | :sl:`moves the line by a given amount` + | :sg:`move((x, y)) -> Line` + | :sg:`move(x, y) -> Line` + + Returns a new `Line` that is moved by the given offset. The original `Line` is + not modified. + + This method is equivalent to the following code: + + .. code-block:: python + + Line(line.ax + x, line.ay + y, line.bx + x, line.by + y) + + .. versionadded:: 2.5.3 + + .. ## Line.move ## + + .. method:: move_ip + + | :sl:`moves the line by a given amount` + | :sg:`move_ip((x, y)) -> None` + | :sg:`move_ip(x, y) -> None` + + Moves the `Line` by the given offset. The original `Line` is modified. Always returns + `None`. + + This method is equivalent to the following code: + + .. code-block:: python + + line.ax += x + line.ay += y + line.bx += x + line.by += y + + .. versionadded:: 2.5.3 + + .. ## Line.move_ip ## + + .. method:: update + + | :sl:`updates the line's attributes` + | :sg:`update((ax, ay), (bx, by)) -> None` + | :sg:`update(ax, ay, bx, by) -> None` + | :sg:`update(line) -> None` + + Updates the `Line`'s attributes. The original `Line` is modified. Always returns `None`. + + This method is equivalent to the following code: + + .. code-block:: python + + line.ax = ax + line.ay = ay + line.bx = bx + line.by = by + + .. versionadded:: 2.5.3 + + .. ## Line.update ## + + .. method:: scale + + | :sl:`scales the line by the given factor from the given origin` + | :sg:`scale(factor, origin) -> Line` + | :sg:`scale(factor_and_origin) -> Line` + + Returns a new `Line` which is scaled by the given factor from the specified origin with 0.0 being + the starting point, 0.5 being the center and 1.0 being the end point. + The original `Line` is not modified. + + .. versionadded:: 2.5.3 + + .. ## Line.scale ## + + .. method:: scale_ip + + | :sl:`scales the line by the given factor from the given origin in place` + | :sg:`scale_ip(factor, origin) -> None` + | :sg:`scale_ip(factor_and_origin) -> None` + + Scales the `Line` by the given factor from the specified origin with 0.0 being + the starting point, 0.5 being the center and 1.0 being the end point. + The original `Line` is modified. + Always returns `None`. + + .. versionadded:: 2.5.3 + + .. ## Line.scale_ip ## + + .. method:: flip_ab + + | :sl:`flips the line a and b points` + | :sg:`flip_ab() -> Line` + + Returns a new `Line` that has the `a` and `b` points flipped. + The original `Line` is not modified. + + .. versionadded:: 2.5.3 + + .. ## Line.flip_ab ## + + .. method:: flip_ab_ip + + | :sl:`flips the line a and b points, in place` + | :sg:`flip_ab_ip() -> None` + + Flips the `Line`'s `a` and `b` points. The original `Line` is modified. + Always returns `None`. + + .. versionadded:: 2.5.3 + + .. ## Line.flip_ab_ip ## diff --git a/src_c/doc/geometry_doc.h b/src_c/doc/geometry_doc.h index dc2b2a0f1a..7873df226f 100644 --- a/src_c/doc/geometry_doc.h +++ b/src_c/doc/geometry_doc.h @@ -36,4 +36,12 @@ #define DOC_LINE_BY "by -> float\ny coordinate of the end point of the line" #define DOC_LINE_A "a -> (float, float)\nthe first point of the line" #define DOC_LINE_B "b -> (float, float)\nthe second point of the line" +#define DOC_LINE_LENGTH "length -> float\nthe length of the line" #define DOC_LINE_COPY "copy() -> Line\ncopies the line" +#define DOC_LINE_MOVE "move((x, y)) -> Line\nmove(x, y) -> Line\nmoves the line by a given amount" +#define DOC_LINE_MOVEIP "move_ip((x, y)) -> None\nmove_ip(x, y) -> None\nmoves the line by a given amount" +#define DOC_LINE_UPDATE "update((ax, ay), (bx, by)) -> None\nupdate(ax, ay, bx, by) -> None\nupdate(line) -> None\nupdates the line's attributes" +#define DOC_LINE_SCALE "scale(factor, origin) -> Line\nscale(factor_and_origin) -> Line\nscales the line by the given factor from the given origin" +#define DOC_LINE_SCALEIP "scale_ip(factor, origin) -> None\nscale_ip(factor_and_origin) -> None\nscales the line by the given factor from the given origin in place" +#define DOC_LINE_FLIPAB "flip_ab() -> Line\nflips the line a and b points" +#define DOC_LINE_FLIPABIP "flip_ab_ip() -> None\nflips the line a and b points, in place" diff --git a/src_c/geometry_common.c b/src_c/geometry_common.c index 4e25c32d9e..7d426fc0b0 100644 --- a/src_c/geometry_common.c +++ b/src_c/geometry_common.c @@ -162,29 +162,23 @@ pgLine_FromObject(PyObject *obj, pgLineBase *out) length = PySequence_Fast_GET_SIZE(obj); PyObject **farray = PySequence_Fast_ITEMS(obj); - if (length == 4) { - if (!pg_DoubleFromObj(farray[0], &out->ax) || - !pg_DoubleFromObj(farray[1], &out->ay) || - !pg_DoubleFromObj(farray[2], &out->bx) || - !pg_DoubleFromObj(farray[3], &out->by)) { - return 0; - } - return 1; - } - else if (length == 2) { - if (!pg_TwoDoublesFromObj(farray[0], &out->ax, &out->ay) || - !pg_TwoDoublesFromObj(farray[1], &out->bx, &out->by)) { - PyErr_Clear(); + switch (length) { + case 4: + return pg_DoubleFromObj(farray[0], &out->ax) && + pg_DoubleFromObj(farray[1], &out->ay) && + pg_DoubleFromObj(farray[2], &out->bx) && + pg_DoubleFromObj(farray[3], &out->by); + case 2: + return pg_TwoDoublesFromObj(farray[0], &out->ax, &out->ay) && + pg_TwoDoublesFromObj(farray[1], &out->bx, &out->by); + case 1: /*looks like an arg?*/ + if (PyUnicode_Check(farray[0]) || + !pgLine_FromObject(farray[0], out)) { + return 0; + } + return 1; + default: return 0; - } - return 1; - } - else if (length == 1) /*looks like an arg?*/ { - if (PyUnicode_Check(farray[0]) || - !pgLine_FromObject(farray[0], out)) { - return 0; - } - return 1; } } else if (PySequence_Check(obj)) { @@ -276,6 +270,26 @@ pgLine_FromObject(PyObject *obj, pgLineBase *out) return 1; } +int +pgLine_FromObjectFastcall(PyObject *const *args, Py_ssize_t nargs, + pgLineBase *out) +{ + switch (nargs) { + case 1: + return pgLine_FromObject(args[0], out); + case 2: + return pg_TwoDoublesFromObj(args[0], &out->ax, &out->ay) && + pg_TwoDoublesFromObj(args[1], &out->bx, &out->by); + case 4: + return pg_DoubleFromObj(args[0], &out->ax) && + pg_DoubleFromObj(args[1], &out->ay) && + pg_DoubleFromObj(args[2], &out->bx) && + pg_DoubleFromObj(args[3], &out->by); + default: + return 0; + } +} + static inline int double_compare(double a, double b) { diff --git a/src_c/geometry_common.h b/src_c/geometry_common.h index 8ecc9b259a..9bff7f242a 100644 --- a/src_c/geometry_common.h +++ b/src_c/geometry_common.h @@ -16,6 +16,10 @@ pgCircle_FromObjectFastcall(PyObject *const *args, Py_ssize_t nargs, int pgLine_FromObject(PyObject *obj, pgLineBase *out); +int +pgLine_FromObjectFastcall(PyObject *const *args, Py_ssize_t nargs, + pgLineBase *out); + static inline int double_compare(double a, double b); diff --git a/src_c/line.c b/src_c/line.c index 93987e946d..2b61906fbf 100644 --- a/src_c/line.c +++ b/src_c/line.c @@ -1,6 +1,14 @@ #include "doc/geometry_doc.h" #include "geometry_common.h" +static double +pgLine_Length(pgLineBase *line) +{ + double dx = line->bx - line->ax; + double dy = line->by - line->ay; + return sqrt(dx * dx + dy * dy); +} + static PyObject * _pg_line_subtype_new4(PyTypeObject *type, double ax, double ay, double bx, double by) @@ -40,7 +48,7 @@ pg_line_dealloc(pgLineObject *self) static int pg_line_init(pgLineObject *self, PyObject *args, PyObject *kwds) { - if (!pgLine_FromObject(args, &(self->line))) { + if (!pgLine_FromObject(args, &self->line)) { PyErr_SetString(PyExc_TypeError, "Invalid line end points, expected 4 " "numbers or 2 sequences of 2 numbers"); @@ -49,6 +57,12 @@ pg_line_init(pgLineObject *self, PyObject *args, PyObject *kwds) return 0; } +static PyObject * +pgLine_New(pgLineBase *l) +{ + return _pg_line_subtype_new4(&pgLine_Type, l->ax, l->ay, l->bx, l->by); +} + static PyObject * pg_line_copy(pgLineObject *self, PyObject *_null) { @@ -56,9 +70,166 @@ pg_line_copy(pgLineObject *self, PyObject *_null) self->line.bx, self->line.by); } +static PyObject * +pg_line_update(pgLineObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + if (!pgLine_FromObjectFastcall(args, nargs, &self->line)) { + return RAISE(PyExc_TypeError, + "Line.update requires a line or LineLike object"); + } + Py_RETURN_NONE; +} + +static PyObject * +pg_line_move(pgLineObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + double Dx, Dy; + + if (!pg_TwoDoublesFromFastcallArgs(args, nargs, &Dx, &Dy)) { + return RAISE(PyExc_TypeError, "move requires a pair of numbers"); + } + + return _pg_line_subtype_new4(Py_TYPE(self), self->line.ax + Dx, + self->line.ay + Dy, self->line.bx + Dx, + self->line.by + Dy); +} + +static PyObject * +pg_line_move_ip(pgLineObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + double Dx, Dy; + + if (!pg_TwoDoublesFromFastcallArgs(args, nargs, &Dx, &Dy)) { + return RAISE(PyExc_TypeError, "move_ip requires a pair of numbers"); + } + + self->line.ax += Dx; + self->line.ay += Dy; + self->line.bx += Dx; + self->line.by += Dy; + + Py_RETURN_NONE; +} + +static PyObject * +pg_line_flip(pgLineObject *self, PyObject *_null) +{ + return _pg_line_subtype_new4(Py_TYPE(self), self->line.bx, self->line.by, + self->line.ax, self->line.ay); +} + +static PyObject * +pg_line_flip_ab_ip(pgLineObject *self, PyObject *_null) +{ + double tx = self->line.bx; + double ty = self->line.by; + + self->line.bx = self->line.ax; + self->line.by = self->line.ay; + + self->line.ax = tx; + self->line.ay = ty; + + Py_RETURN_NONE; +} + +static PG_FORCEINLINE double +_lerp_helper(double start, double end, double amount) +{ + return start + (end - start) * amount; +} + +static int +_line_scale_helper(pgLineBase *line, double factor, double origin) +{ + if (factor == 1.0) { + return 1; + } + else if (factor <= 0.0) { + PyErr_SetString(PyExc_ValueError, + "Can only scale by a positive non zero number"); + return 0; + } + + if (origin < 0.0 || origin > 1.0) { + PyErr_SetString(PyExc_ValueError, "Origin must be between 0 and 1"); + return 0; + } + + double ax = line->ax; + double ay = line->ay; + double bx = line->bx; + double by = line->by; + + double x1_factor = ax * factor; + double y1_factor = ay * factor; + double x2_factor = bx * factor; + double y2_factor = by * factor; + + double fac_m_one = factor - 1; + double dx = _lerp_helper(fac_m_one * ax, fac_m_one * bx, origin); + double dy = _lerp_helper(fac_m_one * ay, fac_m_one * by, origin); + + line->ax = x1_factor - dx; + line->ay = y1_factor - dy; + line->bx = x2_factor - dx; + line->by = y2_factor - dy; + + return 1; +} + +static PyObject * +pg_line_scale(pgLineObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + double factor, origin; + + if (!pg_TwoDoublesFromFastcallArgs(args, nargs, &factor, &origin)) { + return RAISE(PyExc_TypeError, + "scale requires a sequence of two numbers"); + } + + PyObject *line; + if (!(line = pgLine_New(&self->line))) { + return NULL; + } + + if (!_line_scale_helper(&pgLine_AsLine(line), factor, origin)) { + Py_DECREF(line); + return NULL; + } + + return line; +} + +static PyObject * +pg_line_scale_ip(pgLineObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + double factor, origin; + + if (!pg_TwoDoublesFromFastcallArgs(args, nargs, &factor, &origin)) { + return RAISE(PyExc_TypeError, + "scale_ip requires a sequence of two numbers"); + } + + if (!_line_scale_helper(&pgLine_AsLine(self), factor, origin)) { + return NULL; + } + + Py_RETURN_NONE; +} + static struct PyMethodDef pg_line_methods[] = { {"__copy__", (PyCFunction)pg_line_copy, METH_NOARGS, DOC_LINE_COPY}, {"copy", (PyCFunction)pg_line_copy, METH_NOARGS, DOC_LINE_COPY}, + {"update", (PyCFunction)pg_line_update, METH_FASTCALL, DOC_LINE_UPDATE}, + {"move", (PyCFunction)pg_line_move, METH_FASTCALL, DOC_LINE_MOVE}, + {"move_ip", (PyCFunction)pg_line_move_ip, METH_FASTCALL, DOC_LINE_MOVEIP}, + {"flip_ab", (PyCFunction)pg_line_flip, METH_NOARGS, DOC_LINE_FLIPAB}, + {"flip_ab_ip", (PyCFunction)pg_line_flip_ab_ip, METH_NOARGS, + DOC_LINE_FLIPABIP}, + {"scale", (PyCFunction)pg_line_scale, METH_FASTCALL, DOC_LINE_SCALE}, + {"scale_ip", (PyCFunction)pg_line_scale_ip, METH_FASTCALL, + DOC_LINE_SCALEIP}, {NULL, NULL, 0, NULL}}; static PyObject * @@ -170,6 +341,12 @@ pg_line_setb(pgLineObject *self, PyObject *value, void *closure) return -1; } +static PyObject * +pg_line_getlength(pgLineObject *self, void *closure) +{ + return PyFloat_FromDouble(pgLine_Length(&self->line)); +} + static PyGetSetDef pg_line_getsets[] = { {"ax", (getter)pg_line_getax, (setter)pg_line_setax, DOC_LINE_AX, NULL}, {"ay", (getter)pg_line_getay, (setter)pg_line_setay, DOC_LINE_AY, NULL}, @@ -177,6 +354,7 @@ static PyGetSetDef pg_line_getsets[] = { {"by", (getter)pg_line_getby, (setter)pg_line_setby, DOC_LINE_BY, NULL}, {"a", (getter)pg_line_geta, (setter)pg_line_seta, DOC_LINE_A, NULL}, {"b", (getter)pg_line_getb, (setter)pg_line_setb, DOC_LINE_B, NULL}, + {"length", (getter)pg_line_getlength, NULL, DOC_LINE_LENGTH, NULL}, {NULL, 0, NULL, NULL, NULL}}; static PyTypeObject pgLine_Type = { diff --git a/test/geometry_test.py b/test/geometry_test.py index d2b5fceb50..445d57e2af 100644 --- a/test/geometry_test.py +++ b/test/geometry_test.py @@ -1967,6 +1967,56 @@ def test_attrib_b(self): with self.assertRaises(AttributeError): del line.b + def test_attrib_length(self): + """a full test for the length attribute""" + expected_length = 3.0 + line = Line(1, 4, 4, 4) + self.assertEqual(line.length, expected_length) + + line.ax = 2 + expected_length = 2.0 + self.assertEqual(line.length, expected_length) + + line.ax = 2.7 + expected_length = 1.2999999999999998 + self.assertAlmostEqual(line.length, expected_length) + + line.ay = 2 + expected_length = 2.3853720883753127 + self.assertAlmostEqual(line.length, expected_length) + + line.ay = 2.7 + expected_length = 1.8384776310850233 + self.assertAlmostEqual(line.length, expected_length) + + line.bx = 2 + expected_length = 1.4764823060233399 + self.assertAlmostEqual(line.length, expected_length) + + line.bx = 2.7 + expected_length = 1.2999999999999998 + self.assertAlmostEqual(line.length, expected_length) + + line.by = 2 + expected_length = 0.7000000000000002 + self.assertAlmostEqual(line.length, expected_length) + + line.by = 2.7 + expected_length = 0.0 + self.assertEqual(line.length, expected_length) + + line1 = Line(7, 3, 2, 3) + line2 = Line(9, 5, 4, 5) + self.assertEqual(line1.length, line2.length) + + line = Line(7.6, 3.2, 2.1, 3.8) + expected_length = 5.532630477449222 + self.assertAlmostEqual(line.length, expected_length) + + line = Line(-9.8, -5.2, -4.4, -5.6) + expected_length = 5.414794548272353 + self.assertAlmostEqual(line.length, expected_length) + def test_meth_copy(self): line = Line(1, 2, 3, 4) # check 1 arg passed @@ -1981,6 +2031,176 @@ def test_meth_copy(self): self.assertIsNot(line, line_2) + def test_meth_move(self): + line = Line(1.1, 2.2, 3.3, 4.4) + + ret = line.move(1, 2) + + self.assertEqual(ret.ax, 2.1) + self.assertEqual(ret.ay, 4.2) + self.assertEqual(ret.bx, 4.3) + self.assertEqual(ret.by, 6.4) + + with self.assertRaises(TypeError): + line.move() + + with self.assertRaises(TypeError): + line.move(1) + + with self.assertRaises(TypeError): + line.move(1, 2, 3) + + with self.assertRaises(TypeError): + line.move("1", "2") + + def test_meth_move_ip(self): + line = Line(1.1, 2.2, 3.3, 4.4) + + line.move_ip(1, 2) + + self.assertEqual(line.ax, 2.1) + self.assertEqual(line.ay, 4.2) + self.assertEqual(line.bx, 4.3) + self.assertEqual(line.by, 6.4) + + with self.assertRaises(TypeError): + line.move_ip() + + with self.assertRaises(TypeError): + line.move_ip(1) + + with self.assertRaises(TypeError): + line.move_ip(1, 2, 3) + + with self.assertRaises(TypeError): + line.move_ip("1", "2") + + def test_meth_scale(self): + line = Line(0, 0, 10, 0).scale(2, 0) + self.assertEqual(line.length, 20) + line = Line(0, 0, 20, 0).scale(2.1, 0) + self.assertEqual(line.length, 42) + line = Line(0, 0, 10, 0).scale(4, 0) + self.assertEqual(line.length, 40) + line = Line(0, 0, 10, 0).scale(3, 0) + self.assertEqual(line.length, 30) + line = Line(10, 10, 20, 20).scale(2, 0) + self.assertAlmostEqual(line.length, 28.284271247461902) + line = Line(10, 10, 20, 20).scale(2, 0.5) + self.assertAlmostEqual(line.length, 28.284271247461902) + line = Line(10, 10, 20, 20).scale(2, 1) + self.assertAlmostEqual(line.length, 28.284271247461902) + + with self.assertRaises(ValueError): + line = line.scale(0, 0.5) + + with self.assertRaises(ValueError): + line = line.scale(2, -0.1) + + with self.assertRaises(ValueError): + line = line.scale(-2, -0.5) + + with self.assertRaises(ValueError): + line = line.scale(17, 1.1) + + with self.assertRaises(ValueError): + line = line.scale(17, 10.0) + + def test_meth_scale_ip(self): + line = Line(0, 0, 10, 0) + line.scale_ip(2, 0) + self.assertEqual(line.length, 20) + line = Line(0, 0, 20, 0) + line.scale_ip(2.1, 0) + self.assertEqual(line.length, 42) + line = Line(0, 0, 10, 0) + line.scale_ip(4, 0) + self.assertEqual(line.length, 40) + line = Line(0, 0, 10, 0) + line.scale_ip(3, 0) + self.assertEqual(line.length, 30) + line = Line(10, 10, 20, 20) + line.scale_ip(2, 0) + self.assertAlmostEqual(line.length, 28.284271247461902) + line = Line(10, 10, 20, 20) + line.scale_ip(2, 0.5) + self.assertAlmostEqual(line.length, 28.284271247461902) + line = Line(10, 10, 20, 20) + line.scale_ip(2, 1.0) + self.assertAlmostEqual(line.length, 28.284271247461902) + + with self.assertRaises(ValueError): + line.scale_ip(0, 0.5) + + with self.assertRaises(ValueError): + line.scale_ip(2, -0.1) + + with self.assertRaises(ValueError): + line.scale_ip(-2, -0.5) + + with self.assertRaises(ValueError): + line.scale_ip(17, 1.1) + + with self.assertRaises(ValueError): + line.scale_ip(17, 10.0) + + def test_meth_flip(self): + line = Line(1.1, 2.2, 3.3, 4.4) + + ret = line.flip_ab() + + self.assertIsInstance(ret, Line) + self.assertEqual(ret.ax, 3.3) + self.assertEqual(ret.ay, 4.4) + self.assertEqual(ret.bx, 1.1) + self.assertEqual(ret.by, 2.2) + + with self.assertRaises(TypeError): + line.flip_ab(1) + + def test_meth_flip_ab_ip(self): + line = Line(1.1, 2.2, 3.3, 4.4) + + line.flip_ab_ip() + + self.assertEqual(line.ax, 3.3) + self.assertEqual(line.ay, 4.4) + self.assertEqual(line.bx, 1.1) + self.assertEqual(line.by, 2.2) + + with self.assertRaises(TypeError): + line.flip_ab_ip(1) + + def test_meth_update(self): + line = Line(0, 0, 1, 1) + + line.update(1, 2, 3, 4) + self.assertEqual(line.ax, 1) + self.assertEqual(line.ay, 2) + self.assertEqual(line.bx, 3) + self.assertEqual(line.by, 4) + + line.update((5, 6), (7, 8)) + self.assertEqual(line.ax, 5) + self.assertEqual(line.ay, 6) + self.assertEqual(line.bx, 7) + self.assertEqual(line.by, 8) + + line.update((9, 10, 11, 12)) + self.assertEqual(line.ax, 9) + self.assertEqual(line.ay, 10) + self.assertEqual(line.bx, 11) + self.assertEqual(line.by, 12) + + with self.assertRaises(TypeError): + line.update() + + with self.assertRaises(TypeError): + line.update(1, 2, 3, 4, 5) + + with self.assertRaises(TypeError): + line.update(1, 2, 3) + def test__str__(self): """Checks whether the __str__ method works correctly.""" l_str = "" From aec311d08713b1546787cad847e258c37da81a18 Mon Sep 17 00:00:00 2001 From: aatle <168398276+aatle@users.noreply.github.com> Date: Sun, 1 Dec 2024 13:12:12 -0800 Subject: [PATCH 43/44] Change Tuple[float, float] to Point in geometry.pyi --- buildconfig/stubs/pygame/geometry.pyi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/buildconfig/stubs/pygame/geometry.pyi b/buildconfig/stubs/pygame/geometry.pyi index 7e3884f228..8821f15e35 100644 --- a/buildconfig/stubs/pygame/geometry.pyi +++ b/buildconfig/stubs/pygame/geometry.pyi @@ -190,10 +190,10 @@ class Line: @overload def scale(self, factor: float, origin: float, /) -> Line: ... @overload - def scale(self, factor_and_origin: Tuple[float, float], /) -> Line: ... + def scale(self, factor_and_origin: Point, /) -> Line: ... @overload def scale_ip(self, factor: float, origin: float, /) -> None: ... @overload - def scale_ip(self, factor_and_origin: Tuple[float, float], /) -> None: ... + def scale_ip(self, factor_and_origin: Point, /) -> None: ... def flip_ab(self) -> Line: ... def flip_ab_ip(self) -> None: ... From af22ab8ee0b7256ab7a84159fb96256272410331 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Dec 2024 06:39:59 +0000 Subject: [PATCH 44/44] Bump docker/build-push-action from 6.9.0 to 6.10.0 Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6.9.0 to 6.10.0. - [Release notes](https://github.com/docker/build-push-action/releases) - [Commits](https://github.com/docker/build-push-action/compare/4f58ea79222b3b9dc2c8bbdd6debcef730109a75...48aba3b46d1b1fec4febb7c5d0c644b249a11355) --- updated-dependencies: - dependency-name: docker/build-push-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/build-manylinux.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-manylinux.yml b/.github/workflows/build-manylinux.yml index a61fa3dfec..ac5bd3666f 100644 --- a/.github/workflows/build-manylinux.yml +++ b/.github/workflows/build-manylinux.yml @@ -75,7 +75,7 @@ jobs: - name: Build and push Docker image if: steps.inspect.outcome == 'failure' - uses: docker/build-push-action@4f58ea79222b3b9dc2c8bbdd6debcef730109a75 + uses: docker/build-push-action@48aba3b46d1b1fec4febb7c5d0c644b249a11355 with: context: ${{ github.workspace }}/buildconfig/manylinux-build/docker_base file: ${{ github.workspace }}/buildconfig/manylinux-build/docker_base/Dockerfile-${{ matrix.arch }}