From 80b86adb66e8159582694ed68896590f1eb8fcdc Mon Sep 17 00:00:00 2001 From: Rahul Savani Date: Mon, 15 Dec 2025 10:19:38 +0000 Subject: [PATCH 1/2] UndefinedOperationError for game.player.{actions,infosets} on non-tree --- src/pygambit/player.pxi | 21 ++++++++++++++++++++- tests/test_strategic.py | 12 ++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/pygambit/player.pxi b/src/pygambit/player.pxi index c68eeeb13..d6f026328 100644 --- a/src/pygambit/player.pxi +++ b/src/pygambit/player.pxi @@ -228,15 +228,34 @@ class Player: previously, information sets were (expensively) re-sorted after every change to the game tree. + Raises + ------ + UndefinedOperationError + If the game does not have a tree representation. + See also -------- Game.sort_infosets """ + if not self.game.is_tree: + raise UndefinedOperationError( + "Operation only defined for games with a tree representation" + ) return PlayerInfosets.wrap(self.player) @property def actions(self) -> PlayerActions: - """Returns the set of actions available to the player at some information set.""" + """Returns the set of actions available to the player at some information set. + + Raises + ------ + UndefinedOperationError + If the game does not have a tree representation. + """ + if not self.game.is_tree: + raise UndefinedOperationError( + "Operation only defined for games with a tree representation" + ) return PlayerActions.wrap(self) @property diff --git a/tests/test_strategic.py b/tests/test_strategic.py index f1c025509..bba1e0140 100644 --- a/tests/test_strategic.py +++ b/tests/test_strategic.py @@ -11,12 +11,24 @@ def test_strategic_game_actions(): _ = game.actions +def test_strategic_game_player_actions(): + game = gbt.Game.new_table([2, 2]) + with pytest.raises(gbt.UndefinedOperationError): + _ = game.players[0].actions + + def test_strategic_game_infosets(): game = gbt.Game.new_table([2, 2]) with pytest.raises(gbt.UndefinedOperationError): _ = game.infosets +def test_strategic_game_player_infosets(): + game = gbt.Game.new_table([2, 2]) + with pytest.raises(gbt.UndefinedOperationError): + _ = game.players[0].infosets + + def test_strategic_game_root(): game = gbt.Game.new_table([2, 2]) with pytest.raises(gbt.UndefinedOperationError): From 4d26eea51cd518724382ab4df124ae416f61d931 Mon Sep 17 00:00:00 2001 From: Rahul Savani Date: Mon, 15 Dec 2025 15:46:30 +0000 Subject: [PATCH 2/2] UndefinedOperationError for calls to game.nodes and game.sort_infosets on non-trees --- src/pygambit/game.pxi | 18 ++++++++++++++++++ tests/test_strategic.py | 9 ++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/pygambit/game.pxi b/src/pygambit/game.pxi index 69ca46587..9654658f7 100644 --- a/src/pygambit/game.pxi +++ b/src/pygambit/game.pxi @@ -742,7 +742,16 @@ class Game: .. versionchanged:: 16.4 Changed from a method ``nodes()`` to a property. + Raises + ------ + UndefinedOperationError + If the game does not have a tree representation. """ + if not self.is_tree: + raise UndefinedOperationError( + "Operation only defined for games with a tree representation" + ) + return GameNodes.wrap(self.game) @property @@ -1885,11 +1894,20 @@ class Game: .. versionadded:: 16.4.0 + Raises + ------ + UndefinedOperationError + If the game does not have a tree representation. + See also -------- Player.infosets Infoset.members """ + if not self.is_tree: + raise UndefinedOperationError( + "Operation only defined for games with a tree representation" + ) self.game.deref().SortInfosets() def add_player(self, label: str = "") -> Player: diff --git a/tests/test_strategic.py b/tests/test_strategic.py index bba1e0140..f6c87e60d 100644 --- a/tests/test_strategic.py +++ b/tests/test_strategic.py @@ -37,7 +37,14 @@ def test_strategic_game_root(): def test_strategic_game_nodes(): game = gbt.Game.new_table([2, 2]) - assert list(game.nodes) == [] + with pytest.raises(gbt.UndefinedOperationError): + _ = game.nodes + + +def test_strategic_game_sort_infosets(): + game = gbt.Game.new_table([2, 2]) + with pytest.raises(gbt.UndefinedOperationError): + _ = game.sort_infosets() def test_game_behav_profile_error():