From 4dc3a6892ae268be8c19d99bcb0656ad24504cfa Mon Sep 17 00:00:00 2001 From: jan Date: Thu, 13 Jul 2023 13:16:01 -0700 Subject: [PATCH] modernize type annotations --- g85/main.py | 35 +++++++++++++++++------------------ g85/read.py | 14 +++++++------- g85/write.py | 33 ++++++++++++++++----------------- 3 files changed, 40 insertions(+), 42 deletions(-) diff --git a/g85/main.py b/g85/main.py index bc0fbc6..203c570 100644 --- a/g85/main.py +++ b/g85/main.py @@ -1,4 +1,3 @@ -from typing import Dict, List, Tuple, Union, Optional import datetime from collections import Counter from dataclasses import dataclass, field @@ -8,25 +7,25 @@ from itertools import chain @dataclass class Device: BinType: str - NullBin: Union[str, int] - ProductId: Optional[str] = None - LotId: Optional[str] = None - WaferSize: Optional[float] = None - CreateDate: Optional[datetime.datetime] = None - DeviceSizeX: Optional[float] = None - DeviceSizeY: Optional[float] = None - SupplierName: Optional[str] = None - OriginLocation: Optional[int] = None + NullBin: str | int + ProductId: str | None = None + LotId: str | None = None + WaferSize: float | None = None + CreateDate: datetime.datetime | None = None + DeviceSizeX: float | None = None + DeviceSizeY: float | None = None + SupplierName: str | None = None + OriginLocation: int | None = None MapType: str = 'Array' Orientation: float = 0 - reference_xy: Optional[Tuple[int, int]] = None + reference_xy: tuple[int, int] | None = None - bin_pass: Dict[Union[int, str], bool] = field(default_factory=dict) # Is this bin passing? - map: Union[List[List[int]], List[List[str]]] = field(default_factory=list) # The actual map + bin_pass: dict[int | str, bool] = field(default_factory=dict) # Is this bin passing? + map: list[list[int]] | list[list[str]] = field(default_factory=list) # The actual map # Map attribs: MapName, MapVersion # SupplierData attribs: ProductCode, RecipeName - misc: Dict[str, str] = field(default_factory=dict) # Any unexpected fields go here + misc: dict[str, str] = field(default_factory=dict) # Any unexpected fields go here @property def Rows(self) -> int: @@ -46,9 +45,9 @@ class Device: class Map: xmlns: str = 'http://www.semi.org' FormatRevision: str = "SEMI G85 0703" - SubstrateType: Optional[str] = None - SubstrateId: Optional[str] = None + SubstrateType: str | None = None + SubstrateId: str | None = None - devices: List[Device] = field(default_factory=list) - misc: Dict[str, str] = field(default_factory=dict) # Any unexpected fields go here + devices: list[Device] = field(default_factory=list) + misc: dict[str, str] = field(default_factory=dict) # Any unexpected fields go here diff --git a/g85/read.py b/g85/read.py index 6783484..987bff7 100644 --- a/g85/read.py +++ b/g85/read.py @@ -1,4 +1,4 @@ -from typing import List, Union, TextIO, Any +from typing import TextIO, Any import logging import datetime from dataclasses import fields @@ -10,7 +10,7 @@ from .main import Map, Device logger = logging.getLogger(__name__) -def read(stream: TextIO) -> List[Map]: +def read(stream: TextIO) -> list[Map]: tree = ElementTree.parse(stream) el_root = tree.getroot() @@ -21,7 +21,7 @@ def read(stream: TextIO) -> List[Map]: return maps -def read_wmaps(el_root: ElementTree.Element) -> List[Map]: +def read_wmaps(el_root: ElementTree.Element) -> list[Map]: map_fields = [ff.name for ff in fields(Map)] maps = [] for el_map in el_root: @@ -41,7 +41,7 @@ def read_wmaps(el_root: ElementTree.Element) -> List[Map]: return maps -def read_devices(el_map: ElementTree.Element) -> List[Device]: +def read_devices(el_map: ElementTree.Element) -> list[Device]: dev_fields = [ff.name for ff in fields(Device)] devices = [] for el_device in el_map: @@ -50,7 +50,7 @@ def read_devices(el_map: ElementTree.Element) -> List[Device]: continue bin_type = el_device.attrib['BinType'] - null_bin: Union[int, str] + null_bin: int | str if bin_type == 'Decimal': null_bin = int(el_device.attrib['NullBin']) else: @@ -108,7 +108,7 @@ def read_devices(el_map: ElementTree.Element) -> List[Device]: device.bin_pass[bin_code] = attrib['BinQuality'].lower() == 'pass' elif tag == 'Data': data_strs = [read_row(rr) for rr in el_entry] - data: Union[List[List[str]], List[List[int]]] + data: list[list[str]] | list[list[int]] if device.BinType == 'Decimal': data = [[int(vv) for vv in rr] for rr in data_strs] else: @@ -118,7 +118,7 @@ def read_devices(el_map: ElementTree.Element) -> List[Device]: return devices -def read_row(el_row: ElementTree.Element) -> List[str]: +def read_row(el_row: ElementTree.Element) -> list[str]: assert _tag(el_row) == 'Row' row_stripped = (el_row.text or '').strip() diff --git a/g85/write.py b/g85/write.py index f7cb384..4aa1bcd 100644 --- a/g85/write.py +++ b/g85/write.py @@ -1,4 +1,4 @@ -from typing import Sequence, Tuple, List, TextIO, Union +from typing import Sequence, TextIO, cast import logging import math from dataclasses import fields @@ -113,26 +113,25 @@ def write_devices(devices: Sequence[Device], el_map: ElementTree.Element) -> Non el_device.set(key, value) -def prepare_data(data: List[List[Union[str, int]]], decimal: bool) -> Tuple[List[str], int]: +def prepare_data(data: list[list[str]] | list[list[int]], decimal: bool) -> tuple[list[str], int]: is_char = isinstance(data[0][0], str) - if is_char: - char_len = len(data[0][0]) - else: - max_value = max(max(rr) for rr in data) - max_digits = math.ceil(math.log10(max_value)) - row_texts = [] - for row in data: - if is_char and char_len == 1: - row_text = ''.join(row) - elif is_char: - row_text = ' '.join(row) + ' ' - else: - row_text = ' '.join(str(vv).zfill(max_digits) for vv in row) + ' ' - row_texts.append(row_text) - if is_char: + data = cast(list[list[str]], data) + char_len = len(data[0][0]) + for srow in data: + if char_len == 1: + row_text = ''.join(srow) + else: + row_text = ' '.join(srow) + ' ' + row_texts.append(row_text) return row_texts, char_len else: + data = cast(list[list[int]], data) + max_value = max(max(rr) for rr in data) + max_digits = math.ceil(math.log10(max_value)) + for irow in data: + row_text = ' '.join(str(vv).zfill(max_digits) for vv in irow) + ' ' + row_texts.append(row_text) return row_texts, max_digits