Skip to content

Commit

Permalink
mypy (#334)
Browse files Browse the repository at this point in the history
  • Loading branch information
ThanatosGit authored May 8, 2024
1 parent 7d435d4 commit b9aa222
Show file tree
Hide file tree
Showing 31 changed files with 204 additions and 152 deletions.
40 changes: 40 additions & 0 deletions .github/workflows/python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,46 @@ jobs:
run:
venv/bin/python -m open_samus_returns_rando --input-path "$SAMUS_RETURNS_PATH" --output-path export/ --input-json tests/test_files/starter_preset_patcher.json

mypy:
runs-on: 'ubuntu-latest'

steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Workaround for worktree config
run: git config --unset-all extensions.worktreeConfig || true

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: "pip"

- name: Install Python packages
run: python -m pip install .[typing]

- name: Mypy on modified files
uses: tsuyoshicho/action-mypy@v4
with:
github_token: ${{ secrets.github_token }}
# Change reviewdog reporter if you need [github-pr-check,github-check,github-pr-review].
reporter: github-check
setup_method: install
fail_on_error: false

- name: Mypy on required files
uses: tsuyoshicho/action-mypy@v4
with:
github_token: ${{ secrets.github_token }}
# Change reviewdog reporter if you need [github-pr-check,github-check,github-pr-review].
reporter: github-check
setup_method: install
target: --config-file=pyproject.toml
fail_on_error: true


pypi:
runs-on: 'ubuntu-latest'
Expand Down
16 changes: 16 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,19 @@ target-version = "py39"
# Flag errors (`C901`) whenever the complexity level exceeds 25.
# Defaults to 10, but we're being very flexible right now
max-complexity = 25

[project.optional-dependencies]
typing = [
"types-jsonschema",
"construct-typing",
"types-pyinstaller",
"mypy"
]

[tool.mypy]
files = [
"src/"
]
follow_imports = "silent"
disallow_untyped_defs = true
local_partial_types = true
2 changes: 1 addition & 1 deletion src/open_samus_returns_rando/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from .patch_util import patch_with_status_update


def patch(input_path: Path, output_path: Path, configuration: dict):
def patch(input_path: Path, output_path: Path, configuration: dict) -> None:
from .samus_returns_patcher import patch_extracted
return patch_extracted(input_path, output_path, configuration)

Expand Down
2 changes: 1 addition & 1 deletion src/open_samus_returns_rando/__pyinstaller/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@
# This function returns a list containing only the path to this
# directory, which is the location of these hooks.

def get_hook_dirs():
def get_hook_dirs() -> list[str]:
return [os.path.dirname(__file__)] # noqa: PTH120
6 changes: 3 additions & 3 deletions src/open_samus_returns_rando/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from open_samus_returns_rando import samus_returns_patcher


def create_parser():
def create_parser() -> argparse.ArgumentParser:
parser = argparse.ArgumentParser()
parser.add_argument("--input-path", required=True, type=Path,
help="Path to where the extracted Metroid: Samus Returns romfs to randomize can be found.")
Expand All @@ -18,7 +18,7 @@ def create_parser():
return parser


def setup_logging():
def setup_logging() -> None:
handlers = {
'default': {
'level': 'DEBUG',
Expand Down Expand Up @@ -49,7 +49,7 @@ def setup_logging():
logging.info("Hello world.")


def main():
def main() -> None:
setup_logging()
parser = create_parser()
args = parser.parse_args()
Expand Down
4 changes: 2 additions & 2 deletions src/open_samus_returns_rando/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@
"s110_surfaceb",
]

def get_package_name(package_name: str, file_name: str):
def get_package_name(package_name: str, file_name: str) -> str:
without = ["bcmdl", "bcwav", "bctex", "bcskla", "bcptl"]
for ending in without:
if file_name.endswith(ending):
return package_name.replace("_discardables", "")
return package_name

def lua_pkgs(pkgs: list[str]):
def lua_pkgs(pkgs: list[str]) -> list[str]:
return [get_package_name(level_pkg, "lc") for level_pkg in pkgs]
8 changes: 4 additions & 4 deletions src/open_samus_returns_rando/debug.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
from open_samus_returns_rando.patcher_editor import PatcherEditor


def unpack_new_actor(new_actor: dict):
def unpack_new_actor(new_actor: dict) -> tuple[str, str, str, list[float]]:
scenario_name = new_actor["new_actor"]["scenario"]
new_actor_name = new_actor["new_actor"]["actor"]
collision_camera_name = new_actor["collision_camera_name"]
new_pos = (new_actor["location"]["x"], new_actor["location"]["y"], new_actor["location"]["z"])
new_pos = [new_actor["location"]["x"], new_actor["location"]["y"], new_actor["location"]["z"]]
return scenario_name,new_actor_name,collision_camera_name,new_pos


def debug_spawn_points(editor: PatcherEditor, spawn_config: list[dict]):
def debug_spawn_points(editor: PatcherEditor, spawn_config: list[dict]) -> None:
# create custom spawn point
_EXAMPLE_SP = {"scenario": "s010_area1", "layer": "5", "actor": "StartPoint0"}
base_actor = editor.resolve_actor_reference(_EXAMPLE_SP)
Expand All @@ -20,7 +20,7 @@ def debug_spawn_points(editor: PatcherEditor, spawn_config: list[dict]):
scenario.add_actor_to_entity_groups(collision_camera_name, new_actor_name)


def debug_custom_pickups(editor: PatcherEditor, pickup_config: list[dict]):
def debug_custom_pickups(editor: PatcherEditor, pickup_config: list[dict]) -> None:
# create custom pickup
_EXAMPLE_PICKUP = {"scenario": "s000_surface", "layer": "9", "actor": "LE_PowerUP_Morphball"}
base_actor = editor.resolve_actor_reference(_EXAMPLE_PICKUP)
Expand Down
23 changes: 12 additions & 11 deletions src/open_samus_returns_rando/lua_editor.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import itertools
from collections.abc import Iterable

from construct import Container
from mercury_engine_data_structures.formats.lua import Lua
Expand Down Expand Up @@ -105,22 +106,22 @@ def ensure_files(self, editor: PatcherEditor) -> None:


class LuaEditor:
def __init__(self):
self._item_classes = {}
self._metroid_dict = {}
self._dna_count_dict = {}
self._hint_dict = {}
def __init__(self) -> None:
self._item_classes: dict[str, ScriptClass] = {}
self._metroid_dict: dict[str, dict[str, str]] = {}
self._dna_count_dict: dict[str, int] = {}
self._hint_dict: dict[str, dict[str, list[str]]] = {}
self._progressive_models = ""
self._custom_level_scripts: dict[str, dict] = self._read_levels()
self._metroid_imports = []
self._metroid_imports: list[str] = []

def _read_levels(self) -> dict[str, dict]:
return {
scenario: {"script": _read_level_lua(scenario), "edited": False}
for scenario in ALL_SCENARIOS
}

def get_parent_for(self, item_id) -> str:
def get_parent_for(self, item_id: str) -> str:
return SPECIFIC_CLASSES.get(item_id, "RandomizerPowerup")

def create_script_class(self, pickup: dict, actordef_id: str = "") -> ScriptClass:
Expand Down Expand Up @@ -174,7 +175,7 @@ def create_script_class(self, pickup: dict, actordef_id: str = "") -> ScriptClas

return new_script_class

def add_progressive_models(self, pickup: dict, actordef_name: str):
def add_progressive_models(self, pickup: dict, actordef_name: str) -> None:
progressive_models = [
{
"item": lua_util.wrap_string(resource["item_id"]),
Expand Down Expand Up @@ -233,7 +234,7 @@ def _create_custom_init(self, editor: PatcherEditor, configuration: dict) -> str
final_inventory.update(inventory)

# Use itertools batched when upgrading to python 3.12
def chunks(array: list[str], n: int):
def chunks(array: list[str], n: int) -> Iterable[list[str]]:
for i in range(0, len(array), n):
yield array[i:i + n]

Expand All @@ -260,7 +261,7 @@ def chunks(array: list[str], n: int):

return lua_util.replace_lua_template("custom_init.lua", replacement)

def _add_replacement_files(self, editor: PatcherEditor, configuration: dict):
def _add_replacement_files(self, editor: PatcherEditor, configuration: dict) -> None:
# Update init.lc
lua_util.create_script_copy(editor, "system/scripts/init")

Expand All @@ -280,7 +281,7 @@ def _add_replacement_files(self, editor: PatcherEditor, configuration: dict):
lua_util.replace_script(editor, "actors/props/heatzone/scripts/heatzone", "custom/heatzone.lua")
lua_util.replace_script(editor, "gui/scripts/sprites_splashes", "custom/sprites_splashes.lua")

def save_modifications(self, editor: PatcherEditor, configuration: dict):
def save_modifications(self, editor: PatcherEditor, configuration: dict) -> None:
self._add_replacement_files(editor, configuration)

# add new system scripts
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from open_samus_returns_rando.patcher_editor import PatcherEditor


def create_collision_camera_table(editor: PatcherEditor, configuration: dict):
def create_collision_camera_table(editor: PatcherEditor, configuration: dict) -> None:
py_dict: dict = configuration["cosmetic_patches"]["camera_names_dict"]

# Surface
Expand Down
6 changes: 3 additions & 3 deletions src/open_samus_returns_rando/misc_patches/credits.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
]
}

def _create_randomizer_credits(spoiler_log: dict[str, str]):
def _create_randomizer_credits(spoiler_log: dict[str, str]) -> tuple[list[tuple[str, str]], int, int, int]:
rando_credits: list[tuple[str, str]] = [
("Randomizer Credits", "CREDIT_TITLE"),
]
Expand All @@ -46,7 +46,7 @@ def _create_randomizer_credits(spoiler_log: dict[str, str]):
amount_subtitle = 0
amount_credit = 0

def new_sort(prefix: str, item) -> tuple[str, str]:
def new_sort(prefix: str, item: str) -> tuple[str, str]:
nonlocal amount_title
nonlocal amount_subtitle
nonlocal amount_credit
Expand All @@ -67,7 +67,7 @@ def new_sort(prefix: str, item) -> tuple[str, str]:
return rando_credits, amount_title, amount_subtitle, amount_credit


def patch_credits(editor: PatcherEditor, spoiler_log: dict[str, str]):
def patch_credits(editor: PatcherEditor, spoiler_log: dict[str, str]) -> None:
english_files = [
"system/localization/mse_english.txt",
]
Expand Down
6 changes: 3 additions & 3 deletions src/open_samus_returns_rando/misc_patches/elevators.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from open_samus_returns_rando.patcher_editor import PatcherEditor


def create_elevator_table(editor: PatcherEditor, configuration: dict):
def create_elevator_table(editor: PatcherEditor, configuration: dict) -> None:
py_dict: dict = configuration["elevators"]

file = lua_util.replace_lua_template("elevators.lua", {"elevator_dict": py_dict}, True)
Expand All @@ -15,14 +15,14 @@ def create_elevator_table(editor: PatcherEditor, configuration: dict):
)


def update_elevators(editor: PatcherEditor, configuration: dict):
def update_elevators(editor: PatcherEditor, configuration: dict) -> None:
for scenario_name, elevators in configuration["elevators"].items():
scenario = editor.get_scenario(scenario_name)
for elevator in elevators:
platform = scenario.raw.actors[10][elevator]["components"][0]
platform["arguments"][1]["value"] = "Scenario.RandoOnElevatorUse"


def patch_elevators(editor: PatcherEditor, configuration: dict):
def patch_elevators(editor: PatcherEditor, configuration: dict) -> None:
create_elevator_table(editor, configuration)
update_elevators(editor, configuration)
9 changes: 0 additions & 9 deletions src/open_samus_returns_rando/misc_patches/exefs.py

This file was deleted.

11 changes: 6 additions & 5 deletions src/open_samus_returns_rando/misc_patches/lua_util.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import re
import typing

from construct import Container
from mercury_engine_data_structures.file_tree_editor import FileTreeEditor
from mercury_engine_data_structures.formats.lua import Lua
from open_samus_returns_rando.files import files_path, templates_path


def replace_lua_template(file: str, replacement: dict[str, str], wrap_strings: bool = False) -> str:
def replace_lua_template(file: str, replacement: dict[str, typing.Any], wrap_strings: bool = False) -> str:
code = templates_path().joinpath(file).read_text()
for key, content in replacement.items():
# Replace `TEMPLATE("key")`-style replacements
Expand All @@ -23,7 +24,7 @@ def replace_lua_template(file: str, replacement: dict[str, str], wrap_strings: b
return code


def lua_convert(data, wrap_strings: bool = False) -> str:
def lua_convert(data: typing.Any, wrap_strings: bool = False) -> str:
if isinstance(data, list):
return "{\n" + "\n".join(
f"{lua_convert(item, wrap_strings)},"
Expand All @@ -46,7 +47,7 @@ def wrap_string(data: str) -> str:
return f'"{data}"'


def create_script_copy(editor: FileTreeEditor, path: str):
def create_script_copy(editor: FileTreeEditor, path: str) -> None:
original = path + "_original.lc"
if not editor.does_asset_exists(original):
original_lc = editor.get_raw_asset(path + ".lc")
Expand All @@ -57,13 +58,13 @@ def create_script_copy(editor: FileTreeEditor, path: str):
)


def replace_script(editor: FileTreeEditor, path: str, replacement_path: str):
def replace_script(editor: FileTreeEditor, path: str, replacement_path: str) -> None:
create_script_copy(editor, path)
lua_content = files_path().joinpath(replacement_path).read_text()
lua_resource = Lua(Container(lua_text=lua_content), editor.target_game)
editor.replace_asset(path + ".lc", lua_resource)

def replace_script_with_content(editor: FileTreeEditor, path: str, lua_content: str):
def replace_script_with_content(editor: FileTreeEditor, path: str, lua_content: str) -> None:
create_script_copy(editor, path)
lua_resource = Lua(Container(lua_text=lua_content), editor.target_game)
editor.replace_asset(path + ".lc", lua_resource)
Expand Down
4 changes: 2 additions & 2 deletions src/open_samus_returns_rando/misc_patches/spawn_points.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class NewSpawnPoint(typing.NamedTuple):
]


def add_spawnpoints(editor: PatcherEditor, new_spawnpoint: NewSpawnPoint):
def add_spawnpoints(editor: PatcherEditor, new_spawnpoint: NewSpawnPoint) -> None:
template_sp = editor.get_scenario("s000_surface").raw.actors[5]["ST_SG_Alpha_001"]

scenario_name = new_spawnpoint.scenario
Expand All @@ -38,6 +38,6 @@ def add_spawnpoints(editor: PatcherEditor, new_spawnpoint: NewSpawnPoint):
scenario_file.add_actor_to_entity_groups(entity_group, new_spawnpoint.name, True)


def patch_custom_spawn_points(editor: PatcherEditor):
def patch_custom_spawn_points(editor: PatcherEditor) -> None:
for new_spawnpoint in new_spawnpoints:
add_spawnpoints(editor, new_spawnpoint)
6 changes: 3 additions & 3 deletions src/open_samus_returns_rando/misc_patches/text_patches.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
}


def patch_text(editor: PatcherEditor, key: str, value: str):
def patch_text(editor: PatcherEditor, key: str, value: str) -> None:
for text_file in ALL_TEXT_FILES:
text = editor.get_file(f"system/localization/{text_file}", Txt)
text.strings[key] = value
Expand All @@ -34,12 +34,12 @@ def get_text(editor: PatcherEditor, key: str, text_file: str = "us_english.txt")
return text.strings[key]


def apply_text_patches(editor: PatcherEditor, patches: dict[str, str]):
def apply_text_patches(editor: PatcherEditor, patches: dict[str, str]) -> None:
for k, v in patches.items():
patch_text(editor, k, v)


def add_spiderboost_status(editor: PatcherEditor):
def add_spiderboost_status(editor: PatcherEditor) -> None:
status = "GUI_STATUS_POWERBOMB"
original = get_text(editor, status)
new = original.replace(
Expand Down
2 changes: 1 addition & 1 deletion src/open_samus_returns_rando/patch_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@


def patch_with_status_update(input_path: Path, output_path: Path, configuration: dict,
status_update: typing.Callable[[float, str], None]):
status_update: typing.Callable[[float, str], None]) -> None:
from open_samus_returns_rando.samus_returns_patcher import patch_extracted
# messages depends on the layout but it is a good approximation
total_logs = 410
Expand Down
Loading

0 comments on commit b9aa222

Please sign in to comment.