Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"features": {
"ghcr.io/devcontainers/features/python:1": {
"installTools": true,
"version": "3.11"
"version": "3.14"
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tturocy @rahulsavani I don't think this devcontainer is documented anywhere - do people use it? If so perhaps we should reference it in the developer/contibutor docs page

},
"ghcr.io/devcontainers-contrib/features/gdbgui:2": {
"version": "latest"
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ jobs:
- uses: actions/checkout@v5
- uses: actions/setup-python@v6
with:
python-version: "3.12"
python-version: "3.14"
- uses: py-actions/flake8@v2

cython-lint:
Expand All @@ -58,7 +58,7 @@ jobs:
- name: Setup Python
uses: actions/setup-python@v6
with:
python-version: "3.12"
python-version: "3.14"
- name: Install Python packages
run: python -m pip install cython-lint
- name: cython-lint
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
strategy:
matrix:
python-version: ['3.9', '3.13']
python-version: ['3.10', '3.14']

steps:
- uses: actions/checkout@v5
Expand Down Expand Up @@ -39,7 +39,7 @@ jobs:
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
strategy:
matrix:
python-version: ['3.13']
python-version: ['3.14']

steps:
- uses: actions/checkout@v4
Expand All @@ -63,7 +63,7 @@ jobs:
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
strategy:
matrix:
python-version: ['3.13']
python-version: ['3.14']

steps:
- uses: actions/checkout@v4
Expand All @@ -88,7 +88,7 @@ jobs:
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
strategy:
matrix:
python-version: ['3.13']
python-version: ['3.14']

steps:
- uses: actions/checkout@v5
Expand Down
2 changes: 1 addition & 1 deletion .readthedocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ formats: all
build:
os: ubuntu-22.04
tools:
python: "3.13"
python: "3.14"
apt_packages:
- libgmp-dev
- pandoc
Expand Down
6 changes: 3 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ name = "pygambit"
version = "16.4.0"
description = "The package for computation in game theory"
readme = "src/README.rst"
requires-python = ">=3.9"
requires-python = ">=3.10"
license = "GPL-2.0-or-later"
authors = [
{name = "Theodore Turocy", email = "ted.turocy@gmail.com"},
Expand All @@ -17,11 +17,11 @@ keywords = ["game theory", "Nash equilibrium"]
classifiers=[
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Science/Research",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
"Programming Language :: Python :: Implementation :: CPython",
"Topic :: Scientific/Engineering :: Mathematics"
]
Expand All @@ -41,7 +41,7 @@ Changelog = "https://github.com/gambitproject/gambit/blob/master/ChangeLog"
[tool.ruff]
line-length = 99
indent-width = 4
target-version = "py39"
target-version = "py310"
include = ["setup.py", "src/pygambit/**/*.py", "tests/**/*.py, doc/tutorials/*.ipynb"]

[tool.ruff.lint]
Expand Down
4 changes: 2 additions & 2 deletions src/pygambit/action.pxi
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ class Action:
return Infoset.wrap(self.action.deref().GetInfoset())

@property
def prob(self) -> typing.Union[decimal.Decimal, Rational]:
def prob(self) -> decimal.Decimal | Rational:
"""
Get the probability a chance action is played.

Expand All @@ -108,7 +108,7 @@ class Action:
return Rational(py_string.decode("ascii"))

@property
def plays(self) -> typing.List[Node]:
def plays(self) -> list[Node]:
"""Returns a list of all terminal `Node` objects consistent with it.
"""
return [
Expand Down
24 changes: 12 additions & 12 deletions src/pygambit/behavmixed.pxi
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ class MixedAction:
def __len__(self) -> len:
return len(self.infoset.actions)

def __iter__(self) -> typing.Iterator[typing.Tuple[Action, ProfileDType], None, None]:
def __iter__(self) -> typing.Iterator[tuple[Action, ProfileDType], None, None]:
"""Iterate over the probabilities assigned to actions by the mixed action.

.. versionadded:: 16.2.0
Expand Down Expand Up @@ -225,7 +225,7 @@ class MixedBehavior:
def __len__(self) -> int:
return len(self.player.actions)

def mixed_actions(self) -> typing.Iterator[typing.Tuple[Infoset, MixedAction], None, None]:
def mixed_actions(self) -> typing.Iterator[tuple[Infoset, MixedAction], None, None]:
"""Iterate over the mixed actions specified by the mixed behavior.

.. versionadded:: 16.2.0
Expand All @@ -240,7 +240,7 @@ class MixedBehavior:
for infoset in self.player.infosets:
yield infoset, self[infoset]

def __iter__(self) -> typing.Iterator[typing.Tuple[Action, ProfileDType], None, None]:
def __iter__(self) -> typing.Iterator[tuple[Action, ProfileDType], None, None]:
"""Iterate over the probabilities assigned to actions by the mixed behavior.

.. versionadded:: 16.2.0
Expand All @@ -257,8 +257,8 @@ class MixedBehavior:

def __getitem__(
self,
index: typing.Union[InfosetReference, ActionReference]
) -> typing.Union[MixedAction, ProfileDType]:
index: InfosetReference | ActionReference
) -> MixedAction | ProfileDType:
"""Access a component of the mixed behavior specified by `index`.

Parameters
Expand Down Expand Up @@ -299,7 +299,7 @@ class MixedBehavior:
)

def __setitem__(self,
index: typing.Union[InfosetReference, ActionReference],
index: InfosetReference | ActionReference,
value: typing.Any) -> None:
"""Sets a component of the mixed behavior to `value`.

Expand Down Expand Up @@ -387,7 +387,7 @@ class MixedBehaviorProfile:
"""The game on which this mixed behavior profile is defined."""
return self._game

def mixed_behaviors(self) -> typing.Iterator[typing.Tuple[Player, MixedBehavior], None, None]:
def mixed_behaviors(self) -> typing.Iterator[tuple[Player, MixedBehavior], None, None]:
"""Iterate over the mixed behaviors in the profile.

.. versionadded:: 16.2.0
Expand All @@ -402,7 +402,7 @@ class MixedBehaviorProfile:
for player in self.game.players:
yield player, self[player]

def mixed_actions(self) -> typing.Iterator[typing.Tuple[Infoset, MixedAction], None, None]:
def mixed_actions(self) -> typing.Iterator[tuple[Infoset, MixedAction], None, None]:
"""Iterate over the mixed actions specified by the profile.

.. versionadded:: 16.2.0
Expand All @@ -417,7 +417,7 @@ class MixedBehaviorProfile:
for infoset in self.game.infosets:
yield infoset, self[infoset]

def __iter__(self) -> typing.Iterator[typing.Tuple[Action, ProfileDType], None, None]:
def __iter__(self) -> typing.Iterator[tuple[Action, ProfileDType], None, None]:
"""Iterate over the probabilities assigned to actions by the profile.

.. versionadded:: 16.2.0
Expand All @@ -434,8 +434,8 @@ class MixedBehaviorProfile:

def __getitem__(
self,
index: typing.Union[PlayerReference, InfosetReference, ActionReference]
) -> typing.Union[MixedBehavior, MixedAction, ProfileDType]:
index: PlayerReference | InfosetReference | ActionReference
) -> MixedBehavior | MixedAction | ProfileDType:
"""Access a component of the mixed behavior specified by `index`.

Parameters
Expand Down Expand Up @@ -506,7 +506,7 @@ class MixedBehaviorProfile:

def __setitem__(
self,
index: typing.Union[PlayerReference, InfosetReference, ActionReference],
index: PlayerReference | InfosetReference | ActionReference,
value: typing.Any
) -> None:
"""Sets a probability, mixed agent strategy, or mixed behavior strategy to `value`.
Expand Down
12 changes: 6 additions & 6 deletions src/pygambit/gambit.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,14 @@ def _to_number(value: typing.Any) -> c_Number:
return c_Number(value.encode("ascii"))


PlayerReference = typing.Union[Player, str]
StrategyReference = typing.Union[Strategy, str]
InfosetReference = typing.Union[Infoset, str]
ActionReference = typing.Union[Action, str]
NodeReference = typing.Union[Node, str]
PlayerReference = Player | str
StrategyReference = Strategy | str
InfosetReference = Infoset | str
ActionReference = Action | str
NodeReference = Node | str
NodeReferenceSet = typing.Iterable[NodeReference]

ProfileDType = typing.Union[float, Rational]
ProfileDType = float | Rational


######################
Expand Down
Loading
Loading