Skip to content

Commit

Permalink
Start fixing errors reported by mypy
Browse files Browse the repository at this point in the history
  • Loading branch information
fenhl committed Dec 16, 2024
1 parent 2d06302 commit 3cdbca2
Show file tree
Hide file tree
Showing 45 changed files with 1,069 additions and 767 deletions.
39 changes: 23 additions & 16 deletions CI.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,39 @@
from __future__ import annotations

import argparse
from io import StringIO
import json
import os.path
import pathlib
import sys
from typing import Any, NoReturn
import unittest
from io import StringIO
from typing import NoReturn

from Main import resolve_settings
from Messages import ITEM_MESSAGES, KEYSANITY_MESSAGES, MISC_MESSAGES
from Patches import get_override_table, get_override_table_bytes
from Rom import Rom
import Unittest as Tests
from Messages import ITEM_MESSAGES, KEYSANITY_MESSAGES, MISC_MESSAGES
from SettingsList import SettingInfos, logic_tricks, validate_settings
import Unittest as Tests
from Utils import data_path


ERROR_COUNT: int = 0
ANY_FIXABLE_ERRORS: bool = False
ANY_UNFIXABLE_ERRORS: bool = False


def error(msg: str, can_fix: bool) -> None:
if not hasattr(error, "count"):
error.count = 0
global ERROR_COUNT
global ANY_FIXABLE_ERRORS
global ANY_UNFIXABLE_ERRORS

print(msg, file=sys.stderr)
error.count += 1
ERROR_COUNT += 1
if can_fix:
error.can_fix = True
ANY_FIXABLE_ERRORS = True
else:
error.cannot_fix = True
ANY_UNFIXABLE_ERRORS = True


def run_unit_tests() -> None:
Expand Down Expand Up @@ -133,7 +140,7 @@ def check_preset_spoilers(fix_errors: bool = False) -> None:
# This is not a perfect check because it doesn't account for everything that gets manually done in Patches.py
# For that, we perform additional checking at patch time
def check_message_duplicates() -> None:
def check_for_duplicates(new_item_messages: list[tuple[int, str]]) -> None:
def check_for_duplicates(new_item_messages: list[tuple[int, Any]]) -> None:
for i in range(0, len(new_item_messages)):
for j in range(i, len(new_item_messages)):
if i != j:
Expand Down Expand Up @@ -264,22 +271,22 @@ def run_ci_checks() -> NoReturn:
exit_ci(args.fix)

def exit_ci(fix_errors: bool = False) -> NoReturn:
if hasattr(error, "count") and error.count:
print(f'CI failed with {error.count} errors.', file=sys.stderr)
if ERROR_COUNT > 0:
print(f'CI failed with {ERROR_COUNT} errors.', file=sys.stderr)
if fix_errors:
if getattr(error, 'cannot_fix', False):
if ANY_UNFIXABLE_ERRORS:
print('Some errors could not be fixed automatically.', file=sys.stderr)
sys.exit(1)
else:
print('All errors fixed.', file=sys.stderr)
sys.exit(0)
else:
if getattr(error, 'can_fix', False):
if getattr(error, 'can_fix_release', False):
if ANY_FIXABLE_ERRORS:
if ANY_FIXABLE_ERRORS_FOR_RELEASE_CHECKS:
release_arg = ' --release'
else:
release_arg = ''
if getattr(error, 'cannot_fix', False):
if ANY_UNFIXABLE_ERRORS:
which_errors = 'some of these errors'
else:
which_errors = 'these errors'
Expand Down
36 changes: 21 additions & 15 deletions Colors.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
from __future__ import annotations
import sys
import random
import re
from collections import namedtuple

if sys.version_info >= (3, 10):
from typing import TypeAlias
else:
TypeAlias = str

Color = namedtuple('Color', ' R G B')

tunic_colors: dict[str, Color] = {
Expand Down Expand Up @@ -152,7 +158,8 @@

# A Button Text Cursor Shop Cursor Save/Death Cursor
# Pause Menu A Cursor Pause Menu A Icon A Note
a_button_colors: dict[str, tuple[Color, Color, Color, Color, Color, Color, Color]] = {
AButtonColors: TypeAlias = "dict[str, tuple[Color, Color, Color, Color, Color, Color, Color]]"
a_button_colors: AButtonColors = {
"N64 Blue": (Color(0x5A, 0x5A, 0xFF), Color(0x00, 0x50, 0xC8), Color(0x00, 0x50, 0xFF), Color(0x64, 0x64, 0xFF),
Color(0x00, 0x32, 0xFF), Color(0x00, 0x64, 0xFF), Color(0x50, 0x96, 0xFF)),
"N64 Green": (Color(0x00, 0x96, 0x00), Color(0x00, 0x96, 0x00), Color(0x00, 0x96, 0x00), Color(0x64, 0x96, 0x64),
Expand Down Expand Up @@ -208,7 +215,8 @@
}

# C Button Pause Menu C Cursor Pause Menu C Icon C Note
c_button_colors: dict[str, tuple[Color, Color, Color, Color]] = {
CButtonColors: TypeAlias = "dict[str, tuple[Color, Color, Color, Color]]"
c_button_colors: CButtonColors = {
"N64 Blue": (Color(0x5A, 0x5A, 0xFF), Color(0x00, 0x32, 0xFF), Color(0x00, 0x64, 0xFF), Color(0x50, 0x96, 0xFF)),
"N64 Green": (Color(0x00, 0x96, 0x00), Color(0x00, 0x96, 0x00), Color(0x00, 0x96, 0x00), Color(0x00, 0x96, 0x00)),
"N64 Red": (Color(0xC8, 0x00, 0x00), Color(0xC8, 0x00, 0x00), Color(0xC8, 0x00, 0x00), Color(0xC8, 0x00, 0x00)),
Expand Down Expand Up @@ -366,14 +374,14 @@ def get_start_button_color_options() -> list[str]:
return meta_color_choices + get_start_button_colors()


def contrast_ratio(color1: list[int], color2: list[int]) -> float:
def contrast_ratio(color1: Color, color2: Color) -> float:
# Based on accessibility standards (WCAG 2.0)
lum1 = relative_luminance(color1)
lum2 = relative_luminance(color2)
return (max(lum1, lum2) + 0.05) / (min(lum1, lum2) + 0.05)


def relative_luminance(color: list[int]) -> float:
def relative_luminance(color: Color) -> float:
color_ratios = list(map(lum_color_ratio, color))
return color_ratios[0] * 0.299 + color_ratios[1] * 0.587 + color_ratios[2] * 0.114

Expand All @@ -386,23 +394,21 @@ def lum_color_ratio(val: float) -> float:
return pow((val + 0.055) / 1.055, 2.4)


def generate_random_color() -> list[int]:
return [random.getrandbits(8), random.getrandbits(8), random.getrandbits(8)]

def generate_random_color() -> Color:
return Color(random.getrandbits(8), random.getrandbits(8), random.getrandbits(8))

def hex_to_color(option: str) -> list[int]:
if not hasattr(hex_to_color, "regex"):
hex_to_color.regex = re.compile(r'^(?:[0-9a-fA-F]{3}){1,2}$')

HEX_TO_COLOR_REGEX: re.Pattern[str] = re.compile(r'^(?:[0-9a-fA-F]{3}){1,2}$')
def hex_to_color(option: str) -> Color:
# build color from hex code
option = option[1:] if option[0] == "#" else option
if not hex_to_color.regex.search(option):
if not HEX_TO_COLOR_REGEX.search(option):
raise Exception(f"Invalid color value provided: {option}")
if len(option) > 3:
return list(int(option[i:i + 2], 16) for i in (0, 2, 4))
return Color(*(int(option[i:i + 2], 16) for i in (0, 2, 4)))
else:
return list(int(f'{option[i]}{option[i]}', 16) for i in (0, 1, 2))
return Color(*(int(f'{option[i]}{option[i]}', 16) for i in (0, 1, 2)))


def color_to_hex(color: list[int]) -> str:
return '#' + ''.join(['{:02X}'.format(c) for c in color])
def color_to_hex(color: Color) -> str:
return '#' + ''.join('{:02X}'.format(c) for c in color)
Loading

0 comments on commit 3cdbca2

Please sign in to comment.