Skip to content

Commit a2ccef0

Browse files
refactor: enforce strict zip and | type annotations in multiple functions and tests
1 parent 9668580 commit a2ccef0

7 files changed

Lines changed: 89 additions & 68 deletions

File tree

src/pygambit/game.pxi

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -557,7 +557,7 @@ class Game:
557557
shape = arrays[0].shape
558558
g = Game.new_table(shape)
559559
for profile in itertools.product(*(range(s) for s in shape)):
560-
for array, player in zip(arrays, g.players):
560+
for array, player in zip(arrays, g.players, strict=True):
561561
g[profile][player] = array[profile]
562562
g.title = title
563563
return g
@@ -628,10 +628,10 @@ class Game:
628628
arrays = list(payoffs.values())
629629
shape = arrays[0].shape
630630
g = Game.new_table(shape)
631-
for (player, label) in zip(g.players, payoffs):
631+
for (player, label) in zip(g.players, payoffs, strict=True):
632632
player.label = label
633633
for profile in itertools.product(*(range(s) for s in shape)):
634-
for array, player in zip(arrays, g.players):
634+
for array, player in zip(arrays, g.players, strict=True):
635635
g[profile][player] = array[profile]
636636
g.title = title
637637
return g
@@ -916,12 +916,12 @@ class Game:
916916
return profile
917917
if len(data) != len(self.players):
918918
raise ValueError("Number of elements does not match number of players")
919-
for (p, d) in zip(self.players, data):
919+
for (p, d) in zip(self.players, data, strict=True):
920920
if len(p.strategies) != len(d):
921921
raise ValueError(
922922
f"Number of elements does not match number of strategies for {p}"
923923
)
924-
for (s, v) in zip(p.strategies, d):
924+
for (s, v) in zip(p.strategies, d, strict=True):
925925
profile[s] = typefunc(v)
926926
return profile
927927

@@ -1000,9 +1000,12 @@ class Game:
10001000
for player in self.players:
10011001
for strategy, prob in zip(
10021002
player.strategies,
1003-
scipy.stats.dirichlet(alpha=[1 for strategy in player.strategies],
1004-
seed=gen).rvs(size=1)[0]
1005-
):
1003+
scipy.stats.dirichlet(
1004+
alpha=[1 for strategy in player.strategies],
1005+
seed=gen
1006+
).rvs(size=1)[0],
1007+
strict=True
1008+
):
10061009
profile[strategy] = prob
10071010
return profile
10081011
elif denom < 1:
@@ -1018,7 +1021,15 @@ class Game:
10181021
) +
10191022
[denom + k]
10201023
)
1021-
for strategy, (hi, lo) in zip(player.strategies, zip(sample[1:], sample[:-1])):
1024+
for strategy, (hi, lo) in zip(
1025+
player.strategies,
1026+
zip(
1027+
sample[1:],
1028+
sample[:-1],
1029+
strict=True
1030+
),
1031+
strict=True
1032+
):
10221033
profile[strategy] = Rational(hi - lo - 1, denom)
10231034
return profile
10241035

@@ -1034,13 +1045,13 @@ class Game:
10341045
for (p, d) in zip(self.players, data):
10351046
if len(p.infosets) != len(d):
10361047
raise ValueError(f"Number of elements does not match number of infosets for {p}")
1037-
for (i, v) in zip(p.infosets, d):
1048+
for (i, v) in zip(p.infosets, d, strict=True):
10381049
if len(i.actions) != len(v):
10391050
raise ValueError(
10401051
f"Number of elements does not match number of "
10411052
f"actions for infoset {i} for {p}"
10421053
)
1043-
for (a, u) in zip(i.actions, v):
1054+
for (a, u) in zip(i.actions, v, strict=True):
10441055
profile[a] = typefunc(u)
10451056
return profile
10461057

@@ -1123,7 +1134,8 @@ class Game:
11231134
for action, prob in zip(
11241135
infoset.actions,
11251136
scipy.stats.dirichlet(alpha=[1 for action in infoset.actions],
1126-
seed=gen).rvs(size=1)[0]
1137+
seed=gen).rvs(size=1)[0],
1138+
strict=True
11271139
):
11281140
profile[action] = prob
11291141
return profile
@@ -1140,7 +1152,14 @@ class Game:
11401152
) +
11411153
[denom + k]
11421154
)
1143-
for action, (hi, lo) in zip(infoset.actions, zip(sample[1:], sample[:-1])):
1155+
for action, (hi, lo) in zip(
1156+
infoset.actions,
1157+
zip(
1158+
sample[1:], sample[:-1],
1159+
strict=True
1160+
),
1161+
strict=True
1162+
):
11441163
profile[action] = Rational(hi - lo - 1, denom)
11451164
return profile
11461165

@@ -1579,7 +1598,7 @@ class Game:
15791598

15801599
resolved_node = cython.cast(Node, resolved_nodes[0])
15811600
self.game.deref().AppendMove(resolved_node.node, resolved_player.player, len(actions))
1582-
for label, action in zip(actions, resolved_node.infoset.actions):
1601+
for label, action in zip(actions, resolved_node.infoset.actions, strict=True):
15831602
action.label = label
15841603
resolved_infoset = cython.cast(Infoset, resolved_node.infoset)
15851604
for n in resolved_nodes[1:]:
@@ -1943,7 +1962,7 @@ class Game:
19431962
c = Outcome.wrap(self.game.deref().NewOutcome())
19441963
if str(label) != "":
19451964
c.label = str(label)
1946-
for player, payoff in zip(self.players, payoffs):
1965+
for player, payoff in zip(self.players, payoffs, strict=True):
19471966
c[player] = payoff
19481967
return c
19491968

src/pygambit/stratmixed.pxi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ class MixedStrategyProfile:
288288
raise ValueError(
289289
"when setting a mixed strategy, must specify exactly one value per strategy"
290290
)
291-
for s, v in zip(player.strategies, value):
291+
for s, v in zip(player.strategies, value, strict=True):
292292
self._setprob_strategy(s, v)
293293

294294
def __setitem__(

tests/test_actions.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ def test_set_action_label(game: gbt.Game, label: str):
2323
)
2424
def test_set_chance_valid_probability(game: gbt.Game, inprobs: list, outprobs: list):
2525
game.set_chance_probs(game.root.infoset, inprobs)
26-
for (action, prob) in zip(game.root.infoset.actions, outprobs):
26+
for (action, prob) in zip(game.root.infoset.actions, outprobs, strict=True):
2727
assert action.prob == prob
2828

2929

@@ -120,7 +120,7 @@ def test_action_delete_chance(game: gbt.Game):
120120
for p in new_probs:
121121
assert p == 1/len(new_probs)
122122
else:
123-
for p1, p2 in zip(old_probs[1:], new_probs):
123+
for p1, p2 in zip(old_probs[1:], new_probs, strict=True):
124124
if p1 == 0:
125125
assert p2 == 0
126126
else:

tests/test_behav.py

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ def _set_action_probs(profile: gbt.MixedBehaviorProfile, probs: list, rational_f
3434
(games.create_stripped_down_poker_efg(), 1, "1/4", True)
3535
]
3636
)
37-
def test_payoff_reference(game: gbt.Game, player_idx: int, payoff: typing.Union[str, float],
37+
def test_payoff_reference(game: gbt.Game, player_idx: int, payoff: str | float,
3838
rational_flag: bool):
3939
profile = game.mixed_behavior_profile(rational=rational_flag)
4040
payoff = gbt.Rational(payoff) if rational_flag else payoff
@@ -55,7 +55,7 @@ def test_payoff_reference(game: gbt.Game, player_idx: int, payoff: typing.Union[
5555
(games.create_stripped_down_poker_efg(), "Bob", "1/4", True),
5656
]
5757
)
58-
def test_payoff_by_label_reference(game: gbt.Game, label: str, payoff: typing.Union[str, float],
58+
def test_payoff_by_label_reference(game: gbt.Game, label: str, payoff: str | float,
5959
rational_flag: bool):
6060
profile = game.mixed_behavior_profile(rational=rational_flag)
6161
payoff = gbt.Rational(payoff) if rational_flag else payoff
@@ -130,7 +130,7 @@ def test_is_defined_at_by_label(game: gbt.Game, label: str, rational_flag: bool)
130130
def test_profile_indexing_by_player_infoset_action_idx_reference(game: gbt.Game, player_idx: int,
131131
infoset_idx: int,
132132
action_idx: int,
133-
prob: typing.Union[str, float],
133+
prob: str | float,
134134
rational_flag: bool):
135135
profile = game.mixed_behavior_profile(rational=rational_flag)
136136
action = game.players[player_idx].infosets[infoset_idx].actions[action_idx]
@@ -157,7 +157,7 @@ def test_profile_indexing_by_player_infoset_action_idx_reference(game: gbt.Game,
157157
]
158158
)
159159
def test_profile_indexing_by_action_label_reference(game: gbt.Game, action_label: str,
160-
prob: typing.Union[str, float],
160+
prob: str | float,
161161
rational_flag: bool):
162162
"""Here we only use the action label, which are all valid"""
163163
profile = game.mixed_behavior_profile(rational=rational_flag)
@@ -181,7 +181,7 @@ def test_profile_indexing_by_action_label_reference(game: gbt.Game, action_label
181181
)
182182
def test_profile_indexing_by_invalid_action_label(game: gbt.Game, action_label: str,
183183
rational_flag: bool,
184-
error: typing.Union[ValueError, KeyError]):
184+
error: ValueError | KeyError):
185185
"""Test that we get a KeyError for a missing label, and a ValueError for an ambigiuous label
186186
"""
187187
with pytest.raises(error):
@@ -225,7 +225,7 @@ def test_profile_indexing_by_invalid_infoset_label(rational_flag: bool):
225225
def test_profile_indexing_by_infoset_and_action_labels_reference(game: gbt.Game,
226226
infoset_label: str,
227227
action_label: str,
228-
prob: typing.Union[str, float],
228+
prob: str | float,
229229
rational_flag: bool):
230230
"""Here we use the infoset label and action label, with some examples where the action label
231231
alone throws a ValueError (checked in a separate test)
@@ -255,7 +255,7 @@ def test_profile_indexing_by_player_infoset_action_labels_reference(game: gbt.Ga
255255
player_label: str,
256256
infoset_label: str,
257257
action_label: str,
258-
prob: typing.Union[str, float],
258+
prob: str | float,
259259
rational_flag: bool):
260260
"""Here we use the infoset label and action label, with some examples where the action label
261261
alone throws a ValueError (checked in a separate test)
@@ -443,7 +443,7 @@ def test_profile_indexing_by_player_label_reference(game: gbt.Game, player_label
443443
(games.create_stripped_down_poker_efg(), 5, "6/10", True),
444444
]
445445
)
446-
def test_set_probabilities_action(game: gbt.Game, action_idx: int, prob: typing.Union[str, float],
446+
def test_set_probabilities_action(game: gbt.Game, action_idx: int, prob: str | float,
447447
rational_flag: bool):
448448
"""Test to set probabilities of actions by action index"""
449449
profile = game.mixed_behavior_profile(rational=rational_flag)
@@ -472,7 +472,7 @@ def test_set_probabilities_action(game: gbt.Game, action_idx: int, prob: typing.
472472
]
473473
)
474474
def test_set_probabilities_action_by_label(game: gbt.Game, label: str,
475-
prob: typing.Union[str, float], rational_flag: bool):
475+
prob: str | float, rational_flag: bool):
476476
profile = game.mixed_behavior_profile(rational=rational_flag)
477477
prob = gbt.Rational(prob) if rational_flag else prob
478478
profile[label] = prob
@@ -634,7 +634,7 @@ def test_set_probabilities_player_by_label(game: gbt.Game, player_label: str, be
634634
(games.create_stripped_down_poker_efg(), 10, 0.25, False)]
635635
)
636636
def test_realiz_prob_nodes_reference(game: gbt.Game, node_idx: int,
637-
realiz_prob: typing.Union[str, float], rational_flag: bool):
637+
realiz_prob: str | float, rational_flag: bool):
638638
profile = game.mixed_behavior_profile(rational=rational_flag)
639639
realiz_prob = (gbt.Rational(realiz_prob) if rational_flag else realiz_prob)
640640
node = list(game.nodes)[node_idx]
@@ -658,7 +658,7 @@ def test_realiz_prob_nodes_reference(game: gbt.Game, node_idx: int,
658658
]
659659
)
660660
def test_infoset_prob_reference(game: gbt.Game, player_idx: int, infoset_idx: int,
661-
prob: typing.Union[str, float], rational_flag: bool):
661+
prob: str | float, rational_flag: bool):
662662
profile = game.mixed_behavior_profile(rational=rational_flag)
663663
ip = profile.infoset_prob(game.players[player_idx].infosets[infoset_idx])
664664
assert ip == (gbt.Rational(prob) if rational_flag else prob)
@@ -681,7 +681,7 @@ def test_infoset_prob_reference(game: gbt.Game, player_idx: int, infoset_idx: in
681681
]
682682
)
683683
def test_infoset_prob_by_label_reference(game: gbt.Game, label: str,
684-
prob: typing.Union[str, float], rational_flag: bool):
684+
prob: str | float, rational_flag: bool):
685685
profile = game.mixed_behavior_profile(rational=rational_flag)
686686
assert profile.infoset_prob(label) == (gbt.Rational(prob) if rational_flag else prob)
687687

@@ -703,7 +703,7 @@ def test_infoset_prob_by_label_reference(game: gbt.Game, label: str,
703703
]
704704
)
705705
def test_infoset_payoff_reference(game: gbt.Game, player_idx: int, infoset_idx: int,
706-
payoff: typing.Union[str, float], rational_flag: bool):
706+
payoff: str | float, rational_flag: bool):
707707
profile = game.mixed_behavior_profile(rational=rational_flag)
708708
iv = profile.infoset_value(game.players[player_idx].infosets[infoset_idx])
709709
assert iv == (gbt.Rational(payoff) if rational_flag else payoff)
@@ -726,7 +726,7 @@ def test_infoset_payoff_reference(game: gbt.Game, player_idx: int, infoset_idx:
726726
]
727727
)
728728
def test_infoset_payoff_by_label_reference(game: gbt.Game, label: str,
729-
payoff: typing.Union[str, float], rational_flag: bool):
729+
payoff: str | float, rational_flag: bool):
730730
profile = game.mixed_behavior_profile(rational=rational_flag)
731731
assert profile.infoset_value(label) == (gbt.Rational(payoff) if rational_flag else payoff)
732732

@@ -761,7 +761,7 @@ def test_infoset_payoff_by_label_reference(game: gbt.Game, label: str,
761761
]
762762
)
763763
def test_action_payoff_reference(game: gbt.Game, player_idx: int, infoset_idx: int,
764-
action_idx: int, payoff: typing.Union[str, float],
764+
action_idx: int, payoff: str | float,
765765
rational_flag: bool):
766766
profile = game.mixed_behavior_profile(rational=rational_flag)
767767
av = profile.action_value(game.players[player_idx].infosets[infoset_idx].actions[action_idx])
@@ -787,7 +787,7 @@ def test_action_payoff_reference(game: gbt.Game, player_idx: int, infoset_idx: i
787787
]
788788
)
789789
def test_action_value_by_label_reference(game: gbt.Game, label: str,
790-
payoff: typing.Union[str, float], rational_flag: bool):
790+
payoff: str | float, rational_flag: bool):
791791
profile = game.mixed_behavior_profile(rational=rational_flag)
792792
assert profile.action_value(label) == (gbt.Rational(payoff) if rational_flag else payoff)
793793

@@ -859,8 +859,8 @@ def test_regret_consistency(game: gbt.Game, rational_flag: bool):
859859
]
860860
)
861861
def test_regret_reference(game: gbt.Game, player_idx: int, infoset_idx: int, action_idx: int,
862-
action_probs: typing.Union[None, list], rational_flag: bool,
863-
tol: typing.Union[gbt.Rational, float], value: typing.Union[str, float]):
862+
action_probs: None | list, rational_flag: bool,
863+
tol: gbt.Rational | float, value: str | float):
864864
action = game.players[player_idx].infosets[infoset_idx].actions[action_idx]
865865
profile = game.mixed_behavior_profile(rational=rational_flag)
866866
if action_probs:
@@ -941,8 +941,8 @@ def test_node_value_consistency(game: gbt.Game, rational_flag: bool):
941941
(games.create_stripped_down_poker_efg(), [1.0, 0.0, 1.0, 0.0, 1.0, 0.0], False, 1.0),
942942
]
943943
)
944-
def test_liap_value_reference(game: gbt.Game, action_probs: typing.Union[None, list],
945-
rational_flag: bool, expected_value: typing.Union[str, float]):
944+
def test_liap_value_reference(game: gbt.Game, action_probs: None | list,
945+
rational_flag: bool, expected_value: str | float):
946946
"""Tests liap_value under profile given by action_probs
947947
(which will be uniform if action_probs is None)
948948
"""
@@ -985,9 +985,9 @@ def test_liap_value_reference(game: gbt.Game, action_probs: typing.Union[None, l
985985
2, 1, "2/7", True),
986986
]
987987
)
988-
def test_node_belief_reference(game: gbt.Game, tol: typing.Union[gbt.Rational, float],
988+
def test_node_belief_reference(game: gbt.Game, tol: gbt.Rational | float,
989989
probs: list, infoset_idx: int, member_idx: int,
990-
value: typing.Union[str, float], rational_flag: bool):
990+
value: str | float, rational_flag: bool):
991991
profile = game.mixed_behavior_profile(rational=rational_flag)
992992
_set_action_probs(profile, probs, rational_flag)
993993
node = game.infosets[infoset_idx].members[member_idx]
@@ -1181,7 +1181,7 @@ def test_specific_profile(game: gbt.Game, rational_flag: bool, data: list):
11811181
for each player over his actions.
11821182
"""
11831183
profile = game.mixed_behavior_profile(rational=rational_flag, data=data)
1184-
for (action, prob) in zip(game.actions, [k for i in data for j in i for k in j]):
1184+
for (action, prob) in zip(game.actions, [k for i in data for j in i for k in j], strict=True):
11851185
assert profile[action] == (gbt.Rational(prob) if rational_flag else prob)
11861186

11871187

0 commit comments

Comments
 (0)