diff --git a/config.py b/config.py index ee8b3c5..236167b 100644 --- a/config.py +++ b/config.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import json import re @@ -29,8 +31,9 @@ class Config: def __init__(self, path: str = "config.json") -> None: self.load(path) - - def load(self, path: str) -> None: + + @staticmethod + def load(path: str) -> None: with open(path, "r") as f: config = json.load(f) @@ -39,5 +42,6 @@ class Config: if hasattr(Config, k): setattr(Config, k, v) + @staticmethod def formatKey(key: str) -> str: - return re.sub(r"([a-z])([A-Z])", r"\1_\2", key).upper() \ No newline at end of file + return re.sub(r"([a-z])([A-Z])", r"\1_\2", key).upper() diff --git a/main.py b/main.py index aa01480..64ed5a8 100755 --- a/main.py +++ b/main.py @@ -1,12 +1,13 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- +from __future__ import annotations + import argparse import os from schema import InstructionSetSchema - description = """Examples: - Default theme (black on white): python main.py schema.xml -o out.jpg @@ -25,7 +26,7 @@ description = """Examples: """ -def processFile(inPath, outPath, confPath, display): +def processFile(inPath: str, outPath: str, confPath: str, display: bool) -> None: schema = InstructionSetSchema(inPath, confPath, display) schema.save(outPath) @@ -66,4 +67,4 @@ if __name__ == "__main__": if output is None: output = os.path.splitext(args.schema)[0] + ".png" - processFile(args.schema, output, args.config, args.display) \ No newline at end of file + processFile(args.schema, output, args.config, args.display) diff --git a/range.py b/range.py index 63b4194..e0dcfb9 100644 --- a/range.py +++ b/range.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import Union +from typing import Union, Optional class Range: @@ -9,22 +9,23 @@ class Range: end: int, name: str, description: str = "", - values: dict[str, Union[str, dict]] = None, - dependsOn: str = None) -> None: + values: Optional[dict[str, Union[str, dict]]] = None, + dependsOn: Optional[tuple[int, int]] = None) -> None: - self.start = start - self.end = end - self.name = name - self.description = description - self.values = values - self.dependsOn = dependsOn - self.lastValueY = -1 + self.start: int = start + self.end: int = end + self.name: str = name + self.description: str = description + self.values: Optional[dict[str, Union[str, dict]]] = values + self.dependsOn: Optional[tuple[int, int]] = dependsOn + self.lastValueY: int = -1 @property def bits(self) -> int: return self.end - self.start + 1 - - def load(start: int, end: int, data: dict): + + @staticmethod + def load(start: int, end: int, data: dict) -> Range: values = None bits = end - start + 1 @@ -45,9 +46,11 @@ class Range: values, dependsOn) + @staticmethod def parseSpan(span: str) -> tuple[int, int]: startEnd = span.split("-") - if len(startEnd) == 1: startEnd.append(startEnd[0]) + if len(startEnd) == 1: + startEnd.append(startEnd[0]) start = int(startEnd[1]) end = int(startEnd[0]) - return (start, end) \ No newline at end of file + return (start, end) diff --git a/renderer.py b/renderer.py index 22d5ab8..115dcd3 100644 --- a/renderer.py +++ b/renderer.py @@ -16,17 +16,23 @@ if TYPE_CHECKING: class Renderer: def __init__(self, config: Config, display: bool = False) -> None: - self.config = config - self.display = display + self.config: Config = config + self.display: bool = display pygame.init() if self.display: - self.win = pygame.display.set_mode([self.config.WIDTH, self.config.HEIGHT]) + self.win: pygame.Surface = pygame.display.set_mode([self.config.WIDTH, self.config.HEIGHT]) - self.surf = pygame.Surface([self.config.WIDTH, self.config.HEIGHT], pygame.SRCALPHA) - self.font = pygame.font.SysFont(self.config.DEFAULT_FONT_FAMILY, self.config.DEFAULT_FONT_SIZE) - self.italicFont = pygame.font.SysFont(self.config.ITALIC_FONT_FAMILY, self.config.ITALIC_FONT_SIZE, italic=True) + self.surf: pygame.Surface = pygame.Surface([self.config.WIDTH, self.config.HEIGHT], pygame.SRCALPHA) + + self.font: pygame.font.Font = pygame.font.SysFont( + self.config.DEFAULT_FONT_FAMILY, + self.config.DEFAULT_FONT_SIZE) + + self.italicFont: pygame.font.Font = pygame.font.SysFont( + self.config.ITALIC_FONT_FAMILY, + self.config.ITALIC_FONT_SIZE, italic=True) - self.margins = self.config.MARGINS + self.margins: list[int, int, int, int] = self.config.MARGINS def render(self, schema: InstructionSetSchema) -> None: self.surf.fill(self.config.BACKGROUND_COLOR) @@ -206,8 +212,7 @@ class Renderer: def drawDependency(self, struct: Structure, - structures: dict[str, - Structure], + structures: dict[str, Structure], bitsX: float, bitsY: float, range_: Range, @@ -274,7 +279,7 @@ class Renderer: descY + bitH - arrowMargin) prevDependY = descY + bitH*2 + arrowMargin - prevRangeY =prevDependY + prevRangeY = prevDependY dependRange.lastValueY = prevDependY descY = self.drawStructure(structures[data["structure"]], structures, rStartX, descY) @@ -315,4 +320,4 @@ class Renderer: self.surf.blit(txt, [ (start.x + end.x - txt.get_width())/2, (start.y + end.y)/2 + arrowLabelDist - ]) \ No newline at end of file + ]) diff --git a/schema.py b/schema.py index 54ba976..a4a710c 100644 --- a/schema.py +++ b/schema.py @@ -17,9 +17,10 @@ class InstructionSetSchema: VALID_EXTENSIONS = ("yaml", "json", "xml") def __init__(self, path: str, configPath: str = "config.json", display: bool = False) -> None: - self.config = Config(configPath) - self.display = display - self.path = path + self.config: Config = Config(configPath) + self.display: bool = display + self.path: str = path + self.structures: dict[str, Structure] = {} self.load() def load(self) -> None: @@ -51,4 +52,4 @@ class InstructionSetSchema: renderer.render(self) renderer.save(path) if self.display: - input("Press ENTER to quit") \ No newline at end of file + input("Press ENTER to quit") diff --git a/structure.py b/structure.py index 1bed8a4..2f26469 100644 --- a/structure.py +++ b/structure.py @@ -7,14 +7,15 @@ class Structure: def __init__(self, name: str, bits: int, - ranges: dict[str, Range], + ranges: dict[tuple[int, int], Range], start: int = 0) -> None: - self.name = name - self.bits = bits - self.ranges = ranges - self.start = start - + self.name: str = name + self.bits: int = bits + self.ranges: dict[tuple[int, int], Range] = ranges + self.start: int = start + + @staticmethod def load(id_: str, data: dict) -> Structure: ranges = {} for rSpan, rData in data["ranges"].items(): @@ -34,4 +35,4 @@ class Structure: def getSortedRanges(self) -> list[Range]: ranges = self.ranges.values() - return list(sorted(ranges, key=lambda r: r.end)) \ No newline at end of file + return list(sorted(ranges, key=lambda r: r.end)) diff --git a/vec.py b/vec.py index 6cedfaf..52a6f9c 100644 --- a/vec.py +++ b/vec.py @@ -5,8 +5,8 @@ from math import sqrt class Vec: def __init__(self, x: float = 0, y: float = 0) -> None: - self.x = x - self.y = y + self.x: float = x + self.y: float = y def __add__(self, v: Vec) -> Vec: return Vec(self.x+v.x, self.y+v.y) @@ -25,5 +25,6 @@ class Vec: def norm(self) -> Vec: mag = self.mag() - if mag == 0: return Vec() - return self/mag \ No newline at end of file + if mag == 0: + return Vec() + return self / mag diff --git a/xml_loader.py b/xml_loader.py index e15920e..0ed2a32 100644 --- a/xml_loader.py +++ b/xml_loader.py @@ -7,7 +7,9 @@ from bs4 import BeautifulSoup if TYPE_CHECKING: from io import TextIOWrapper + class XMLLoader: + @staticmethod def load(file_: TextIOWrapper) -> dict: schema = {} bs = BeautifulSoup(file_.read(), "xml") @@ -19,10 +21,12 @@ class XMLLoader: schema["structures"] = structures return schema - + + @staticmethod def parseStructure(structElmt: any) -> dict: - struct = {} - struct["bits"] = structElmt.get("bits") + struct = { + "bits": structElmt.get("bits") + } ranges = {} rangeElmts = structElmt.findAll("range") for rangeElmt in rangeElmts: @@ -32,11 +36,14 @@ class XMLLoader: struct["ranges"] = ranges return struct + @staticmethod def parseRange(rangeElmt: any) -> dict: - range_ = {} - range_["name"] = rangeElmt.get("name") + range_ = { + "name": rangeElmt.get("name") + } desc = rangeElmt.find("description") - if desc is not None: range_["description"] = desc.getText() + if desc is not None: + range_["description"] = desc.getText() valuesElmt = rangeElmt.find("values") if valuesElmt is not None: @@ -47,6 +54,7 @@ class XMLLoader: return range_ + @staticmethod def parseValues(valuesElmt: any) -> dict: values = {} caseElmts = valuesElmt.findAll("case") @@ -64,4 +72,4 @@ class XMLLoader: else: values[val] = desc - return values \ No newline at end of file + return values