From 6feb62222b1e16fd24bf75618725335f5babb2cc Mon Sep 17 00:00:00 2001 From: Paul V Craven Date: Mon, 20 Apr 2026 12:36:32 -0500 Subject: [PATCH 1/5] Update pyglet dependency from 3.0.dev2 to 3.0.dev3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adapt to breaking API changes in pyglet 3.0.dev3: - OpenGLConfig → OpenGLUserConfig with GraphicsAPI enum - pyglet.media.load → load_audio/load_video - pyglet.gl module moved to pyglet.graphics.api.gl Co-Authored-By: Claude Opus 4.6 --- arcade/application.py | 15 +++++++++++---- arcade/examples/gui/exp_controller_inventory.py | 2 +- arcade/future/video/video_player.py | 2 +- arcade/gl/backends/opengl/context.py | 2 +- arcade/gl/context.py | 2 +- arcade/sound.py | 2 +- pyproject.toml | 2 +- 7 files changed, 17 insertions(+), 10 deletions(-) diff --git a/arcade/application.py b/arcade/application.py index e72554437..6e220166a 100644 --- a/arcade/application.py +++ b/arcade/application.py @@ -20,6 +20,7 @@ import pyglet.config import pyglet.window.mouse +from pyglet.config import GraphicsAPI from pyglet.display.base import Screen, ScreenMode from pyglet.event import EVENT_HANDLE_STATE, EVENT_UNHANDLED from pyglet.window import MouseCursor @@ -211,15 +212,21 @@ def __init__( self._pixel_perfect: bool = pixel_perfect """If True, ignore OS DPI scaling and use a 1:1 pixel ratio.""" + _GL_API_MAP = { + "opengl": GraphicsAPI.OPENGL, + "opengles": GraphicsAPI.OPENGL_ES_3, + } + config = None # Attempt to make window with antialiasing if gl_api == "opengl" or gl_api == "opengles": + graphics_api = _GL_API_MAP[gl_api] if antialiasing: try: - config = pyglet.config.OpenGLConfig( + config = pyglet.config.OpenGLUserConfig( major_version=gl_version[0], minor_version=gl_version[1], - opengl_api=gl_api.replace("open", ""), # type: ignore # pending: upstream fix + api=graphics_api, double_buffer=True, sample_buffers=1, samples=samples, @@ -236,10 +243,10 @@ def __init__( antialiasing = False # If we still don't have a config if not config: - config = pyglet.config.OpenGLConfig( + config = pyglet.config.OpenGLUserConfig( major_version=gl_version[0], minor_version=gl_version[1], - opengl_api=gl_api.replace("open", ""), # type: ignore # pending: upstream fix + api=graphics_api, double_buffer=True, depth_size=24, stencil_size=8, diff --git a/arcade/examples/gui/exp_controller_inventory.py b/arcade/examples/gui/exp_controller_inventory.py index 5359b8746..a65f89a08 100644 --- a/arcade/examples/gui/exp_controller_inventory.py +++ b/arcade/examples/gui/exp_controller_inventory.py @@ -18,7 +18,7 @@ import pyglet.font from pyglet.event import EVENT_HANDLED -from pyglet.gl import GL_NEAREST +from pyglet.graphics.api.gl import GL_NEAREST from pyglet.input import Controller import arcade diff --git a/arcade/future/video/video_player.py b/arcade/future/video/video_player.py index 8c61d896b..35bdc3583 100644 --- a/arcade/future/video/video_player.py +++ b/arcade/future/video/video_player.py @@ -25,7 +25,7 @@ class VideoPlayer: def __init__(self, path: str | Path, loop: bool = False): self.player = pyglet.media.VideoPlayer() self.player.loop = loop - self.player.queue(pyglet.media.load(str(arcade.resources.resolve(path)))) + self.player.queue(pyglet.media.load_video(str(arcade.resources.resolve(path)))) self.player.play() self.ctx = arcade.get_window().ctx diff --git a/arcade/gl/backends/opengl/context.py b/arcade/gl/backends/opengl/context.py index dab2fc70a..009937598 100644 --- a/arcade/gl/backends/opengl/context.py +++ b/arcade/gl/backends/opengl/context.py @@ -534,7 +534,7 @@ def get(self, enum, default=0) -> int: value = c_int() gl.glGetIntegerv(enum, value) return value.value - except pyglet.gl.lib.GLException: + except gl.lib.GLException: return default def get_float(self, enum, default=0.0) -> float: diff --git a/arcade/gl/context.py b/arcade/gl/context.py index 41131dc67..2466715cb 100644 --- a/arcade/gl/context.py +++ b/arcade/gl/context.py @@ -597,7 +597,7 @@ def blend_func(self) -> Tuple[int, int] | Tuple[int, int, int, int]: These enums can be accessed in the ``arcade.gl`` module or simply as attributes of the context object. - The raw enums from ``pyglet.gl`` can also be used. + The raw enums from ``pyglet.graphics.api.gl`` can also be used. Example:: diff --git a/arcade/sound.py b/arcade/sound.py index e401ba492..1ebfed06c 100644 --- a/arcade/sound.py +++ b/arcade/sound.py @@ -73,7 +73,7 @@ def __init__(self, file_name: str | Path, streaming: bool = False): raise FileNotFoundError(f"The sound file '{file_name}' is not a file or can't be read.") self.file_name = str(file_name) - self.source: Source = media.load(self.file_name, streaming=streaming) + self.source: Source = media.load_audio(self.file_name, streaming=streaming) """ The :py:class:`pyglet.media.Source` object that holds the audio data. """ diff --git a/pyproject.toml b/pyproject.toml index 7db78ad5f..723d6ba2c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -22,7 +22,7 @@ classifiers = [ dependencies = [ "pillow>=11.3.0", "pytiled-parser~=2.2.9", - "pyglet==3.0.dev2", + "pyglet==3.0.dev3", ] dynamic = ["version"] From daea82c085db52d95f053339999e5dc350076368 Mon Sep 17 00:00:00 2001 From: Paul V Craven Date: Mon, 20 Apr 2026 13:01:56 -0500 Subject: [PATCH 2/5] Update Sphinx to 9.1.0, RTD theme to 3.1.0, Pillow to >=12.2.0 Also patch pyglet LibraryMock to add __bool__/__iter__ so doc builds don't crash when ffmpeg codec init runs under sys.is_pyglet_doc_run. Co-Authored-By: Claude Opus 4.6 --- doc/conf.py | 7 +++++++ pyproject.toml | 6 +++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/doc/conf.py b/doc/conf.py index d8dd62815..2633b7b8a 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -52,6 +52,13 @@ # 2. The commit: https://github.com/pyglet/pyglet/commit/97076c3a33a7d368cc9c9e44ca67769b6a16a905 sys.is_pyglet_doc_run = True +# pyglet 3.0.dev3 LibraryMock lacks __iter__/__bool__, causing crashes +# when ffmpeg codec init calls get_input_extensions() during doc builds. +# Patch before any pyglet imports trigger media codec loading. +import pyglet.lib # noqa: E402 +pyglet.lib.LibraryMock.__bool__ = lambda self: False +pyglet.lib.LibraryMock.__iter__ = lambda self: iter([]) + # --- Pre-processing Tasks # Report our diagnostic info diff --git a/pyproject.toml b/pyproject.toml index 723d6ba2c..905e32e72 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,7 +20,7 @@ classifiers = [ "Topic :: Software Development :: Libraries :: Python Modules", ] dependencies = [ - "pillow>=11.3.0", + "pillow>=12.2.0", "pytiled-parser~=2.2.9", "pyglet==3.0.dev3", ] @@ -40,8 +40,8 @@ extras = [ ] # Used for dev work dev = [ - "sphinx==8.1.3", # April 2024 | Updated 2024-07-15, 7.4+ is broken with sphinx-autobuild - "sphinx_rtd_theme==3.0.2", # Nov 2024 + "sphinx==9.1.0", # April 2026 + "sphinx_rtd_theme==3.1.0", # April 2026 "sphinx-rtd-dark-mode==1.3.0", "sphinx-autobuild==2024.10.3", # April 2024 | Due to this, Python 3.10+ is required to serve docs "sphinx-copybutton==0.5.2", # April 2023 From 9d76cfc39a0d22204891b90f92a61bb6ca3490de Mon Sep 17 00:00:00 2001 From: Paul V Craven Date: Mon, 20 Apr 2026 13:07:28 -0500 Subject: [PATCH 3/5] Use arcade.gl.enums.NEAREST instead of pyglet GL import Per review feedback: pyglet.graphics.api.gl imports are backend-specific and would break WebGL. arcade.gl.enums is backend-agnostic. Co-Authored-By: Claude Opus 4.6 --- arcade/examples/gui/exp_controller_inventory.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arcade/examples/gui/exp_controller_inventory.py b/arcade/examples/gui/exp_controller_inventory.py index a65f89a08..9cc755111 100644 --- a/arcade/examples/gui/exp_controller_inventory.py +++ b/arcade/examples/gui/exp_controller_inventory.py @@ -18,10 +18,10 @@ import pyglet.font from pyglet.event import EVENT_HANDLED -from pyglet.graphics.api.gl import GL_NEAREST from pyglet.input import Controller import arcade +from arcade.gl.enums import NEAREST from arcade import Rect from arcade.examples.gui.exp_controller_support_grid import ( ControllerIndicator, @@ -412,8 +412,8 @@ def on_draw_before_ui(self): if __name__ == "__main__": # pixelate the font - pyglet.font.base.Font.texture_min_filter = GL_NEAREST # type: ignore - pyglet.font.base.Font.texture_mag_filter = GL_NEAREST # type: ignore + pyglet.font.base.Font.texture_min_filter = NEAREST # type: ignore + pyglet.font.base.Font.texture_mag_filter = NEAREST # type: ignore load_kenney_fonts() From 8f632a3ae5e5bf0ba45a36a9b36252f66bf12756 Mon Sep 17 00:00:00 2001 From: Paul V Craven Date: Mon, 20 Apr 2026 13:10:30 -0500 Subject: [PATCH 4/5] Revert Sphinx/RTD theme upgrade (requires Python >=3.12) Sphinx 9.1.0 requires Python >=3.12 but arcade supports >=3.10. Revert to Sphinx 8.1.3 and sphinx-rtd-theme 3.0.2. The LibraryMock patch in conf.py is still needed for pyglet 3.0.dev3 doc builds. Co-Authored-By: Claude Opus 4.6 --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 905e32e72..cacaf269c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -40,8 +40,8 @@ extras = [ ] # Used for dev work dev = [ - "sphinx==9.1.0", # April 2026 - "sphinx_rtd_theme==3.1.0", # April 2026 + "sphinx==8.1.3", # April 2024 | Updated 2024-07-15, 7.4+ is broken with sphinx-autobuild + "sphinx_rtd_theme==3.0.2", # Nov 2024 "sphinx-rtd-dark-mode==1.3.0", "sphinx-autobuild==2024.10.3", # April 2024 | Due to this, Python 3.10+ is required to serve docs "sphinx-copybutton==0.5.2", # April 2023 From 5483762352bfd8e715fcabcf2fc06d79e83bf43d Mon Sep 17 00:00:00 2001 From: Paul V Craven Date: Mon, 20 Apr 2026 13:47:48 -0500 Subject: [PATCH 5/5] Revert Pillow bump to keep pyodide/WASM compatibility Pyodide only ships Pillow 11.3.0 and PyPI doesn't support WASM wheels yet, so requiring >=12.2.0 would break web deployments. Co-Authored-By: Claude Opus 4.6 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index cacaf269c..723d6ba2c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,7 +20,7 @@ classifiers = [ "Topic :: Software Development :: Libraries :: Python Modules", ] dependencies = [ - "pillow>=12.2.0", + "pillow>=11.3.0", "pytiled-parser~=2.2.9", "pyglet==3.0.dev3", ]