Package: release.debian.org Severity: normal Tags: trixie X-Debbugs-Cc: [email protected] Control: affects -1 + src:pysiogame User: [email protected] Usertags: pu
[ Reason ] Fix grave #1132223 which crashes the game. According to the related bug report #1023469 the game was last functional with bullseye. [ Impact ] Cannot play the game at all. [ Tests ] Starting the game without the patches results in a crash. Starting with the patches is okay. [ Risks ] None, trixie users are not able to play. [ Checklist ] [x] *all* changes are documented in the d/changelog [x] I reviewed all changes and I approve them [x] attach debdiff against the package in (old)stable [x] the issue is verified as fixed in unstable [ Changes ] Apply two patches suggested by a Debian user.
diff -Nru pysiogame-4.20.01/debian/changelog pysiogame-4.20.01/debian/changelog --- pysiogame-4.20.01/debian/changelog 2025-03-17 00:20:55.000000000 +0100 +++ pysiogame-4.20.01/debian/changelog 2026-10-03 00:44:49.000000000 +0200 @@ -1,3 +1,15 @@ +pysiogame (4.20.01-3+deb13u1) trixie; urgency=medium + + * Team Upload + * Add patch subsurface to clip subsurface rectangles to the display, so that + the game no longer dies with "ValueError: subsurface rectangle outside + surface area". Closes: #1132223 + * Add patch game-boards-import to load the game modules with importlib + instead of exec/eval, so that starting a game no longer dies with + "NameError: name 'game_boards' is not defined". Closes: #1132223 + + -- Bastian Germann <[email protected]> Sat, 03 Oct 2026 00:44:49 +0200 + pysiogame (4.20.01-3) unstable; urgency=medium * Team Upload diff -Nru pysiogame-4.20.01/debian/patches/game-boards-import.patch pysiogame-4.20.01/debian/patches/game-boards-import.patch --- pysiogame-4.20.01/debian/patches/game-boards-import.patch 1970-01-01 01:00:00.000000000 +0100 +++ pysiogame-4.20.01/debian/patches/game-boards-import.patch 2026-10-03 00:44:19.000000000 +0200 @@ -0,0 +1,36 @@ +Description: Import the game board modules with importlib instead of exec/eval + "exec("import game_boards.game000")" followed by + "eval("game_boards.game000.Board")" relies on exec() making the imported name + visible to the eval() that follows. That is implementation defined in Python + 3 and results in "NameError: name 'game_boards' is not defined", so no game + could be started on Debian 13. + . + Use importlib.import_module() and getattr() instead, which is both explicit + and safe. +Author: william <[email protected]> +Origin: https://bugs.debian.org/1132223 +Bug-Debian: https://bugs.debian.org/1132223 +Last-Update: 2026-10-03 +--- +--- a/eduactiv8.py ++++ b/eduactiv8.py +@@ -37,6 +37,7 @@ + android = None + + import gc ++import importlib + import os + import pygame + import sys +@@ -472,8 +473,9 @@ + del (self.game_board) # delete all previous game objects + self.game_board = None + +- exec("import game_boards.%s" % m.game_constructor[0:7]) +- self.game_const = eval("game_boards.%s" % m.game_constructor) ++ game_module_name, game_class_name = m.game_constructor.rsplit(".", 1) ++ game_module = importlib.import_module("game_boards.%s" % game_module_name) ++ self.game_const = getattr(game_module, game_class_name) + self.game_board = self.game_const(self, self.speaker, self.config, self.size[0], self.size[1]) + m.game_started_id = m.active_game_id + self.layout = self.game_board.layout diff -Nru pysiogame-4.20.01/debian/patches/series pysiogame-4.20.01/debian/patches/series --- pysiogame-4.20.01/debian/patches/series 2025-03-17 00:14:50.000000000 +0100 +++ pysiogame-4.20.01/debian/patches/series 2026-10-03 00:44:19.000000000 +0200 @@ -1,2 +1,4 @@ warnings.patch python3.patch +subsurface.patch +game-boards-import.patch diff -Nru pysiogame-4.20.01/debian/patches/subsurface.patch pysiogame-4.20.01/debian/patches/subsurface.patch --- pysiogame-4.20.01/debian/patches/subsurface.patch 1970-01-01 01:00:00.000000000 +0100 +++ pysiogame-4.20.01/debian/patches/subsurface.patch 2026-10-03 00:44:19.000000000 +0200 @@ -0,0 +1,80 @@ +Description: Do not crash when the display is smaller than the calculated layout + pygame raises "ValueError: subsurface rectangle outside surface area" if the + requested rectangle is not fully contained in the display surface. This + happens at startup and on every resize, because the display surface handed + out by SDL can be smaller than the resolution the layout was calculated from, + and because sizer.py hardcodes the size of the dialog window to 620x400. + . + Clip every subsurface rectangle to the boundaries of the display surface + instead, so that an undersized window only degrades the layout instead of + killing the game. The bare "except: pass" around the game panel subsurface + goes away as well - keeping a stale subsurface of a display that no longer + exists is worse than a freshly copied one. +Author: william <[email protected]> +Origin: https://bugs.debian.org/1132223 +Bug-Debian: https://bugs.debian.org/1132223 +Last-Update: 2026-10-03 +--- +diff --git a/eduactiv8.py b/eduactiv8.py +index 2359cc7..6413444 100755 +--- a/eduactiv8.py ++++ b/eduactiv8.py +@@ -125,22 +125,39 @@ class GamePlay: + # mouse over [surface, group of objects, top most object] + self.mouse_over = [None, None, None] + ++ def get_subsurface(self, rect): ++ """return a subsurface of the display, clipped to the display area ++ ++ pygame refuses rectangles that stick out of the display surface, so a ++ window that ended up smaller than the resolution the layout was ++ calculated for used to abort the game with "subsurface rectangle ++ outside surface area". Trim the rectangle to what actually fits and ++ fall back to the whole display if nothing is left of it.""" ++ if rect is None: ++ return self.screen.copy() ++ screen_w, screen_h = self.screen.get_size() ++ x, y, w, h = rect ++ x = max(x, 0) ++ y = max(y, 0) ++ w = min(w, screen_w - x) ++ h = min(h, screen_h - y) ++ if w <= 0 or h <= 0: ++ return self.screen.copy() ++ return self.screen.subsurface((x, y, w, h)) ++ + def create_subsurfaces(self): + # create subsurfaces & set some of the initial layout constraints + +- self.game_bg = self.screen.subsurface(self.sizer.game_bg_pos) +- #self.game = self.screen.subsurface(self.game_board.layout.game_pos) # game panel - all action happens here +- self.info_bar = self.screen.subsurface(self.sizer.info_bar_pos) # info panel - level control, game info, etc. +- self.score_bar = self.screen.subsurface(self.sizer.score_bar_pos) # top panel - holding username, score etc. +- self.dialogbg = self.screen.subsurface(self.sizer.dialogbg_pos) +- self.dialogwnd = self.screen.subsurface(self.sizer.dialogwnd_pos) ++ self.game_bg = self.get_subsurface(self.sizer.game_bg_pos) ++ #self.game = self.get_subsurface(self.game_board.layout.game_pos) # game panel - all action happens here ++ self.info_bar = self.get_subsurface(self.sizer.info_bar_pos) # info panel - level control, game info, etc. ++ self.score_bar = self.get_subsurface(self.sizer.score_bar_pos) # top panel - holding username, score etc. ++ self.dialogbg = self.get_subsurface(self.sizer.dialogbg_pos) ++ self.dialogwnd = self.get_subsurface(self.sizer.dialogwnd_pos) + self.sb.resize() + + def recreate_game_screen(self): +- try: +- self.game = self.screen.subsurface(self.layout.game_pos) +- except: +- pass ++ self.game = self.get_subsurface(self.layout.game_pos) + + def fs_rescale(self, info): + """rescale the game after fullscreen toggle, this will restart the board +@@ -154,7 +171,7 @@ class GamePlay: + # adjust the layout to accommodate changes to number of squares automatically added due to screen ratio change + self.game_board.layout.update_layout(self.game_board.data[0], self.game_board.data[1]) + self.create_subsurfaces() +- self.game = self.screen.subsurface(self.game_board.layout.game_pos) ++ self.game = self.get_subsurface(self.game_board.layout.game_pos) + info.new_game(self.game_board, self.info_bar) + #self.m.reset_scroll() +

