Skip to content

Commit

Permalink
Merge pull request randovania#230 from randovania/chore/ci
Browse files Browse the repository at this point in the history
Test with Python 3.13
  • Loading branch information
henriquegemignani authored Oct 12, 2024
2 parents fa92e98 + 7f18617 commit 8ef9048
Show file tree
Hide file tree
Showing 29 changed files with 93 additions and 115 deletions.
5 changes: 3 additions & 2 deletions .github/workflows/python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"
python-version: "3.12"

- name: Install Python packages
run: python -m pip install --upgrade build
Expand Down Expand Up @@ -57,7 +57,8 @@ jobs:
python:
- { version: "3.10" }
- { version: "3.11" }
- { version: "3.12.0-beta - 3.12.0" }
- { version: "3.12" }
- { version: "3.13" }

steps:
- name: Checkout
Expand Down
5 changes: 3 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ classifiers = [
"Intended Audience :: Developers",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
]
requires-python = ">=3.10"
dynamic = ["version"]
Expand All @@ -27,7 +29,6 @@ dependencies = [
"zstandard",
]


[project.readme]
file = "README.md"
content-type = "text/markdown"
Expand Down Expand Up @@ -67,7 +68,7 @@ lint.select = ["E", "F", "W", "C90", "I", "UP"]
src = ["src"]

# Version to target for generated code.
target-version = "py38"
target-version = "py310"

[tool.ruff.lint.mccabe]
# Flag errors (`C901`) whenever the complexity level exceeds 25.
Expand Down
5 changes: 2 additions & 3 deletions src/mercury_engine_data_structures/_dread_data_construct.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import struct
import typing

import construct

Expand Down Expand Up @@ -30,7 +29,7 @@ def __init__(self):
),
)

def _parse(self, stream, context, path) -> typing.Dict[str, int]:
def _parse(self, stream, context, path) -> dict[str, int]:
key_struct = struct.Struct("=H")
value_struct = struct.Struct("=Q")

Expand All @@ -44,7 +43,7 @@ def _parse(self, stream, context, path) -> typing.Dict[str, int]:

return result

def _build(self, obj: typing.Dict[str, int], stream, context, path):
def _build(self, obj: dict[str, int], stream, context, path):
return self._build_construct._build(list(obj.items()), stream, context, path)


Expand Down
3 changes: 1 addition & 2 deletions src/mercury_engine_data_structures/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import typing
from concurrent.futures import ProcessPoolExecutor
from pathlib import Path
from typing import Optional

from mercury_engine_data_structures import formats
from mercury_engine_data_structures.construct_extensions.json import convert_to_raw_python
Expand Down Expand Up @@ -205,7 +204,7 @@ async def compare_all_files_in_path(args):
input_path: Path = args.input_path
file_format: str = args.format
game: Game = args.game
limit: Optional[int] = args.limit
limit: int | None = args.limit

def apply_limit(it):
if limit is None:
Expand Down
2 changes: 1 addition & 1 deletion src/mercury_engine_data_structures/common_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ def _emitbuild(code):
return result


def make_enum(values: typing.Union[typing.List[str], typing.Dict[str, int]], *, add_invalid: bool = True):
def make_enum(values: list[str] | dict[str, int], *, add_invalid: bool = True):
if isinstance(values, dict):
mapping = copy.copy(values)
else:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
import enum
import typing

import construct


class StrictEnum(construct.Adapter):
def __init__(self, enum_class: typing.Type[enum.IntEnum]):
def __init__(self, enum_class: type[enum.IntEnum]):
super().__init__(construct.Int32ul)
self.enum_class = enum_class

def _decode(self, obj: int, context, path):
return self.enum_class(obj)

def _encode(self, obj: typing.Union[str, enum.IntEnum, int], context, path) -> int:
def _encode(self, obj: str | enum.IntEnum | int, context, path) -> int:
if isinstance(obj, str):
obj = getattr(self.enum_class, obj)

Expand All @@ -39,7 +38,7 @@ def _encode_enum_{i}(obj, io, this):
return f"_encode_enum_{i}(obj, io, this)"


def BitMaskEnum(enum_type: typing.Type[enum.IntEnum]):
def BitMaskEnum(enum_type: type[enum.IntEnum]):
flags = {}
for enumentry in enum_type:
flags[enumentry.name] = 2**enumentry.value
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import re
from typing import Dict, Optional, Type, Union

import construct


def _resolve_id(type_class: Union[construct.Construct, Type[construct.Construct]]) -> int:
def _resolve_id(type_class: construct.Construct | type[construct.Construct]) -> int:
if isinstance(type_class, construct.Renamed):
return _resolve_id(type_class.subcon)
return id(type_class)
Expand All @@ -16,8 +15,8 @@ def _resolve_id(type_class: Union[construct.Construct, Type[construct.Construct]

def emit_switch_cases_parse(
code: construct.CodeGen,
fields: Dict[Union[str, int], Union[construct.Construct, Type[construct.Construct]]],
custom_table_name: Optional[str] = None,
fields: dict[str | int, construct.Construct | type[construct.Construct]],
custom_table_name: str | None = None,
) -> str:
"""Construct codegen helper for handling the switch cases dict in _emitparse."""
table_name = custom_table_name
Expand Down Expand Up @@ -48,8 +47,8 @@ def {code_name}(io, this):

def emit_switch_cases_build(
code: construct.CodeGen,
fields: Dict[Union[str, int], Union[construct.Construct, Type[construct.Construct]]],
custom_table_name: Optional[str] = None,
fields: dict[str | int, construct.Construct | type[construct.Construct]],
custom_table_name: str | None = None,
) -> str:
"""Construct codegen helper for handling the switch cases dict in _emitbuild."""
table_name = custom_table_name
Expand Down
8 changes: 3 additions & 5 deletions src/mercury_engine_data_structures/crc.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
Module for calculating CRC hashes with the algorithm and data used by Mercury Engine.
"""

import typing

_crc32_constants = [
0x00000000,
0x77073096,
Expand Down Expand Up @@ -523,7 +521,7 @@
]


def _algorithm(data: typing.Union[bytes, str], constants: typing.List[int], checksum: int) -> int:
def _algorithm(data: bytes | str, constants: list[int], checksum: int) -> int:
if isinstance(data, str):
data = data.encode("utf-8")

Expand All @@ -533,15 +531,15 @@ def _algorithm(data: typing.Union[bytes, str], constants: typing.List[int], chec
return checksum


def crc32(data: typing.Union[bytes, str]) -> int:
def crc32(data: bytes | str) -> int:
return _algorithm(
data,
_crc32_constants,
0xFFFFFFFF,
)


def crc64(data: typing.Union[bytes, str]) -> int:
def crc64(data: bytes | str) -> int:
return _algorithm(
data,
_crc64_constants,
Expand Down
15 changes: 7 additions & 8 deletions src/mercury_engine_data_structures/dread_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,21 @@
import json
import typing
from pathlib import Path
from typing import Dict, Optional

from mercury_engine_data_structures._dread_data_construct import KnownHashes

_root = Path(__file__).parent


@functools.lru_cache
def get_raw_types() -> Dict[str, typing.Any]:
def get_raw_types() -> dict[str, typing.Any]:
path = _root.joinpath("dread_types.json")
with path.open() as f:
return json.load(f)


@functools.lru_cache
def all_name_to_asset_id() -> Dict[str, int]:
def all_name_to_asset_id() -> dict[str, int]:
bin_path = _root.joinpath("dread_resource_names.bin")
if bin_path.exists():
return dict(KnownHashes.parse_file(bin_path))
Expand All @@ -28,16 +27,16 @@ def all_name_to_asset_id() -> Dict[str, int]:


@functools.lru_cache
def all_asset_id_to_name() -> Dict[int, str]:
def all_asset_id_to_name() -> dict[int, str]:
return {asset_id: name for name, asset_id in all_name_to_asset_id().items()}


def name_for_asset_id(asset_id: int) -> Optional[str]:
def name_for_asset_id(asset_id: int) -> str | None:
return all_asset_id_to_name().get(asset_id)


@functools.lru_cache
def all_name_to_property_id() -> Dict[str, int]:
def all_name_to_property_id() -> dict[str, int]:
bin_path = _root.joinpath("dread_property_names.bin")
if bin_path.exists():
return dict(KnownHashes.parse_file(bin_path))
Expand All @@ -48,13 +47,13 @@ def all_name_to_property_id() -> Dict[str, int]:


@functools.lru_cache
def all_property_id_to_name() -> Dict[int, str]:
def all_property_id_to_name() -> dict[int, str]:
names = all_name_to_property_id()

return {asset_id: name for name, asset_id in names.items()}


def all_files_ending_with(ext: str, exclusions: Optional[list[str]] = None) -> list[str]:
def all_files_ending_with(ext: str, exclusions: list[str] | None = None) -> list[str]:
if not ext.startswith("."):
ext = "." + ext

Expand Down
24 changes: 11 additions & 13 deletions src/mercury_engine_data_structures/file_tree_editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
import logging
import os.path
import typing
from collections.abc import Iterator
from pathlib import Path
from typing import Dict, Iterator, Optional, Set

import construct

Expand Down Expand Up @@ -60,11 +60,11 @@ class FileTreeEditor:
_modified_resources: mapping of asset id to bytes. When saving, these asset ids are replaced
"""

headers: Dict[str, construct.Container]
_files_for_asset_id: Dict[AssetId, Set[Optional[str]]]
_ensured_asset_ids: Dict[str, Set[AssetId]]
_modified_resources: Dict[AssetId, Optional[bytes]]
_in_memory_pkgs: Dict[str, Pkg]
headers: dict[str, construct.Container]
_files_for_asset_id: dict[AssetId, set[str | None]]
_ensured_asset_ids: dict[str, set[AssetId]]
_modified_resources: dict[AssetId, bytes | None]
_in_memory_pkgs: dict[str, Pkg]
_toc: Toc

def __init__(self, root: Path, target_game: Game):
Expand All @@ -78,7 +78,7 @@ def __init__(self, root: Path, target_game: Game):
def path_for_pkg(self, pkg_name: str) -> Path:
return self.root.joinpath(pkg_name)

def _add_pkg_name_for_asset_id(self, asset_id: AssetId, pkg_name: Optional[str]):
def _add_pkg_name_for_asset_id(self, asset_id: AssetId, pkg_name: str | None):
self._files_for_asset_id[asset_id] = self._files_for_asset_id.get(asset_id, set())
self._files_for_asset_id[asset_id].add(pkg_name)

Expand Down Expand Up @@ -154,7 +154,7 @@ def does_asset_exists(self, asset_id: NameOrAssetId) -> bool:

return asset_id in self._files_for_asset_id

def get_raw_asset(self, asset_id: NameOrAssetId, *, in_pkg: Optional[str] = None) -> bytes:
def get_raw_asset(self, asset_id: NameOrAssetId, *, in_pkg: str | None = None) -> bytes:
"""
Gets the bytes data for the given asset name/id, optionally restricting from which pkg.
:raises ValueError if the asset doesn't exist.
Expand Down Expand Up @@ -189,9 +189,7 @@ def get_raw_asset(self, asset_id: NameOrAssetId, *, in_pkg: Optional[str] = None

raise ValueError(f"Unknown asset_id: {original_name}")

def get_parsed_asset(
self, name: str, *, in_pkg: Optional[str] = None, type_hint: typing.Type[_T] = BaseResource
) -> _T:
def get_parsed_asset(self, name: str, *, in_pkg: str | None = None, type_hint: type[_T] = BaseResource) -> _T:
"""
Gets the resource with the given name and decodes it based on the extension.
"""
Expand All @@ -214,7 +212,7 @@ def get_file(self, path: str, type_hint: type[_T] = BaseResource) -> _T:
"""
return self.get_parsed_asset(path, type_hint=type_hint)

def add_new_asset(self, name: str, new_data: typing.Union[bytes, BaseResource], in_pkgs: typing.Iterable[str]):
def add_new_asset(self, name: str, new_data: bytes | BaseResource, in_pkgs: typing.Iterable[str]):
"""
Adds an asset that doesn't already exist.
"""
Expand All @@ -241,7 +239,7 @@ def add_new_asset(self, name: str, new_data: typing.Union[bytes, BaseResource],
for pkg_name in in_pkgs:
self.ensure_present(pkg_name, asset_id)

def replace_asset(self, asset_id: NameOrAssetId, new_data: typing.Union[bytes, BaseResource]):
def replace_asset(self, asset_id: NameOrAssetId, new_data: bytes | BaseResource):
"""
Replaces an existing asset.
See `add_new_asset` for new assets.
Expand Down
4 changes: 1 addition & 3 deletions src/mercury_engine_data_structures/formats/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
from typing import Type

from mercury_engine_data_structures.formats.bapd import Bapd
from mercury_engine_data_structures.formats.base_resource import AssetType, BaseResource
from mercury_engine_data_structures.formats.bcmdl import Bcmdl
Expand Down Expand Up @@ -105,5 +103,5 @@
}


def format_for(type_name: AssetType) -> Type[BaseResource]:
def format_for(type_name: AssetType) -> type[BaseResource]:
return ALL_FORMATS[type_name.upper()]
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def raw(self) -> Container:

AssetType = str
AssetId = int
NameOrAssetId = typing.Union[str, AssetId]
NameOrAssetId = str | AssetId


def resolve_asset_id(value: NameOrAssetId, game: Game) -> AssetId:
Expand Down
4 changes: 1 addition & 3 deletions src/mercury_engine_data_structures/formats/bmmdef.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
from typing import Tuple

from construct import Construct, Container

from mercury_engine_data_structures.formats import standard_format
Expand All @@ -25,7 +23,7 @@ def add_icon(
uSpriteCol: int,
sInspectorLabel: str,
sDisabledIconId: str = "",
vAnchorOffset: Tuple[int, int] = (0, 0),
vAnchorOffset: tuple[int, int] = (0, 0),
bAutoScale: bool = True,
**kwargs,
):
Expand Down
2 changes: 1 addition & 1 deletion src/mercury_engine_data_structures/formats/bmsad.py
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,7 @@ def __set__(self, inst: ActorDefFunc, value: T):


Vec3 = list
FieldType = typing.Union[bool, str, float, int, Vec3]
FieldType = bool | str | float | int | Vec3


class ComponentFields:
Expand Down
4 changes: 2 additions & 2 deletions src/mercury_engine_data_structures/formats/bmsld.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import logging
from typing import Iterator, Tuple
from collections.abc import Iterator

import construct
from construct import Const, Construct, Container, Flag, Float32l, Hex, Int32ul, Struct, Switch
Expand Down Expand Up @@ -145,7 +145,7 @@ class Bmsld(BaseResource):
def construct_class(cls, target_game: Game) -> Construct:
return BMSLD

def all_actors(self) -> Iterator[Tuple[int, str, construct.Container]]:
def all_actors(self) -> Iterator[tuple[int, str, construct.Container]]:
for layer in self.raw.actors:
for actor_name, actor in layer.items():
yield layer, actor_name, actor
Expand Down
Loading

0 comments on commit 8ef9048

Please sign in to comment.