diff --git a/archeryutils/classifications/classification_utils.py b/archeryutils/classifications/classification_utils.py index 7c61190..c33a249 100644 --- a/archeryutils/classifications/classification_utils.py +++ b/archeryutils/classifications/classification_utils.py @@ -14,6 +14,7 @@ """ import json +from functools import cache from pathlib import Path from typing import Literal, TypedDict @@ -40,17 +41,11 @@ class AGBAgeData(TypedDict): step: int -def read_ages_json( - age_file: Path = Path(__file__).parent / "AGB_ages.json", -) -> dict[str, AGBAgeData]: +@cache +def read_ages_json() -> dict[str, AGBAgeData]: """ Read AGB age categories in from neighbouring json file to list of dicts. - Parameters - ---------- - age_file : Path, default="./AGB_ages.json" - path to json file with age information - Returns ------- ages : list of dict @@ -65,15 +60,17 @@ def read_ages_json( ---------- Archery GB Rules of Shooting """ - with open(age_file, encoding="utf-8") as json_file: - ages = json.load(json_file) - if isinstance(ages, dict): - return ages - msg = ( - f"Unexpected ages input when reading from json file. " - f"Expected dict() but got {type(ages)}. Check {age_file}." - ) - raise TypeError(msg) + age_file = Path(__file__).parent.joinpath("data", "AGB_ages.json") + ages = json.loads(age_file.read_text(encoding="utf-8")) + + if not isinstance(ages, dict): + msg = ( + f"Unexpected ages input when reading from json file. " + f"Expected dict() but got {type(ages)}. Check {age_file}." + ) + raise TypeError(msg) + + return ages class AGBBowstyleData(TypedDict): @@ -94,17 +91,11 @@ class AGBBowstyleData(TypedDict): ageStep_field: float -def read_bowstyles_json( - bowstyles_file: Path = Path(__file__).parent / "AGB_bowstyles.json", -) -> dict[str, AGBBowstyleData]: +@cache +def read_bowstyles_json() -> dict[str, AGBBowstyleData]: """ Read AGB bowstyles in from neighbouring json file to list of dicts. - Parameters - ---------- - bowstyles_file : Path, default="./AGB_bowstyles.json" - path to json file - Returns ------- bowstyles : list of dict @@ -119,28 +110,24 @@ def read_bowstyles_json( ---------- Archery GB Rules of Shooting """ - with open(bowstyles_file, encoding="utf-8") as json_file: - bowstyles = json.load(json_file) - if isinstance(bowstyles, dict): - return bowstyles - msg = ( - f"Unexpected bowstyles input when reading from json file. " - f"Expected dict() but got {type(bowstyles)}. Check {bowstyles_file}." - ) - raise TypeError(msg) + bowstyles_file = Path(__file__).parent.joinpath("data", "AGB_bowstyles.json") + bowstyles = json.loads(bowstyles_file.read_text(encoding="utf-8")) + if not isinstance(bowstyles, dict): + msg = ( + f"Unexpected bowstyles input when reading from json file. " + f"Expected dict() but got {type(bowstyles)}. Check {bowstyles_file}." + ) + raise TypeError(msg) + + return bowstyles -def read_genders_json( - genders_file: Path = Path(__file__).parent / "AGB_genders.json", -) -> list[Literal["Male", "Female"]]: + +@cache +def read_genders_json() -> list[Literal["Male", "Female"]]: """ Read AGB genders in from neighbouring json file to list of dict. - Parameters - ---------- - genders_file : Path, default="./AGB_genders.json" - path to json file - Returns ------- genders : list of str @@ -156,15 +143,17 @@ def read_genders_json( Archery GB Rules of Shooting """ # Read in gender info as list - with open(genders_file, encoding="utf-8") as json_file: - genders = json.load(json_file)["genders"] - if isinstance(genders, list): - return genders - msg = ( - f"Unexpected genders input when reading from json file. " - f"Expected list() but got {type(genders)}. Check {genders_file}." - ) - raise TypeError(msg) + genders_file = Path(__file__).parent.joinpath("data", "AGB_genders.json") + genders = json.loads(genders_file.read_text(encoding="utf-8"))["genders"] + + if not isinstance(genders, list): + msg = ( + f"Unexpected genders input when reading from json file. " + f"Expected list() but got {type(genders)}. Check {genders_file}." + ) + raise TypeError(msg) + + return genders class AGBClassificationData(TypedDict): @@ -175,6 +164,7 @@ class AGBClassificationData(TypedDict): classes_long: list[str] +@cache def read_classes_json( class_system: str, ) -> AGBClassificationData: @@ -203,21 +193,20 @@ def read_classes_json( ---------- Archery GB Rules of Shooting """ - if class_system == "agb_indoor": - filename = "AGB_classes_in.json" - elif class_system == "agb_outdoor": - filename = "AGB_classes_out.json" - elif class_system == "agb_field": + match class_system: + case "agb_indoor": + filename = "AGB_classes_in" # Field classifications are same as outdoor - filename = "AGB_classes_out.json" - else: - msg = ( - "Unexpected classification system specified. " - "Expected one of 'agb_indoor', 'agb_outdoor', 'agb_field'." - ) - raise ValueError(msg) - - classes_file = Path(__file__).parent / filename + case "agb_outdoor" | "agb_field": + filename = "AGB_classes_out" + case _: + msg = ( + "Unexpected classification system specified. " + "Expected one of 'agb_indoor', 'agb_outdoor', 'agb_field'." + ) + raise ValueError(msg) + + classes_file = Path(__file__).parent.joinpath("data", filename).with_suffix(".json") # Read in classification names as dict with open(classes_file, encoding="utf-8") as json_file: diff --git a/archeryutils/classifications/AGB_ages.json b/archeryutils/classifications/data/AGB_ages.json similarity index 100% rename from archeryutils/classifications/AGB_ages.json rename to archeryutils/classifications/data/AGB_ages.json diff --git a/archeryutils/classifications/AGB_bowstyles.json b/archeryutils/classifications/data/AGB_bowstyles.json similarity index 100% rename from archeryutils/classifications/AGB_bowstyles.json rename to archeryutils/classifications/data/AGB_bowstyles.json diff --git a/archeryutils/classifications/AGB_classes_in.json b/archeryutils/classifications/data/AGB_classes_in.json similarity index 100% rename from archeryutils/classifications/AGB_classes_in.json rename to archeryutils/classifications/data/AGB_classes_in.json diff --git a/archeryutils/classifications/AGB_classes_out.json b/archeryutils/classifications/data/AGB_classes_out.json similarity index 100% rename from archeryutils/classifications/AGB_classes_out.json rename to archeryutils/classifications/data/AGB_classes_out.json diff --git a/archeryutils/classifications/AGB_genders.json b/archeryutils/classifications/data/AGB_genders.json similarity index 100% rename from archeryutils/classifications/AGB_genders.json rename to archeryutils/classifications/data/AGB_genders.json diff --git a/pyproject.toml b/pyproject.toml index 9e73ef0..6b6b910 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -77,7 +77,7 @@ include = ["archeryutils", "archeryutils.*"] # package names should match these namespaces = false # to disable scanning PEP 420 namespaces (true by default) [tool.setuptools.package-data] -archeryutils = ["*.json", "round_data_files/*.json", "classifications/*.json"] +archeryutils = ["*.json", "round_data_files/*.json", "classifications/data/*.json"] [tool.mypy] warn_unused_configs = true