Skip to content

Commit 7529cf9

Browse files
authored
Merge pull request #443 from iiasa/python-3.14
Confirm support for Python 3.14, drop 3.9
2 parents 0cf55ca + 6df6532 commit 7529cf9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

97 files changed

+424
-471
lines changed

.github/workflows/pytest-snapshots.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ concurrency:
1515

1616
env:
1717
gams-version: 43.4.1
18-
python-version: "3.13"
18+
python-version: "3.14"
1919
upstream: main
2020

2121
jobs:

.github/workflows/pytest.yaml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ defaults:
2222
env:
2323
gams-version: 43.4.1
2424
label: "safe to test"
25-
python-version: "3.13"
25+
python-version: "3.14"
2626

2727
jobs:
2828
check:
@@ -98,13 +98,13 @@ jobs:
9898
# - Latest supported Python version for those or other dependencies.
9999
# Minimum version given in pyproject.toml + earlier version of Python
100100
# For this job only, the oldest version of Python supported by message-ix-models
101-
- { upstream: v3.8.0, python: "3.9" } # Released 2024-01-12
102-
- { upstream: v3.9.0, python: "3.13" } # 2024-06-04
103-
- { upstream: v3.10.0, python: "3.13" } # 2025-02-21
101+
- { upstream: v3.8.0, python: "3.10" } # Released 2024-01-12
102+
- { upstream: v3.9.0, python: "3.14" } # 2024-06-04
103+
- { upstream: v3.10.0, python: "3.14" } # 2025-02-21
104104
# Latest released version + latest released Python
105-
- { upstream: v3.11.0, python: "3.13" } # 2025-05-27
105+
- { upstream: v3.11.0, python: "3.14" } # 2025-05-27
106106
# Development version + latest released Python
107-
- { upstream: main, python: "3.13" }
107+
- { upstream: main, python: "3.14" }
108108

109109
exclude:
110110
# Specific version combinations that are invalid / not to be used

doc/conf.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import os
77
from pathlib import Path
8-
from typing import TYPE_CHECKING, Optional
8+
from typing import TYPE_CHECKING
99

1010
if TYPE_CHECKING:
1111
import sphinx.application
@@ -186,7 +186,7 @@ def setup(app: "sphinx.application.Sphinx") -> None:
186186
# -- Options for sphinx.ext.intersphinx ------------------------------------------------
187187

188188

189-
def local_inv(name: str, *parts: str) -> Optional[str]:
189+
def local_inv(name: str, *parts: str) -> str | None:
190190
"""Construct the path to a local intersphinx inventory."""
191191
if 0 == len(parts):
192192
parts = ("doc", "_build", "html")

doc/whatsnew.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ What's new
44
Next release
55
============
66

7+
- :mod:`message_ix_models` is tested and compatible with `Python 3.14 <https://www.python.org/downloads/release/python-3140/>`__ (:pull:`443`).
8+
- Support for Python 3.9 is dropped (:pull:`443`), as it has reached end-of-life.
79
- Fix water module reporting failures and improve calculations (:issue:`407`, :pull:`396`).
810
- Improve and extend :doc:`/material/index` (:pull:`418`).
911
See :doc:`version 1.2.0 </material/v1.2.0>` for details.

message_ix_models/model/build.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import logging
22
from collections.abc import Callable, Mapping
3-
from typing import Optional, Union
43

54
import ixmp
65
import pandas as pd
@@ -30,8 +29,8 @@ def _add_unit(mp: ixmp.Platform, unit: str, comment: str) -> None:
3029
# FIXME Reduce complexity from 14 to ≤13
3130
def apply_spec( # noqa: C901
3231
scenario: Scenario,
33-
spec: Union[Spec, Mapping[str, ScenarioInfo]],
34-
data: Optional[Callable] = None,
32+
spec: Spec | Mapping[str, ScenarioInfo],
33+
data: Callable | None = None,
3534
**options,
3635
):
3736
"""Apply `spec` to `scenario`.

message_ix_models/model/buildings/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import logging
88
from dataclasses import dataclass, field
99
from pathlib import Path
10-
from typing import Any, Optional, cast
10+
from typing import Any, cast
1111

1212
import ixmp
1313
import message_ix
@@ -92,7 +92,7 @@ class Config:
9292
with_materials: bool = True
9393

9494
#: Path for STURM output.
95-
_output_path: Optional[Path] = None
95+
_output_path: Path | None = None
9696

9797
#: Run the ACCESS model on every iteration.
9898
run_access: bool = False

message_ix_models/model/config.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import logging
22
from dataclasses import dataclass, field
3-
from typing import TYPE_CHECKING, Optional
3+
from typing import TYPE_CHECKING
44

55
from message_ix_models.util.config import ConfigHelper
66
from message_ix_models.util.node import identify_nodes
@@ -73,7 +73,7 @@ def check(self):
7373
)
7474

7575
def regions_from_scenario(
76-
self, scenario: Optional["message_ix.Scenario"] = None
76+
self, scenario: "message_ix.Scenario | None" = None
7777
) -> None:
7878
"""Update :attr:`regions` by inspection of an existing `scenario`.
7979

message_ix_models/model/emissions.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import re
33
from dataclasses import dataclass, field
44
from pathlib import Path
5-
from typing import TYPE_CHECKING, Optional
5+
from typing import TYPE_CHECKING
66

77
import genno
88
import pandas as pd
@@ -73,7 +73,7 @@ def get(self) -> "AnyQuantity":
7373
return load_file(self.path, dims=dims)
7474

7575

76-
def get_emission_factors(units: Optional[str] = None) -> "AnyQuantity":
76+
def get_emission_factors(units: str | None = None) -> "AnyQuantity":
7777
"""Return carbon emission factors.
7878
7979
Values are from the file :file:`message_ix_models/data/ipcc/1996_v3_t1-2.csv`, in
@@ -152,7 +152,7 @@ def get_emission_factors(units: Optional[str] = None) -> "AnyQuantity":
152152
def add_tax_emission(
153153
scen: Scenario,
154154
price: float,
155-
conversion_factor: Optional[float] = None,
155+
conversion_factor: float | None = None,
156156
drate_parameter="drate",
157157
) -> None:
158158
"""Add a global CO₂ price to `scen`.
@@ -217,7 +217,7 @@ def add_tax_emission(
217217
scen.add_par(name, data)
218218

219219

220-
def split_species(unit_expr: str) -> tuple[str, Optional[str]]:
220+
def split_species(unit_expr: str) -> tuple[str, str | None]:
221221
"""Split `unit_expr` to an expression without a unit mention, and maybe species."""
222222
if match := re.fullmatch("(.*)(CO2|C)(.*)", unit_expr):
223223
return f"{match.group(1)}{match.group(3)}", match.group(2)

message_ix_models/model/macro.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from functools import lru_cache
1010
from itertools import product
1111
from pathlib import Path
12-
from typing import TYPE_CHECKING, Literal, Optional, Union
12+
from typing import TYPE_CHECKING, Literal
1313

1414
import pandas as pd
1515

@@ -30,8 +30,8 @@
3030
def generate(
3131
parameter: Literal["aeei", "config", "depr", "drate", "lotol"],
3232
context: "Context",
33-
commodities: Union[list[str], list["Code"]] = COMMODITY,
34-
value: Optional[float] = None,
33+
commodities: list[str] | list["Code"] = COMMODITY,
34+
value: float | None = None,
3535
) -> pd.DataFrame:
3636
"""Generate uniform data for one :mod:`message_ix.macro` `parameter`.
3737

0 commit comments

Comments
 (0)